// All-in-one for kishlery.com 16/03/2010 11:04:05
// Here starts http://ajax.googleapis.com/ajax/libs/mootools/1.2.4/mootools-yui-compressed.js
//MooTools, <http://mootools.net>, My Object Oriented (JavaScript) Tools. Copyright (c) 2006-2009 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
var MooTools = {
    version: "1.2.4",
    build: "0d9113241a90b9cd5643b926795852a2026710d4"
};
var Native = function (k) {
    k = k || {};
    var a = k.name;
    var i = k.legacy;
    var b = k.protect;
    var c = k.implement;
    var h = k.generics;
    var f = k.initialize;
    var g = k.afterImplement ||
    function () {};
    var d = f || i;
    h = h !== false;
    d.constructor = Native;
    d.$family = {
        name: "native"
    };
    if (i && f) {
        d.prototype = i.prototype;
    }
    d.prototype.constructor = d;
    if (a) {
        var e = a.toLowerCase();
        d.prototype.$family = {
            name: e
        };
        Native.typize(d, e);
    }
    var j = function (n, l, o, m) {
        if (!b || m || !n.prototype[l]) {
            n.prototype[l] = o;
        }
        if (h) {
            Native.genericize(n, l, b);
        }
        g.call(n, l, o);
        return n;
    };
    d.alias = function (n, l, p) {
        if (typeof n == "string") {
            var o = this.prototype[n];
            if ((n = o)) {
                return j(this, l, n, p);
            }
        }
        for (var m in n) {
            this.alias(m, n[m], l);
        }
        return this;
    };
    d.implement = function (m, l, o) {
        if (typeof m == "string") {
            return j(this, m, l, o);
        }
        for (var n in m) {
            j(this, n, m[n], l);
        }
        return this;
    };
    if (c) {
        d.implement(c);
    }
    return d;
};
Native.genericize = function (b, c, a) {
    if ((!a || !b[c]) && typeof b.prototype[c] == "function") {
        b[c] = function () {
            var d = Array.prototype.slice.call(arguments);
            return b.prototype[c].apply(d.shift(), d);
        };
    }
};
Native.implement = function (d, c) {
    for (var b = 0, a = d.length; b < a; b++) {
        d[b].implement(c);
    }
};
Native.typize = function (a, b) {
    if (!a.type) {
        a.type = function (c) {
            return ($type(c) === b);
        };
    }
};
(function () {
    var a = {
        Array: Array,
        Date: Date,
        Function: Function,
        Number: Number,
        RegExp: RegExp,
        String: String
    };
    for (var h in a) {
        new Native({
            name: h,
            initialize: a[h],
            protect: true
        });
    }
    var d = {
        "boolean": Boolean,
        "native": Native,
        object: Object
    };
    for (var c in d) {
        Native.typize(d[c], c);
    }
    var f = {
        Array: ["concat", "indexOf", "join", "lastIndexOf", "pop", "push", "reverse", "shift", "slice", "sort", "splice", "toString", "unshift", "valueOf"],
        String: ["charAt", "charCodeAt", "concat", "indexOf", "lastIndexOf", "match", "replace", "search", "slice", "split", "substr", "substring", "toLowerCase", "toUpperCase", "valueOf"]
    };
    for (var e in f) {
        for (var b = f[e].length; b--;) {
            Native.genericize(a[e], f[e][b], true);
        }
    }
})();
var Hash = new Native({
    name: "Hash",
    initialize: function (a) {
        if ($type(a) == "hash") {
            a = $unlink(a.getClean());
        }
        for (var b in a) {
            this[b] = a[b];
        }
        return this;
    }
});
Hash.implement({
    forEach: function (b, c) {
        for (var a in this) {
            if (this.hasOwnProperty(a)) {
                b.call(c, this[a], a, this);
            }
        }
    },
    getClean: function () {
        var b = {};
        for (var a in this) {
            if (this.hasOwnProperty(a)) {
                b[a] = this[a];
            }
        }
        return b;
    },
    getLength: function () {
        var b = 0;
        for (var a in this) {
            if (this.hasOwnProperty(a)) {
                b++;
            }
        }
        return b;
    }
});
Hash.alias("forEach", "each");
Array.implement({
    forEach: function (c, d) {
        for (var b = 0, a = this.length; b < a; b++) {
            c.call(d, this[b], b, this);
        }
    }
});
Array.alias("forEach", "each");

function $A(b) {
    if (b.item) {
        var a = b.length,
            c = new Array(a);
        while (a--) {
                c[a] = b[a];
            }
        return c;
    }
    return Array.prototype.slice.call(b);
}
function $arguments(a) {
    return function () {
        return arguments[a];
    };
}
function $chk(a) {
    return !!(a || a === 0);
}
function $clear(a) {
    clearTimeout(a);
    clearInterval(a);
    return null;
}
function $defined(a) {
    return (a != undefined);
}
function $each(c, b, d) {
    var a = $type(c);
    ((a == "arguments" || a == "collection" || a == "array") ? Array : Hash).each(c, b, d);
}
function $empty() {}
function $extend(c, a) {
    for (var b in (a || {})) {
        c[b] = a[b];
    }
    return c;
}
function $H(a) {
    return new Hash(a);
}
function $lambda(a) {
    return ($type(a) == "function") ? a : function () {
        return a;
    };
}
function $merge() {
    var a = Array.slice(arguments);
    a.unshift({});
    return $mixin.apply(null, a);
}
function $mixin(e) {
    for (var d = 1, a = arguments.length; d < a; d++) {
        var b = arguments[d];
        if ($type(b) != "object") {
            continue;
        }
        for (var c in b) {
            var g = b[c],
                f = e[c];
            e[c] = (f && $type(g) == "object" && $type(f) == "object") ? $mixin(f, g) : $unlink(g);
        }
    }
    return e;
}
function $pick() {
    for (var b = 0, a = arguments.length;
    b < a; b++) {
        if (arguments[b] != undefined) {
            return arguments[b];
        }
    }
    return null;
}
function $random(b, a) {
    return Math.floor(Math.random() * (a - b + 1) + b);
}
function $splat(b) {
    var a = $type(b);
    return (a) ? ((a != "array" && a != "arguments") ? [b] : b) : [];
}
var $time = Date.now ||
function () {
    return +new Date;
};

function $try() {
    for (var b = 0, a = arguments.length; b < a;
    b++) {
        try {
            return arguments[b]();
        } catch (c) {}
    }
    return null;
}
function $type(a) {
    if (a == undefined) {
        return false;
    }
    if (a.$family) {
        return (a.$family.name == "number" && !isFinite(a)) ? false : a.$family.name;
    }
    if (a.nodeName) {
        switch (a.nodeType) {
        case 1:
            return "element";
        case 3:
            return (/\S/).test(a.nodeValue) ? "textnode" : "whitespace";
        }
    } else {
        if (typeof a.length == "number") {
            if (a.callee) {
                return "arguments";
            } else {
                if (a.item) {
                    return "collection";
                }
            }
        }
    }
    return typeof a;
}
function $unlink(c) {
    var b;
    switch ($type(c)) {
    case "object":
        b = {};
        for (var e in c) {
            b[e] = $unlink(c[e]);
        }
        break;
    case "hash":
        b = new Hash(c);
        break;
    case "array":
        b = [];
        for (var d = 0, a = c.length; d < a; d++) {
            b[d] = $unlink(c[d]);
        }
        break;
    default:
        return c;
    }
    return b;
}
var Browser = $merge({
    Engine: {
        name: "unknown",
        version: 0
    },
    Platform: {
        name: (window.orientation != undefined) ? "ipod" : (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase()
    },
    Features: {
        xpath: !! (document.evaluate),
        air: !! (window.runtime),
        query: !! (document.querySelector)
    },
    Plugins: {},
    Engines: {
        presto: function () {
            return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925));
        },
        trident: function () {
            return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4);
        },
        webkit: function () {
            return (navigator.taintEnabled) ? false : ((Browser.Features.xpath) ? ((Browser.Features.query) ? 525 : 420) : 419);
        },
        gecko: function () {
            return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18);
        }
    }
}, Browser || {});
Browser.Platform[Browser.Platform.name] = true;
Browser.detect = function () {
    for (var b in this.Engines) {
        var a = this.Engines[b]();
        if (a) {
            this.Engine = {
                name: b,
                version: a
            };
            this.Engine[b] = this.Engine[b + a] = true;
            break;
        }
    }
    return {
        name: b,
        version: a
    };
};
Browser.detect();
Browser.Request = function () {
    return $try(function () {
        return new XMLHttpRequest();
    }, function () {
        return new ActiveXObject("MSXML2.XMLHTTP");
    }, function () {
        return new ActiveXObject("Microsoft.XMLHTTP");
    });
};
Browser.Features.xhr = !! (Browser.Request());
Browser.Plugins.Flash = (function () {
    var a = ($try(function () {
        return navigator.plugins["Shockwave Flash"].description;
    }, function () {
        return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version");
    }) || "0 r0").match(/\d+/g);
    return {
        version: parseInt(a[0] || 0 + "." + a[1], 10) || 0,
        build: parseInt(a[2], 10) || 0
    };
})();

function $exec(b) {
    if (!b) {
        return b;
    }
    if (window.execScript) {
        window.execScript(b);
    } else {
        var a = document.createElement("script");
        a.setAttribute("type", "text/javascript");
        a[(Browser.Engine.webkit && Browser.Engine.version < 420) ? "innerText" : "text"] = b;
        document.head.appendChild(a);
        document.head.removeChild(a);
    }
    return b;
}
Native.UID = 1;
var $uid = (Browser.Engine.trident) ?
function (a) {
    return (a.uid || (a.uid = [Native.UID++]))[0];
} : function (a) {
    return a.uid || (a.uid = Native.UID++);
};
var Window = new Native({
    name: "Window",
    legacy: (Browser.Engine.trident) ? null : window.Window,
    initialize: function (a) {
        $uid(a);
        if (!a.Element) {
            a.Element = $empty;
            if (Browser.Engine.webkit) {
                a.document.createElement("iframe");
            }
            a.Element.prototype = (Browser.Engine.webkit) ? window["[[DOMElement.prototype]]"] : {};
        }
        a.document.window = a;
        return $extend(a, Window.Prototype);
    },
    afterImplement: function (b, a) {
        window[b] = Window.Prototype[b] = a;
    }
});
Window.Prototype = {
    $family: {
        name: "window"
    }
};
new Window(window);
var Document = new Native({
    name: "Document",
    legacy: (Browser.Engine.trident) ? null : window.Document,
    initialize: function (a) {
        $uid(a);
        a.head = a.getElementsByTagName("head")[0];
        a.html = a.getElementsByTagName("html")[0];
        if (Browser.Engine.trident && Browser.Engine.version <= 4) {
            $try(function () {
                a.execCommand("BackgroundImageCache", false, true);
            });
        }
        if (Browser.Engine.trident) {
            a.window.attachEvent("onunload", function () {
                a.window.detachEvent("onunload", arguments.callee);
                a.head = a.html = a.window = null;
            });
        }
        return $extend(a, Document.Prototype);
    },
    afterImplement: function (b, a) {
        document[b] = Document.Prototype[b] = a;
    }
});
Document.Prototype = {
    $family: {
        name: "document"
    }
};
new Document(document);
Array.implement({
    every: function (c, d) {
        for (var b = 0, a = this.length; b < a; b++) {
            if (!c.call(d, this[b], b, this)) {
                return false;
            }
        }
        return true;
    },
    filter: function (d, e) {
        var c = [];
        for (var b = 0, a = this.length; b < a; b++) {
            if (d.call(e, this[b], b, this)) {
                c.push(this[b]);
            }
        }
        return c;
    },
    clean: function () {
        return this.filter($defined);
    },
    indexOf: function (c, d) {
        var a = this.length;
        for (var b = (d < 0) ? Math.max(0, a + d) : d || 0; b < a; b++) {
            if (this[b] === c) {
                return b;
            }
        }
        return -1;
    },
    map: function (d, e) {
        var c = [];
        for (var b = 0, a = this.length; b < a; b++) {
            c[b] = d.call(e, this[b], b, this);
        }
        return c;
    },
    some: function (c, d) {
        for (var b = 0, a = this.length; b < a; b++) {
            if (c.call(d, this[b], b, this)) {
                return true;
            }
        }
        return false;
    },
    associate: function (c) {
        var d = {},
            b = Math.min(this.length, c.length);
        for (var a = 0; a < b; a++) {
                d[c[a]] = this[a];
            }
        return d;
    },
    link: function (c) {
        var a = {};
        for (var e = 0, b = this.length; e < b; e++) {
            for (var d in c) {
                if (c[d](this[e])) {
                    a[d] = this[e];
                    delete c[d];
                    break;
                }
            }
        }
        return a;
    },
    contains: function (a, b) {
        return this.indexOf(a, b) != -1;
    },
    extend: function (c) {
        for (var b = 0, a = c.length; b < a; b++) {
            this.push(c[b]);
        }
        return this;
    },
    getLast: function () {
        return (this.length) ? this[this.length - 1] : null;
    },
    getRandom: function () {
        return (this.length) ? this[$random(0, this.length - 1)] : null;
    },
    include: function (a) {
        if (!this.contains(a)) {
            this.push(a);
        }
        return this;
    },
    combine: function (c) {
        for (var b = 0, a = c.length; b < a; b++) {
            this.include(c[b]);
        }
        return this;
    },
    erase: function (b) {
        for (var a = this.length; a--; a) {
            if (this[a] === b) {
                this.splice(a, 1);
            }
        }
        return this;
    },
    empty: function () {
        this.length = 0;
        return this;
    },
    flatten: function () {
        var d = [];
        for (var b = 0, a = this.length; b < a; b++) {
            var c = $type(this[b]);
            if (!c) {
                continue;
            }
            d = d.concat((c == "array" || c == "collection" || c == "arguments") ? Array.flatten(this[b]) : this[b]);
        }
        return d;
    },
    hexToRgb: function (b) {
        if (this.length != 3) {
            return null;
        }
        var a = this.map(function (c) {
            if (c.length == 1) {
                c += c;
            }
            return c.toInt(16);
        });
        return (b) ? a : "rgb(" + a + ")";
    },
    rgbToHex: function (d) {
        if (this.length < 3) {
            return null;
        }
        if (this.length == 4 && this[3] == 0 && !d) {
            return "transparent";
        }
        var b = [];
        for (var a = 0; a < 3; a++) {
            var c = (this[a] - 0).toString(16);
            b.push((c.length == 1) ? "0" + c : c);
        }
        return (d) ? b : "#" + b.join("");
    }
});
Function.implement({
    extend: function (a) {
        for (var b in a) {
            this[b] = a[b];
        }
        return this;
    },
    create: function (b) {
        var a = this;
        b = b || {};
        return function (d) {
            var c = b.arguments;
            c = (c != undefined) ? $splat(c) : Array.slice(arguments, (b.event) ? 1 : 0);
            if (b.event) {
                c = [d || window.event].extend(c);
            }
            var e = function () {
                return a.apply(b.bind || null, c);
            };
            if (b.delay) {
                return setTimeout(e, b.delay);
            }
            if (b.periodical) {
                return setInterval(e, b.periodical);
            }
            if (b.attempt) {
                return $try(e);
            }
            return e();
        };
    },
    run: function (a, b) {
        return this.apply(b, $splat(a));
    },
    pass: function (a, b) {
        return this.create({
            bind: b,
            arguments: a
        });
    },
    bind: function (b, a) {
        return this.create({
            bind: b,
            arguments: a
        });
    },
    bindWithEvent: function (b, a) {
        return this.create({
            bind: b,
            arguments: a,
            event: true
        });
    },
    attempt: function (a, b) {
        return this.create({
            bind: b,
            arguments: a,
            attempt: true
        })();
    },
    delay: function (b, c, a) {
        return this.create({
            bind: c,
            arguments: a,
            delay: b
        })();
    },
    periodical: function (c, b, a) {
        return this.create({
            bind: b,
            arguments: a,
            periodical: c
        })();
    }
});
Number.implement({
    limit: function (b, a) {
        return Math.min(a, Math.max(b, this));
    },
    round: function (a) {
        a = Math.pow(10, a || 0);
        return Math.round(this * a) / a;
    },
    times: function (b, c) {
        for (var a = 0;
        a < this; a++) {
            b.call(c, a, this);
        }
    },
    toFloat: function () {
        return parseFloat(this);
    },
    toInt: function (a) {
        return parseInt(this, a || 10);
    }
});
Number.alias("times", "each");
(function (b) {
    var a = {};
    b.each(function (c) {
        if (!Number[c]) {
            a[c] = function () {
                return Math[c].apply(null, [this].concat($A(arguments)));
            };
        }
    });
    Number.implement(a);
})(["abs", "acos", "asin", "atan", "atan2", "ceil", "cos", "exp", "floor", "log", "max", "min", "pow", "sin", "sqrt", "tan"]);
String.implement({
    test: function (a, b) {
        return ((typeof a == "string") ? new RegExp(a, b) : a).test(this);
    },
    contains: function (a, b) {
        return (b) ? (b + this + b).indexOf(b + a + b) > -1 : this.indexOf(a) > -1;
    },
    trim: function () {
        return this.replace(/^\s+|\s+$/g, "");
    },
    clean: function () {
        return this.replace(/\s+/g, " ").trim();
    },
    camelCase: function () {
        return this.replace(/-\D/g, function (a) {
            return a.charAt(1).toUpperCase();
        });
    },
    hyphenate: function () {
        return this.replace(/[A-Z]/g, function (a) {
            return ("-" + a.charAt(0).toLowerCase());
        });
    },
    capitalize: function () {
        return this.replace(/\b[a-z]/g, function (a) {
            return a.toUpperCase();
        });
    },
    escapeRegExp: function () {
        return this.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
    },
    toInt: function (a) {
        return parseInt(this, a || 10);
    },
    toFloat: function () {
        return parseFloat(this);
    },
    hexToRgb: function (b) {
        var a = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
        return (a) ? a.slice(1).hexToRgb(b) : null;
    },
    rgbToHex: function (b) {
        var a = this.match(/\d{1,3}/g);
        return (a) ? a.rgbToHex(b) : null;
    },
    stripScripts: function (b) {
        var a = "";
        var c = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function () {
            a += arguments[1] + "\n";
            return "";
        });
        if (b === true) {
            $exec(a);
        } else {
            if ($type(b) == "function") {
                b(a, c);
            }
        }
        return c;
    },
    substitute: function (a, b) {
        return this.replace(b || (/\\?\{([^{}]+)\}/g), function (d, c) {
            if (d.charAt(0) == "\\") {
                return d.slice(1);
            }
            return (a[c] != undefined) ? a[c] : "";
        });
    }
});
Hash.implement({
    has: Object.prototype.hasOwnProperty,
    keyOf: function (b) {
        for (var a in this) {
            if (this.hasOwnProperty(a) && this[a] === b) {
                return a;
            }
        }
        return null;
    },
    hasValue: function (a) {
        return (Hash.keyOf(this, a) !== null);
    },
    extend: function (a) {
        Hash.each(a || {}, function (c, b) {
            Hash.set(this, b, c);
        }, this);
        return this;
    },
    combine: function (a) {
        Hash.each(a || {}, function (c, b) {
            Hash.include(this, b, c);
        }, this);
        return this;
    },
    erase: function (a) {
        if (this.hasOwnProperty(a)) {
            delete this[a];
        }
        return this;
    },
    get: function (a) {
        return (this.hasOwnProperty(a)) ? this[a] : null;
    },
    set: function (a, b) {
        if (!this[a] || this.hasOwnProperty(a)) {
            this[a] = b;
        }
        return this;
    },
    empty: function () {
        Hash.each(this, function (b, a) {
            delete this[a];
        }, this);
        return this;
    },
    include: function (a, b) {
        if (this[a] == undefined) {
            this[a] = b;
        }
        return this;
    },
    map: function (b, c) {
        var a = new Hash;
        Hash.each(this, function (e, d) {
            a.set(d, b.call(c, e, d, this));
        }, this);
        return a;
    },
    filter: function (b, c) {
        var a = new Hash;
        Hash.each(this, function (e, d) {
            if (b.call(c, e, d, this)) {
                a.set(d, e);
            }
        }, this);
        return a;
    },
    every: function (b, c) {
        for (var a in this) {
            if (this.hasOwnProperty(a) && !b.call(c, this[a], a)) {
                return false;
            }
        }
        return true;
    },
    some: function (b, c) {
        for (var a in this) {
            if (this.hasOwnProperty(a) && b.call(c, this[a], a)) {
                return true;
            }
        }
        return false;
    },
    getKeys: function () {
        var a = [];
        Hash.each(this, function (c, b) {
            a.push(b);
        });
        return a;
    },
    getValues: function () {
        var a = [];
        Hash.each(this, function (b) {
            a.push(b);
        });
        return a;
    },
    toQueryString: function (a) {
        var b = [];
        Hash.each(this, function (f, e) {
            if (a) {
                e = a + "[" + e + "]";
            }
            var d;
            switch ($type(f)) {
            case "object":
                d = Hash.toQueryString(f, e);
                break;
            case "array":
                var c = {};
                f.each(function (h, g) {
                    c[g] = h;
                });
                d = Hash.toQueryString(c, e);
                break;
            default:
                d = e + "=" + encodeURIComponent(f);
            }
            if (f != undefined) {
                b.push(d);
            }
        });
        return b.join("&");
    }
});
Hash.alias({
    keyOf: "indexOf",
    hasValue: "contains"
});
var Event = new Native({
    name: "Event",
    initialize: function (a, f) {
        f = f || window;
        var k = f.document;
        a = a || f.event;
        if (a.$extended) {
            return a;
        }
        this.$extended = true;
        var j = a.type;
        var g = a.target || a.srcElement;
        while (g && g.nodeType == 3) {
            g = g.parentNode;
        }
        if (j.test(/key/)) {
            var b = a.which || a.keyCode;
            var m = Event.Keys.keyOf(b);
            if (j == "keydown") {
                var d = b - 111;
                if (d > 0 && d < 13) {
                    m = "f" + d;
                }
            }
            m = m || String.fromCharCode(b).toLowerCase();
        } else {
            if (j.match(/(click|mouse|menu)/i)) {
                k = (!k.compatMode || k.compatMode == "CSS1Compat") ? k.html : k.body;
                var i = {
                    x: a.pageX || a.clientX + k.scrollLeft,
                    y: a.pageY || a.clientY + k.scrollTop
                };
                var c = {
                    x: (a.pageX) ? a.pageX - f.pageXOffset : a.clientX,
                    y: (a.pageY) ? a.pageY - f.pageYOffset : a.clientY
                };
                if (j.match(/DOMMouseScroll|mousewheel/)) {
                    var h = (a.wheelDelta) ? a.wheelDelta / 120 : -(a.detail || 0) / 3;
                }
                var e = (a.which == 3) || (a.button == 2);
                var l = null;
                if (j.match(/over|out/)) {
                    switch (j) {
                    case "mouseover":
                        l = a.relatedTarget || a.fromElement;
                        break;
                    case "mouseout":
                        l = a.relatedTarget || a.toElement;
                    }
                    if (!(function () {
                        while (l && l.nodeType == 3) {
                            l = l.parentNode;
                        }
                        return true;
                    }).create({
                        attempt: Browser.Engine.gecko
                    })()) {
                        l = false;
                    }
                }
            }
        }
        return $extend(this, {
            event: a,
            type: j,
            page: i,
            client: c,
            rightClick: e,
            wheel: h,
            relatedTarget: l,
            target: g,
            code: b,
            key: m,
            shift: a.shiftKey,
            control: a.ctrlKey,
            alt: a.altKey,
            meta: a.metaKey
        });
    }
});
Event.Keys = new Hash({
    enter: 13,
    up: 38,
    down: 40,
    left: 37,
    right: 39,
    esc: 27,
    space: 32,
    backspace: 8,
    tab: 9,
    "delete": 46
});
Event.implement({
    stop: function () {
        return this.stopPropagation().preventDefault();
    },
    stopPropagation: function () {
        if (this.event.stopPropagation) {
            this.event.stopPropagation();
        } else {
            this.event.cancelBubble = true;
        }
        return this;
    },
    preventDefault: function () {
        if (this.event.preventDefault) {
            this.event.preventDefault();
        } else {
            this.event.returnValue = false;
        }
        return this;
    }
});

