//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006 Valerio Proietti, <http://mad4milk.net>, MIT Style License.

var Class = function(properties){
    var klass = function(){
        for (var p in this){
            if (this[p]) this[p]._proto_ = this;
        }
        if (arguments[0] != 'noinit' && this.initialize) return this.initialize.apply(this, arguments);
    };
    klass.extend = this.extend;
    klass.implement = this.implement;
    klass.prototype = properties;
    return klass;
};

Class.empty = function(){};

Class.create = function(properties){
    return new Class(properties);
};

Class.prototype = {

    extend: function(properties){
        var pr0t0typ3 = new this('noinit');
        for (var property in properties){
            var previous = pr0t0typ3[property];
            var current = properties[property];
            if (previous && previous != current) current = previous.parentize(current) || current;
            pr0t0typ3[property] = current;
        }
        return new Class(pr0t0typ3);
    },

    implement: function(properties){
        for (var property in properties) this.prototype[property] = properties[property];
    }

};

Object.extend = function(){
    var args = arguments;
    if (args[1]) args = [args[0], args[1]];
    else args = [this, args[0]];
    for (var property in args[1]) args[0][property] = args[1][property];
    return args[0];
};

Object.Native = function(){
    for (var i = 0; i < arguments.length; i++) arguments[i].extend = Class.prototype.implement;
};

new Object.Native(Function, Array, String, Number);

Function.extend({

    parentize: function(current){
        var previous = this;
        return function(){
            this.parent = previous;
            return current.apply(this, arguments);
        };
    }

});

Function.extend({

    pass: function(args, bind){
        var fn = this;
        if ($type(args) != 'array') args = [args];
        return function(){
            return fn.apply(bind || fn._proto_ || fn, args);
        };
    },

    bind: function(bind){
        var fn = this;
        return function(){
            return fn.apply(bind, arguments);
        };
    },

    bindAsEventListener: function(bind){
        var fn = this;
        return function(event){
            fn.call(bind, event || window.event);
            return false;
        };
    },

    delay: function(ms, bind){
        return setTimeout(this.bind(bind || this._proto_ || this), ms);
    },

    periodical: function(ms, bind){
        return setInterval(this.bind(bind || this._proto_ || this), ms);
    }

});

function $clear(timer){
    clearTimeout(timer);
    clearInterval(timer);
    return null;
};

function $type(obj){
    if (!obj) return false;
    var type = false;
    if (obj instanceof Function) type = 'function';
    else if (obj.nodeName){
        if (obj.nodeType == 3 && !/\S/.test(obj.nodeValue)) type = 'textnode';
        else if (obj.nodeType == 1) type = 'element';
    }
    else if (obj instanceof Array) type = 'array';
    else if (typeof obj == 'object') type = 'object';
    else if (typeof obj == 'string') type = 'string';
    else if (typeof obj == 'number' && isFinite(obj)) type = 'number';
    return type;
};

var Chain = new Class({

    chain: function(fn){
        this.chains = this.chains || [];
        this.chains.push(fn);
        return this;
    },

    callChain: function(){
        if (this.chains && this.chains.length) this.chains.splice(0, 1)[0].delay(10, this);
    },

    clearChain: function(){
        this.chains = [];
    }

});

if (!Array.prototype.forEach){

    Array.prototype.forEach = function(fn, bind){
        for(var i = 0; i < this.length ; i++) fn.call(bind, this[i], i);
    };
}

Array.extend({

    each: Array.prototype.forEach,

    copy: function(){
        var newArray = [];
        for (var i = 0; i < this.length; i++) newArray.push(this[i]);
        return newArray;
    },

    remove: function(item){
        for (var i = 0; i < this.length; i++){
            if (this[i] == item) this.splice(i, 1);
        }
        return this;
    },

    test: function(item){
        for (var i = 0; i < this.length; i++){
            if (this[i] == item) return true;
        };
        return false;
    },

    extend: function(newArray){
        for (var i = 0; i < newArray.length; i++) this.push(newArray[i]);
        return this;
    },

    associate: function(keys){
        var newArray = [];
        for (var i =0; i < this.length; i++) newArray[keys[i]] = this[i];
        return newArray;
    }

});

