// MooTools: the javascript framework.
// Load this file's selection again by visiting: http://mootools.net/more/23a310c7ca53825a3355cd08ee05400c 
// Or build this file again with packager using: packager build More/Slider More/Assets More/Scroller
/*
---
copyrights:
- [MooTools](http://mootools.net)

licenses:
- [MIT License](http://mootools.net/license.txt)
...
*/
MooTools.More = { version: "1.4.0.1", build: "a4244edf2aa97ac8a196fc96082dd35af1abab87" }; Class.Mutators.Binds = function(a) {
    if (!this.prototype.initialize) {
        this.implement("initialize", function() { });
    } return Array.from(a).concat(this.prototype.Binds || []);
}; Class.Mutators.initialize = function(a) {
    return function() {
        Array.from(this.Binds).each(function(b) {
            var c = this[b];
            if (c) { this[b] = c.bind(this); } 
        }, this); return a.apply(this, arguments);
    };
}; var Drag = new Class({ Implements: [Events, Options], options: { snap: 6, unit: "px", grid: false, style: true, limit: false, handle: false, invert: false, preventDefault: false, stopPropagation: false, modifiers: { x: "left", y: "top"} }, initialize: function() {
    var b = Array.link(arguments, { options: Type.isObject, element: function(c) {
        return c != null;
    } 
    }); this.element = document.id(b.element); this.document = this.element.getDocument(); this.setOptions(b.options || {}); var a = typeOf(this.options.handle); this.handles = ((a == "array" || a == "collection") ? $$(this.options.handle) : document.id(this.options.handle)) || this.element;
    this.mouse = { now: {}, pos: {} }; this.value = { start: {}, now: {} }; this.selection = (Browser.ie) ? "selectstart" : "mousedown"; if (Browser.ie && !Drag.ondragstartFixed) {
        document.ondragstart = Function.from(false);
        Drag.ondragstartFixed = true;
    } 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: Function.from(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(a) {
    var j = this.options; if (a.rightClick) { return; } if (j.preventDefault) { a.preventDefault(); } if (j.stopPropagation) {
        a.stopPropagation();
    } this.mouse.start = a.page; this.fireEvent("beforeStart", this.element); var c = j.limit; this.limit = { x: [], y: [] }; var e, g; for (e in j.modifiers) {
        if (!j.modifiers[e]) {
            continue;
        } var b = this.element.getStyle(j.modifiers[e]); if (b && !b.match(/px$/)) {
            if (!g) { g = this.element.getCoordinates(this.element.getOffsetParent()); } b = g[j.modifiers[e]];
        } if (j.style) { this.value.now[e] = (b || 0).toInt(); } else { this.value.now[e] = this.element[j.modifiers[e]]; } if (j.invert) { this.value.now[e] *= -1; } this.mouse.pos[e] = a.page[e] - this.value.now[e];
        if (c && c[e]) { var d = 2; while (d--) { var f = c[e][d]; if (f || f === 0) { this.limit[e][d] = (typeof f == "function") ? f() : f; } } } 
    } if (typeOf(this.options.grid) == "number") {
        this.options.grid = { x: this.options.grid, y: this.options.grid };
    } var h = { mousemove: this.bound.check, mouseup: this.bound.cancel }; h[this.selection] = this.bound.eventStop; this.document.addEvents(h);
}, 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, a]).fireEvent("snap", this.element);
    } 
}, drag: function(b) {
    var a = this.options; if (a.preventDefault) {
        b.preventDefault();
    } this.mouse.now = b.page; for (var c in a.modifiers) {
        if (!a.modifiers[c]) { continue; } this.value.now[c] = this.mouse.now[c] - this.mouse.pos[c]; if (a.invert) {
            this.value.now[c] *= -1;
        } if (a.limit && this.limit[c]) {
            if ((this.limit[c][1] || this.limit[c][1] === 0) && (this.value.now[c] > this.limit[c][1])) { this.value.now[c] = this.limit[c][1]; } else {
                if ((this.limit[c][0] || this.limit[c][0] === 0) && (this.value.now[c] < this.limit[c][0])) {
                    this.value.now[c] = this.limit[c][0];
                } 
            } 
        } if (a.grid[c]) { this.value.now[c] -= ((this.value.now[c] - (this.limit[c][0] || 0)) % a.grid[c]); } if (a.style) {
            this.element.setStyle(a.modifiers[c], this.value.now[c] + a.unit);
        } else { this.element[a.modifiers[c]] = this.value.now[c]; } 
    } this.fireEvent("drag", [this.element, b]);
}, cancel: function(a) {
    this.document.removeEvents({ mousemove: this.bound.check, mouseup: this.bound.cancel });
    if (a) { this.document.removeEvent(this.selection, this.bound.eventStop); this.fireEvent("cancel", this.element); } 
}, stop: function(b) {
    var a = { mousemove: this.bound.drag, mouseup: this.bound.stop };
    a[this.selection] = this.bound.eventStop; this.document.removeEvents(a); if (b) { this.fireEvent("complete", [this.element, b]); } 
} 
}); Element.implement({ makeResizable: function(a) {
    var b = new Drag(this, Object.merge({ modifiers: { x: "width", y: "height"} }, a));
    this.store("resizer", b); return b.addEvent("drag", function() { this.fireEvent("resize", b); } .bind(this));
} 
}); (function() {
    var b = function(e, d) {
        var f = []; Object.each(d, function(g) {
            Object.each(g, function(h) {
                e.each(function(i) {
                    f.push(i + "-" + h + (i == "border" ? "-width" : ""));
                });
            });
        }); return f;
    }; var c = function(f, e) { var d = 0; Object.each(e, function(h, g) { if (g.test(f)) { d = d + h.toInt(); } }); return d; }; var a = function(d) {
        return !!(!d || d.offsetHeight || d.offsetWidth);
    }; Element.implement({ measure: function(h) {
        if (a(this)) { return h.call(this); } var g = this.getParent(), e = []; while (!a(g) && g != document.body) {
            e.push(g.expose());
            g = g.getParent();
        } var f = this.expose(), d = h.call(this); f(); e.each(function(i) { i(); }); return d;
    }, expose: function() {
        if (this.getStyle("display") != "none") {
            return function() { };
        } var d = this.style.cssText; this.setStyles({ display: "block", position: "absolute", visibility: "hidden" }); return function() { this.style.cssText = d; } .bind(this);
    }, getDimensions: function(d) {
        d = Object.merge({ computeSize: false }, d); var i = { x: 0, y: 0 }; var h = function(j, e) {
            return (e.computeSize) ? j.getComputedSize(e) : j.getSize();
        }; var f = this.getParent("body"); if (f && this.getStyle("display") == "none") { i = this.measure(function() { return h(this, d); }); } else { if (f) { try { i = h(this, d); } catch (g) { } } } return Object.append(i, (i.x || i.x === 0) ? { width: i.x, height: i.y} : { x: i.width, y: i.height });
    }, getComputedSize: function(d) {
        if (d && d.plains) { d.planes = d.plains; } d = Object.merge({ styles: ["padding", "border"], planes: { height: ["top", "bottom"], width: ["left", "right"] }, mode: "both" }, d);
        var g = {}, e = { width: 0, height: 0 }, f; if (d.mode == "vertical") { delete e.width; delete d.planes.width; } else {
            if (d.mode == "horizontal") {
                delete e.height; delete d.planes.height;
            } 
        } b(d.styles, d.planes).each(function(h) { g[h] = this.getStyle(h).toInt(); }, this); Object.each(d.planes, function(i, h) {
            var k = h.capitalize(), j = this.getStyle(h);
            if (j == "auto" && !f) { f = this.getDimensions(); } j = g[h] = (j == "auto") ? f[h] : j.toInt(); e["total" + k] = j; i.each(function(m) {
                var l = c(m, g); e["computed" + m.capitalize()] = l;
                e["total" + k] += l;
            });
        }, this); return Object.append(e, g);
    } 
    });
})(); var Slider = new Class({ Implements: [Events, Options], Binds: ["clickedElement", "draggedKnob", "scrolledElement"], options: { onTick: function(a) {
    this.setKnobPosition(a);
}, initialStep: 0, snap: false, offset: 0, range: false, wheel: false, steps: 100, mode: "horizontal"
}, initialize: function(f, a, e) {
    this.setOptions(e); e = this.options; this.element = document.id(f);
    a = this.knob = document.id(a); this.previousChange = this.previousEnd = this.step = -1; var b = {}, d = { x: false, y: false }; switch (e.mode) {
        case "vertical": this.axis = "y"; this.property = "top";
            this.offset = "offsetHeight"; break; case "horizontal": this.axis = "x"; this.property = "left"; this.offset = "offsetWidth";
    } this.setSliderDimensions(); this.setRange(e.range);
    if (a.getStyle("position") == "static") { a.setStyle("position", "relative"); } a.setStyle(this.property, -e.offset); d[this.axis] = this.property; b[this.axis] = [-e.offset, this.full - e.offset];
    var c = { snap: 0, limit: b, modifiers: d, onDrag: this.draggedKnob, onStart: this.draggedKnob, onBeforeStart: (function() { this.isDragging = true; }).bind(this), onCancel: function() {
        this.isDragging = false;
    } .bind(this), onComplete: function() { this.isDragging = false; this.draggedKnob(); this.end(); } .bind(this)
    }; if (e.snap) { this.setSnap(c); } this.drag = new Drag(a, c);
    this.attach(); if (e.initialStep != null) { this.set(e.initialStep); } 
}, attach: function() {
    this.element.addEvent("mousedown", this.clickedElement); if (this.options.wheel) {
        this.element.addEvent("mousewheel", this.scrolledElement);
    } this.drag.attach(); return this;
}, detach: function() {
    this.element.removeEvent("mousedown", this.clickedElement).removeEvent("mousewheel", this.scrolledElement);
    this.drag.detach(); return this;
}, autosize: function() {
    this.setSliderDimensions().setKnobPosition(this.toPosition(this.step)); this.drag.options.limit[this.axis] = [-this.options.offset, this.full - this.options.offset];
    if (this.options.snap) { this.setSnap(); } return this;
}, setSnap: function(a) {
    if (!a) { a = this.drag.options; } a.grid = Math.ceil(this.stepWidth); a.limit[this.axis][1] = this.full;
    return this;
}, setKnobPosition: function(a) { if (this.options.snap) { a = this.toPosition(this.step); } this.knob.setStyle(this.property, a); return this; }, setSliderDimensions: function() {
    this.full = this.element.measure(function() {
        this.half = this.knob[this.offset] / 2;
        return this.element[this.offset] - this.knob[this.offset] + (this.options.offset * 2);
    } .bind(this)); return this;
}, 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); return this.checkStep().fireEvent("tick", this.toPosition(this.step)).end();
}, setRange: function(a, b) {
    this.min = Array.pick([a[0], 0]);
    this.max = Array.pick([a[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); if (a) { this.set(Array.pick([b, this.step]).floor(this.min).max(this.max)); } return this;
}, clickedElement: function(c) {
    if (this.isDragging || c.target == this.knob) {
        return;
    } var b = this.range < 0 ? -1 : 1, 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().fireEvent("tick", a).end();
}, scrolledElement: function(a) {
    var b = (this.options.mode == "horizontal") ? (a.wheel < 0) : (a.wheel > 0);
    this.set(this.step + (b ? -1 : 1) * this.stepSize); a.stop();
}, draggedKnob: function() {
    var b = this.range < 0 ? -1 : 1, 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() {
    var a = this.step; if (this.previousChange != a) {
        this.previousChange = a;
        this.fireEvent("change", a);
    } return this;
}, end: function() {
    var a = this.step; if (this.previousEnd !== a) { this.previousEnd = a; this.fireEvent("complete", a + ""); } return this;
}, 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 Asset = { javascript: function(d, b) {
    if (!b) { b = {}; } var a = new Element("script", { src: d, type: "text/javascript" }), e = b.document || document, c = b.onload || b.onLoad;
    delete b.onload; delete b.onLoad; delete b.document; if (c) {
        if (typeof a.onreadystatechange != "undefined") {
            a.addEvent("readystatechange", function() {
                if (["loaded", "complete"].contains(this.readyState)) {
                    c.call(this);
                } 
            });
        } else { a.addEvent("load", c); } 
    } return a.set(b).inject(e.head);
}, css: function(d, a) {
    if (!a) { a = {}; } var b = new Element("link", { rel: "stylesheet", media: "screen", type: "text/css", href: d });
    var c = a.onload || a.onLoad, e = a.document || document; delete a.onload; delete a.onLoad; delete a.document; if (c) { b.addEvent("load", c); } return b.set(a).inject(e.head);
}, image: function(c, b) {
    if (!b) { b = {}; } var d = new Image(), a = document.id(d) || new Element("img"); ["load", "abort", "error"].each(function(e) {
        var g = "on" + e, f = "on" + e.capitalize(), h = b[g] || b[f] || function() { };
        delete b[f]; 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(c, b) {
    c = Array.from(c); var d = function() { }, a = 0;
    b = Object.merge({ onComplete: d, onProgress: d, onError: d, properties: {} }, b); return new Elements(c.map(function(f, e) {
        return Asset.image(f, Object.append(b.properties, { onload: function() {
            a++;
            b.onProgress.call(this, a, e, f); if (a == c.length) { b.onComplete(); } 
        }, onerror: function() { a++; b.onError.call(this, a, e, f); if (a == c.length) { b.onComplete(); } } 
        }));
    }));
} 
}; var Scroller = new Class({ Implements: [Events, Options], options: { area: 20, velocity: 1, onChange: function(a, b) { this.element.scrollTo(a, b); }, fps: 50 }, initialize: function(b, a) {
    this.setOptions(a);
    this.element = document.id(b); this.docBody = document.id(this.element.getDocument().body); this.listener = (typeOf(this.element) != "element") ? this.docBody : this.element;
    this.timer = null; this.bound = { attach: this.attach.bind(this), detach: this.detach.bind(this), getCoords: this.getCoords.bind(this) };
}, start: function() {
    this.listener.addEvents({ mouseover: this.bound.attach, mouseleave: this.bound.detach });
    return this;
}, stop: function() {
    this.listener.removeEvents({ mouseover: this.bound.attach, mouseleave: this.bound.detach }); this.detach(); this.timer = clearInterval(this.timer);
    return this;
}, attach: function() { this.listener.addEvent("mousemove", this.bound.getCoords); }, detach: function() {
    this.listener.removeEvent("mousemove", this.bound.getCoords);
    this.timer = clearInterval(this.timer);
}, getCoords: function(a) {
    this.page = (this.listener.get("tag") == "body") ? a.client : a.page; if (!this.timer) {
        this.timer = this.scroll.periodical(Math.round(1000 / this.options.fps), this);
    } 
}, scroll: function() {
    var c = this.element.getSize(), a = this.element.getScroll(), h = this.element != this.docBody ? this.element.getOffsets() : { x: 0, y: 0 }, d = this.element.getScrollSize(), g = { x: 0, y: 0 }, e = this.options.area.top || this.options.area, b = this.options.area.bottom || this.options.area;
    for (var f in this.page) {
        if (this.page[f] < (e + h[f]) && a[f] != 0) { g[f] = (this.page[f] - e - h[f]) * this.options.velocity; } else {
            if (this.page[f] + b > (c[f] + h[f]) && a[f] + c[f] != d[f]) {
                g[f] = (this.page[f] - c[f] + b - h[f]) * this.options.velocity;
            } 
        } g[f] = g[f].round();
    } if (g.y || g.x) { this.fireEvent("change", [a.x + g.x, a.y + g.y]); } 
} 
});