function Class(b) {
    if (b instanceof Function) {
        b = {
            initialize: b
        };
    }
    var a = function () {
        Object.reset(this);
        if (a._prototyping) {
            return this;
        }
        this._current = $empty;
        var c = (this.initialize) ? this.initialize.apply(this, arguments) : this;
        delete this._current;
        delete this.caller;
        return c;
    }.extend(this);
    a.implement(b);
    a.constructor = Class;
    a.prototype.constructor = a;
    return a;
}
Function.prototype.protect = function () {
    this._protected = true;
    return this;
};
Object.reset = function (a, c) {
    if (c == null) {
        for (var e in a) {
            Object.reset(a, e);
        }
        return a;
    }
    delete a[c];
    switch ($type(a[c])) {
    case "object":
        var d = function () {};
        d.prototype = a[c];
        var b = new d;
        a[c] = Object.reset(b);
        break;
    case "array":
        a[c] = $unlink(a[c]);
        break;
    }
    return a;
};
new Native({
    name: "Class",
    initialize: Class
}).extend({
    instantiate: function (b) {
        b._prototyping = true;
        var a = new b;
        delete b._prototyping;
        return a;
    },
    wrap: function (a, b, c) {
        if (c._origin) {
            c = c._origin;
        }
        return function () {
            if (c._protected && this._current == null) {
                throw new Error('The method "' + b + '" cannot be called.');
            }
            var e = this.caller,
                f = this._current;
            this.caller = f;
            this._current = arguments.callee;
            var d = c.apply(this, arguments);
            this._current = f;
            this.caller = e;
            return d;
        }.extend({
            _owner: a,
            _origin: c,
            _name: b
        });
    }
});
Class.implement({
    implement: function (a, d) {
        if ($type(a) == "object") {
            for (var e in a) {
                this.implement(e, a[e]);
            }
            return this;
        }
        var f = Class.Mutators[a];
        if (f) {
            d = f.call(this, d);
            if (d == null) {
                return this;
            }
        }
        var c = this.prototype;
        switch ($type(d)) {
        case "function":
            if (d._hidden) {
                return this;
            }
            c[a] = Class.wrap(this, a, d);
            break;
        case "object":
            var b = c[a];
            if ($type(b) == "object") {
                $mixin(b, d);
            } else {
                c[a] = $unlink(d);
            }
            break;
        case "array":
            c[a] = $unlink(d);
            break;
        default:
            c[a] = d;
        }
        return this;
    }
});
Class.Mutators = {
    Extends: function (a) {
        this.parent = a;
        this.prototype = Class.instantiate(a);
        this.implement("parent", function () {
            var b = this.caller._name,
                c = this.caller._owner.parent.prototype[b];
            if (!c) {
                    throw new Error('The method "' + b + '" has no parent.');
                }
            return c.apply(this, arguments);
        }.protect());
    },
    Implements: function (a) {
        $splat(a).each(function (b) {
            if (b instanceof Function) {
                b = Class.instantiate(b);
            }
            this.implement(b);
        }, this);
    }
};
var Chain = new Class({
    $chain: [],
    chain: function () {
        this.$chain.extend(Array.flatten(arguments));
        return this;
    },
    callChain: function () {
        return (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;
    },
    clearChain: function () {
        this.$chain.empty();
        return this;
    }
});
var Events = new Class({
    $events: {},
    addEvent: function (c, b, a) {
        c = Events.removeOn(c);
        if (b != $empty) {
            this.$events[c] = this.$events[c] || [];
            this.$events[c].include(b);
            if (a) {
                b.internal = true;
            }
        }
        return this;
    },
    addEvents: function (a) {
        for (var b in a) {
            this.addEvent(b, a[b]);
        }
        return this;
    },
    fireEvent: function (c, b, a) {
        c = Events.removeOn(c);
        if (!this.$events || !this.$events[c]) {
            return this;
        }
        this.$events[c].each(function (d) {
            d.create({
                bind: this,
                delay: a,
                "arguments": b
            })();
        }, this);
        return this;
    },
    removeEvent: function (b, a) {
        b = Events.removeOn(b);
        if (!this.$events[b]) {
            return this;
        }
        if (!a.internal) {
            this.$events[b].erase(a);
        }
        return this;
    },
    removeEvents: function (c) {
        var d;
        if ($type(c) == "object") {
            for (d in c) {
                this.removeEvent(d, c[d]);
            }
            return this;
        }
        if (c) {
            c = Events.removeOn(c);
        }
        for (d in this.$events) {
            if (c && c != d) {
                continue;
            }
            var b = this.$events[d];
            for (var a = b.length; a--; a) {
                this.removeEvent(d, b[a]);
            }
        }
        return this;
    }
});
Events.removeOn = function (a) {
    return a.replace(/^on([A-Z])/, function (b, c) {
        return c.toLowerCase();
    });
};
var Options = new Class({
    setOptions: function () {
        this.options = $merge.run([this.options].extend(arguments));
        if (!this.addEvent) {
            return this;
        }
        for (var a in this.options) {
            if ($type(this.options[a]) != "function" || !(/^on[A-Z]/).test(a)) {
                continue;
            }
            this.addEvent(a, this.options[a]);
            delete this.options[a];
        }
        return this;
    }
});
var Element = new Native({
    name: "Element",
    legacy: window.Element,
    initialize: function (a, b) {
        var c = Element.Constructors.get(a);
        if (c) {
            return c(b);
        }
        if (typeof a == "string") {
            return document.newElement(a, b);
        }
        return document.id(a).set(b);
    },
    afterImplement: function (a, b) {
        Element.Prototype[a] = b;
        if (Array[a]) {
            return;
        }
        Elements.implement(a, function () {
            var c = [],
                g = true;
            for (var e = 0, d = this.length; e < d; e++) {
                    var f = this[e][a].apply(this[e], arguments);
                    c.push(f);
                    if (g) {
                        g = ($type(f) == "element");
                    }
                }
            return (g) ? new Elements(c) : c;
        });
    }
});
Element.Prototype = {
    $family: {
        name: "element"
    }
};
Element.Constructors = new Hash;
var IFrame = new Native({
    name: "IFrame",
    generics: false,
    initialize: function () {
        var f = Array.link(arguments, {
            properties: Object.type,
            iframe: $defined
        });
        var d = f.properties || {};
        var c = document.id(f.iframe);
        var e = d.onload || $empty;
        delete d.onload;
        d.id = d.name = $pick(d.id, d.name, c ? (c.id || c.name) : "IFrame_" + $time());
        c = new Element(c || "iframe", d);
        var b = function () {
            var g = $try(function () {
                return c.contentWindow.location.host;
            });
            if (!g || g == window.location.host) {
                var h = new Window(c.contentWindow);
                new Document(c.contentWindow.document);
                $extend(h.Element.prototype, Element.Prototype);
            }
            e.call(c.contentWindow, c.contentWindow.document);
        };
        var a = $try(function () {
            return c.contentWindow;
        });
        ((a && a.document.body) || window.frames[d.id]) ? b() : c.addListener("load", b);
        return c;
    }
});
var Elements = new Native({
    initialize: function (f, b) {
        b = $extend({
            ddup: true,
            cash: true
        }, b);
        f = f || [];
        if (b.ddup || b.cash) {
            var g = {},
                e = [];
            for (var c = 0, a = f.length; c < a; c++) {
                    var d = document.id(f[c], !b.cash);
                    if (b.ddup) {
                        if (g[d.uid]) {
                            continue;
                        }
                        g[d.uid] = true;
                    }
                    if (d) {
                        e.push(d);
                    }
                }
            f = e;
        }
        return (b.cash) ? $extend(f, this) : f;
    }
});
Elements.implement({
    filter: function (a, b) {
        if (!a) {
            return this;
        }
        return new Elements(Array.filter(this, (typeof a == "string") ?
        function (c) {
            return c.match(a);
        } : a, b));
    }
});
Document.implement({
    newElement: function (a, b) {
        if (Browser.Engine.trident && b) {
            ["name", "type", "checked"].each(function (c) {
                if (!b[c]) {
                    return;
                }
                a += " " + c + '="' + b[c] + '"';
                if (c != "checked") {
                    delete b[c];
                }
            });
            a = "<" + a + ">";
        }
        return document.id(this.createElement(a)).set(b);
    },
    newTextNode: function (a) {
        return this.createTextNode(a);
    },
    getDocument: function () {
        return this;
    },
    getWindow: function () {
        return this.window;
    },
    id: (function () {
        var a = {
            string: function (d, c, b) {
                d = b.getElementById(d);
                return (d) ? a.element(d, c) : null;
            },
            element: function (b, e) {
                $uid(b);
                if (!e && !b.$family && !(/^object|embed$/i).test(b.tagName)) {
                    var c = Element.Prototype;
                    for (var d in c) {
                        b[d] = c[d];
                    }
                }
                return b;
            },
            object: function (c, d, b) {
                if (c.toElement) {
                    return a.element(c.toElement(b), d);
                }
                return null;
            }
        };
        a.textnode = a.whitespace = a.window = a.document = $arguments(0);
        return function (c, e, d) {
            if (c && c.$family && c.uid) {
                return c;
            }
            var b = $type(c);
            return (a[b]) ? a[b](c, e, d || document) : null;
        };
    })()
});
if (window.$ == null) {
    Window.implement({
        $: function (a, b) {
            return document.id(a, b, this.document);
        }
    });
}
Window.implement({
    $$: function (a) {
        if (arguments.length == 1 && typeof a == "string") {
            return this.document.getElements(a);
        }
        var f = [];
        var c = Array.flatten(arguments);
        for (var d = 0, b = c.length; d < b; d++) {
            var e = c[d];
            switch ($type(e)) {
            case "element":
                f.push(e);
                break;
            case "string":
                f.extend(this.document.getElements(e, true));
            }
        }
        return new Elements(f);
    },
    getDocument: function () {
        return this.document;
    },
    getWindow: function () {
        return this;
    }
});
Native.implement([Element, Document], {
    getElement: function (a, b) {
        return document.id(this.getElements(a, true)[0] || null, b);
    },
    getElements: function (a, d) {
        a = a.split(",");
        var c = [];
        var b = (a.length > 1);
        a.each(function (e) {
            var f = this.getElementsByTagName(e.trim());
            (b) ? c.extend(f) : c = f;
        }, this);
        return new Elements(c, {
            ddup: b,
            cash: !d
        });
    }
});
(function () {
    var h = {},
        f = {};
    var i = {
            input: "checked",
            option: "selected",
            textarea: (Browser.Engine.webkit && Browser.Engine.version < 420) ? "innerHTML" : "value"
        };
    var c = function (l) {
            return (f[l] || (f[l] = {}));
        };
    var g = function (n, l) {
            if (!n) {
                return;
            }
            var m = n.uid;
            if (Browser.Engine.trident) {
                if (n.clearAttributes) {
                    var q = l && n.cloneNode(false);
                    n.clearAttributes();
                    if (q) {
                        n.mergeAttributes(q);
                    }
                } else {
                    if (n.removeEvents) {
                        n.removeEvents();
                    }
                }
                if ((/object/i).test(n.tagName)) {
                    for (var o in n) {
                        if (typeof n[o] == "function") {
                            n[o] = $empty;
                        }
                    }
                    Element.dispose(n);
                }
            }
            if (!m) {
                return;
            }
            h[m] = f[m] = null;
        };
    var d = function () {
            Hash.each(h, g);
            if (Browser.Engine.trident) {
                $A(document.getElementsByTagName("object")).each(g);
            }
            if (window.CollectGarbage) {
                CollectGarbage();
            }
            h = f = null;
        };
    var j = function (n, l, s, m, p, r) {
            var o = n[s || l];
            var q = [];
            while (o) {
                if (o.nodeType == 1 && (!m || Element.match(o, m))) {
                    if (!p) {
                        return document.id(o, r);
                    }
                    q.push(o);
                }
                o = o[l];
            }
            return (p) ? new Elements(q, {
                ddup: false,
                cash: !r
            }) : null;
        };
    var e = {
            html: "innerHTML",
            "class": "className",
            "for": "htmlFor",
            defaultValue: "defaultValue",
            text: (Browser.Engine.trident || (Browser.Engine.webkit && Browser.Engine.version < 420)) ? "innerText" : "textContent"
        };
    var b = ["compact", "nowrap", "ismap", "declare", "noshade", "checked", "disabled", "readonly", "multiple", "selected", "noresize", "defer"];
    var k = ["value", "type", "defaultValue", "accessKey", "cellPadding", "cellSpacing", "colSpan", "frameBorder", "maxLength", "readOnly", "rowSpan", "tabIndex", "useMap"];
    b = b.associate(b);
    Hash.extend(e, b);
    Hash.extend(e, k.associate(k.map(String.toLowerCase)));
    var a = {
            before: function (m, l) {
                if (l.parentNode) {
                    l.parentNode.insertBefore(m, l);
                }
            },
            after: function (m, l) {
                if (!l.parentNode) {
                    return;
                }
                var n = l.nextSibling;
                (n) ? l.parentNode.insertBefore(m, n) : l.parentNode.appendChild(m);
            },
            bottom: function (m, l) {
                l.appendChild(m);
            },
            top: function (m, l) {
                var n = l.firstChild;
                (n) ? l.insertBefore(m, n) : l.appendChild(m);
            }
        };
    a.inside = a.bottom;
    Hash.each(a, function (l, m) {
            m = m.capitalize();
            Element.implement("inject" + m, function (n) {
                l(this, document.id(n, true));
                return this;
            });
            Element.implement("grab" + m, function (n) {
                l(document.id(n, true), this);
                return this;
            });
        });
    Element.implement({
            set: function (o, m) {
                switch ($type(o)) {
                case "object":
                    for (var n in o) {
                        this.set(n, o[n]);
                    }
                    break;
                case "string":
                    var l = Element.Properties.get(o);
                    (l && l.set) ? l.set.apply(this, Array.slice(arguments, 1)) : this.setProperty(o, m);
                }
                return this;
            },
            get: function (m) {
                var l = Element.Properties.get(m);
                return (l && l.get) ? l.get.apply(this, Array.slice(arguments, 1)) : this.getProperty(m);
            },
            erase: function (m) {
                var l = Element.Properties.get(m);
                (l && l.erase) ? l.erase.apply(this) : this.removeProperty(m);
                return this;
            },
            setProperty: function (m, n) {
                var l = e[m];
                if (n == undefined) {
                    return this.removeProperty(m);
                }
                if (l && b[m]) {
                    n = !! n;
                }(l) ? this[l] = n : this.setAttribute(m, "" + n);
                return this;
            },
            setProperties: function (l) {
                for (var m in l) {
                    this.setProperty(m, l[m]);
                }
                return this;
            },
            getProperty: function (m) {
                var l = e[m];
                var n = (l) ? this[l] : this.getAttribute(m, 2);
                return (b[m]) ? !! n : (l) ? n : n || null;
            },
            getProperties: function () {
                var l = $A(arguments);
                return l.map(this.getProperty, this).associate(l);
            },
            removeProperty: function (m) {
                var l = e[m];
                (l) ? this[l] = (l && b[m]) ? false : "" : this.removeAttribute(m);
                return this;
            },
            removeProperties: function () {
                Array.each(arguments, this.removeProperty, this);
                return this;
            },
            hasClass: function (l) {
                return this.className.contains(l, " ");
            },
            addClass: function (l) {
                if (!this.hasClass(l)) {
                    this.className = (this.className + " " + l).clean();
                }
                return this;
            },
            removeClass: function (l) {
                this.className = this.className.replace(new RegExp("(^|\\s)" + l + "(?:\\s|$)"), "$1");
                return this;
            },
            toggleClass: function (l) {
                return this.hasClass(l) ? this.removeClass(l) : this.addClass(l);
            },
            adopt: function () {
                Array.flatten(arguments).each(function (l) {
                    l = document.id(l, true);
                    if (l) {
                        this.appendChild(l);
                    }
                }, this);
                return this;
            },
            appendText: function (m, l) {
                return this.grab(this.getDocument().newTextNode(m), l);
            },
            grab: function (m, l) {
                a[l || "bottom"](document.id(m, true), this);
                return this;
            },
            inject: function (m, l) {
                a[l || "bottom"](this, document.id(m, true));
                return this;
            },
            replaces: function (l) {
                l = document.id(l, true);
                l.parentNode.replaceChild(this, l);
                return this;
            },
            wraps: function (m, l) {
                m = document.id(m, true);
                return this.replaces(m).grab(m, l);
            },
            getPrevious: function (l, m) {
                return j(this, "previousSibling", null, l, false, m);
            },
            getAllPrevious: function (l, m) {
                return j(this, "previousSibling", null, l, true, m);
            },
            getNext: function (l, m) {
                return j(this, "nextSibling", null, l, false, m);
            },
            getAllNext: function (l, m) {
                return j(this, "nextSibling", null, l, true, m);
            },
            getFirst: function (l, m) {
                return j(this, "nextSibling", "firstChild", l, false, m);
            },
            getLast: function (l, m) {
                return j(this, "previousSibling", "lastChild", l, false, m);
            },
            getParent: function (l, m) {
                return j(this, "parentNode", null, l, false, m);
            },
            getParents: function (l, m) {
                return j(this, "parentNode", null, l, true, m);
            },
            getSiblings: function (l, m) {
                return this.getParent().getChildren(l, m).erase(this);
            },
            getChildren: function (l, m) {
                return j(this, "nextSibling", "firstChild", l, true, m);
            },
            getWindow: function () {
                return this.ownerDocument.window;
            },
            getDocument: function () {
                return this.ownerDocument;
            },
            getElementById: function (o, n) {
                var m = this.ownerDocument.getElementById(o);
                if (!m) {
                    return null;
                }
                for (var l = m.parentNode; l != this; l = l.parentNode) {
                    if (!l) {
                        return null;
                    }
                }
                return document.id(m, n);
            },
            getSelected: function () {
                return new Elements($A(this.options).filter(function (l) {
                    return l.selected;
                }));
            },
            getComputedStyle: function (m) {
                if (this.currentStyle) {
                    return this.currentStyle[m.camelCase()];
                }
                var l = this.getDocument().defaultView.getComputedStyle(this, null);
                return (l) ? l.getPropertyValue([m.hyphenate()]) : null;
            },
            toQueryString: function () {
                var l = [];
                this.getElements("input, select, textarea", true).each(function (m) {
                    if (!m.name || m.disabled || m.type == "submit" || m.type == "reset" || m.type == "file") {
                        return;
                    }
                    var n = (m.tagName.toLowerCase() == "select") ? Element.getSelected(m).map(function (o) {
                        return o.value;
                    }) : ((m.type == "radio" || m.type == "checkbox") && !m.checked) ? null : m.value;
                    $splat(n).each(function (o) {
                        if (typeof o != "undefined") {
                            l.push(m.name + "=" + encodeURIComponent(o));
                        }
                    });
                });
                return l.join("&");
            },
            clone: function (o, l) {
                o = o !== false;
                var r = this.cloneNode(o);
                var n = function (v, u) {
                    if (!l) {
                        v.removeAttribute("id");
                    }
                    if (Browser.Engine.trident) {
                        v.clearAttributes();
                        v.mergeAttributes(u);
                        v.removeAttribute("uid");
                        if (v.options) {
                            var w = v.options,
                                s = u.options;
                            for (var t = w.length; t--;) {
                                    w[t].selected = s[t].selected;
                                }
                        }
                    }
                    var x = i[u.tagName.toLowerCase()];
                    if (x && u[x]) {
                        v[x] = u[x];
                    }
                };
                if (o) {
                    var p = r.getElementsByTagName("*"),
                        q = this.getElementsByTagName("*");
                    for (var m = p.length; m--;) {
                            n(p[m], q[m]);
                        }
                }
                n(r, this);
                return document.id(r);
            },
            destroy: function () {
                Element.empty(this);
                Element.dispose(this);
                g(this, true);
                return null;
            },
            empty: function () {
                $A(this.childNodes).each(function (l) {
                    Element.destroy(l);
                });
                return this;
            },
            dispose: function () {
                return (this.parentNode) ? this.parentNode.removeChild(this) : this;
            },
            hasChild: function (l) {
                l = document.id(l, true);
                if (!l) {
                    return false;
                }
                if (Browser.Engine.webkit && Browser.Engine.version < 420) {
                    return $A(this.getElementsByTagName(l.tagName)).contains(l);
                }
                return (this.contains) ? (this != l && this.contains(l)) : !! (this.compareDocumentPosition(l) & 16);
            },
            match: function (l) {
                return (!l || (l == this) || (Element.get(this, "tag") == l));
            }
        });
    Native.implement([Element, Window, Document], {
            addListener: function (o, n) {
                if (o == "unload") {
                    var l = n,
                        m = this;
                    n = function () {
                            m.removeListener("unload", n);
                            l();
                        };
                } else {
                    h[this.uid] = this;
                }
                if (this.addEventListener) {
                    this.addEventListener(o, n, false);
                } else {
                    this.attachEvent("on" + o, n);
                }
                return this;
            },
            removeListener: function (m, l) {
                if (this.removeEventListener) {
                    this.removeEventListener(m, l, false);
                } else {
                    this.detachEvent("on" + m, l);
                }
                return this;
            },
            retrieve: function (m, l) {
                var o = c(this.uid),
                    n = o[m];
                if (l != undefined && n == undefined) {
                        n = o[m] = l;
                    }
                return $pick(n);
            },
            store: function (m, l) {
                var n = c(this.uid);
                n[m] = l;
                return this;
            },
            eliminate: function (l) {
                var m = c(this.uid);
                delete m[l];
                return this;
            }
        });
    window.addListener("unload", d);
})();
Element.Properties = new Hash;
Element.Properties.style = {
    set: function (a) {
        this.style.cssText = a;
    },
    get: function () {
        return this.style.cssText;
    },
    erase: function () {
        this.style.cssText = "";
    }
};
Element.Properties.tag = {
    get: function () {
        return this.tagName.toLowerCase();
    }
};
Element.Properties.html = (function () {
    var c = document.createElement("div");
    var a = {
        table: [1, "<table>", "</table>"],
        select: [1, "<select>", "</select>"],
        tbody: [2, "<table><tbody>", "</tbody></table>"],
        tr: [3, "<table><tbody><tr>", "</tr></tbody></table>"]
    };
    a.thead = a.tfoot = a.tbody;
    var b = {
        set: function () {
            var e = Array.flatten(arguments).join("");
            var f = Browser.Engine.trident && a[this.get("tag")];
            if (f) {
                var g = c;
                g.innerHTML = f[1] + e + f[2];
                for (var d = f[0]; d--;) {
                    g = g.firstChild;
                }
                this.empty().adopt(g.childNodes);
            } else {
                this.innerHTML = e;
            }
        }
    };
    b.erase = b.set;
    return b;
})();
if (Browser.Engine.webkit && Browser.Engine.version < 420) {
    Element.Properties.text = {
        get: function () {
            if (this.innerText) {
                return this.innerText;
            }
            var a = this.ownerDocument.newElement("div", {
                html: this.innerHTML
            }).inject(this.ownerDocument.body);
            var b = a.innerText;
            a.destroy();
            return b;
        }
    };
}
Element.Properties.events = {
    set: function (a) {
        this.addEvents(a);
    }
};
Native.implement([Element, Window, Document], {
    addEvent: function (e, g) {
        var h = this.retrieve("events", {});
        h[e] = h[e] || {
            keys: [],
            values: []
        };
        if (h[e].keys.contains(g)) {
            return this;
        }
        h[e].keys.push(g);
        var f = e,
            a = Element.Events.get(e),
            c = g,
            i = this;
        if (a) {
                if (a.onAdd) {
                    a.onAdd.call(this, g);
                }
                if (a.condition) {
                    c = function (j) {
                        if (a.condition.call(this, j)) {
                            return g.call(this, j);
                        }
                        return true;
                    };
                }
                f = a.base || f;
            }
        var d = function () {
                return g.call(i);
            };
        var b = Element.NativeEvents[f];
        if (b) {
                if (b == 2) {
                    d = function (j) {
                        j = new Event(j, i.getWindow());
                        if (c.call(i, j) === false) {
                            j.stop();
                        }
                    };
                }
                this.addListener(f, d);
            }
        h[e].values.push(d);
        return this;
    },
    removeEvent: function (c, b) {
        var a = this.retrieve("events");
        if (!a || !a[c]) {
            return this;
        }
        var f = a[c].keys.indexOf(b);
        if (f == -1) {
            return this;
        }
        a[c].keys.splice(f, 1);
        var e = a[c].values.splice(f, 1)[0];
        var d = Element.Events.get(c);
        if (d) {
            if (d.onRemove) {
                d.onRemove.call(this, b);
            }
            c = d.base || c;
        }
        return (Element.NativeEvents[c]) ? this.removeListener(c, e) : this;
    },
    addEvents: function (a) {
        for (var b in a) {
            this.addEvent(b, a[b]);
        }
        return this;
    },
    removeEvents: function (a) {
        var c;
        if ($type(a) == "object") {
            for (c in a) {
                this.removeEvent(c, a[c]);
            }
            return this;
        }
        var b = this.retrieve("events");
        if (!b) {
            return this;
        }
        if (!a) {
            for (c in b) {
                this.removeEvents(c);
            }
            this.eliminate("events");
        } else {
            if (b[a]) {
                while (b[a].keys[0]) {
                    this.removeEvent(a, b[a].keys[0]);
                }
                b[a] = null;
            }
        }
        return this;
    },
    fireEvent: function (d, b, a) {
        var c = this.retrieve("events");
        if (!c || !c[d]) {
            return this;
        }
        c[d].keys.each(function (e) {
            e.create({
                bind: this,
                delay: a,
                "arguments": b
            })();
        }, this);
        return this;
    },
    cloneEvents: function (d, a) {
        d = document.id(d);
        var c = d.retrieve("events");
        if (!c) {
            return this;
        }
        if (!a) {
            for (var b in c) {
                this.cloneEvents(d, b);
            }
        } else {
            if (c[a]) {
                c[a].keys.each(function (e) {
                    this.addEvent(a, e);
                }, this);
            }
        }
        return this;
    }
});
Element.NativeEvents = {
    click: 2,
    dblclick: 2,
    mouseup: 2,
    mousedown: 2,
    contextmenu: 2,
    mousewheel: 2,
    DOMMouseScroll: 2,
    mouseover: 2,
    mouseout: 2,
    mousemove: 2,
    selectstart: 2,
    selectend: 2,
    keydown: 2,
    keypress: 2,
    keyup: 2,
    focus: 2,
    blur: 2,
    change: 2,
    reset: 2,
    select: 2,
    submit: 2,
    load: 1,
    unload: 1,
    beforeunload: 2,
    resize: 1,
    move: 1,
    DOMContentLoaded: 1,
    readystatechange: 1,
    error: 1,
    abort: 1,
    scroll: 1
};
(function () {
    var a = function (b) {
        var c = b.relatedTarget;
        if (c == undefined) {
            return true;
        }
        if (c === false) {
            return false;
        }
        return ($type(this) != "document" && c != this && c.prefix != "xul" && !this.hasChild(c));
    };
    Element.Events = new Hash({
        mouseenter: {
            base: "mouseover",
            condition: a
        },
        mouseleave: {
            base: "mouseout",
            condition: a
        },
        mousewheel: {
            base: (Browser.Engine.gecko) ? "DOMMouseScroll" : "mousewheel"
        }
    });
})();
Element.Properties.styles = {
    set: function (a) {
        this.setStyles(a);
    }
};
Element.Properties.opacity = {
    set: function (a, b) {
        if (!b) {
            if (a == 0) {
                if (this.style.visibility != "hidden") {
                    this.style.visibility = "hidden";
                }
            } else {
                if (this.style.visibility != "visible") {
                    this.style.visibility = "visible";
                }
            }
        }
        if (!this.currentStyle || !this.currentStyle.hasLayout) {
            this.style.zoom = 1;
        }
        if (Browser.Engine.trident) {
            this.style.filter = (a == 1) ? "" : "alpha(opacity=" + a * 100 + ")";
        }
        this.style.opacity = a;
        this.store("opacity", a);
    },
    get: function () {
        return this.retrieve("opacity", 1);
    }
};
Element.implement({
    setOpacity: function (a) {
        return this.set("opacity", a, true);
    },
    getOpacity: function () {
        return this.get("opacity");
    },
    setStyle: function (b, a) {
        switch (b) {
        case "opacity":
            return this.set("opacity", parseFloat(a));
        case "float":
            b = (Browser.Engine.trident) ? "styleFloat" : "cssFloat";
        }
        b = b.camelCase();
        if ($type(a) != "string") {
            var c = (Element.Styles.get(b) || "@").split(" ");
            a = $splat(a).map(function (e, d) {
                if (!c[d]) {
                    return "";
                }
                return ($type(e) == "number") ? c[d].replace("@", Math.round(e)) : e;
            }).join(" ");
        } else {
            if (a == String(Number(a))) {
                a = Math.round(a);
            }
        }
        this.style[b] = a;
        return this;
    },
    getStyle: function (g) {
        switch (g) {
        case "opacity":
            return this.get("opacity");
        case "float":
            g = (Browser.Engine.trident) ? "styleFloat" : "cssFloat";
        }
        g = g.camelCase();
        var a = this.style[g];
        if (!$chk(a)) {
            a = [];
            for (var f in Element.ShortStyles) {
                if (g != f) {
                    continue;
                }
                for (var e in Element.ShortStyles[f]) {
                    a.push(this.getStyle(e));
                }
                return a.join(" ");
            }
            a = this.getComputedStyle(g);
        }
        if (a) {
            a = String(a);
            var c = a.match(/rgba?\([\d\s,]+\)/);
            if (c) {
                a = a.replace(c[0], c[0].rgbToHex());
            }
        }
        if (Browser.Engine.presto || (Browser.Engine.trident && !$chk(parseInt(a, 10)))) {
            if (g.test(/^(height|width)$/)) {
                var b = (g == "width") ? ["left", "right"] : ["top", "bottom"],
                    d = 0;
                b.each(function (h) {
                        d += this.getStyle("border-" + h + "-width").toInt() + this.getStyle("padding-" + h).toInt();
                    }, this);
                return this["offset" + g.capitalize()] - d + "px";
            }
            if ((Browser.Engine.presto) && String(a).test("px")) {
                return a;
            }
            if (g.test(/(border(.+)Width|margin|padding)/)) {
                return "0px";
            }
        }
        return a;
    },
    setStyles: function (b) {
        for (var a in b) {
            this.setStyle(a, b[a]);
        }
        return this;
    },
    getStyles: function () {
        var a = {};
        Array.flatten(arguments).each(function (b) {
            a[b] = this.getStyle(b);
        }, this);
        return a;
    }
});
Element.Styles = new Hash({
    left: "@px",
    top: "@px",
    bottom: "@px",
    right: "@px",
    width: "@px",
    height: "@px",
    maxWidth: "@px",
    maxHeight: "@px",
    minWidth: "@px",
    minHeight: "@px",
    backgroundColor: "rgb(@, @, @)",
    backgroundPosition: "@px @px",
    color: "rgb(@, @, @)",
    fontSize: "@px",
    letterSpacing: "@px",
    lineHeight: "@px",
    clip: "rect(@px @px @px @px)",
    margin: "@px @px @px @px",
    padding: "@px @px @px @px",
    border: "@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",
    borderWidth: "@px @px @px @px",
    borderStyle: "@ @ @ @",
    borderColor: "rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",
    zIndex: "@",
    zoom: "@",
    fontWeight: "@",
    textIndent: "@px",
    opacity: "@"
});
Element.ShortStyles = {
    margin: {},
    padding: {},
    border: {},
    borderWidth: {},
    borderStyle: {},
    borderColor: {}
};
["Top", "Right", "Bottom", "Left"].each(function (g) {
    var f = Element.ShortStyles;
    var b = Element.Styles;
    ["margin", "padding"].each(function (h) {
        var i = h + g;
        f[h][i] = b[i] = "@px";
    });
    var e = "border" + g;
    f.border[e] = b[e] = "@px @ rgb(@, @, @)";
    var d = e + "Width",
        a = e + "Style",
        c = e + "Color";
    f[e] = {};
    f.borderWidth[d] = f[e][d] = b[d] = "@px";
    f.borderStyle[a] = f[e][a] = b[a] = "@";
    f.borderColor[c] = f[e][c] = b[c] = "rgb(@, @, @)";
});
(function () {
    Element.implement({
        scrollTo: function (h, i) {
            if (b(this)) {
                this.getWindow().scrollTo(h, i);
            } else {
                this.scrollLeft = h;
                this.scrollTop = i;
            }
            return this;
        },
        getSize: function () {
            if (b(this)) {
                return this.getWindow().getSize();
            }
            return {
                x: this.offsetWidth,
                y: this.offsetHeight
            };
        },
        getScrollSize: function () {
            if (b(this)) {
                return this.getWindow().getScrollSize();
            }
            return {
                x: this.scrollWidth,
                y: this.scrollHeight
            };
        },
        getScroll: function () {
            if (b(this)) {
                return this.getWindow().getScroll();
            }
            return {
                x: this.scrollLeft,
                y: this.scrollTop
            };
        },
        getScrolls: function () {
            var i = this,
                h = {
                    x: 0,
                    y: 0
                };
            while (i && !b(i)) {
                    h.x += i.scrollLeft;
                    h.y += i.scrollTop;
                    i = i.parentNode;
                }
            return h;
        },
        getOffsetParent: function () {
            var h = this;
            if (b(h)) {
                return null;
            }
            if (!Browser.Engine.trident) {
                return h.offsetParent;
            }
            while ((h = h.parentNode) && !b(h)) {
                if (d(h, "position") != "static") {
                    return h;
                }
            }
            return null;
        },
        getOffsets: function () {
            if (this.getBoundingClientRect) {
                var j = this.getBoundingClientRect(),
                    m = document.id(this.getDocument().documentElement),
                    p = m.getScroll(),
                    k = this.getScrolls(),
                    i = this.getScroll(),
                    h = (d(this, "position") == "fixed");
                return {
                        x: j.left.toInt() + k.x - i.x + ((h) ? 0 : p.x) - m.clientLeft,
                        y: j.top.toInt() + k.y - i.y + ((h) ? 0 : p.y) - m.clientTop
                    };
            }
            var l = this,
                n = {
                    x: 0,
                    y: 0
                };
            if (b(this)) {
                    return n;
                }
            while (l && !b(l)) {
                    n.x += l.offsetLeft;
                    n.y += l.offsetTop;
                    if (Browser.Engine.gecko) {
                        if (!f(l)) {
                            n.x += c(l);
                            n.y += g(l);
                        }
                        var o = l.parentNode;
                        if (o && d(o, "overflow") != "visible") {
                            n.x += c(o);
                            n.y += g(o);
                        }
                    } else {
                        if (l != this && Browser.Engine.webkit) {
                            n.x += c(l);
                            n.y += g(l);
                        }
                    }
                    l = l.offsetParent;
                }
            if (Browser.Engine.gecko && !f(this)) {
                    n.x -= c(this);
                    n.y -= g(this);
                }
            return n;
        },
        getPosition: function (k) {
            if (b(this)) {
                return {
                    x: 0,
                    y: 0
                };
            }
            var l = this.getOffsets(),
                i = this.getScrolls();
            var h = {
                    x: l.x - i.x,
                    y: l.y - i.y
                };
            var j = (k && (k = document.id(k))) ? k.getPosition() : {
                    x: 0,
                    y: 0
                };
            return {
                    x: h.x - j.x,
                    y: h.y - j.y
                };
        },
        getCoordinates: function (j) {
            if (b(this)) {
                return this.getWindow().getCoordinates();
            }
            var h = this.getPosition(j),
                i = this.getSize();
            var k = {
                    left: h.x,
                    top: h.y,
                    width: i.x,
                    height: i.y
                };
            k.right = k.left + k.width;
            k.bottom = k.top + k.height;
            return k;
        },
        computePosition: function (h) {
            return {
                left: h.x - e(this, "margin-left"),
                top: h.y - e(this, "margin-top")
            };
        },
        setPosition: function (h) {
            return this.setStyles(this.computePosition(h));
        }
    });
    Native.implement([Document, Window], {
        getSize: function () {
            if (Browser.Engine.presto || Browser.Engine.webkit) {
                var i = this.getWindow();
                return {
                    x: i.innerWidth,
                    y: i.innerHeight
                };
            }
            var h = a(this);
            return {
                x: h.clientWidth,
                y: h.clientHeight
            };
        },
        getScroll: function () {
            var i = this.getWindow(),
                h = a(this);
            return {
                    x: i.pageXOffset || h.scrollLeft,
                    y: i.pageYOffset || h.scrollTop
                };
        },
        getScrollSize: function () {
            var i = a(this),
                h = this.getSize();
            return {
                    x: Math.max(i.scrollWidth, h.x),
                    y: Math.max(i.scrollHeight, h.y)
                };
        },
        getPosition: function () {
            return {
                x: 0,
                y: 0
            };
        },
        getCoordinates: function () {
            var h = this.getSize();
            return {
                top: 0,
                left: 0,
                bottom: h.y,
                right: h.x,
                height: h.y,
                width: h.x
            };
        }
    });
    var d = Element.getComputedStyle;

    function e(h, i) {
        return d(h, i).toInt() || 0;
    }
    function f(h) {
        return d(h, "-moz-box-sizing") == "border-box";
    }
    function g(h) {
        return e(h, "border-top-width");
    }
    function c(h) {
        return e(h, "border-left-width");
    }
    function b(h) {
        return (/^(?:body|html)$/i).test(h.tagName);
    }
    function a(h) {
        var i = h.getDocument();
        return (!i.compatMode || i.compatMode == "CSS1Compat") ? i.html : i.body;
    }
})();
Element.alias("setPosition", "position");
Native.implement([Window, Document, Element], {
    getHeight: function () {
        return this.getSize().y;
    },
    getWidth: function () {
        return this.getSize().x;
    },
    getScrollTop: function () {
        return this.getScroll().y;
    },
    getScrollLeft: function () {
        return this.getScroll().x;
    },
    getScrollHeight: function () {
        return this.getScrollSize().y;
    },
    getScrollWidth: function () {
        return this.getScrollSize().x;
    },
    getTop: function () {
        return this.getPosition().y;
    },
    getLeft: function () {
        return this.getPosition().x;
    }
});
Native.implement([Document, Element], {
    getElements: function (h, g) {
        h = h.split(",");
        var c, e = {};
        for (var d = 0, b = h.length; d < b; d++) {
            var a = h[d],
                f = Selectors.Utils.search(this, a, e);
            if (d != 0 && f.item) {
                    f = $A(f);
                }
            c = (d == 0) ? f : (c.item) ? $A(c).concat(f) : c.concat(f);
        }
        return new Elements(c, {
            ddup: (h.length > 1),
            cash: !g
        });
    }
});
Element.implement({
    match: function (b) {
        if (!b || (b == this)) {
            return true;
        }
        var d = Selectors.Utils.parseTagAndID(b);
        var a = d[0],
            e = d[1];
        if (!Selectors.Filters.byID(this, e) || !Selectors.Filters.byTag(this, a)) {
                return false;
            }
        var c = Selectors.Utils.parseSelector(b);
        return (c) ? Selectors.Utils.filter(this, c, {}) : true;
    }
});
var Selectors = {
    Cache: {
        nth: {},
        parsed: {}
    }
};
Selectors.RegExps = {
    id: (/#([\w-]+)/),
    tag: (/^(\w+|\*)/),
    quick: (/^(\w+|\*)$/),
    splitter: (/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g),
    combined: (/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)(["']?)([^\4]*?)\4)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g)
};
Selectors.Utils = {
    chk: function (b, c) {
        if (!c) {
            return true;
        }
        var a = $uid(b);
        if (!c[a]) {
            return c[a] = true;
        }
        return false;
    },
    parseNthArgument: function (h) {
        if (Selectors.Cache.nth[h]) {
            return Selectors.Cache.nth[h];
        }
        var e = h.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/);
        if (!e) {
            return false;
        }
        var g = parseInt(e[1], 10);
        var d = (g || g === 0) ? g : 1;
        var f = e[2] || false;
        var c = parseInt(e[3], 10) || 0;
        if (d != 0) {
            c--;
            while (c < 1) {
                c += d;
            }
            while (c >= d) {
                c -= d;
            }
        } else {
            d = c;
            f = "index";
        }
        switch (f) {
        case "n":
            e = {
                a: d,
                b: c,
                special: "n"
            };
            break;
        case "odd":
            e = {
                a: 2,
                b: 0,
                special: "n"
            };
            break;
        case "even":
            e = {
                a: 2,
                b: 1,
                special: "n"
            };
            break;
        case "first":
            e = {
                a: 0,
                special: "index"
            };
            break;
        case "last":
            e = {
                special: "last-child"
            };
            break;
        case "only":
            e = {
                special: "only-child"
            };
            break;
        default:
            e = {
                a: (d - 1),
                special: "index"
            };
        }
        return Selectors.Cache.nth[h] = e;
    },
    parseSelector: function (e) {
        if (Selectors.Cache.parsed[e]) {
            return Selectors.Cache.parsed[e];
        }
        var d, h = {
            classes: [],
            pseudos: [],
            attributes: []
        };
        while ((d = Selectors.RegExps.combined.exec(e))) {
            var i = d[1],
                g = d[2],
                f = d[3],
                b = d[5],
                c = d[6],
                j = d[7];
            if (i) {
                    h.classes.push(i);
                } else {
                    if (c) {
                        var a = Selectors.Pseudo.get(c);
                        if (a) {
                            h.pseudos.push({
                                parser: a,
                                argument: j
                            });
                        } else {
                            h.attributes.push({
                                name: c,
                                operator: "=",
                                value: j
                            });
                        }
                    } else {
                        if (g) {
                            h.attributes.push({
                                name: g,
                                operator: f,
                                value: b
                            });
                        }
                    }
                }
        }
        if (!h.classes.length) {
            delete h.classes;
        }
        if (!h.attributes.length) {
            delete h.attributes;
        }
        if (!h.pseudos.length) {
            delete h.pseudos;
        }
        if (!h.classes && !h.attributes && !h.pseudos) {
            h = null;
        }
        return Selectors.Cache.parsed[e] = h;
    },
    parseTagAndID: function (b) {
        var a = b.match(Selectors.RegExps.tag);
        var c = b.match(Selectors.RegExps.id);
        return [(a) ? a[1] : "*", (c) ? c[1] : false];
    },
    filter: function (f, c, e) {
        var d;
        if (c.classes) {
            for (d = c.classes.length; d--; d) {
                var g = c.classes[d];
                if (!Selectors.Filters.byClass(f, g)) {
                    return false;
                }
            }
        }
        if (c.attributes) {
            for (d = c.attributes.length;
            d--; d) {
                var b = c.attributes[d];
                if (!Selectors.Filters.byAttribute(f, b.name, b.operator, b.value)) {
                    return false;
                }
            }
        }
        if (c.pseudos) {
            for (d = c.pseudos.length; d--; d) {
                var a = c.pseudos[d];
                if (!Selectors.Filters.byPseudo(f, a.parser, a.argument, e)) {
                    return false;
                }
            }
        }
        return true;
    },
    getByTagAndID: function (b, a, d) {
        if (d) {
            var c = (b.getElementById) ? b.getElementById(d, true) : Element.getElementById(b, d, true);
            return (c && Selectors.Filters.byTag(c, a)) ? [c] : [];
        } else {
            return b.getElementsByTagName(a);
        }
    },
    search: function (o, h, t) {
        var b = [];
        var c = h.trim().replace(Selectors.RegExps.splitter, function (k, j, i) {
            b.push(j);
            return ":)" + i;
        }).split(":)");
        var p, e, A;
        for (var z = 0, v = c.length; z < v; z++) {
            var y = c[z];
            if (z == 0 && Selectors.RegExps.quick.test(y)) {
                p = o.getElementsByTagName(y);
                continue;
            }
            var a = b[z - 1];
            var q = Selectors.Utils.parseTagAndID(y);
            var B = q[0],
                r = q[1];
            if (z == 0) {
                    p = Selectors.Utils.getByTagAndID(o, B, r);
                } else {
                    var d = {},
                        g = [];
                    for (var x = 0, w = p.length;
                        x < w; x++) {
                            g = Selectors.Getters[a](g, p[x], B, r, d);
                        }
                    p = g;
                }
            var f = Selectors.Utils.parseSelector(y);
            if (f) {
                    e = [];
                    for (var u = 0, s = p.length; u < s; u++) {
                        A = p[u];
                        if (Selectors.Utils.filter(A, f, t)) {
                            e.push(A);
                        }
                    }
                    p = e;
                }
        }
        return p;
    }
};
Selectors.Getters = {
    " ": function (h, g, j, a, e) {
        var d = Selectors.Utils.getByTagAndID(g, j, a);
        for (var c = 0, b = d.length; c < b; c++) {
            var f = d[c];
            if (Selectors.Utils.chk(f, e)) {
                h.push(f);
            }
        }
        return h;
    },
    ">": function (h, g, j, a, f) {
        var c = Selectors.Utils.getByTagAndID(g, j, a);
        for (var e = 0, d = c.length; e < d; e++) {
            var b = c[e];
            if (b.parentNode == g && Selectors.Utils.chk(b, f)) {
                h.push(b);
            }
        }
        return h;
    },
    "+": function (c, b, a, e, d) {
        while ((b = b.nextSibling)) {
            if (b.nodeType == 1) {
                if (Selectors.Utils.chk(b, d) && Selectors.Filters.byTag(b, a) && Selectors.Filters.byID(b, e)) {
                    c.push(b);
                }
                break;
            }
        }
        return c;
    },
    "~": function (c, b, a, e, d) {
        while ((b = b.nextSibling)) {
            if (b.nodeType == 1) {
                if (!Selectors.Utils.chk(b, d)) {
                    break;
                }
                if (Selectors.Filters.byTag(b, a) && Selectors.Filters.byID(b, e)) {
                    c.push(b);
                }
            }
        }
        return c;
    }
};
Selectors.Filters = {
    byTag: function (b, a) {
        return (a == "*" || (b.tagName && b.tagName.toLowerCase() == a));
    },
    byID: function (a, b) {
        return (!b || (a.id && a.id == b));
    },
    byClass: function (b, a) {
        return (b.className && b.className.contains && b.className.contains(a, " "));
    },
    byPseudo: function (a, d, c, b) {
        return d.call(a, c, b);
    },
    byAttribute: function (c, d, b, e) {
        var a = Element.prototype.getProperty.call(c, d);
        if (!a) {
            return (b == "!=");
        }
        if (!b || e == undefined) {
            return true;
        }
        switch (b) {
        case "=":
            return (a == e);
        case "*=":
            return (a.contains(e));
        case "^=":
            return (a.substr(0, e.length) == e);
        case "$=":
            return (a.substr(a.length - e.length) == e);
        case "!=":
            return (a != e);
        case "~=":
            return a.contains(e, " ");
        case "|=":
            return a.contains(e, "-");
        }
        return false;
    }
};
Selectors.Pseudo = new Hash({
    checked: function () {
        return this.checked;
    },
    empty: function () {
        return !(this.innerText || this.textContent || "").length;
    },
    not: function (a) {
        return !Element.match(this, a);
    },
    contains: function (a) {
        return (this.innerText || this.textContent || "").contains(a);
    },
    "first-child": function () {
        return Selectors.Pseudo.index.call(this, 0);
    },
    "last-child": function () {
        var a = this;
        while ((a = a.nextSibling)) {
            if (a.nodeType == 1) {
                return false;
            }
        }
        return true;
    },
    "only-child": function () {
        var b = this;
        while ((b = b.previousSibling)) {
            if (b.nodeType == 1) {
                return false;
            }
        }
        var a = this;
        while ((a = a.nextSibling)) {
            if (a.nodeType == 1) {
                return false;
            }
        }
        return true;
    },
    "nth-child": function (g, e) {
        g = (g == undefined) ? "n" : g;
        var c = Selectors.Utils.parseNthArgument(g);
        if (c.special != "n") {
            return Selectors.Pseudo[c.special].call(this, c.a, e);
        }
        var f = 0;
        e.positions = e.positions || {};
        var d = $uid(this);
        if (!e.positions[d]) {
            var b = this;
            while ((b = b.previousSibling)) {
                if (b.nodeType != 1) {
                    continue;
                }
                f++;
                var a = e.positions[$uid(b)];
                if (a != undefined) {
                    f = a + f;
                    break;
                }
            }
            e.positions[d] = f;
        }
        return (e.positions[d] % c.a == c.b);
    },
    index: function (a) {
        var b = this,
            c = 0;
        while ((b = b.previousSibling)) {
                if (b.nodeType == 1 && ++c > a) {
                    return false;
                }
            }
        return (c == a);
    },
    even: function (b, a) {
        return Selectors.Pseudo["nth-child"].call(this, "2n+1", a);
    },
    odd: function (b, a) {
        return Selectors.Pseudo["nth-child"].call(this, "2n", a);
    },
    selected: function () {
        return this.selected;
    },
    enabled: function () {
        return (this.disabled === false);
    }
});
Element.Events.domready = {
    onAdd: function (a) {
        if (Browser.loaded) {
            a.call(this);
        }
    }
};
(function () {
    var b = function () {
        if (Browser.loaded) {
            return;
        }
        Browser.loaded = true;
        window.fireEvent("domready");
        document.fireEvent("domready");
    };
    window.addEvent("load", b);
    if (Browser.Engine.trident) {
        var a = document.createElement("div");
        (function () {
            ($try(function () {
                a.doScroll();
                return document.id(a).inject(document.body).set("html", "temp").dispose();
            })) ? b() : arguments.callee.delay(50);
        })();
    } else {
        if (Browser.Engine.webkit && Browser.Engine.version < 525) {
            (function () {
                (["loaded", "complete"].contains(document.readyState)) ? b() : arguments.callee.delay(50);
            })();
        } else {
            document.addEvent("DOMContentLoaded", b);
        }
    }
})();
var JSON = new Hash(this.JSON && {
    stringify: JSON.stringify,
    parse: JSON.parse
}).extend({
    $specialChars: {
        "\b": "\\b",
        "\t": "\\t",
        "\n": "\\n",
        "\f": "\\f",
        "\r": "\\r",
        '"': '\\"',
        "\\": "\\\\"
    },
    $replaceChars: function (a) {
        return JSON.$specialChars[a] || "\\u00" + Math.floor(a.charCodeAt() / 16).toString(16) + (a.charCodeAt() % 16).toString(16);
    },
    encode: function (b) {
        switch ($type(b)) {
        case "string":
            return '"' + b.replace(/[\x00-\x1f\\"]/g, JSON.$replaceChars) + '"';
        case "array":
            return "[" + String(b.map(JSON.encode).clean()) + "]";
        case "object":
        case "hash":
            var a = [];
            Hash.each(b, function (e, d) {
                var c = JSON.encode(e);
                if (c) {
                    a.push(JSON.encode(d) + ":" + c);
                }
            });
            return "{" + a + "}";
        case "number":
        case "boolean":
            return String(b);
        case false:
            return "null";
        }
        return null;
    },
    decode: function (string, secure) {
        if ($type(string) != "string" || !string.length) {
            return null;
        }
        if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, "@").replace(/"[^"\\\n\r]*"/g, ""))) {
            return null;
        }
        return eval("(" + string + ")");
    }
});
Native.implement([Hash, Array, String, Number], {
    toJSON: function () {
        return JSON.encode(this);
    }
});
var Cookie = new Class({
    Implements: Options,
    options: {
        path: false,
        domain: false,
        duration: false,
        secure: false,
        document: document
    },
    initialize: function (b, a) {
        this.key = b;
        this.setOptions(a);
    },
    write: function (b) {
        b = encodeURIComponent(b);
        if (this.options.domain) {
            b += "; domain=" + this.options.domain;
        }
        if (this.options.path) {
            b += "; path=" + this.options.path;
        }
        if (this.options.duration) {
            var a = new Date();
            a.setTime(a.getTime() + this.options.duration * 24 * 60 * 60 * 1000);
            b += "; expires=" + a.toGMTString();
        }
        if (this.options.secure) {
            b += "; secure";
        }
        this.options.document.cookie = this.key + "=" + b;
        return this;
    },
    read: function () {
        var a = this.options.document.cookie.match("(?:^|;)\\s*" + this.key.escapeRegExp() + "=([^;]*)");
        return (a) ? decodeURIComponent(a[1]) : null;
    },
    dispose: function () {
        new Cookie(this.key, $merge(this.options, {
            duration: -1
        })).write("");
        return this;
    }
});
Cookie.write = function (b, c, a) {
    return new Cookie(b, a).write(c);
};
Cookie.read = function (a) {
    return new Cookie(a).read();
};
Cookie.dispose = function (b, a) {
    return new Cookie(b, a).dispose();
};
var Swiff = new Class({
    Implements: [Options],
    options: {
        id: null,
        height: 1,
        width: 1,
        container: null,
        properties: {},
        params: {
            quality: "high",
            allowScriptAccess: "always",
            wMode: "transparent",
            swLiveConnect: true
        },
        callBacks: {},
        vars: {}
    },
    toElement: function () {
        return this.object;
    },
    initialize: function (l, m) {
        this.instance = "Swiff_" + $time();
        this.setOptions(m);
        m = this.options;
        var b = this.id = m.id || this.instance;
        var a = document.id(m.container);
        Swiff.CallBacks[this.instance] = {};
        var e = m.params,
            g = m.vars,
            f = m.callBacks;
        var h = $extend({
                height: m.height,
                width: m.width
            }, m.properties);
        var k = this;
        for (var d in f) {
                Swiff.CallBacks[this.instance][d] = (function (n) {
                    return function () {
                        return n.apply(k.object, arguments);
                    };
                })(f[d]);
                g[d] = "Swiff.CallBacks." + this.instance + "." + d;
            }
        e.flashVars = Hash.toQueryString(g);
        if (Browser.Engine.trident) {
                h.classid = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
                e.movie = l;
            } else {
                h.type = "application/x-shockwave-flash";
                h.data = l;
            }
        var j = '<object id="' + b + '"';
        for (var i in h) {
                j += " " + i + '="' + h[i] + '"';
            }
        j += ">";
        for (var c in e) {
                if (e[c]) {
                    j += '<param name="' + c + '" value="' + e[c] + '" />';
                }
            }
        j += "</object>";
        this.object = ((a) ? a.empty() : new Element("div")).set("html", j).firstChild;
    },
    replaces: function (a) {
        a = document.id(a, true);
        a.parentNode.replaceChild(this.toElement(), a);
        return this;
    },
    inject: function (a) {
        document.id(a, true).appendChild(this.toElement());
        return this;
    },
    remote: function () {
        return Swiff.remote.apply(Swiff, [this.toElement()].extend(arguments));
    }
});
Swiff.CallBacks = {};
Swiff.remote = function (obj, fn) {
    var rs = obj.CallFunction('<invoke name="' + fn + '" returntype="javascript">' + __flash__argumentsToXML(arguments, 2) + "</invoke>");
    return eval(rs);
};
var Fx = new Class({
    Implements: [Chain, Events, Options],
    options: {
        fps: 50,
        unit: false,
        duration: 500,
        link: "ignore"
    },
    initialize: function (a) {
        this.subject = this.subject || this;
        this.setOptions(a);
        this.options.duration = Fx.Durations[this.options.duration] || this.options.duration.toInt();
        var b = this.options.wait;
        if (b === false) {
            this.options.link = "cancel";
        }
    },
    getTransition: function () {
        return function (a) {
            return -(Math.cos(Math.PI * a) - 1) / 2;
        };
    },
    step: function () {
        var a = $time();
        if (a < this.time + this.options.duration) {
            var b = this.transition((a - this.time) / this.options.duration);
            this.set(this.compute(this.from, this.to, b));
        } else {
            this.set(this.compute(this.from, this.to, 1));
            this.complete();
        }
    },
    set: function (a) {
        return a;
    },
    compute: function (c, b, a) {
        return Fx.compute(c, b, a);
    },
    check: function () {
        if (!this.timer) {
            return true;
        }
        switch (this.options.link) {
        case "cancel":
            this.cancel();
            return true;
        case "chain":
            this.chain(this.caller.bind(this, arguments));
            return false;
        }
        return false;
    },
    start: function (b, a) {
        if (!this.check(b, a)) {
            return this;
        }
        this.from = b;
        this.to = a;
        this.time = 0;
        this.transition = this.getTransition();
        this.startTimer();
        this.onStart();
        return this;
    },
    complete: function () {
        if (this.stopTimer()) {
            this.onComplete();
        }
        return this;
    },
    cancel: function () {
        if (this.stopTimer()) {
            this.onCancel();
        }
        return this;
    },
    onStart: function () {
        this.fireEvent("start", this.subject);
    },
    onComplete: function () {
        this.fireEvent("complete", this.subject);
        if (!this.callChain()) {
            this.fireEvent("chainComplete", this.subject);
        }
    },
    onCancel: function () {
        this.fireEvent("cancel", this.subject).clearChain();
    },
    pause: function () {
        this.stopTimer();
        return this;
    },
    resume: function () {
        this.startTimer();
        return this;
    },
    stopTimer: function () {
        if (!this.timer) {
            return false;
        }
        this.time = $time() - this.time;
        this.timer = $clear(this.timer);
        return true;
    },
    startTimer: function () {
        if (this.timer) {
            return false;
        }
        this.time = $time() - this.time;
        this.timer = this.step.periodical(Math.round(1000 / this.options.fps), this);
        return true;
    }
});
Fx.compute = function (c, b, a) {
    return (b - c) * a + c;
};
Fx.Durations = {
    "short": 250,
    normal: 500,
    "long": 1000
};
Fx.CSS = new Class({
    Extends: Fx,
    prepare: function (d, e, b) {
        b = $splat(b);
        var c = b[1];
        if (!$chk(c)) {
            b[1] = b[0];
            b[0] = d.getStyle(e);
        }
        var a = b.map(this.parse);
        return {
            from: a[0],
            to: a[1]
        };
    },
    parse: function (a) {
        a = $lambda(a)();
        a = (typeof a == "string") ? a.split(" ") : $splat(a);
        return a.map(function (c) {
            c = String(c);
            var b = false;
            Fx.CSS.Parsers.each(function (f, e) {
                if (b) {
                    return;
                }
                var d = f.parse(c);
                if ($chk(d)) {
                    b = {
                        value: d,
                        parser: f
                    };
                }
            });
            b = b || {
                value: c,
                parser: Fx.CSS.Parsers.String
            };
            return b;
        });
    },
    compute: function (d, c, b) {
        var a = [];
        (Math.min(d.length, c.length)).times(function (e) {
            a.push({
                value: d[e].parser.compute(d[e].value, c[e].value, b),
                parser: d[e].parser
            });
        });
        a.$family = {
            name: "fx:css:value"
        };
        return a;
    },
    serve: function (c, b) {
        if ($type(c) != "fx:css:value") {
            c = this.parse(c);
        }
        var a = [];
        c.each(function (d) {
            a = a.concat(d.parser.serve(d.value, b));
        });
        return a;
    },
    render: function (a, d, c, b) {
        a.setStyle(d, this.serve(c, b));
    },
    search: function (a) {
        if (Fx.CSS.Cache[a]) {
            return Fx.CSS.Cache[a];
        }
        var b = {};
        Array.each(document.styleSheets, function (e, d) {
            var c = e.href;
            if (c && c.contains("://") && !c.contains(document.domain)) {
                return;
            }
            var f = e.rules || e.cssRules;
            Array.each(f, function (j, g) {
                if (!j.style) {
                    return;
                }
                var h = (j.selectorText) ? j.selectorText.replace(/^\w+/, function (i) {
                    return i.toLowerCase();
                }) : null;
                if (!h || !h.test("^" + a + "$")) {
                    return;
                }
                Element.Styles.each(function (k, i) {
                    if (!j.style[i] || Element.ShortStyles[i]) {
                        return;
                    }
                    k = String(j.style[i]);
                    b[i] = (k.test(/^rgb/)) ? k.rgbToHex() : k;
                });
            });
        });
        return Fx.CSS.Cache[a] = b;
    }
});
Fx.CSS.Cache = {};
Fx.CSS.Parsers = new Hash({
    Color: {
        parse: function (a) {
            if (a.match(/^#[0-9a-f]{3,6}$/i)) {
                return a.hexToRgb(true);
            }
            return ((a = a.match(/(\d+),\s*(\d+),\s*(\d+)/))) ? [a[1], a[2], a[3]] : false;
        },
        compute: function (c, b, a) {
            return c.map(function (e, d) {
                return Math.round(Fx.compute(c[d], b[d], a));
            });
        },
        serve: function (a) {
            return a.map(Number);
        }
    },
    Number: {
        parse: parseFloat,
        compute: Fx.compute,
        serve: function (b, a) {
            return (a) ? b + a : b;
        }
    },
    String: {
        parse: $lambda(false),
        compute: $arguments(1),
        serve: $arguments(0)
    }
});
Fx.Tween = new Class({
    Extends: Fx.CSS,
    initialize: function (b, a) {
        this.element = this.subject = document.id(b);
        this.parent(a);
    },
    set: function (b, a) {
        if (arguments.length == 1) {
            a = b;
            b = this.property || this.options.property;
        }
        this.render(this.element, b, a, this.options.unit);
        return this;
    },
    start: function (c, e, d) {
        if (!this.check(c, e, d)) {
            return this;
        }
        var b = Array.flatten(arguments);
        this.property = this.options.property || b.shift();
        var a = this.prepare(this.element, this.property, b);
        return this.parent(a.from, a.to);
    }
});
Element.Properties.tween = {
    set: function (a) {
        var b = this.retrieve("tween");
        if (b) {
            b.cancel();
        }
        return this.eliminate("tween").store("tween:options", $extend({
            link: "cancel"
        }, a));
    },
    get: function (a) {
        if (a || !this.retrieve("tween")) {
            if (a || !this.retrieve("tween:options")) {
                this.set("tween", a);
            }
            this.store("tween", new Fx.Tween(this, this.retrieve("tween:options")));
        }
        return this.retrieve("tween");
    }
};
Element.implement({
    tween: function (a, c, b) {
        this.get("tween").start(arguments);
        return this;
    },
    fade: function (c) {
        var e = this.get("tween"),
            d = "opacity",
            a;
        c = $pick(c, "toggle");
        switch (c) {
            case "in":
                e.start(d, 1);
                break;
            case "out":
                e.start(d, 0);
                break;
            case "show":
                e.set(d, 1);
                break;
            case "hide":
                e.set(d, 0);
                break;
            case "toggle":
                var b = this.retrieve("fade:flag", this.get("opacity") == 1);
                e.start(d, (b) ? 0 : 1);
                this.store("fade:flag", !b);
                a = true;
                break;
            default:
                e.start(d, arguments);
            }
        if (!a) {
                this.eliminate("fade:flag");
            }
        return this;
    },
    highlight: function (c, a) {
        if (!a) {
            a = this.retrieve("highlight:original", this.getStyle("background-color"));
            a = (a == "transparent") ? "#fff" : a;
        }
        var b = this.get("tween");
        b.start("background-color", c || "#ffff88", a).chain(function () {
            this.setStyle("background-color", this.retrieve("highlight:original"));
            b.callChain();
        }.bind(this));
        return this;
    }
});
Fx.Morph = new Class({
    Extends: Fx.CSS,
    initialize: function (b, a) {
        this.element = this.subject = document.id(b);
        this.parent(a);
    },
    set: function (a) {
        if (typeof a == "string") {
            a = this.search(a);
        }
        for (var b in a) {
            this.render(this.element, b, a[b], this.options.unit);
        }
        return this;
    },
    compute: function (e, d, c) {
        var a = {};
        for (var b in e) {
            a[b] = this.parent(e[b], d[b], c);
        }
        return a;
    },
    start: function (b) {
        if (!this.check(b)) {
            return this;
        }
        if (typeof b == "string") {
            b = this.search(b);
        }
        var e = {},
            d = {};
        for (var c in b) {
                var a = this.prepare(this.element, c, b[c]);
                e[c] = a.from;
                d[c] = a.to;
            }
        return this.parent(e, d);
    }
});
Element.Properties.morph = {
    set: function (a) {
        var b = this.retrieve("morph");
        if (b) {
            b.cancel();
        }
        return this.eliminate("morph").store("morph:options", $extend({
            link: "cancel"
        }, a));
    },
    get: function (a) {
        if (a || !this.retrieve("morph")) {
            if (a || !this.retrieve("morph:options")) {
                this.set("morph", a);
            }
            this.store("morph", new Fx.Morph(this, this.retrieve("morph:options")));
        }
        return this.retrieve("morph");
    }
};
Element.implement({
    morph: function (a) {
        this.get("morph").start(a);
        return this;
    }
});
Fx.implement({
    getTransition: function () {
        var a = this.options.transition || Fx.Transitions.Sine.easeInOut;
        if (typeof a == "string") {
            var b = a.split(":");
            a = Fx.Transitions;
            a = a[b[0]] || a[b[0].capitalize()];
            if (b[1]) {
                a = a["ease" + b[1].capitalize() + (b[2] ? b[2].capitalize() : "")];
            }
        }
        return a;
    }
});
Fx.Transition = function (b, a) {
    a = $splat(a);
    return $extend(b, {
        easeIn: function (c) {
            return b(c, a);
        },
        easeOut: function (c) {
            return 1 - b(1 - c, a);
        },
        easeInOut: function (c) {
            return (c <= 0.5) ? b(2 * c, a) / 2 : (2 - b(2 * (1 - c), a)) / 2;
        }
    });
};
Fx.Transitions = new Hash({
    linear: $arguments(0)
});
Fx.Transitions.extend = function (a) {
    for (var b in a) {
        Fx.Transitions[b] = new Fx.Transition(a[b]);
    }
};
Fx.Transitions.extend({
    Pow: function (b, a) {
        return Math.pow(b, a[0] || 6);
    },
    Expo: function (a) {
        return Math.pow(2, 8 * (a - 1));
    },
    Circ: function (a) {
        return 1 - Math.sin(Math.acos(a));
    },
    Sine: function (a) {
        return 1 - Math.sin((1 - a) * Math.PI / 2);
    },
    Back: function (b, a) {
        a = a[0] || 1.618;
        return Math.pow(b, 2) * ((a + 1) * b - a);
    },
    Bounce: function (f) {
        var e;
        for (var d = 0, c = 1; 1; d += c, c /= 2) {
            if (f >= (7 - 4 * d) / 11) {
                e = c * c - Math.pow((11 - 6 * d - 11 * f) / 4, 2);
                break;
            }
        }
        return e;
    },
    Elastic: function (b, a) {
        return Math.pow(2, 10 * --b) * Math.cos(20 * b * Math.PI * (a[0] || 1) / 3);
    }
});
["Quad", "Cubic", "Quart", "Quint"].each(function (b, a) {
    Fx.Transitions[b] = new Fx.Transition(function (c) {
        return Math.pow(c, [a + 2]);
    });
});
var Request = new Class({
    Implements: [Chain, Events, Options],
    options: {
        url: "",
        data: "",
        headers: {
            "X-Requested-With": "XMLHttpRequest",
            Accept: "text/javascript, text/html, application/xml, text/xml, */*"
        },
        async: true,
        format: false,
        method: "post",
        link: "ignore",
        isSuccess: null,
        emulation: true,
        urlEncoded: true,
        encoding: "utf-8",
        evalScripts: false,
        evalResponse: false,
        noCache: false
    },
    initialize: function (a) {
        this.xhr = new Browser.Request();
        this.setOptions(a);
        this.options.isSuccess = this.options.isSuccess || this.isSuccess;
        this.headers = new Hash(this.options.headers);
    },
    onStateChange: function () {
        if (this.xhr.readyState != 4 || !this.running) {
            return;
        }
        this.running = false;
        this.status = 0;
        $try(function () {
            this.status = this.xhr.status;
        }.bind(this));
        this.xhr.onreadystatechange = $empty;
        if (this.options.isSuccess.call(this, this.status)) {
            this.response = {
                text: this.xhr.responseText,
                xml: this.xhr.responseXML
            };
            this.success(this.response.text, this.response.xml);
        } else {
            this.response = {
                text: null,
                xml: null
            };
            this.failure();
        }
    },
    isSuccess: function () {
        return ((this.status >= 200) && (this.status < 300));
    },
    processScripts: function (a) {
        if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader("Content-type"))) {
            return $exec(a);
        }
        return a.stripScripts(this.options.evalScripts);
    },
    success: function (b, a) {
        this.onSuccess(this.processScripts(b), a);
    },
    onSuccess: function () {
        this.fireEvent("complete", arguments).fireEvent("success", arguments).callChain();
    },
    failure: function () {
        this.onFailure();
    },
    onFailure: function () {
        this.fireEvent("complete").fireEvent("failure", this.xhr);
    },
    setHeader: function (a, b) {
        this.headers.set(a, b);
        return this;
    },
    getHeader: function (a) {
        return $try(function () {
            return this.xhr.getResponseHeader(a);
        }.bind(this));
    },
    check: function () {
        if (!this.running) {
            return true;
        }
        switch (this.options.link) {
        case "cancel":
            this.cancel();
            return true;
        case "chain":
            this.chain(this.caller.bind(this, arguments));
            return false;
        }
        return false;
    },
    send: function (k) {
        if (!this.check(k)) {
            return this;
        }
        this.running = true;
        var i = $type(k);
        if (i == "string" || i == "element") {
            k = {
                data: k
            };
        }
        var d = this.options;
        k = $extend({
            data: d.data,
            url: d.url,
            method: d.method
        }, k);
        var g = k.data,
            b = String(k.url),
            a = k.method.toLowerCase();
        switch ($type(g)) {
            case "element":
                g = document.id(g).toQueryString();
                break;
            case "object":
            case "hash":
                g = Hash.toQueryString(g);
            }
        if (this.options.format) {
                var j = "format=" + this.options.format;
                g = (g) ? j + "&" + g : j;
            }
        if (this.options.emulation && !["get", "post"].contains(a)) {
                var h = "_method=" + a;
                g = (g) ? h + "&" + g : h;
                a = "post";
            }
        if (this.options.urlEncoded && a == "post") {
                var c = (this.options.encoding) ? "; charset=" + this.options.encoding : "";
                this.headers.set("Content-type", "application/x-www-form-urlencoded" + c);
            }
        if (this.options.noCache) {
                var f = "noCache=" + new Date().getTime();
                g = (g) ? f + "&" + g : f;
            }
        var e = b.lastIndexOf("/");
        if (e > -1 && (e = b.indexOf("#")) > -1) {
                b = b.substr(0, e);
            }
        if (g && a == "get") {
                b = b + (b.contains("?") ? "&" : "?") + g;
                g = null;
            }
        this.xhr.open(a.toUpperCase(), b, this.options.async);
        this.xhr.onreadystatechange = this.onStateChange.bind(this);
        this.headers.each(function (m, l) {
                try {
                    this.xhr.setRequestHeader(l, m);
                } catch (n) {
                    this.fireEvent("exception", [l, m]);
                }
            }, this);
        this.fireEvent("request");
        this.xhr.send(g);
        if (!this.options.async) {
                this.onStateChange();
            }
        return this;
    },
    cancel: function () {
        if (!this.running) {
            return this;
        }
        this.running = false;
        this.xhr.abort();
        this.xhr.onreadystatechange = $empty;
        this.xhr = new Browser.Request();
        this.fireEvent("cancel");
        return this;
    }
});
(function () {
    var a = {};
    ["get", "post", "put", "delete", "GET", "POST", "PUT", "DELETE"].each(function (b) {
        a[b] = function () {
            var c = Array.link(arguments, {
                url: String.type,
                data: $defined
            });
            return this.send($extend(c, {
                method: b
            }));
        };
    });
    Request.implement(a);
})();
Element.Properties.send = {
    set: function (a) {
        var b = this.retrieve("send");
        if (b) {
            b.cancel();
        }
        return this.eliminate("send").store("send:options", $extend({
            data: this,
            link: "cancel",
            method: this.get("method") || "post",
            url: this.get("action")
        }, a));
    },
    get: function (a) {
        if (a || !this.retrieve("send")) {
            if (a || !this.retrieve("send:options")) {
                this.set("send", a);
            }
            this.store("send", new Request(this.retrieve("send:options")));
        }
        return this.retrieve("send");
    }
};
Element.implement({
    send: function (a) {
        var b = this.get("send");
        b.send({
            data: this,
            url: a || b.options.url
        });
        return this;
    }
});
Request.HTML = new Class({
    Extends: Request,
    options: {
        update: false,
        append: false,
        evalScripts: true,
        filter: false
    },
    processHTML: function (c) {
        var b = c.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
        c = (b) ? b[1] : c;
        var a = new Element("div");
        return $try(function () {
            var d = "<root>" + c + "</root>",
                g;
            if (Browser.Engine.trident) {
                    g = new ActiveXObject("Microsoft.XMLDOM");
                    g.async = false;
                    g.loadXML(d);
                } else {
                    g = new DOMParser().parseFromString(d, "text/xml");
                }
            d = g.getElementsByTagName("root")[0];
            if (!d) {
                    return null;
                }
            for (var f = 0, e = d.childNodes.length;
                f < e; f++) {
                    var h = Element.clone(d.childNodes[f], true, true);
                    if (h) {
                        a.grab(h);
                    }
                }
            return a;
        }) || a.set("html", c);
    },
    success: function (d) {
        var c = this.options,
            b = this.response;
        b.html = d.stripScripts(function (e) {
                b.javascript = e;
            });
        var a = this.processHTML(b.html);
        b.tree = a.childNodes;
        b.elements = a.getElements("*");
        if (c.filter) {
                b.tree = b.elements.filter(c.filter);
            }
        if (c.update) {
                document.id(c.update).empty().set("html", b.html);
            } else {
                if (c.append) {
                    document.id(c.append).adopt(a.getChildren());
                }
            }
        if (c.evalScripts) {
                $exec(b.javascript);
            }
        this.onSuccess(b.tree, b.elements, b.html, b.javascript);
    }
});
Element.Properties.load = {
    set: function (a) {
        var b = this.retrieve("load");
        if (b) {
            b.cancel();
        }
        return this.eliminate("load").store("load:options", $extend({
            data: this,
            link: "cancel",
            update: this,
            method: "get"
        }, a));
    },
    get: function (a) {
        if (a || !this.retrieve("load")) {
            if (a || !this.retrieve("load:options")) {
                this.set("load", a);
            }
            this.store("load", new Request.HTML(this.retrieve("load:options")));
        }
        return this.retrieve("load");
    }
};
Element.implement({
    load: function () {
        this.get("load").send(Array.link(arguments, {
            data: Object.type,
            url: String.type
        }));
        return this;
    }
});
Request.JSON = new Class({
    Extends: Request,
    options: {
        secure: true
    },
    initialize: function (a) {
        this.parent(a);
        this.headers.extend({
            Accept: "application/json",
            "X-Request": "JSON"
        });
    },
    success: function (a) {
        this.response.json = JSON.decode(a, this.options.secure);
        this.onSuccess(this.response.json, a);
    }
});

// Here starts ../inc/mootools-1.2.4.4-more.js
//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2009 Aaron Newton <http://clientcide.com/>, Valerio Proietti <http://mad4milk.net> & the MooTools team <http://mootools.net/developers>, MIT Style License.
MooTools.More = {
    version: "1.2.4.4",
    build: "6f6057dc645fdb7547689183b2311063bd653ddf"
};
(function () {
    var c = this;
    var b = function () {
        if (c.console && console.log) {
            try {
                console.log.apply(console, arguments);
            } catch (d) {
                console.log(Array.slice(arguments));
            }
        } else {
            Log.logged.push(arguments);
        }
        return this;
    };
    var a = function () {
        this.logged.push(arguments);
        return this;
    };
    this.Log = new Class({
        logged: [],
        log: a,
        resetLog: function () {
            this.logged.empty();
            return this;
        },
        enableLog: function () {
            this.log = b;
            this.logged.each(function (d) {
                this.log.apply(this, d);
            }, this);
            return this.resetLog();
        },
        disableLog: function () {
            this.log = a;
            return this;
        }
    });
    Log.extend(new Log).enableLog();
    Log.logger = function () {
        return this.log.apply(this, arguments);
    };
})();
Fx.Scroll = new Class({
    Extends: Fx,
    options: {
        offset: {
            x: 0,
            y: 0
        },
        wheelStops: true
    },
    initialize: function (b, a) {
        this.element = this.subject = document.id(b);
        this.parent(a);
        var d = this.cancel.bind(this, false);
        if ($type(this.element) != "element") {
            this.element = document.id(this.element.getDocument().body);
        }
        var c = this.element;
        if (this.options.wheelStops) {
            this.addEvent("start", function () {
                c.addEvent("mousewheel", d);
            }, true);
            this.addEvent("complete", function () {
                c.removeEvent("mousewheel", d);
            }, true);
        }
    },
    set: function () {
        var a = Array.flatten(arguments);
        if (Browser.Engine.gecko) {
            a = [Math.round(a[0]), Math.round(a[1])];
        }
        this.element.scrollTo(a[0], a[1]);
    },
    compute: function (c, b, a) {
        return [0, 1].map(function (d) {
            return Fx.compute(c[d], b[d], a);
        });
    },
    start: function (c, g) {
        if (!this.check(c, g)) {
            return this;
        }
        var e = this.element.getScrollSize(),
            b = this.element.getScroll(),
            d = {
                x: c,
                y: g
            };
        for (var f in d) {
                var a = e[f];
                if ($chk(d[f])) {
                    d[f] = ($type(d[f]) == "number") ? d[f] : a;
                } else {
                    d[f] = b[f];
                }
                d[f] += this.options.offset[f];
            }
        return this.parent([b.x, b.y], [d.x, d.y]);
    },
    toTop: function () {
        return this.start(false, 0);
    },
    toLeft: function () {
        return this.start(0, false);
    },
    toRight: function () {
        return this.start("right", false);
    },
    toBottom: function () {
        return this.start(false, "bottom");
    },
    toElement: function (b) {
        var a = document.id(b).getPosition(this.element);
        return this.start(a.x, a.y);
    },
    scrollIntoView: function (c, e, d) {
        e = e ? $splat(e) : ["x", "y"];
        var h = {};
        c = document.id(c);
        var f = c.getPosition(this.element);
        var i = c.getSize();
        var g = this.element.getScroll();
        var a = this.element.getSize();
        var b = {
            x: f.x + i.x,
            y: f.y + i.y
        };
        ["x", "y"].each(function (j) {
            if (e.contains(j)) {
                if (b[j] > g[j] + a[j]) {
                    h[j] = b[j] - a[j];
                }
                if (f[j] < g[j]) {
                    h[j] = f[j];
                }
            }
            if (h[j] == null) {
                h[j] = g[j];
            }
            if (d && d[j]) {
                h[j] = h[j] + d[j];
            }
        }, this);
        if (h.x != g.x || h.y != g.y) {
            this.start(h.x, h.y);
        }
        return this;
    },
    scrollToCenter: function (c, e, d) {
        e = e ? $splat(e) : ["x", "y"];
        c = $(c);
        var h = {},
            f = c.getPosition(this.element),
            i = c.getSize(),
            g = this.element.getScroll(),
            a = this.element.getSize(),
            b = {
                x: f.x + i.x,
                y: f.y + i.y
            };
            ["x", "y"].each(function (j) {
                if (e.contains(j)) {
                    h[j] = f[j] - (a[j] - i[j]) / 2;
                }
                if (h[j] == null) {
                    h[j] = g[j];
                }
                if (d && d[j]) {
                    h[j] = h[j] + d[j];
                }
            }, this);
        if (h.x != g.x || h.y != g.y) {
                this.start(h.x, h.y);
            }
        return this;
    }
});
Request.JSONP = new Class({
    Implements: [Chain, Events, Options, Log],
    options: {
        url: "",
        data: {},
        retries: 0,
        timeout: 0,
        link: "ignore",
        callbackKey: "callback",
        injectScript: document.head
    },
    initialize: function (a) {
        this.setOptions(a);
        if (this.options.log) {
            this.enableLog();
        }
        this.running = false;
        this.requests = 0;
        this.triesRemaining = [];
    },
    check: function () {
        if (!this.running) {
            return true;
        }
        switch (this.options.link) {
        case "cancel":
            this.cancel();
            return true;
        case "chain":
            this.chain(this.caller.bind(this, arguments));
            return false;
        }
        return false;
    },
    send: function (c) {
        if (!$chk(arguments[1]) && !this.check(c)) {
            return this;
        }
        var e = $type(c),
            a = this.options,
            b = $chk(arguments[1]) ? arguments[1] : this.requests++;
        if (e == "string" || e == "element") {
                c = {
                    data: c
                };
            }
        c = $extend({
                data: a.data,
                url: a.url
            }, c);
        if (!$chk(this.triesRemaining[b])) {
                this.triesRemaining[b] = this.options.retries;
            }
        var d = this.triesRemaining[b];
            (function () {
                var f = this.getScript(c);
                this.log("JSONP retrieving script with url: " + f.get("src"));
                this.fireEvent("request", f);
                this.running = true;
                (function () {
                    if (d) {
                        this.triesRemaining[b] = d - 1;
                        if (f) {
                            f.destroy();
                            this.send(c, b).fireEvent("retry", this.triesRemaining[b]);
                        }
                    } else {
                        if (f && this.options.timeout) {
                            f.destroy();
                            this.cancel().fireEvent("failure");
                        }
                    }
                }).delay(this.options.timeout, this);
            }).delay(Browser.Engine.trident ? 50 : 0, this);
        return this;
    },
    cancel: function () {
        if (!this.running) {
            return this;
        }
        this.running = false;
        this.fireEvent("cancel");
        return this;
    },
    getScript: function (c) {
        var b = Request.JSONP.counter,
            d;
        Request.JSONP.counter++;
        switch ($type(c.data)) {
            case "element":
                d = document.id(c.data).toQueryString();
                break;
            case "object":
            case "hash":
                d = Hash.toQueryString(c.data);
            }
        var e = c.url + (c.url.test("\\?") ? "&" : "?") + (c.callbackKey || this.options.callbackKey) + "=Request.JSONP.request_map.request_" + b + (d ? "&" + d : "");
        if (e.length > 2083) {
                this.log("JSONP " + e + " will fail in Internet Explorer, which enforces a 2083 bytes length limit on URIs");
            }
        var a = new Element("script", {
                type: "text/javascript",
                src: e
            });
        Request.JSONP.request_map["request_" + b] = function () {
                this.success(arguments, a);
            }.bind(this);
        return a.inject(this.options.injectScript);
    },
    success: function (b, a) {
        if (a) {
            a.destroy();
        }
        this.running = false;
        this.log("JSONP successfully retrieved: ", b);
        this.fireEvent("complete", b).fireEvent("success", b).callChain();
    }
});
Request.JSONP.counter = 0;
Request.JSONP.request_map = {};
var Asset = {
    javascript: function (f, d) {
        d = $extend({
            onload: $empty,
            document: document,
            check: $lambda(true)
        }, d);
        if (d.onLoad) {
            d.onload = d.onLoad;
        }
        var b = new Element("script", {
            src: f,
            type: "text/javascript"
        });
        var e = d.onload.bind(b),
            a = d.check,
            g = d.document;
        delete d.onload;
        delete d.check;
        delete d.document;
        b.addEvents({
                load: e,
                readystatechange: function () {
                    if (["loaded", "complete"].contains(this.readyState)) {
                        e();
                    }
                }
            }).set(d);
        if (Browser.Engine.webkit419) {
                var c = (function () {
                    if (!$try(a)) {
                        return;
                    }
                    $clear(c);
                    e();
                }).periodical(50);
            }
        return b.inject(g.head);
    },
    css: function (b, a) {
        return new Element("link", $merge({
            rel: "stylesheet",
            media: "screen",
            type: "text/css",
            href: b
        }, a)).inject(document.head);
    },
    image: function (c, b) {
        b = $merge({
            onload: $empty,
            onabort: $empty,
            onerror: $empty
        }, b);
        var d = new Image();
        var a = document.id(d) || new Element("img");
        ["load", "abort", "error"].each(function (e) {
            var g = "on" + e;
            var f = e.capitalize();
            if (b["on" + f]) {
                b[g] = b["on" + f];
            }
            var h = b[g];
            delete b[g];
            d[g] = function () {
                if (!d) {
                    return;
                }
                if (!a.parentNode) {
                    a.width = d.width;
                    a.height = d.height;
                }
                d = d.onload = d.onabort = d.onerror = null;
                h.delay(1, a, a);
                a.fireEvent(e, a, 1);
            };
        });
        d.src = a.src = c;
        if (d && d.complete) {
            d.onload.delay(1);
        }
        return a.set(b);
    },
    images: function (d, c) {
        c = $merge({
            onComplete: $empty,
            onProgress: $empty,
            onError: $empty,
            properties: {}
        }, c);
        d = $splat(d);
        var a = [];
        var b = 0;
        return new Elements(d.map(function (e) {
            return Asset.image(e, $extend(c.properties, {
                onload: function () {
                    c.onProgress.call(this, b, d.indexOf(e));
                    b++;
                    if (b == d.length) {
                        c.onComplete();
                    }
                },
                onerror: function () {
                    c.onError.call(this, b, d.indexOf(e));
                    b++;
                    if (b == d.length) {
                        c.onComplete();
                    }
                }
            }));
        }));
    }
};

// Here starts ../inc/kishlery.js

var Kishlery = new Class({
    Implements: Options,
    nodes: null,
    owner_id: null,
    ownername: null,
    showOwner: null,
    mainContainer: null,
    picsContainer: null,
    previous: null,
    current: null,
    buttons: null,
    thumbnails: null,
    thumbsContainer: null,
    mosaic: null,
    dashboard: null,
    myPictures: new Array(),
    isPicChecked: new Array(),
    isPicLoaded: new Array(),
    myThumbs: new Array(),
    isThumbLoaded: new Array(),
    myThumbs2: new Array(),
    stopLoading: null,
    scroll: null,
    scrollThumbs: null,
    title: null,
    reqPos: null,
    url: null,
    preCounter: null,
    log: new Array(),
    options: {
        buffer: 5,
        interval: 4000,
        flip: false,
        id: '',
        mode: 'photoset',
        limit: '',
        tags: '',
        sort: 'date-posted-desc',
        maxSize: 0,
        forceHeight: false,
        linkToFlickr: true,
        activateKeyboard: true,
        showTitle: true,
        showOwner: true,
        showButtons: true,
        showThumbnails: true,
        showMosaic: true,
        showMosaicImmediately: false,
        bigMosaic: true,
        singleMode: false,
        playImmediately: true,
        centeringMargin: true,
        showLog: false,
        quickView: true
    },
    initialize: function (el, options) {
	//this.randomizeNo;
        this.mainContainer = $(el);
        if (!this.mainContainer) {
            this.log.push('Error: div ' + el + ' not found.');
            this.displayLog();
            return;
        }
        var root = window.location.href.contains('kishnel.dev') ? 'http://www.kishnel.dev/kishlery' : 'http://www.kishnel.com/kishlery';
        this.setOptions(options);
        new Asset.css(root + '/inc/kishlery.css');
        if (this.options.maxSize) this.options.maxSize = this.options.maxSize.toInt();
        if (this.options.singleMode) {
            window.addEvent('resize', function () {
                this.adaptToContainer(false);
                QuickView.cancel();
            }.bind(this));
        }
        window.addEvent('scroll', QuickView.cancel);
        this.reqPos = document.location.hash.substr(1) * 1;
        var self = this;
        this.url = root + '/inc/kishlery.php';
        new Request.JSONP({
            url: this.url,
            data: {
                id: this.options.id,
                per_page: this.options.limit,
                mode: this.options.mode,
                tags: this.options.tags,
                sort: this.options.sort
            },
            onComplete: function (json) {
                self.nextStep(json);
            }
        }).send();
    },
    nextStep: function (json) {
        if (!json) return;
        var obj = this;
        var randOrd = function () {
            return (Math.round(Math.random()) - 0.5);
        }
        this.log = json.log;
        switch (this.options.mode) {
        case 'photoset':
            if (!json.photoset) {
                obj.log.push('Error: ' + json.message);
                obj.displayLog();
                return;
            }
            this.nodes = json.photoset.photo;
            this.owner_id = json.photoset.owner;
            this.ownername = json.photoset.ownername;
            break;
        case 'user':
            if (!json.photos) {
                obj.displayLog();
                return;
            }
            if (json.photos.total.toInt() == 0) {
                obj.log.push('Error: no pictures found.');
                obj.displayLog();
                return;
            }
            this.nodes = json.photos.photo;
            this.owner_id = json.photos.photo[0].owner;
            this.ownername = this.options.id;
            break;
        case 'group':
            if (!json.photos) {
                obj.displayLog();
                return;
            }
            if (!json.photos.total) {
                obj.log.push('Error: no pictures found.');
                obj.displayLog();
                return;
            }
            this.nodes = json.photos.photo;
            break;
        case 'folder':
            if (!json.photos) {
                obj.displayLog();
                return;
            }
            this.nodes = json.photos.photo;
            this.options.linkToFlickr = false;
            break;
        }
        this.doHTML();
        if (this.options.sort == 'random') this.nodes.sort(randOrd);
        if (this.nodes.length <= this.options.buffer) this.options.buffer = this.nodes.length;
        this.keyboardControls();
        this.scroll = new Fx.Scroll(this.picsContainer, {
            wait: false,
            duration: 800,
            transition: Fx.Transitions.Quint.easeInOut
        });
        if (this.options.singleMode) {
            this.play = new Slideshow2(this.picsContainer);
        }
        else {
            this.play = new Slideshow(this.picsContainer, {
                wait: true,
                transition: Fx.Transitions.linear,
                onStart: function () {
                    if (obj.buttons) obj.buttons.getElement('.KLplay').addClass('pause');
                },
                onComplete: function () {
                    if (obj.buttons) obj.buttons.getElement('.KLplay').removeClass('pause');
                },
                onCancel: function () {
                    if (obj.buttons) obj.buttons.getElement('.KLplay').removeClass('pause');
                }
            });
        }
        this.load(0);
    },
    doHTML: function () {
        this.preCounter = new Element('span').addClass('KLpre_counter').set('html', '<span>Loading...</span>').inject(this.mainContainer);
        this.picsContainer = new Element('div').addClass('KLpics_container');
        if (this.options.singleMode) {
            var self = this;
            this.picsContainer.set('morph', {
                onComplete: function () {
                    self.myPictures[self.current].tween('opacity', 1);
                }
            });
            this.mainContainer.addClass('KLsingle_mode');
        }
	// this.randomizeNo();
        if (this.options.maxSize) this.picsContainer.setStyle('height', this.options.maxSize + 'px');
        this.picsContainer.inject(this.mainContainer);
        this.dashboard = new Element('div').addClass('KLdashboard').inject(this.mainContainer);
        this.createTitle();
        this.createButtons();
        this.createThumbnails();
        this.createMosaic();
        this.createFooter();
    },
    createTitle: function () {
        if (!this.options.showTitle) return;
        this.title = new Element('div').addClass('KLtitle').inject(this.dashboard);
        if (this.options.linkToFlickr) new Element('a', {
            href: '#',
            target: '_blank'
        }).addClass('KLtitleText').set('html', '&nbsp;').inject(this.title);
        else new Element('span').addClass('KLtitleText').inject(this.title).set('html', '&nbsp;');
        if (this.options.showOwner) {
            var div = new Element('div').addClass('KLinfo').inject(this.title);
            if (this.options.linkToFlickr) new Element('a', {
                href: '#',
                target: '_blank'
            }).set('html', '&nbsp;').inject(div);
            else new Element('span').set('html', '&nbsp;').inject(div);
        }
    },
    setTitle: function () {
        if (!this.options.showTitle) return;
        var currentPic = this.myPictures[this.current];
        if (!currentPic) return false;
        if (this.options.mode == 'folder') var urls = this.getPicUrlFromFolder(this.nodes[this.current]);
        else var urls = this.getPicUrl(this.nodes[this.current]);
        var t = this.title.getElement('.KLtitleText');
        t.set('text', currentPic.alt);
        if (this.options.linkToFlickr && urls[2]) t.href = urls[2];
        if (this.options.showOwner && urls[3]) {
            var i = this.title.getElement('.KLinfo');
            i.getFirst().set('html', urls[3]);
            if (this.options.linkToFlickr && urls[4]) i.getFirst().href = urls[4];
        }
    },
    createButtons: function () {
        if (!this.options.showButtons) return;
        this.buttons = new Element('div').addClass('KLbuttons').inject(this.dashboard);
        new Element('a', {
            'href': './',
            'title': 'Previous image'
        }).addClass('KLback').addClass('button').inject(this.buttons).addEvent('click', function () {
            this.moveTo(this.current - 1);
            return false;
        }.bind(this));
        new Element('a', {
            'href': './',
            'title': 'Start slideshow'
        }).addClass('KLplay').addClass('button').inject(this.buttons).addEvent('click', function () {
            this.play.go(this);
            return false;
        }.bind(this));
        new Element('a', {
            'href': './',
            'title': 'Next image'
        }).addClass('KLnext').addClass('button').inject(this.buttons).addEvent('click', function () {
            this.moveTo(this.current + 1);
            return false;
        }.bind(this));
        var div = new Element('div').addClass('KLcounter').set('html', '<span>0/' + this.nodes.length + '</span>').inject(this.buttons).addEvent('click', function () {
            this.toggleLoading();
        }.bind(this));
        if (this.options.showMosaic) {
            new Element('a', {
                'href': './',
                'title': 'Toggle Thumbs'
            }).addClass('KLthumbs_switcher').addClass('button').inject(this.buttons).addEvent('click', function () {
                this.toggleMosaic();
                return false;
            }.bind(this));
        }
    },
    createThumbnails: function () {
        if (!this.options.showThumbnails) return;
        this.thumbnails = new Element('div').addClass('KLthumbnails').inject(this.dashboard);
        this.thumbsContainer = new Element('div').addClass('KLthumbsContainer');
        this.scrollThumbs = new Fx.Scroll(this.thumbsContainer, {
            wait: false,
            duration: 1000,
            transition: Fx.Transitions.Quint.easeInOut
        });
        var scrollAnimation = new Fx.Scroll(this.thumbsContainer, {
            transition: Fx.Transitions.Quint.easeInOut
        });
        var a = new Element('a', {
            'href': './'
        }).addClass('KLthumbs_back').inject(this.thumbnails).addEvent('click', function () {
            scrollAnimation.start(this.thumbsContainer.scrollLeft - 1 * this.thumbsContainer.getWidth());
            return false;
        }.bind(this));
        this.thumbsContainer.inject(this.thumbnails);
        var a = new Element('a', {
            'href': './'
        }).addClass('KLthumbs_forward').inject(this.thumbnails).addEvent('click', function () {
            scrollAnimation.start(this.thumbsContainer.scrollLeft + 1 * this.thumbsContainer.getWidth());
            return false;
        }.bind(this));
    },
    createMosaic: function () {
        if (!this.options.showMosaic) return;
        var self = this;
        this.mosaic = new Element('div').addClass('KLmosaic').setOpacity(0).set('html', '<div></div>').inject(this.mainContainer);
        this.mosaic.set('tween', {
            onComplete: function (el) {
                if (el.getStyle('opacity') == 0) el.setStyle('display', 'none');
            }
        });
    },
    createFooter: function () {
        new Element('div').addClass('KLfooter').set('html', '<table width="100%" border="0"><tr><td align="left">Follow us on <a href="http://www.flickr.com/photos/maynerrd/collections/72157623572309888/" target="_blank"><img src="flickr_32.png" width="12" height="12" alt="" border="0"> Flickr</a> or <a href="http://www.facebook.com/group.php?gid=74441741815" target="_blank"><img src="facebook_32.png" width="12" height="12" alt="" border="0"> Facebook</a> or <a href="http://bigstretch.wordpress.com/" target="_blank"><img src="wordpress_logo.jpg" width="12" height="12" alt="" border="0"> Blog</a></td><td align="right" style="font-size:9px;color:#aaaaaa;">All Content Copyright © 2010 Big Stretch Photography | <span style="font-family:arial, helvetica, sans-serif;font-size:9px;color:#aaaaaa;">powered by <a href="http://www.kishlery.com/" style="font-size:9px;color:#aaaaaa;" target="_blank">kishlery.com</a> + <a href="http://www.mootools.net/" style="font-size:9px;color:#aaaaaa;" target="_blank">mootools</a></td></tr></table>').inject(this.mainContainer, 'after');
    },
    keyboardControls: function () {
        if (!this.options.activateKeyboard) return;
        document.addEvent('keydown', function (event) {
            var event = new Event(event);
            switch (event.key) {
            case 'right':
                this.moveTo(this.current + 1);
                break;
            case 'left':
                this.moveTo(this.current - 1);
                break;
            case 'space':
                QuickView.show(this);
                event.preventDefault();
                break;
            case 'enter':
                this.play.go(this);
                break;
            case 'esc':
                this.toggleLoading();
                QuickView.hide();
                break;
            }
        }.bind(this));
    },
    load: function (i) {
        if (i >= this.nodes.length || this.stopLoading) {
            if (this.reqPos) this.moveTo(this.reqPos);
            return;
        }
        if (i < this.options.buffer) {
            var width = 200 * (i + 1) / this.options.buffer;
            if (this.preCounter) this.preCounter.getElement('span').setStyle('width', width + 'px');
        }
        if (i + 1 == this.options.buffer) this.openCurtains();
        if (this.options.mode == 'folder') var urls = this.getPicUrlFromFolder(this.nodes[i]);
        else var urls = this.getPicUrl(this.nodes[i]);
        this.loadPic(urls, i);
    },
    getPicUrl: function (node) {
        if (node.owner && (this.options.mode == 'photoset' || this.options.mode == 'group')) {
            this.owner_id = node.owner;
            this.ownername = node.ownername ? node.ownername : null;
        }
        return new Array('http://farm' + node.farm + '.static.flickr.com/' + node.server + '/' + node.id + '_' + node.secret + '.jpg', 'http://farm' + node.farm + '.static.flickr.com/' + node.server + '/' + node.id + '_' + node.secret + '_s.jpg', 'http://www.flickr.com/photos/' + this.owner_id + '/' + node.id + '/', this.ownername, 'http://www.flickr.com/photos/' + this.owner_id + '/');
    },
    getPicUrlFromFolder: function (node) {
        return new Array(node.url, node.thumb, null, node.author, null);
    },
    loadPic: function (urls, i) {
        var obj = this;
        obj.myPictures[i] = new Asset.image(urls[0], {
            alt: obj.nodes[i].title,
            onload: function () {
                if (obj.isPicLoaded[i]) return false;
                var w = this.width;
                var h = this.height;
                if (obj.options.maxSize) {
                    if (obj.options.forceHeight) {
                        var max = this.height > obj.options.maxSize ? obj.options.maxSize : this.height;
                        w = (this.width * max / this.height).round();
                        h = max;
                    }
                    else {
                        if (this.width > this.height) {
                            var max = this.width > obj.options.maxSize ? obj.options.maxSize : this.width;
                            w = max;
                            h = (this.height * max / this.width).round();
                        }
                        else {
                            var max = this.height > obj.options.maxSize ? obj.options.maxSize : this.height;
                            w = (this.width * max / this.height).round();
                            h = max;
                        }
                    }
                    this.setStyles({
                        'width': w,
                        'height': h
                    });
                }
                if (obj.options.singleMode) this.setStyle('opacity', 0);
                if (obj.options.singleMode) obj.options.centeringMargin = true;
                if (obj.options.centeringMargin) {
                    var m = obj.mainContainer.getWidth() / 2 - w / 2;
                    if (i == 0) this.setStyle('marginLeft', m);
                    if (i == obj.nodes.length - 1) this.setStyle('marginRight', m);
                }
                this.addEvent('click', function () {
                    obj.moveTo(i);
                });
                obj.isPicLoaded[i] = true;
                if (obj.options.mode == 'folder') obj.isPicChecked[i] = 2;
                else obj.isPicChecked[i] = false;
                obj.loadThumb(urls, i);
            }
        });
    },
    loadThumb: function (urls, i) {
        var obj = this;
        return new Asset.image(urls[1], {
            alt: obj.nodes[i].title,
            onload: function () {
                if (obj.isThumbLoaded[i]) return false;
                if (obj.thumbnails) {
                    obj.myThumbs[i] = this;
                    obj.myThumbs[i].addEvent('click', function () {
                        obj.moveTo(i);
                    });
                    if (i == 0) obj.myThumbs[i].addClass('KLselected');
                }
                if (obj.mosaic) {
                    obj.myThumbs2[i] = this.clone();
                    obj.myThumbs2[i].addEvent('click', function () {
                        obj.moveTo(i);
                    });
                    if (i == 0) obj.myThumbs2[i].addClass('KLselected');
                }
                obj.updateCounter(i);
                obj.isThumbLoaded[i] = true;
                obj.injectImages(urls, i);
                obj.load(i + 1);
            }
        });
    },
    injectImages: function (urls, i) {
        this.myPictures[i].inject(this.picsContainer);
        if (this.thumbnails) {
            this.myThumbs[i].setOpacity(0).inject(this.thumbsContainer);
            this.myThumbs[i].tween('opacity', 1);
        }
        if (this.mosaic) {
            this.myThumbs2[i].inject(this.mosaic.getElement('div'));
            this.myThumbs2[i].tween('opacity', 1);
        }
    },
    toggleLoading: function () {
        if (this.myThumbs2.length < this.buffer) return false;
        var span = this.buttons.getElement('.KLcounter');
        if (this.stopLoading) {
            span.removeClass('KLstopped');
            this.stopLoading = null;
            this.load(this.myThumbs2.length);
        }
        else {
            span.addClass('KLstopped');
            this.stopLoading = true;
        }
    },
    adaptToContainer: function (animation, postActions) {
        if (!this.mainContainer) return false;
        var p = this.mainContainer.getParent();
        var h = p.getHeight();
        h -= p.getStyle('margin-top').toInt();
        h -= p.getStyle('margin-bottom').toInt();
        h -= this.mainContainer.getStyle('margin-top').toInt();
        h -= this.mainContainer.getStyle('margin-bottom').toInt();
        p.getChildren().each(function (el) {
            if (el.hasClass('KLmainContainer')) return;
            if (el.getStyle('position') == 'absolute') return;
            if (el.getStyle('margin-top').toInt() > 0) h -= el.getStyle('margin-top').toInt();
            if (el.getStyle('margin-bottom').toInt() > 0) h -= el.getStyle('margin-bottom').toInt();
            h -= el.getHeight();
        });
        if (animation) {
            this.mainContainer.set('tween', {
                onComplete: function () {
                    postActions();
                }
            });
            this.mainContainer.tween('height', h);
        }
        else this.mainContainer.setStyle('height', h);
    },
    updateCounter: function (i) {
        if (!this.options.showButtons) return;
        var c = this.mainContainer.getElement('.KLcounter span');
        var percentage = (i + 1) * 100 / this.nodes.length;
        c.set('html', (i + 1) + '/' + this.nodes.length + '&nbsp;').setStyle('width', percentage + 'px');
        if (percentage >= 100) {
            percentage = 100;
            this.mainContainer.getElement('.KLcounter').tween('opacity', 0);
        }
    },
    openCurtains: function () {
        var self = this;
        if (this.preCounter) {
            this.preCounter.set('tween', {
                onComplete: function () {
                    self.preCounter.destroy();
                    self.preCounter = null;
                }
            });
            this.preCounter.tween('opacity', 0);
        }
        this.mainContainer.set('tween', {
            duration: 1000,
            transition: Fx.Transitions.Quint.easeInOut,
            onComplete: function () {
                self.openCurtains2();
            }
        });
        this.mainContainer.tween('height', 0);
    },
    openCurtains2: function () {
        var self = this;
        this.dashboard.setStyle('display', 'block');
        this.picsContainer.setStyle('display', 'block');
        var postActions = function () {
            if (self.options.showMosaicImmediately) self.toggleMosaic();
            if (self.options.playImmediately)(function () {
                self.play.go(self);
            }).delay(1000);
        }
        if (this.options.singleMode) {
            this.picsContainer.setStyles({
                width: 50,
                height: 0,
                marginTop: 10
            });
            this.adaptToContainer(true, postActions);
        }
        else if (this.options.forceHeight && this.options.maxSize) {
            var h = this.options.maxSize + this.dashboard.getHeight();
            h += this.dashboard.getStyle('margin-top').toInt();
            this.mainContainer.set('tween', {
                onComplete: postActions
            });
            this.mainContainer.tween('height', h);
        }
        else {
            this.mainContainer.setStyle('height', 'auto');
            postActions();
        }
        if (!this.reqPos)(function () {
            this.moveTo(0);
        }).delay(500, this);
        this.displayLog();
    },
    moveTo: function (num, periodical) {
        if (!this.play) return;
        if (!periodical) this.play.cancel();
        this.closeMosaic();
        if (num < 0) num = 0;
        var pic = this.myPictures[num];
        if (!pic) {
            this.play.cancel();
            return;
        }
        if (this.options.quickView) {
            var prev = this.picsContainer.getElement('.current');
            if (prev) prev.removeClass('current');
            pic.addClass('current');
        }
        this.previous = this.current;
        this.current = num;
        if (this.previous == this.current) {
            QuickView.show(this);
            return;
        }
        QuickView.cancel();
        this.selectButton(num);
        this.setTitle();
        if (this.options.singleMode) this.singleMotion(pic);
        else this.slideMotion(pic);
    },
    singleMotion: function (pic) {
        if (this.myPictures[this.previous]) this.myPictures[this.previous].setOpacity(0);
        var amount = pic.getPosition(this.picsContainer).x - 1;
        if (Browser.Engine.presto) pic.addClass('opera');
        this.scroll.set(amount, 0);
        var viewport = this.mainContainer.getHeight() - this.dashboard.getHeight();
        var marginTop = (viewport - pic.getHeight()) / 2;
        this.picsContainer.morph({
            height: pic.getHeight(),
            width: pic.getWidth(),
            marginTop: marginTop
        });
    },
    slideMotion: function (pic) {
        var w = this.picsContainer.getWidth();
        var offset = pic != this.picsContainer.getLast() ? (w - pic.getWidth()) / 2 : 0;
        this.scroll.options.offset.x = -offset;
        var amount = pic.offsetLeft;
        this.scroll.start(amount);
    },
    selectButton: function (num) {
        var thumb = this.myThumbs[num];
        var thumb2 = this.myThumbs2[num];
        if (thumb) {
            if (this.thumbsContainer.getElement('.KLselected')) this.thumbsContainer.getElement('.KLselected').removeClass('KLselected');
            thumb.addClass('KLselected');
        }
        if (thumb2) {
            if (this.mosaic.getElement('.KLselected')) this.mosaic.getElement('.KLselected').removeClass('KLselected');
            thumb2.addClass('KLselected');
        }
        if (this.thumbnails) {
            var amount = thumb.offsetLeft - this.thumbsContainer.getWidth() / 2 + thumb.getWidth() / 2;
            this.scrollThumbs.start(amount);
        }
    },
    toggleMosaic: function () {
        if (!this.mosaic) return;
        if (this.mosaic.getStyle('opacity') > 0) this.closeMosaic();
        else {
            var el = this.options.bigMosaic ? this.mainContainer : this.picsContainer;
            this.play.cancel();
            this.mosaic.setStyles({
                height: el.getHeight(),
                opacity: 0,
                display: 'block'
            });
            this.mosaic.tween('opacity', .9);
        }
    },
    closeMosaic: function () {
        if (!this.mosaic) return;
        if (this.mosaic.getStyle('opacity') == 0) return;
        this.mosaic.tween('opacity', 0);
    },
    urldecode: function (str) {
        str = unescape(str);
        str = str.replace(/\+/g, ' ');
        return str;
    },
    displayLog: function (txt) {
        var self = this;
        var error_html = '';
        var displayErrors = false;
        self.log.each(function (txt) {
            var t = self.urldecode(txt);
            if (t.contains('Error:')) {
                displayErrors = true;
                error_html += '<li>' + t + '</li>';
            }
            else if (self.options.showLog && typeof console != "undefined" && typeof console.log != "undefined") {
                console.log(t);
            }
        });
        if (!displayErrors) return;
        var error = new Element('div').set('html', '<ul>' + error_html + '</ul>').addClass('error').setOpacity(0).inject(this.mainContainer);
        if (error.getHeight() > this.mainContainer.getHeight()) {
            self.mainContainer.tween('height', error.getHeight() + 20);
        }
        if (this.mainContainer.getChildren().length > 1) error.addClass('floating');
        (function () {
            error.tween('opacity', .9);
        }).delay(500);
    }
}); // end kishlery
var QuickView = {
    div: null,
    mask: null,
    oldCoors: null,
    obj: null,
    show: function (obj) {
        if (!obj.options.quickView) return;
        if (!obj.current) obj.current = 0;
        if (this.div) return this.hide();
        this.obj = obj;
        var scroll = window.getScroll();
        this.mask = new Element('div').addClass('KLmask').setOpacity(0).setStyles({
            top: scroll.y,
            left: scroll.x
        }).inject(document.body);
        this.mask.tween('opacity', .7);
        this.div = new Element('div').addClass('KLquickView').addEvent('click', this.hide).inject(document.body);
        var winSize = window.getSize();
        var margin = 120;
        var max = 1024;
        var maxWinWidth = winSize.x - margin > max ? max : winSize.x - margin;
        var maxWinHeight = winSize.y - margin > max ? max : winSize.y - margin;
        var pic = obj.myPictures[obj.current];
        var picH = pic.getHeight();
        var picW = pic.getWidth();
        pic.clone().addClass('clone').inject(this.div);
        this.oldCoors = pic.getCoordinates();
        this.div.setStyles(this.oldCoors);
        this.div.setStyle('display', 'block');
        if (picW > picH) {
            var w = maxWinWidth;
            var h = (picH * w / picW).round();
            if (h > maxWinHeight) {
                h = maxWinHeight;
                w = (picW * h / picH).round();
            }
        }
        else {
            var h = maxWinHeight;
            var w = (picW * h / picH).round();
            if (w > maxWinWidth) {
                w = maxWinWidth;
                h = (picH * w / picW).round();
            }
        }
        if (h < picH) h = picH + 50;
        if (w < picW) w = picW + 50;
        var t = (winSize.y / 2 - h / 2) + scroll.y;
        var l = (winSize.x / 2 - w / 2) + scroll.x;
        this.div.set('morph', {
            duration: 500,
            transition: Fx.Transitions.Quint.easeInOut
        });
        this.div.morph({
            height: h,
            width: w,
            top: t,
            left: l
        });
        this.loadLargeImage();
    },
    loadLargeImage: function () {
        var self = this;
        var node = this.obj.nodes[this.obj.current];
        var url = 'http://farm' + node.farm + '.static.flickr.com/' + node.server + '/' + node.id + '_' + node.secret + '_b.jpg';
        var isChecked = self.obj.isPicChecked[self.obj.current];
        self.div.addClass('loading');
        var card = new Element('div').addClass('card').addEvent('click', this.flip).inject(this.div);
        new Element('div').addClass('loader').inject(self.div);
        if (isChecked == 1) {
            this.loadImage(url, node, card);
        }
        else if (isChecked == 2) {
            self.div.addClass('notFound');
            return;
        }
        else {
            new Request.JSONP({
                url: this.obj.url,
                data: {
                    mode: 'checkImage',
                    url: url
                },
                onComplete: function (txt) {
                    if (txt != 1) {
                        self.div.addClass('notFound');
                        self.obj.isPicChecked[self.obj.current] = 2;
                        return;
                    }
                    self.obj.isPicChecked[self.obj.current] = 1;
                    self.loadImage(url, node, card);
                }
            }).send();
        }
    },
    loadImage: function (url, node, card) {
        var self = this;
        new Asset.image(url, {
            alt: node.title,
            onload: function () {
                if (!self.div) return;
                self.div.removeClass('loading');
            }
        }).addClass('front').inject(card);
        if (this.obj.options.flip) new Element('div').addClass('back').set('html', 'Qualcosa da scrivere...').inject(card);
    },
    hide: function () {
        if (!QuickView.div) return;
        QuickView.div.set('morph', {
            duration: 500,
            transition: Fx.Transitions.Quint.easeInOut,
            onComplete: function () {
                if (QuickView.div) {
                    QuickView.div.destroy();
                    QuickView.div = null;
                }
            }
        });
        QuickView.div.morph(QuickView.oldCoors);
        QuickView.mask.set('tween', {
            onComplete: function () {
                if (QuickView.mask) {
                    QuickView.mask.destroy();
                    QuickView.mask = null;
                }
            }
        });
        QuickView.mask.tween('opacity', 0);
    },
    cancel: function () {
        if (QuickView.div) {
            QuickView.div.destroy();
            QuickView.div = null;
        }
        if (QuickView.mask) {
            QuickView.mask.destroy();
            QuickView.mask = null;
        }
    },
    flip: function (e) {
        if (!QuickView.obj.options.flip) return;
        e.stopPropagation();
        var div = QuickView.div.getElement('.card');
        if (div.hasClass('flipped')) div.removeClass('flipped');
        else div.addClass('flipped');
    }
}
var Slideshow = new Class({
    Extends: Fx.Scroll,
    pxs: 60,
    parentObj: null,
    go: function (obj) {
        this.parentObj = obj;
        if (!this.parentObj.picsContainer) return;
        this.parentObj.closeMosaic();
        if (this.timer) {
            this.cancel();
            return false;
        }
        if (this.parentObj.current == this.parentObj.myPictures.length - 1) {
            this.parentObj.scroll.chain(function () {
                this.go(this.parentObj);
            }.bind(this));
            this.parentObj.moveTo(0);
            return false;
        }
        var from = this.parentObj.picsContainer.scrollLeft + this.parentObj.picsContainer.getWidth();
        var to = this.parentObj.picsContainer.scrollWidth;
        var duration = ((to - from) / this.pxs * 1000).round();
        this.options.duration = duration;
        this.start(to);
    },
    step: function () {
        var time = $time();
        var now = this.parentObj.picsContainer.scrollLeft + this.parentObj.picsContainer.getWidth();
        var next = this.parentObj.myPictures[this.parentObj.current + 1];
        if (next && now >= next.offsetLeft + next.getWidth()) {
            this.parentObj.current++;
            this.parentObj.selectButton(this.parentObj.current);
            this.parentObj.setTitle();
        }
        if (time < this.time + this.options.duration) {
            var delta = this.options.transition((time - this.time) / this.options.duration);
            this.set(this.compute(this.from, this.to, delta));
        }
        else {
            this.set(this.compute(this.from, this.to, 1));
            this.complete();
            this.parentObj.selectButton(this.parentObj.current);
        }
    }
});
var Slideshow2 = new Class({
    timer: null,
    parentObj: null,
    interval: 5000,
    go: function (obj) {
        this.parentObj = obj;
        this.interval = obj.options.interval < 1000 ? 1000 : obj.options.interval;
        if (!this.parentObj.picsContainer) return;
        if (this.timer) {
            this.cancel();
            return false;
        }
        this.move();
        if (!this.timer) {
            this.parentObj.buttons.getElement('.KLplay').addClass('pause');
            this.timer = this.move.periodical(this.interval, this);
        }
    },
    move: function () {
        this.parentObj.moveTo(this.parentObj.current + 1, true);
    },
    cancel: function () {
        if (!this.parentObj) return false;
        $clear(this.timer);
        this.timer = null;
        this.parentObj.buttons.getElement('.KLplay').removeClass('pause');
    }
});