function $A(array){
    return Array.prototype.copy.call(array);
};

String.extend({

    test: function(regex, params){
        return this.match(new RegExp(regex, params));
    },
    toInt: function(){
        return parseInt(this);
    },

    camelCase: function(){
        return this.replace(/-\D/gi, function(match){
            return match.charAt(match.length - 1).toUpperCase();
        });
    },
    capitalize: function(){
        return this.toLowerCase().replace(/\b[a-z]/g, function(match){
            return match.toUpperCase();
        });
    },

    trim: function(){
        return this.replace(/^\s*|\s*$/g, '');
    },

    clean: function(){
        return this.replace(/\s\s/g, ' ').trim();
    },

    rgbToHex: function(array){
        var rgb = this.test('([\\d]{1,3})', 'g');
        if (rgb[3] == 0) return 'transparent';
        var hex = [];
        for (var i = 0; i < 3; i++){
            var bit = (rgb[i]-0).toString(16);
            hex.push(bit.length == 1 ? '0'+bit : bit);
        }
        var hexText = '#'+hex.join('');
        if (array) return hex;
        else return hexText;
    },

    hexToRgb: function(array){
        var hex = this.test('^[#]{0,1}([\\w]{1,2})([\\w]{1,2})([\\w]{1,2})$');
        var rgb = [];
        for (var i = 1; i < hex.length; i++){
            if (hex[i].length == 1) hex[i] += hex[i];
            rgb.push(parseInt(hex[i], 16));
        }
        var rgbText = 'rgb('+rgb.join(',')+')';
        if (array) return rgb;
        else return rgbText;
    }

});

Number.extend({

    toInt: function(){
        return this;
    }

});

