﻿//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2008 Valerio Proietti, <http://mad4milk.net>, MIT Style License.

Fx.Slide = new Class({ Extends: Fx, options: { mode: "vertical" }, initialize: function(B, A) {
    this.addEvent("complete", function() {
        this.open = (this.wrapper["offset" + this.layout.capitalize()] != 0);
        if (this.open && Browser.Engine.webkit419) { this.element.dispose().inject(this.wrapper); } 
    }, true); this.element = this.subject = $(B); this.parent(A); var C = this.element.retrieve("wrapper");
    this.wrapper = C || new Element("div", { styles: $extend(this.element.getStyles("margin", "position"), { overflow: "hidden" }) }).wraps(this.element); this.element.store("wrapper", this.wrapper).setStyle("margin", 0);
    this.now = []; this.open = true;
}, vertical: function() { this.margin = "margin-top"; this.layout = "height"; this.offset = this.element.offsetHeight; }, horizontal: function() {
    this.margin = "margin-left";
    this.layout = "width"; this.offset = this.element.offsetWidth;
}, set: function(A) {
    this.element.setStyle(this.margin, A[0]); this.wrapper.setStyle(this.layout, A[1]);
    return this;
}, compute: function(E, D, C) { var B = []; var A = 2; A.times(function(F) { B[F] = Fx.compute(E[F], D[F], C); }); return B; }, start: function(B, E) {
    if (!this.check(arguments.callee, B, E)) {
        return this;
    } this[E || this.options.mode](); var D = this.element.getStyle(this.margin).toInt(); var C = this.wrapper.getStyle(this.layout).toInt(); var A = [[D, C], [0, this.offset]];
    var G = [[D, C], [-this.offset, 0]]; var F; switch (B) {
        case "in": F = A; break; case "out": F = G; break; case "toggle": F = (this.wrapper["offset" + this.layout.capitalize()] == 0) ? A : G;
    } return this.parent(F[0], F[1]);
}, slideIn: function(A) { return this.start("in", A); }, slideOut: function(A) { return this.start("out", A); }, hide: function(A) {
    this[A || this.options.mode]();
    this.open = false; return this.set([-this.offset, 0]);
}, show: function(A) { this[A || this.options.mode](); this.open = true; return this.set([0, this.offset]); }, toggle: function(A) {
    return this.start("toggle", A);
} 
}); Element.Properties.slide = { set: function(B) {
    var A = this.retrieve("slide"); if (A) { A.cancel(); } return this.eliminate("slide").store("slide:options", $extend({ link: "cancel" }, B));
}, get: function(A) {
    if (A || !this.retrieve("slide")) {
        if (A || !this.retrieve("slide:options")) { this.set("slide", A); } this.store("slide", new Fx.Slide(this, this.retrieve("slide:options")));
    } return this.retrieve("slide");
} 
}; Element.implement({ slide: function(D, E) {
    D = D || "toggle"; var B = this.get("slide"), A; switch (D) {
        case "hide": B.hide(E); break; case "show": B.show(E);
            break; case "toggle": var C = this.retrieve("slide:flag", B.open); B[(C) ? "slideOut" : "slideIn"](E); this.store("slide:flag", !C); A = true; break; default: B.start(D, E);
    } if (!A) { this.eliminate("slide:flag"); } return this;
} 
}); Fx.Scroll = new Class({ Extends: Fx, options: { offset: { x: 0, y: 0 }, wheelStops: true }, initialize: function(B, A) {
    this.element = this.subject = $(B);
    this.parent(A); var D = this.cancel.bind(this, false); if ($type(this.element) != "element") { this.element = $(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); this.element.scrollTo(A[0], A[1]); }, compute: function(E, D, C) {
    var B = []; var A = 2; A.times(function(F) {
        B.push(Fx.compute(E[F], D[F], C));
    }); return B;
}, start: function(C, H) {
    if (!this.check(arguments.callee, C, H)) { return this; } var E = this.element.getSize(), F = this.element.getScrollSize(); var B = this.element.getScroll(), D = { x: C, y: H };
    for (var G in D) { var A = F[G] - E[G]; if ($chk(D[G])) { D[G] = ($type(D[G]) == "number") ? D[G].limit(0, A) : A; } else { D[G] = B[G]; } D[G] += this.options.offset[G]; } 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 = $(B).getPosition(this.element); return this.start(A.x, A.y); } 
}); Fx.Elements = new Class({ Extends: Fx.CSS, initialize: function(B, A) {
    this.elements = this.subject = $$(B);
    this.parent(A);
}, compute: function(G, H, I) {
    var C = {}; for (var D in G) { var A = G[D], E = H[D], F = C[D] = {}; for (var B in A) { F[B] = this.parent(A[B], E[B], I); } } return C;
}, set: function(B) { for (var C in B) { var A = B[C]; for (var D in A) { this.render(this.elements[C], D, A[D], this.options.unit); } } return this; }, start: function(C) {
    if (!this.check(arguments.callee, C)) {
        return this;
    } var H = {}, I = {}; for (var D in C) { var F = C[D], A = H[D] = {}, G = I[D] = {}; for (var B in F) { var E = this.prepare(this.elements[D], B, F[B]); A[B] = E.from; G[B] = E.to; } } return this.parent(H, I);
} 
}); var Drag = new Class({ Implements: [Events, Options], options: { snap: 6, unit: "px", grid: false, style: true, limit: false, handle: false, invert: false, preventDefault: false, modifiers: { x: "left", y: "top"} }, initialize: function() {
    var B = Array.link(arguments, { options: Object.type, element: $defined });
    this.element = $(B.element); this.document = this.element.getDocument(); this.setOptions(B.options || {}); var A = $type(this.options.handle); this.handles = (A == "array" || A == "collection") ? $$(this.options.handle) : $(this.options.handle) || this.element;
    this.mouse = { now: {}, pos: {} }; this.value = { start: {}, now: {} }; this.selection = (Browser.Engine.trident) ? "selectstart" : "mousedown"; this.bound = { start: this.start.bind(this), check: this.check.bind(this), drag: this.drag.bind(this), stop: this.stop.bind(this), cancel: this.cancel.bind(this), eventStop: $lambda(false) };
    this.attach();
}, attach: function() { this.handles.addEvent("mousedown", this.bound.start); return this; }, detach: function() {
    this.handles.removeEvent("mousedown", this.bound.start);
    return this;
}, start: function(C) {
    if (this.options.preventDefault) { C.preventDefault(); } this.fireEvent("beforeStart", this.element); this.mouse.start = C.page;
    var A = this.options.limit; this.limit = { x: [], y: [] }; for (var D in this.options.modifiers) {
        if (!this.options.modifiers[D]) { continue; } if (this.options.style) {
            this.value.now[D] = this.element.getStyle(this.options.modifiers[D]).toInt();
        } else { this.value.now[D] = this.element[this.options.modifiers[D]]; } if (this.options.invert) { this.value.now[D] *= -1; } this.mouse.pos[D] = C.page[D] - this.value.now[D];
        if (A && A[D]) { for (var B = 2; B--; B) { if ($chk(A[D][B])) { this.limit[D][B] = $lambda(A[D][B])(); } } } 
    } if ($type(this.options.grid) == "number") {
        this.options.grid = { x: this.options.grid, y: this.options.grid };
    } this.document.addEvents({ mousemove: this.bound.check, mouseup: this.bound.cancel }); this.document.addEvent(this.selection, this.bound.eventStop);
}, check: function(A) {
    if (this.options.preventDefault) {
        A.preventDefault();
    } var B = Math.round(Math.sqrt(Math.pow(A.page.x - this.mouse.start.x, 2) + Math.pow(A.page.y - this.mouse.start.y, 2))); if (B > this.options.snap) {
        this.cancel(); this.document.addEvents({ mousemove: this.bound.drag, mouseup: this.bound.stop });
        this.fireEvent("start", this.element).fireEvent("snap", this.element);
    } 
}, drag: function(A) {
    if (this.options.preventDefault) { A.preventDefault(); } this.mouse.now = A.page;
    for (var B in this.options.modifiers) {
        if (!this.options.modifiers[B]) { continue; } this.value.now[B] = this.mouse.now[B] - this.mouse.pos[B]; if (this.options.invert) {
            this.value.now[B] *= -1;
        } if (this.options.limit && this.limit[B]) {
            if ($chk(this.limit[B][1]) && (this.value.now[B] > this.limit[B][1])) { this.value.now[B] = this.limit[B][1]; } else {
                if ($chk(this.limit[B][0]) && (this.value.now[B] < this.limit[B][0])) {
                    this.value.now[B] = this.limit[B][0];
                } 
            } 
        } if (this.options.grid[B]) { this.value.now[B] -= (this.value.now[B] % this.options.grid[B]); } if (this.options.style) {
            this.element.setStyle(this.options.modifiers[B], this.value.now[B] + this.options.unit);
        } else { this.element[this.options.modifiers[B]] = this.value.now[B]; } 
    } this.fireEvent("drag", this.element);
}, cancel: function(A) {
    this.document.removeEvent("mousemove", this.bound.check);
    this.document.removeEvent("mouseup", this.bound.cancel); if (A) {
        this.document.removeEvent(this.selection, this.bound.eventStop); this.fireEvent("cancel", this.element);
    } 
}, stop: function(A) {
    this.document.removeEvent(this.selection, this.bound.eventStop); this.document.removeEvent("mousemove", this.bound.drag); this.document.removeEvent("mouseup", this.bound.stop);
    if (A) { this.fireEvent("complete", this.element); } 
} 
}); Element.implement({ makeResizable: function(A) {
    return new Drag(this, $merge({ modifiers: { x: "width", y: "height"} }, A));
} 
}); Drag.Move = new Class({ Extends: Drag, options: { droppables: [], container: false }, initialize: function(C, B) {
    this.parent(C, B); this.droppables = $$(this.options.droppables);
    this.container = $(this.options.container); if (this.container && $type(this.container) != "element") { this.container = $(this.container.getDocument().body); } C = this.element;
    var D = C.getStyle("position"); var A = (D != "static") ? D : "absolute"; if (C.getStyle("left") == "auto" || C.getStyle("top") == "auto") {
        C.position(C.getPosition(C.offsetParent));
    } C.setStyle("position", A); this.addEvent("start", function() { this.checkDroppables(); }, true);
}, start: function(B) {
    if (this.container) {
        var D = this.element, J = this.container, E = J.getCoordinates(D.offsetParent), F = {}, A = {};
        ["top", "right", "bottom", "left"].each(function(K) { F[K] = J.getStyle("padding-" + K).toInt(); A[K] = D.getStyle("margin-" + K).toInt(); }, this); var C = D.offsetWidth + A.left + A.right, I = D.offsetHeight + A.top + A.bottom;
        var H = [E.left + F.left, E.right - F.right - C]; var G = [E.top + F.top, E.bottom - F.bottom - I]; this.options.limit = { x: H, y: G };
    } this.parent(B);
}, checkAgainst: function(B) {
    B = B.getCoordinates();
    var A = this.mouse.now; return (A.x > B.left && A.x < B.right && A.y < B.bottom && A.y > B.top);
}, checkDroppables: function() {
    var A = this.droppables.filter(this.checkAgainst, this).getLast();
    if (this.overed != A) {
        if (this.overed) { this.fireEvent("leave", [this.element, this.overed]); } if (A) { this.overed = A; this.fireEvent("enter", [this.element, A]); } else {
            this.overed = null;
        } 
    } 
}, drag: function(A) { this.parent(A); if (this.droppables.length) { this.checkDroppables(); } }, stop: function(A) {
    this.checkDroppables(); this.fireEvent("drop", [this.element, this.overed]);
    this.overed = null; return this.parent(A);
} 
}); Element.implement({ makeDraggable: function(A) { return new Drag.Move(this, A); } }); Hash.Cookie = new Class({ Extends: Cookie, options: { autoSave: true }, initialize: function(B, A) {
    this.parent(B, A);
    this.load();
}, save: function() {
    var A = JSON.encode(this.hash); if (!A || A.length > 4096) { return false; } if (A == "{}") { this.dispose(); } else { this.write(A); } return true;
}, load: function() { this.hash = new Hash(JSON.decode(this.read(), true)); return this; } 
}); Hash.Cookie.implement((function() {
    var A = {}; Hash.each(Hash.prototype, function(C, B) {
        A[B] = function() {
            var D = C.apply(this.hash, arguments);
            if (this.options.autoSave) { this.save(); } return D;
        };
    }); return A;
})()); var Color = new Native({ initialize: function(B, C) {
    if (arguments.length >= 3) {
        C = "rgb"; B = Array.slice(arguments, 0, 3);
    } else { if (typeof B == "string") { if (B.match(/rgb/)) { B = B.rgbToHex().hexToRgb(true); } else { if (B.match(/hsb/)) { B = B.hsbToRgb(); } else { B = B.hexToRgb(true); } } } } C = C || "rgb";
    switch (C) { case "hsb": var A = B; B = B.hsbToRgb(); B.hsb = A; break; case "hex": B = B.hexToRgb(true); break; } B.rgb = B.slice(0, 3); B.hsb = B.hsb || B.rgbToHsb(); B.hex = B.rgbToHex();
    return $extend(B, this);
} 
}); Color.implement({ mix: function() {
    var A = Array.slice(arguments); var C = ($type(A.getLast()) == "number") ? A.pop() : 50; var B = this.slice();
    A.each(function(D) { D = new Color(D); for (var E = 0; E < 3; E++) { B[E] = Math.round((B[E] / 100 * (100 - C)) + (D[E] / 100 * C)); } }); return new Color(B, "rgb");
}, invert: function() {
    return new Color(this.map(function(A) {
        return 255 - A;
    }));
}, setHue: function(A) { return new Color([A, this.hsb[1], this.hsb[2]], "hsb"); }, setSaturation: function(A) {
    return new Color([this.hsb[0], A, this.hsb[2]], "hsb");
}, setBrightness: function(A) { return new Color([this.hsb[0], this.hsb[1], A], "hsb"); } 
}); function $RGB(C, B, A) { return new Color([C, B, A], "rgb"); } function $HSB(C, B, A) {
    return new Color([C, B, A], "hsb");
} function $HEX(A) { return new Color(A, "hex"); } Array.implement({ rgbToHsb: function() {
    var B = this[0], C = this[1], J = this[2]; var G, F, H; var I = Math.max(B, C, J), E = Math.min(B, C, J);
    var K = I - E; H = I / 255; F = (I != 0) ? K / I : 0; if (F == 0) { G = 0; } else {
        var D = (I - B) / K; var A = (I - C) / K; var L = (I - J) / K; if (B == I) { G = L - A; } else { if (C == I) { G = 2 + D - L; } else { G = 4 + A - D; } } G /= 6;
        if (G < 0) { G++; } 
    } return [Math.round(G * 360), Math.round(F * 100), Math.round(H * 100)];
}, hsbToRgb: function() {
    var C = Math.round(this[2] / 100 * 255); if (this[1] == 0) {
        return [C, C, C];
    } else {
        var A = this[0] % 360; var E = A % 60; var F = Math.round((this[2] * (100 - this[1])) / 10000 * 255); var D = Math.round((this[2] * (6000 - this[1] * E)) / 600000 * 255); var B = Math.round((this[2] * (6000 - this[1] * (60 - E))) / 600000 * 255);
        switch (Math.floor(A / 60)) {
            case 0: return [C, B, F]; case 1: return [D, C, F]; case 2: return [F, C, B]; case 3: return [F, D, C]; case 4: return [B, F, C]; case 5: return [C, F, D];
        } 
    } return false;
} 
}); String.implement({ rgbToHsb: function() { var A = this.match(/\d{1,3}/g); return (A) ? hsb.rgbToHsb() : null; }, hsbToRgb: function() {
    var A = this.match(/\d{1,3}/g);
    return (A) ? A.hsbToRgb() : null;
} 
}); var Group = new Class({ initialize: function() { this.instances = Array.flatten(arguments); this.events = {}; this.checker = {}; }, addEvent: function(B, A) {
    this.checker[B] = this.checker[B] || {};
    this.events[B] = this.events[B] || []; if (this.events[B].contains(A)) { return false; } else { this.events[B].push(A); } this.instances.each(function(C, D) {
        C.addEvent(B, this.check.bind(this, [B, C, D]));
    }, this); return this;
}, check: function(C, A, B) {
    this.checker[C][B] = true; var D = this.instances.every(function(F, E) { return this.checker[C][E] || false; }, this); if (!D) {
        return;
    } this.checker[C] = {}; this.events[C].each(function(E) { E.call(this, this.instances, A); }, this);
} 
}); var Asset = new Hash({ javascript: function(F, D) {
    D = $extend({ onload: $empty, document: document, check: $lambda(true) }, D);
    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(); } } }).setProperties(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 = $(D) || new Element("img"); ["load", "abort", "error"].each(function(E) {
        var F = "on" + E;
        var G = B[F]; delete B[F]; D[F] = function() {
            if (!D) { return; } if (!A.parentNode) { A.width = D.width; A.height = D.height; } D = D.onload = D.onabort = D.onerror = null; G.delay(1, A, A);
            A.fireEvent(E, A, 1);
        };
    }); D.src = A.src = C; if (D && D.complete) { D.onload.delay(1); } return A.setProperties(B);
}, images: function(D, C) {
    C = $merge({ onComplete: $empty, onProgress: $empty }, C);
    if (!D.push) { D = [D]; } var A = []; var B = 0; D.each(function(F) {
        var E = new Asset.image(F, { onload: function() {
            C.onProgress.call(this, B, D.indexOf(F)); B++; if (B == D.length) {
                C.onComplete();
            } 
        } 
        }); A.push(E);
    }); return new Elements(A);
} 
}); var Sortables = new Class({ Implements: [Events, Options], options: { snap: 4, opacity: 1, clone: false, revert: false, handle: false, constrain: false }, initialize: function(A, B) {
    this.setOptions(B);
    this.elements = []; this.lists = []; this.idle = true; this.addLists($$($(A) || A)); if (!this.options.clone) { this.options.revert = false; } if (this.options.revert) {
        this.effect = new Fx.Morph(null, $merge({ duration: 250, link: "cancel" }, this.options.revert));
    } 
}, attach: function() { this.addLists(this.lists); return this; }, detach: function() { this.lists = this.removeLists(this.lists); return this; }, addItems: function() {
    Array.flatten(arguments).each(function(A) {
        this.elements.push(A);
        var B = A.retrieve("sortables:start", this.start.bindWithEvent(this, A)); (this.options.handle ? A.getElement(this.options.handle) || A : A).addEvent("mousedown", B);
    }, this); return this;
}, addLists: function() {
    Array.flatten(arguments).each(function(A) { this.lists.push(A); this.addItems(A.getChildren()); }, this); return this;
}, removeItems: function() {
    var A = []; Array.flatten(arguments).each(function(B) {
        A.push(B); this.elements.erase(B); var C = B.retrieve("sortables:start"); (this.options.handle ? B.getElement(this.options.handle) || B : B).removeEvent("mousedown", C);
    }, this); return $$(A);
}, removeLists: function() {
    var A = []; Array.flatten(arguments).each(function(B) {
        A.push(B); this.lists.erase(B); this.removeItems(B.getChildren());
    }, this); return $$(A);
}, getClone: function(B, A) {
    if (!this.options.clone) { return new Element("div").inject(document.body); } if ($type(this.options.clone) == "function") {
        return this.options.clone.call(this, B, A, this.list);
    } return A.clone(true).setStyles({ margin: "0px", position: "absolute", visibility: "hidden", width: A.getStyle("width") }).inject(this.list).position(A.getPosition(A.getOffsetParent()));
}, getDroppables: function() {
    var A = this.list.getChildren(); if (!this.options.constrain) { A = this.lists.concat(A).erase(this.list); } return A.erase(this.clone).erase(this.element);
}, insert: function(C, B) {
    var A = "inside"; if (this.lists.contains(B)) { this.list = B; this.drag.droppables = this.getDroppables(); } else {
        A = this.element.getAllPrevious().contains(B) ? "before" : "after";
    } this.element.inject(B, A); this.fireEvent("sort", [this.element, this.clone]);
}, start: function(B, A) {
    if (!this.idle) { return; } this.idle = false; this.element = A;
    this.opacity = A.get("opacity"); this.list = A.getParent(); this.clone = this.getClone(B, A); this.drag = new Drag.Move(this.clone, { snap: this.options.snap, container: this.options.constrain && this.element.getParent(), droppables: this.getDroppables(), onSnap: function() {
        B.stop();
        this.clone.setStyle("visibility", "visible"); this.element.set("opacity", this.options.opacity || 0); this.fireEvent("start", [this.element, this.clone]);
    } .bind(this), onEnter: this.insert.bind(this), onCancel: this.reset.bind(this), onComplete: this.end.bind(this)
    });
    this.clone.inject(this.element, "before"); this.drag.start(B);
}, end: function() {
    this.drag.detach(); this.element.set("opacity", this.opacity); if (this.effect) {
        var A = this.element.getStyles("width", "height");
        var B = this.clone.computePosition(this.element.getPosition(this.clone.offsetParent)); this.effect.element = this.clone; this.effect.start({ top: B.top, left: B.left, width: A.width, height: A.height, opacity: 0.25 }).chain(this.reset.bind(this));
    } else { this.reset(); } 
}, reset: function() { this.idle = true; this.clone.destroy(); this.fireEvent("complete", this.element); }, serialize: function() {
    var C = Array.link(arguments, { modifier: Function.type, index: $defined });
    var B = this.lists.map(function(D) { return D.getChildren().map(C.modifier || function(E) { return E.get("id"); }, this); }, this); var A = C.index; if (this.lists.length == 1) {
        A = 0;
    } return $chk(A) && A >= 0 && A < this.lists.length ? B[A] : B;
} 
}); var Tips = new Class({ Implements: [Events, Options], options: { onShow: function(A) {
    A.setStyle("visibility", "visible");
}, onHide: function(A) { A.setStyle("visibility", "hidden"); }, showDelay: 100, hideDelay: 100, className: null, offsets: { x: 16, y: 16 }, fixed: false
}, initialize: function() {
    var C = Array.link(arguments, { options: Object.type, elements: $defined });
    this.setOptions(C.options || null); this.tip = new Element("div").inject(document.body); if (this.options.className) {
        this.tip.addClass(this.options.className);
    } var B = new Element("div", { "class": "tip-top" }).inject(this.tip); this.container = new Element("div", { "class": "tip" }).inject(this.tip); var A = new Element("div", { "class": "tip-bottom" }).inject(this.tip);
    this.tip.setStyles({ position: "absolute", top: 0, left: 0, visibility: "hidden" }); if (C.elements) { this.attach(C.elements); } 
}, attach: function(A) {
    $$(A).each(function(D) {
        var G = D.retrieve("tip:title", D.get("title"));
        var F = D.retrieve("tip:text", D.get("rel") || D.get("href")); var E = D.retrieve("tip:enter", this.elementEnter.bindWithEvent(this, D)); var C = D.retrieve("tip:leave", this.elementLeave.bindWithEvent(this, D));
        D.addEvents({ mouseenter: E, mouseleave: C }); if (!this.options.fixed) {
            var B = D.retrieve("tip:move", this.elementMove.bindWithEvent(this, D)); D.addEvent("mousemove", B);
        } D.store("tip:native", D.get("title")); D.erase("title");
    }, this); return this;
}, detach: function(A) {
    $$(A).each(function(C) {
        C.removeEvent("mouseenter", C.retrieve("tip:enter") || $empty);
        C.removeEvent("mouseleave", C.retrieve("tip:leave") || $empty); C.removeEvent("mousemove", C.retrieve("tip:move") || $empty); C.eliminate("tip:enter").eliminate("tip:leave").eliminate("tip:move");
        var B = C.retrieve("tip:native"); if (B) { C.set("title", B); } 
    }); return this;
}, elementEnter: function(B, A) {
    $A(this.container.childNodes).each(Element.dispose);
    var D = A.retrieve("tip:title"); if (D) { this.titleElement = new Element("div", { "class": "tip-title" }).inject(this.container); this.fill(this.titleElement, D); } var C = A.retrieve("tip:text");
    if (C) { this.textElement = new Element("div", { "class": "tip-text" }).inject(this.container); this.fill(this.textElement, C); } this.timer = $clear(this.timer); this.timer = this.show.delay(this.options.showDelay, this);
    this.position((!this.options.fixed) ? B : { page: A.getPosition() });
}, elementLeave: function(A) {
    $clear(this.timer); this.timer = this.hide.delay(this.options.hideDelay, this);
}, elementMove: function(A) { this.position(A); }, position: function(D) {
    var B = window.getSize(), A = window.getScroll(); var E = { x: this.tip.offsetWidth, y: this.tip.offsetHeight };
    var C = { x: "left", y: "top" }; for (var F in C) {
        var G = D.page[F] + this.options.offsets[F]; if ((G + E[F] - A[F]) > B[F]) { G = D.page[F] - this.options.offsets[F] - E[F]; } this.tip.setStyle(C[F], G);
    } 
}, fill: function(A, B) { (typeof B == "string") ? A.set("html", B) : A.adopt(B); }, show: function() { this.fireEvent("show", this.tip); }, hide: function() {
    this.fireEvent("hide", this.tip);
} 
}); var SmoothScroll = new Class({ Extends: Fx.Scroll, initialize: function(B, C) {
    C = C || document; var E = C.getDocument(), D = C.getWindow(); this.parent(E, B); this.links = (this.options.links) ? $$(this.options.links) : $$(E.links);
    var A = D.location.href.match(/^[^#]*/)[0] + "#"; this.links.each(function(G) {
        if (G.href.indexOf(A) != 0) { return; } var F = G.href.substr(A.length); if (F && $(F)) {
            this.useLink(G, F);
        } 
    }, this); if (!Browser.Engine.webkit419) { this.addEvent("complete", function() { D.location.hash = this.anchor; }, true); } 
}, useLink: function(B, A) {
    B.addEvent("click", function(C) {
        this.anchor = A;
        this.toElement(A); C.stop();
    } .bind(this));
} 
}); var Slider = new Class({ Implements: [Events, Options], options: { onTick: function(A) {
    if (this.options.snap) {
        A = this.toPosition(this.step);
    } this.knob.setStyle(this.property, A);
}, snap: false, offset: 0, range: false, wheel: false, steps: 100, mode: "horizontal"
}, initialize: function(E, A, D) {
    this.setOptions(D);
    this.element = $(E); this.knob = $(A); this.previousChange = this.previousEnd = this.step = -1; this.element.addEvent("mousedown", this.clickedElement.bind(this)); if (this.options.wheel) {
        this.element.addEvent("mousewheel", this.scrolledElement.bindWithEvent(this));
    } var F, B = {}, C = { x: false, y: false }; switch (this.options.mode) {
        case "vertical": this.axis = "y"; this.property = "top"; F = "offsetHeight"; break; case "horizontal": this.axis = "x";
            this.property = "left"; F = "offsetWidth";
    } this.half = this.knob[F] / 2; this.full = this.element[F] - this.knob[F] + (this.options.offset * 2); this.min = $chk(this.options.range[0]) ? this.options.range[0] : 0;
    this.max = $chk(this.options.range[1]) ? this.options.range[1] : this.options.steps; this.range = this.max - this.min; this.steps = this.options.steps || this.full; this.stepSize = Math.abs(this.range) / this.steps;
    this.stepWidth = this.stepSize * this.full / Math.abs(this.range); this.knob.setStyle("position", "relative").setStyle(this.property, -this.options.offset); C[this.axis] = this.property;
    B[this.axis] = [-this.options.offset, this.full - this.options.offset]; this.drag = new Drag(this.knob, { snap: 0, limit: B, modifiers: C, onDrag: this.draggedKnob.bind(this), onStart: this.draggedKnob.bind(this), onComplete: function() {
        this.draggedKnob();
        this.end();
    } .bind(this)
    }); if (this.options.snap) { this.drag.options.grid = Math.ceil(this.stepWidth); this.drag.options.limit[this.axis][1] = this.full; } 
}, set: function(A) {
    if (!((this.range > 0) ^ (A < this.min))) {
        A = this.min;
    } if (!((this.range > 0) ^ (A > this.max))) { A = this.max; } this.step = Math.round(A); this.checkStep(); this.end(); this.fireEvent("tick", this.toPosition(this.step)); return this;
}, clickedElement: function(C) {
    var B = this.range < 0 ? -1 : 1; var A = C.page[this.axis] - this.element.getPosition()[this.axis] - this.half; A = A.limit(-this.options.offset, this.full - this.options.offset);
    this.step = Math.round(this.min + B * this.toStep(A)); this.checkStep(); this.end(); this.fireEvent("tick", A);
}, scrolledElement: function(A) {
    var B = (this.options.mode == "horizontal") ? (A.wheel < 0) : (A.wheel > 0);
    this.set(B ? this.step - this.stepSize : this.step + this.stepSize); A.stop();
}, draggedKnob: function() {
    var B = this.range < 0 ? -1 : 1; var A = this.drag.value.now[this.axis];
    A = A.limit(-this.options.offset, this.full - this.options.offset); this.step = Math.round(this.min + B * this.toStep(A)); this.checkStep();
}, checkStep: function() {
    if (this.previousChange != this.step) {
        this.previousChange = this.step;
        this.fireEvent("change", this.step);
    } 
}, end: function() {
    if (this.previousEnd !== this.step) {
        this.previousEnd = this.step; this.fireEvent("complete", this.step + "");
    } 
}, toStep: function(A) { var B = (A + this.options.offset) * this.stepSize / this.full * this.steps; return this.options.steps ? Math.round(B -= B % this.stepSize) : B; }, toPosition: function(A) {
    return (this.full * Math.abs(this.min - A)) / (this.steps * this.stepSize) - this.options.offset;
} 
}); var Scroller = new Class({ Implements: [Events, Options], options: { area: 20, velocity: 1, onChange: function(A, B) { this.element.scrollTo(A, B); } }, initialize: function(B, A) {
    this.setOptions(A);
    this.element = $(B); this.listener = ($type(this.element) != "element") ? $(this.element.getDocument().body) : this.element; this.timer = null; this.coord = this.getCoords.bind(this);
}, start: function() { this.listener.addEvent("mousemove", this.coord); }, stop: function() {
    this.listener.removeEvent("mousemove", this.coord); this.timer = $clear(this.timer);
}, getCoords: function(A) { this.page = (this.listener.get("tag") == "body") ? A.client : A.page; if (!this.timer) { this.timer = this.scroll.periodical(50, this); } }, scroll: function() {
    var B = this.element.getSize(), A = this.element.getScroll(), E = this.element.getPosition(), D = { x: 0, y: 0 };
    for (var C in this.page) {
        if (this.page[C] < (this.options.area + E[C]) && A[C] != 0) { D[C] = (this.page[C] - this.options.area - E[C]) * this.options.velocity; } else {
            if (this.page[C] + this.options.area > (B[C] + E[C]) && B[C] + B[C] != A[C]) {
                D[C] = (this.page[C] - B[C] + this.options.area - E[C]) * this.options.velocity;
            } 
        } 
    } if (D.y || D.x) { this.fireEvent("change", [A.x + D.x, A.y + D.y]); } 
} 
}); var Accordion = new Class({ Extends: Fx.Elements, options: { display: 0, show: false, height: true, width: false, opacity: true, fixedHeight: false, fixedWidth: false, wait: false, alwaysHide: false }, initialize: function() {
    var C = Array.link(arguments, { container: Element.type, options: Object.type, togglers: $defined, elements: $defined });
    this.parent(C.elements, C.options); this.togglers = $$(C.togglers); this.container = $(C.container); this.previous = -1; if (this.options.alwaysHide) {
        this.options.wait = true;
    } if ($chk(this.options.show)) { this.options.display = false; this.previous = this.options.show; } if (this.options.start) {
        this.options.display = false; this.options.show = false;
    } this.effects = {}; if (this.options.opacity) { this.effects.opacity = "fullOpacity"; } if (this.options.width) {
        this.effects.width = this.options.fixedWidth ? "fullWidth" : "offsetWidth";
    } if (this.options.height) { this.effects.height = this.options.fixedHeight ? "fullHeight" : "scrollHeight"; } for (var B = 0, A = this.togglers.length; B < A; B++) {
        this.addSection(this.togglers[B], this.elements[B]);
    } this.elements.each(function(E, D) {
        if (this.options.show === D) { this.fireEvent("active", [this.togglers[D], E]); } else {
            for (var F in this.effects) {
                E.setStyle(F, 0);
            } 
        } 
    }, this); if ($chk(this.options.display)) { this.display(this.options.display); } 
}, addSection: function(E, C, G) {
    E = $(E); C = $(C); var F = this.togglers.contains(E);
    var B = this.togglers.length; this.togglers.include(E); this.elements.include(C); if (B && (!F || G)) {
        G = $pick(G, B - 1); E.inject(this.togglers[G], "before"); C.inject(E, "after");
    } else { if (this.container && !F) { E.inject(this.container); C.inject(this.container); } } var A = this.togglers.indexOf(E); E.addEvent("click", this.display.bind(this, A));
    if (this.options.height) { C.setStyles({ "padding-top": 0, "border-top": "none", "padding-bottom": 0, "border-bottom": "none" }); } if (this.options.width) {
        C.setStyles({ "padding-left": 0, "border-left": "none", "padding-right": 0, "border-right": "none" });
    } C.fullOpacity = 1; if (this.options.fixedWidth) { C.fullWidth = this.options.fixedWidth; } if (this.options.fixedHeight) { C.fullHeight = this.options.fixedHeight; } C.setStyle("overflow", "hidden");
    if (!F) { for (var D in this.effects) { C.setStyle(D, 0); } } return this;
}, display: function(A) {
    A = ($type(A) == "element") ? this.elements.indexOf(A) : A; if ((this.timer && this.options.wait) || (A === this.previous && !this.options.alwaysHide)) {
        return this;
    } this.previous = A; var B = {}; this.elements.each(function(E, D) {
        B[D] = {}; var C = (D != A) || (this.options.alwaysHide && (E.offsetHeight > 0)); this.fireEvent(C ? "background" : "active", [this.togglers[D], E]);
        for (var F in this.effects) { B[D][F] = C ? 0 : E[this.effects[F]]; } 
    }, this); return this.start(B);
} 
});