var Element = new Class({

    initialize: function(el){
        if ($type(el) == 'string') el = document.createElement(el);
        return $(el);
    },

    inject: function(el, where){
        el = $(el) || new Element(el);
        switch(where){
            case "before": $(el.parentNode).insertBefore(this, el); break;
            case "after": {
                    if (!el.getNext()) $(el.parentNode).appendChild(this);
                    else $(el.parentNode).insertBefore(this, el.getNext());
            } break;
            case "inside": el.appendChild(this); break;
        }
        return this;
    },

    injectBefore: function(el){
        return this.inject(el, 'before');
    },

    injectAfter: function(el){
        return this.inject(el, 'after');
    },

    injectInside: function(el){
        return this.inject(el, 'inside');
    },

    adopt: function(el){
        this.appendChild($(el) || new Element(el));
        return this;
    },

    remove: function(){
        this.parentNode.removeChild(this);
    },

    clone: function(contents){
        return $(this.cloneNode(contents || true));
    },

    replaceWith: function(el){
        var el = $(el) || new Element(el);
        this.parentNode.replaceChild(el, this);
        return el;
    },

    appendText: function(text){
        if (this.getTag() == 'style' && window.ActiveXObject) this.styleSheet.cssText = text;
        else this.appendChild(document.createTextNode(text));
        return this;
    },

    hasClass: function(className){
        return !!this.className.test("\\b"+className+"\\b");
    },

    addClass: function(className){
        if (!this.hasClass(className)) this.className = (this.className+' '+className.trim()).clean();
        return this;
    },

    removeClass: function(className){
        if (this.hasClass(className)) this.className = this.className.replace(className.trim(), '').clean();
        return this;
    },

    toggleClass: function(className){
        if (this.hasClass(className)) return this.removeClass(className);
        else return this.addClass(className);
    },

    setStyle: function(property, value){
        if (property == 'opacity') this.setOpacity(parseFloat(value));
        else this.style[property.camelCase()] = value;
        return this;
    },

    setStyles: function(source){
        if ($type(source) == 'object') {
            for (var property in source) this.setStyle(property, source[property]);
        } else if ($type(source) == 'string') {
            if (window.ActiveXObject) this.cssText = source;
            else this.setAttribute('style', source);
        }
        return this;
    },

    setOpacity: function(opacity){
        if (opacity == 0){
            if(this.style.visibility != "hidden") this.style.visibility = "hidden";
        } else {
            if(this.style.visibility != "visible") this.style.visibility = "visible";
        }
        if (window.ActiveXObject) this.style.filter = "alpha(opacity=" + opacity*100 + ")";
        this.style.opacity = opacity;
        return this;
    },

    getStyle: function(property){
        var proPerty = property.camelCase();
        var style = this.style[proPerty] || false;
        if (!style) {
            if (document.defaultView) style = document.defaultView.getComputedStyle(this,null).getPropertyValue(property);
            else if (this.currentStyle) style = this.currentStyle[proPerty];
        }
        if (style && ['color', 'backgroundColor', 'borderColor'].test(proPerty) && style.test('rgb')) style = style.rgbToHex();
        return style;
    },

    addEvent: function(action, fn){
        this[action+fn] = fn.bind(this);
        if (this.addEventListener) this.addEventListener(action, fn, false);
        else this.attachEvent('on'+action, this[action+fn]);
        var el = this;
        if (this != window) Unload.functions.push(function(){
            el.removeEvent(action, fn);
            el[action+fn] = null;
        });
        return this;
    },

    removeEvent: function(action, fn){
        if (this.removeEventListener) this.removeEventListener(action, fn, false);
        else this.detachEvent('on'+action, this[action+fn]);
        return this;
    },

    getBrother: function(what){
        var el = this[what+'Sibling'];
        while ($type(el) == 'textnode') el = el[what+'Sibling'];
        return $(el);
    },

    getPrevious: function(){
        return this.getBrother('previous');
    },

    getNext: function(){
        return this.getBrother('next');
    },

    getFirst: function(){
        var el = this.firstChild;
        while ($type(el) == 'textnode') el = el.nextSibling;
        return $(el);
    },

    getLast: function(){
        var el = this.lastChild;
        while ($type(el) == 'textnode')
        el = el.previousSibling;
        return $(el);
    },

    setProperty: function(property, value){
        var el = false;
        switch(property){
            case 'class': this.className = value; break;
            case 'style': this.setStyles(value); break;
            case 'name': if (window.ActiveXObject && this.getTag() == 'input'){
                el = $(document.createElement('<input name="'+value+'" />'));
                $A(this.attributes).each(function(attribute){
                    if (attribute.name != 'name') el.setProperty(attribute.name, attribute.value);

                });
                if (this.parentNode) this.replaceWith(el);
            };
            default: this.setAttribute(property, value);
        }
        return el || this;
    },

    setProperties: function(source){
        for (var property in source) this.setProperty(property, source[property]);
        return this;
    },

    setHTML: function(html){
        this.innerHTML = html;
        return this;
    },

    getProperty: function(property){
        return this.getAttribute(property);
    },

    getTag: function(){
        return this.tagName.toLowerCase();
    },

    getOffset: function(what){
        what = what.capitalize();
        var el = this;
        var offset = 0;
        do {
            offset += el['offset'+what] || 0;
            el = el.offsetParent;
        } while (el);
        return offset;
    },

    getTop: function(){
        return this.getOffset('top');
    },

    getLeft: function(){
        return this.getOffset('left');
    },

    getValue: function(){
        var value = false;
        switch(this.getTag()){
            case 'select': value = this.getElementsByTagName('option')[this.selectedIndex].value; break;
            case 'input': if ( (this.checked && ['checkbox', 'radio'].test(this.type)) || (['hidden', 'text', 'password'].test(this.type)) )
                value = this.value; break;
            case 'textarea': value = this.value;
        }
        return value;
    }

});

new Object.Native(Element);

Element.extend({
    hasClassName: Element.prototype.hasClass,
    addClassName: Element.prototype.addClass,
    removeClassName: Element.prototype.removeClass,
    toggleClassName: Element.prototype.toggleClass
});

function $Element(el, method, args){
    if ($type(args) != 'array') args = [args];
    return Element.prototype[method].apply(el, args);
};

function $(el){
    if ($type(el) == 'string') el = document.getElementById(el);
    if ($type(el) == 'element'){
        if (!el.extend){
            Unload.elements.push(el);
            el.extend = Object.extend;
            el.extend(Element.prototype);
        }
        return el;
    } else return false;
};

window.addEvent = document.addEvent = Element.prototype.addEvent;
window.removeEvent = document.removeEvent = Element.prototype.removeEvent;

var Unload = {

    elements: [], functions: [], vars: [],

    unload: function(){
        Unload.functions.each(function(fn){
            fn();
        });

        window.removeEvent('unload', window.removeFunction);

        Unload.elements.each(function(el){
            for(var p in Element.prototype){
                window[p] = null;
                document[p] = null;
                el[p] = null;
            }
            el.extend = null;
        });
    }

};

window.removeFunction = Unload.unload;
window.addEvent('unload', window.removeFunction);
var Fx = fx = {};

Fx.Base = new Class({

    setOptions: function(options){
        this.options = Object.extend({
            onStart: Class.empty,
            onComplete: Class.empty,
            transition: Fx.Transitions.sineInOut,
            duration: 500,
            unit: 'px',
            wait: true,
            fps: 50
        }, options || {});
    },

    step: function(){
        var time = new Date().getTime();
        // BEGIN change
        if (time < this.time + this.options.duration + this.pauseOffset){
            this.cTime = time - this.time - this.pauseOffset;
        // END change
            this.setNow();
        } else {
            this.options.onComplete.pass(this.element, this).delay(10);
            this.isComplete = true;
            this.clearTimer();
            this.callChain();
            this.now = this.to;
        }
        this.increase();
    },

    set: function(to){
        this.now = to;
        this.increase();
        return this;
    },

    setNow: function(){
        this.now = this.compute(this.from, this.to);
    },

    compute: function(from, to){
        return this.options.transition(this.cTime, from, (to - from), this.options.duration);
    },

    custom: function(from, to){
        if (!this.options.wait) this.clearTimer();
        if (this.timer) return;
        this.options.onStart.pass(this.element, this).delay(10);
        this.from = from;
        this.to = to;
        this.time = new Date().getTime();
        // BEGIN change
        this.isStarted = true;
        this.isComplete = false;
        this.pauseOffset = 0;
        this.set(from);
        // END change
        this.timer = this.step.periodical(Math.round(1000/this.options.fps), this);
        return this;
    },

    clearTimer: function(){
        this.timer = $clear(this.timer);
        // BEGIN change
        if (!this.stopTime && !this.isComplete) {
            this.stopTime = new Date().getTime();
        }
        // END change
        return this;
    },

    // BEGIN change
    start: function(from, to) { this.custom(from, to); },
    stop: function() { this.clearTimer(); },

    resume: function(){
        if (this.stopTime && !this.isComplete) {
            this.pauseOffset += new Date().getTime() - this.stopTime;
            this.stopTime = 0;
            this.timer = this.step.periodical(Math.round(1000/this.options.fps), this);
        }
        return this;
    },
    // END change

    setStyle: function(element, property, value){
        element.setStyle(property, value + this.options.unit);
    }

});

Fx.Base.implement(new Chain);

Fx.Style = Fx.Base.extend({

    initialize: function(el, property, options){
        this.element = $(el);
        this.setOptions(options);
        this.property = property.camelCase();
    },

    hide: function(){
        return this.set(0);
    },

    goTo: function(val){
        return this.custom(this.now || 0, val);
    },

    increase: function(){
        this.setStyle(this.element, this.property, this.now);
    }

});

Fx.Styles = Fx.Base.extend({

    initialize: function(el, options){
        this.element = $(el);
        this.setOptions(options);
        this.now = {};
    },

    setNow: function(){
        for (var p in this.from) this.now[p] = this.compute(this.from[p], this.to[p]);
    },

    custom: function(objFromTo){
        if (this.timer && this.options.wait) return;
        var from = {};
        var to = {};
        for (var p in objFromTo){
            from[p] = objFromTo[p][0];
            to[p] = objFromTo[p][1];
        }
        return this.parent(from, to);
    },

    increase: function(){
        for (var p in this.now) this.setStyle(this.element, p, this.now[p]);
    }

});

Element.extend({

    effect: function(property, options){
        return new Fx.Style(this, property, options);
    },

    effects: function(options){
        return new Fx.Styles(this, options);
    }

});

Fx.Transitions = {
    linear: function(t, b, c, d){
        return c*t/d + b;
    },
    sineInOut: function(t, b, c, d){
        return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
    }

};

var Ajax = ajax = new Class({

    setOptions: function(options){
        this.options = {
            method: 'post',
            postBody: null,
            async: true,
            onComplete: Class.empty,
            onStateChange: Class.empty,
            update: null,
            evalScripts: false
        };
        Object.extend(this.options, options || {});
    },

    initialize: function(url, options){
        this.setOptions(options);
        this.url = url;
        this.transport = this.getTransport();
    },

    request: function(){
        this.transport.open(this.options.method, this.url, this.options.async);
        this.transport.onreadystatechange = this.onStateChange.bind(this);
        if (this.options.method == 'post'){
            this.transport.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
            if (this.transport.overrideMimeType) this.transport.setRequestHeader('Connection', 'close');
        }
        switch($type(this.options.postBody)){
            case 'element': this.options.postBody = $(this.options.postBody).toQueryString(); break;
            case 'object': this.options.postBody = Object.toQueryString(this.options.postBody);
        }
        if($type(this.options.postBody) == 'string') this.transport.send(this.options.postBody);
        else this.transport.send(null);
        return this;
    },

    onStateChange: function(){
        this.options.onStateChange.delay(10, this);
        if (this.transport.readyState == 4 && this.transport.status == 200){
            if (this.options.update) $(this.options.update).setHTML(this.transport.responseText);
            this.options.onComplete.pass([this.transport.responseText, this.transport.responseXML], this).delay(20);
            if (this.options.evalScripts) this.evalScripts.delay(30, this);
            this.transport.onreadystatechange = Class.empty;
            this.callChain();
        }
    },

    evalScripts: function(){
        if(scripts = this.transport.responseText.match(/<script[^>]*?>[\S\s]*?<\/script>/g)){
            scripts.each(function(script){
                eval(script.replace(/^<script[^>]*?>/, '').replace(/<\/script>$/, ''));
            });
        }
    },

    getTransport: function(){
        if (window.XMLHttpRequest) return new XMLHttpRequest();
        else if (window.ActiveXObject) return new ActiveXObject('Microsoft.XMLHTTP');
    }

});

// BEGIN change
Ajax.implement({
    initialize: function(url, options){
        this.setOptions(options);
        this.url = url;
        this.transport = this.getTransport();
        this.tried = 0;
    },
    responseIsSuccess: function(status){
        try {
            if(this.transport.readyState != 4 ||
                 this.transport.status == "undefined" ||
                (this.transport.status < 200 || this.transport.status >= 300))
                    return false;
            return true;
        } catch(e) {
            return false;
        }
    },
    responseIsFailure: function(){
        return !this.responseIsSuccess();
    },
    onStateChange: function(){
        if (this.transport.readyState == 4 && this.responseIsSuccess()){
            if (this.options.update) $(this.options.update).setHTML(this.transport.responseText);
            this.options.onComplete.pass([this.transport.responseText, this.transport.responseXML], this).delay(20);
            if (this.options.evalScripts) this.evalScripts.delay(30, this);
            this.transport.onreadystatechange = Class.empty;
            this.callChain();
        } else if(this.transport.readyState == 4 && this.responseIsFailure()) {
            if($type(this.options.onFailure)=='function') this.options.onFailure.pass(this.transport, this).delay(20);
        }
    }
});
// END change

Ajax.implement(new Chain);

Object.toQueryString = function(source){
    var queryString = [];
    for (var property in source) queryString.push(encodeURIComponent(property)+'='+encodeURIComponent(source[property]));
    return queryString.join('&');
};

Element.extend({

    send: function(options){
        options = Object.extend(options, {postBody: this.toQueryString(), method: 'post'});
        return new Ajax(this.getProperty('action'), options).request();
    },

    toQueryString: function(){
        var queryString = [];
        $A(this.getElementsByTagName('*')).each(function(el){
            var name = $(el).name;
            var value = el.getValue();
            if (value && name) queryString.push(encodeURIComponent(name)+'='+encodeURIComponent(value));
        });
        return queryString.join('&');
    }

});

Fx.Transitions = {
    linear: function(t, b, c, d){
        return c*t/d + b;
    },
    quadIn: function(t, b, c, d){
        return c*(t/=d)*t + b;
    },
    quadOut: function(t, b, c, d){
        return -c *(t/=d)*(t-2) + b;
    },
    quadInOut: function(t, b, c, d){
        if ((t/=d/2) < 1) return c/2*t*t + b;
        return -c/2 * ((--t)*(t-2) - 1) + b;
    },
    cubicIn: function(t, b, c, d){
        return c*(t/=d)*t*t + b;
    },
    cubicOut: function(t, b, c, d){
        return c*((t=t/d-1)*t*t + 1) + b;
    },
    cubicInOut: function(t, b, c, d){
        if ((t/=d/2) < 1) return c/2*t*t*t + b;
        return c/2*((t-=2)*t*t + 2) + b;
    },
    quartIn: function(t, b, c, d){
        return c*(t/=d)*t*t*t + b;
    },
    quartOut: function(t, b, c, d){
        return -c * ((t=t/d-1)*t*t*t - 1) + b;
    },
    quartInOut: function(t, b, c, d){
        if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
        return -c/2 * ((t-=2)*t*t*t - 2) + b;
    },
    quintIn: function(t, b, c, d){
        return c*(t/=d)*t*t*t*t + b;
    },
    quintOut: function(t, b, c, d){
        return c*((t=t/d-1)*t*t*t*t + 1) + b;
    },
    quintInOut: function(t, b, c, d){
        if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
        return c/2*((t-=2)*t*t*t*t + 2) + b;
    },
    sineIn: function(t, b, c, d){
        return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
    },
    sineOut: function(t, b, c, d){
        return c * Math.sin(t/d * (Math.PI/2)) + b;
    },
    sineInOut: function(t, b, c, d){
        return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
    },
    expoIn: function(t, b, c, d){
        return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
    },
    expoOut: function(t, b, c, d){
        return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
    },
    expoInOut: function(t, b, c, d){
        if (t==0) return b;
        if (t==d) return b+c;
        if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
        return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
    },
    circIn: function(t, b, c, d){
        return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
    },
    circOut: function(t, b, c, d){
        return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
    },
    circInOut: function(t, b, c, d){
        if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
        return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
    },
    elasticIn: function(t, b, c, d, a, p){
        if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3; if (!a) a = 1;
        if (a < Math.abs(c)){ a=c; var s=p/4; }
        else var s = p/(2*Math.PI) * Math.asin(c/a);
        return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
    },
    elasticOut: function(t, b, c, d, a, p){
        if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3; if (!a) a = 1;
        if (a < Math.abs(c)){ a=c; var s=p/4; }
        else var s = p/(2*Math.PI) * Math.asin(c/a);
        return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
    },
    elasticInOut: function(t, b, c, d, a, p){
        if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5); if (!a) a = 1;
        if (a < Math.abs(c)){ a=c; var s=p/4; }
        else var s = p/(2*Math.PI) * Math.asin(c/a);
        if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
        return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
    },
    backIn: function(t, b, c, d, s){
        if (!s) s = 1.70158;
        return c*(t/=d)*t*((s+1)*t - s) + b;
    },
    backOut: function(t, b, c, d, s){
        if (!s) s = 1.70158;
        return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
    },
    backInOut: function(t, b, c, d, s){
        if (!s) s = 1.70158;
        if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
        return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
    },
    bounceIn: function(t, b, c, d){
        return c - Fx.Transitions.bounceOut (d-t, 0, c, d) + b;
    },
    bounceOut: function(t, b, c, d){
        if ((t/=d) < (1/2.75)){
            return c*(7.5625*t*t) + b;
        } else if (t < (2/2.75)){
            return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
        } else if (t < (2.5/2.75)){
            return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
        } else {
            return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
        }
    },
    bounceInOut: function(t, b, c, d){
        if (t < d/2) return Fx.Transitions.bounceIn(t*2, 0, c, d) * .5 + b;
        return Fx.Transitions.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
    }

};