/** * @license * jQuery Tools 1.2.5 / Tooltip Slide Effect * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/tooltip/slide.html * * Since: September 2009 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { // version number var t = $.tools.tooltip; // extend global configuragion with effect specific defaults $.extend(t.conf, { direction: 'up', // down, left, right bounce: false, slideOffset: 10, slideInSpeed: 200, slideOutSpeed: 200, slideFade: !$.browser.msie }); // directions for slide effect var dirs = { up: ['-', 'top'], down: ['+', 'top'], left: ['-', 'left'], right: ['+', 'left'] }; /* default effect: "slide" */ t.addEffect("slide", // show effect function(done) { // variables var conf = this.getConf(), tip = this.getTip(), params = conf.slideFade ? {opacity: conf.opacity} : {}, dir = dirs[conf.direction] || dirs.up; // direction params[dir[1]] = dir[0] +'='+ conf.slideOffset; // perform animation if (conf.slideFade) { tip.css({opacity:0}); } tip.show().animate(params, conf.slideInSpeed, done); }, // hide effect function(done) { // variables var conf = this.getConf(), offset = conf.slideOffset, params = conf.slideFade ? {opacity: 0} : {}, dir = dirs[conf.direction] || dirs.up; // direction var sign = "" + dir[0]; if (conf.bounce) { sign = sign == '+' ? '-' : '+'; } params[dir[1]] = sign +'='+ offset; // perform animation this.getTip().animate(params, conf.slideOutSpeed, function() { $(this).hide(); done.call(); }); } ); })(jQuery); /** * @license * jQuery Tools 1.2.5 Tooltip - UI essentials * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/tooltip/ * * Since: November 2008 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { // static constructs $.tools = $.tools || {version: '1.2.5'}; $.tools.tooltip = { conf: { // default effect variables effect: 'toggle', fadeOutSpeed: "fast", predelay: 0, delay: 30, opacity: 1, tip: 0, // 'top', 'bottom', 'right', 'left', 'center' position: ['top', 'center'], offset: [0, 0], relative: false, cancelDefault: true, // type to event mapping events: { def: "mouseenter,mouseleave", input: "focus,blur", widget: "focus mouseenter,blur mouseleave", tooltip: "mouseenter,mouseleave" }, // 1.2 layout: '<div/>', tipClass: 'tooltip' }, addEffect: function(name, loadFn, hideFn) { effects[name] = [loadFn, hideFn]; } }; var effects = { toggle: [ function(done) { var conf = this.getConf(), tip = this.getTip(), o = conf.opacity; if (o < 1) { tip.css({opacity: o}); } tip.show(); done.call(); }, function(done) { this.getTip().hide(); done.call(); } ], fade: [ function(done) { var conf = this.getConf(); this.getTip().fadeTo(conf.fadeInSpeed, conf.opacity, done); }, function(done) { this.getTip().fadeOut(this.getConf().fadeOutSpeed, done); } ] }; /* calculate tip position relative to the trigger */ function getPosition(trigger, tip, conf) { // get origin top/left position var top = conf.relative ? trigger.position().top : trigger.offset().top, left = conf.relative ? trigger.position().left : trigger.offset().left, pos = conf.position[0]; top -= tip.outerHeight() - conf.offset[0]; left += trigger.outerWidth() + conf.offset[1]; // iPad position fix if (/iPad/i.test(navigator.userAgent)) { top -= $(window).scrollTop(); } // adjust Y var height = tip.outerHeight() + trigger.outerHeight(); if (pos == 'center') { top += height / 2; } if (pos == 'bottom') { top += height; } // adjust X pos = conf.position[1]; var width = tip.outerWidth() + trigger.outerWidth(); if (pos == 'center') { left -= width / 2; } if (pos == 'left') { left -= width; } return {top: top, left: left}; } function Tooltip(trigger, conf) { var self = this, fire = trigger.add(self), tip, timer = 0, pretimer = 0, title = trigger.attr("title"), tipAttr = trigger.attr("data-tooltip"), effect = effects[conf.effect], shown, // get show/hide configuration isInput = trigger.is(":input"), isWidget = isInput && trigger.is(":checkbox, :radio, select, :button, :submit"), type = trigger.attr("type"), evt = conf.events[type] || conf.events[isInput ? (isWidget ? 'widget' : 'input') : 'def']; // check that configuration is sane if (!effect) { throw "Nonexistent effect \"" + conf.effect + "\""; } evt = evt.split(/,\s*/); if (evt.length != 2) { throw "Tooltip: bad events configuration for " + type; } // trigger --> show trigger.bind(evt[0], function(e) { clearTimeout(timer); if (conf.predelay) { pretimer = setTimeout(function() { self.show(e); }, conf.predelay); } else { self.show(e); } // trigger --> hide }).bind(evt[1], function(e) { clearTimeout(pretimer); if (conf.delay) { timer = setTimeout(function() { self.hide(e); }, conf.delay); } else { self.hide(e); } }); // remove default title if (title && conf.cancelDefault) { trigger.removeAttr("title"); trigger.data("title", title); } $.extend(self, { show: function(e) { // tip not initialized yet if (!tip) { // data-tooltip if (tipAttr) { tip = $(tipAttr); // single tip element for all } else if (conf.tip) { tip = $(conf.tip).eq(0); // autogenerated tooltip } else if (title) { tip = $(conf.layout).addClass(conf.tipClass).appendTo(document.body) .hide().append(title); // manual tooltip } else { tip = trigger.next(); if (!tip.length) { tip = trigger.parent().next(); } } if (!tip.length) { throw "Cannot find tooltip for " + trigger; } } if (self.isShown()) { return self; } // stop previous animation tip.stop(true, true); // get position var pos = getPosition(trigger, tip, conf); // restore title for single tooltip element if (conf.tip) { tip.html(trigger.data("title")); } // onBeforeShow e = e || $.Event(); e.type = "onBeforeShow"; fire.trigger(e, [pos]); if (e.isDefaultPrevented()) { return self; } // onBeforeShow may have altered the configuration pos = getPosition(trigger, tip, conf); // set position tip.css({position:'absolute', top: pos.top, left: pos.left}); shown = true; // invoke effect effect[0].call(self, function() { e.type = "onShow"; shown = 'full'; fire.trigger(e); }); // tooltip events var event = conf.events.tooltip.split(/,\s*/); if (!tip.data("__set")) { tip.bind(event[0], function() { clearTimeout(timer); clearTimeout(pretimer); }); if (event[1] && !trigger.is("input:not(:checkbox, :radio), textarea")) { tip.bind(event[1], function(e) { // being moved to the trigger element if (e.relatedTarget != trigger[0]) { trigger.trigger(evt[1].split(" ")[0]); } }); } tip.data("__set", true); } return self; }, hide: function(e) { if (!tip || !self.isShown()) { return self; } // onBeforeHide e = e || $.Event(); e.type = "onBeforeHide"; fire.trigger(e); if (e.isDefaultPrevented()) { return; } shown = false; effects[conf.effect][1].call(self, function() { e.type = "onHide"; fire.trigger(e); }); return self; }, isShown: function(fully) { return fully ? shown == 'full' : shown; }, getConf: function() { return conf; }, getTip: function() { return tip; }, getTrigger: function() { return trigger; } }); // callbacks $.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","), function(i, name) { // configuration if ($.isFunction(conf[name])) { $(self).bind(name, conf[name]); } // API self[name] = function(fn) { if (fn) { $(self).bind(name, fn); } return self; }; }); } // jQuery plugin implementation $.fn.tooltip = function(conf) { // return existing instance var api = this.data("tooltip"); if (api) { return api; } conf = $.extend(true, {}, $.tools.tooltip.conf, conf); // position can also be given as string if (typeof conf.position == 'string') { conf.position = conf.position.split(/,?\s/); } // install tooltip for each entry in jQuery object this.each(function() { api = new Tooltip($(this), conf); $(this).data("tooltip", api); }); return conf.api ? api: this; }; }) (jQuery); /** * @license * jQuery Tools 1.2.5 / Tooltip Dynamic Positioning * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/tooltip/dynamic.html * * Since: July 2009 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { // version number var t = $.tools.tooltip; t.dynamic = { conf: { classNames: "top right bottom left" } }; /* * See if element is on the viewport. Returns an boolean array specifying which * edges are hidden. Edges are in following order: * * [top, right, bottom, left] * * For example following return value means that top and right edges are hidden * * [true, true, false, false] * */ function getCropping(el) { var w = $(window); var right = w.width() + w.scrollLeft(); var bottom = w.height() + w.scrollTop(); return [ el.offset().top <= w.scrollTop(), // top right <= el.offset().left + el.width(), // right bottom <= el.offset().top + el.height(), // bottom w.scrollLeft() >= el.offset().left // left ]; } /* Returns true if all edges of an element are on viewport. false if not @param crop the cropping array returned by getCropping function */ function isVisible(crop) { var i = crop.length; while (i--) { if (crop[i]) { return false; } } return true; } // dynamic plugin $.fn.dynamic = function(conf) { if (typeof conf == 'number') { conf = {speed: conf}; } conf = $.extend({}, t.dynamic.conf, conf); var cls = conf.classNames.split(/\s/), orig; this.each(function() { var api = $(this).tooltip().onBeforeShow(function(e, pos) { // get nessessary variables var tip = this.getTip(), tipConf = this.getConf(); /* We store the original configuration and use it to restore back to the original state. */ if (!orig) { orig = [ tipConf.position[0], tipConf.position[1], tipConf.offset[0], tipConf.offset[1], $.extend({}, tipConf) ]; } /* display tip in it's default position and by setting visibility to hidden. this way we can check whether it will be on the viewport */ $.extend(tipConf, orig[4]); tipConf.position = [orig[0], orig[1]]; tipConf.offset = [orig[2], orig[3]]; tip.css({ visibility: 'hidden', position: 'absolute', top: pos.top, left: pos.left }).show(); // now let's see for hidden edges var crop = getCropping(tip); // possibly alter the configuration if (!isVisible(crop)) { // change the position and add class if (crop[2]) { $.extend(tipConf, conf.top); tipConf.position[0] = 'top'; tip.addClass(cls[0]); } if (crop[3]) { $.extend(tipConf, conf.right); tipConf.position[1] = 'right'; tip.addClass(cls[1]); } if (crop[0]) { $.extend(tipConf, conf.bottom); tipConf.position[0] = 'bottom'; tip.addClass(cls[2]); } if (crop[1]) { $.extend(tipConf, conf.left); tipConf.position[1] = 'left'; tip.addClass(cls[3]); } // vertical offset if (crop[0] || crop[2]) { tipConf.offset[0] *= -1; } // horizontal offset if (crop[1] || crop[3]) { tipConf.offset[1] *= -1; } } tip.css({visibility: 'visible'}).hide(); }); // restore positioning as soon as possible api.onBeforeShow(function() { var c = this.getConf(), tip = this.getTip(); setTimeout(function() { c.position = [orig[0], orig[1]]; c.offset = [orig[2], orig[3]]; }, 0); }); // remove custom class names and restore original effect api.onHide(function() { var tip = this.getTip(); tip.removeClass(conf.classNames); }); ret = api; }); return conf.api ? ret : this; }; }) (jQuery); /** * @license * jQuery Tools 1.2.5 Rangeinput - HTML5 <input type="range" /> for humans * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/rangeinput/ * * Since: Mar 2010 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { $.tools = $.tools || {version: '1.2.5'}; var tool; tool = $.tools.rangeinput = { conf: { min: 0, max: 100, // as defined in the standard step: 'any', // granularity of the value. a non-zero float or int (or "any") steps: 0, value: 0, precision: undefined, vertical: 0, keyboard: true, progress: false, speed: 100, // set to null if not needed css: { input: 'range', slider: 'slider', progress: 'progress', handle: 'handle' } } }; //{{{ fn.drag /* FULL featured drag and drop. 0.7 kb minified, 0.3 gzipped. done. Who told d'n'd is rocket science? Usage: $(".myelement").drag({y: false}).bind("drag", function(event, x, y) { // do your custom thing }); Configuration: x: true, // enable horizontal drag y: true, // enable vertical drag drag: true // true = perform drag, false = only fire events Events: dragStart, drag, dragEnd. */ var doc, draggable; $.fn.drag = function(conf) { // disable IE specialities document.ondragstart = function () { return false; }; conf = $.extend({x: true, y: true, drag: true}, conf); doc = doc || $(document).bind("mousedown mouseup", function(e) { var el = $(e.target); // start if (e.type == "mousedown" && el.data("drag")) { var offset = el.position(), x0 = e.pageX - offset.left, y0 = e.pageY - offset.top, start = true; doc.bind("mousemove.drag", function(e) { var x = e.pageX -x0, y = e.pageY -y0, props = {}; if (conf.x) { props.left = x; } if (conf.y) { props.top = y; } if (start) { el.trigger("dragStart"); start = false; } if (conf.drag) { el.css(props); } el.trigger("drag", [y, x]); draggable = el; }); e.preventDefault(); } else { try { if (draggable) { draggable.trigger("dragEnd"); } } finally { doc.unbind("mousemove.drag"); draggable = null; } } }); return this.data("drag", true); }; //}}} function round(value, precision) { var n = Math.pow(10, precision); return Math.round(value * n) / n; } // get hidden element's width or height even though it's hidden function dim(el, key) { var v = parseInt(el.css(key), 10); if (v) { return v; } var s = el[0].currentStyle; return s && s.width && parseInt(s.width, 10); } function hasEvent(el) { var e = el.data("events"); return e && e.onSlide; } function RangeInput(input, conf) { // private variables var self = this, css = conf.css, root = $("<div><div/><a href='#'/></div>").data("rangeinput", self), vertical, value, // current value origo, // handle's start point len, // length of the range pos; // current position of the handle // create range input.before(root); var handle = root.addClass(css.slider).find("a").addClass(css.handle), progress = root.find("div").addClass(css.progress); // get (HTML5) attributes into configuration $.each("min,max,step,value".split(","), function(i, key) { var val = input.attr(key); if (parseFloat(val)) { conf[key] = parseFloat(val, 10); } }); var range = conf.max - conf.min, step = conf.step == 'any' ? 0 : conf.step, precision = conf.precision; if (precision === undefined) { try { precision = step.toString().split(".")[1].length; } catch (err) { precision = 0; } } // Replace built-in range input (type attribute cannot be changed) if (input.attr("type") == 'range') { var tmp = $("<input/>"); $.each("class,disabled,id,maxlength,name,readonly,required,size,style,tabindex,title,value".split(","), function(i, attr) { tmp.attr(attr, input.attr(attr)); }); tmp.val(conf.value); input.replaceWith(tmp); input = tmp; } input.addClass(css.input); var fire = $(self).add(input), fireOnSlide = true; /** The flesh and bone of this tool. All sliding is routed trough this. @param evt types include: click, keydown, blur and api (setValue call) @param isSetValue when called trough setValue() call (keydown, blur, api) vertical configuration gives additional complexity. */ function slide(evt, x, val, isSetValue) { // calculate value based on slide position if (val === undefined) { val = x / len * range; // x is calculated based on val. we need to strip off min during calculation } else if (isSetValue) { val -= conf.min; } // increment in steps if (step) { val = Math.round(val / step) * step; } // count x based on value or tweak x if stepping is done if (x === undefined || step) { x = val * len / range; } // crazy value? if (isNaN(val)) { return self; } // stay within range x = Math.max(0, Math.min(x, len)); val = x / len * range; if (isSetValue || !vertical) { val += conf.min; } // in vertical ranges value rises upwards if (vertical) { if (isSetValue) { x = len -x; } else { val = conf.max - val; } } // precision val = round(val, precision); // onSlide var isClick = evt.type == "click"; if (fireOnSlide && value !== undefined && !isClick) { evt.type = "onSlide"; fire.trigger(evt, [val, x]); if (evt.isDefaultPrevented()) { return self; } } // speed & callback var speed = isClick ? conf.speed : 0, callback = isClick ? function() { evt.type = "change"; fire.trigger(evt, [val]); } : null; if (vertical) { handle.animate({top: x}, speed, callback); if (conf.progress) { progress.animate({height: len - x + handle.width() / 2}, speed); } } else { handle.animate({left: x}, speed, callback); if (conf.progress) { progress.animate({width: x + handle.width() / 2}, speed); } } // store current value value = val; pos = x; // se input field's value input.val(val); return self; } $.extend(self, { getValue: function() { return value; }, setValue: function(val, e) { init(); return slide(e || $.Event("api"), undefined, val, true); }, getConf: function() { return conf; }, getProgress: function() { return progress; }, getHandle: function() { return handle; }, getInput: function() { return input; }, step: function(am, e) { e = e || $.Event(); var step = conf.step == 'any' ? 1 : conf.step; self.setValue(value + step * (am || 1), e); }, // HTML5 compatible name stepUp: function(am) { return self.step(am || 1); }, // HTML5 compatible name stepDown: function(am) { return self.step(-am || -1); } }); // callbacks $.each("onSlide,change".split(","), function(i, name) { // from configuration if ($.isFunction(conf[name])) { $(self).bind(name, conf[name]); } // API methods self[name] = function(fn) { if (fn) { $(self).bind(name, fn); } return self; }; }); // dragging handle.drag({drag: false}).bind("dragStart", function() { /* do some pre- calculations for seek() function. improves performance */ init(); // avoid redundant event triggering (= heavy stuff) fireOnSlide = hasEvent($(self)) || hasEvent(input); }).bind("drag", function(e, y, x) { if (input.is(":disabled")) { return false; } slide(e, vertical ? y : x); }).bind("dragEnd", function(e) { if (!e.isDefaultPrevented()) { e.type = "change"; fire.trigger(e, [value]); } }).click(function(e) { return e.preventDefault(); }); // clicking root.click(function(e) { if (input.is(":disabled") || e.target == handle[0]) { return e.preventDefault(); } init(); var fix = handle.width() / 2; slide(e, vertical ? len-origo-fix + e.pageY : e.pageX -origo -fix); }); if (conf.keyboard) { input.keydown(function(e) { if (input.attr("readonly")) { return; } var key = e.keyCode, up = $([75, 76, 38, 33, 39]).index(key) != -1, down = $([74, 72, 40, 34, 37]).index(key) != -1; if ((up || down) && !(e.shiftKey || e.altKey || e.ctrlKey)) { // UP: k=75, l=76, up=38, pageup=33, right=39 if (up) { self.step(key == 33 ? 10 : 1, e); // DOWN: j=74, h=72, down=40, pagedown=34, left=37 } else if (down) { self.step(key == 34 ? -10 : -1, e); } return e.preventDefault(); } }); } input.blur(function(e) { var val = $(this).val(); if (val !== value) { self.setValue(val, e); } }); // HTML5 DOM methods $.extend(input[0], { stepUp: self.stepUp, stepDown: self.stepDown}); // calculate all dimension related stuff function init() { vertical = conf.vertical || dim(root, "height") > dim(root, "width"); if (vertical) { len = dim(root, "height") - dim(handle, "height"); origo = root.offset().top + len; } else { len = dim(root, "width") - dim(handle, "width"); origo = root.offset().left; } } function begin() { init(); self.setValue(conf.value !== undefined ? conf.value : conf.min); } begin(); // some browsers cannot get dimensions upon initialization if (!len) { $(window).load(begin); } } $.expr[':'].range = function(el) { var type = el.getAttribute("type"); return type && type == 'range' || !!$(el).filter("input").data("rangeinput"); }; // jQuery plugin implementation $.fn.rangeinput = function(conf) { // already installed if (this.data("rangeinput")) { return this; } // extend configuration with globals conf = $.extend(true, {}, tool.conf, conf); var els; this.each(function() { var el = new RangeInput($(this), $.extend(true, {}, conf)); var input = el.getInput().data("rangeinput", el); els = els ? els.add(input) : input; }); return els ? els : this; }; }) (jQuery); /** * @license * jQuery Tools 1.2.5 History "Back button for AJAX apps" * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/toolbox/history.html * * Since: Mar 2010 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { var hash, iframe, links, inited; $.tools = $.tools || {version: '1.2.5'}; $.tools.history = { init: function(els) { if (inited) { return; } // IE if ($.browser.msie && $.browser.version < '8') { // create iframe that is constantly checked for hash changes if (!iframe) { iframe = $("<iframe/>").attr("src", "javascript:false;").hide().get(0); $("body").append(iframe); setInterval(function() { var idoc = iframe.contentWindow.document, h = idoc.location.hash; if (hash !== h) { $.event.trigger("hash", h); } }, 100); setIframeLocation(location.hash || '#'); } // other browsers scans for location.hash changes directly without iframe hack } else { setInterval(function() { var h = location.hash; if (h !== hash) { $.event.trigger("hash", h); } }, 100); } links = !links ? els : links.add(els); els.click(function(e) { var href = $(this).attr("href"); if (iframe) { setIframeLocation(href); } // handle non-anchor links if (href.slice(0, 1) != "#") { location.href = "#" + href; return e.preventDefault(); } }); inited = true; } }; function setIframeLocation(h) { if (h) { var doc = iframe.contentWindow.document; doc.open().close(); doc.location.hash = h; } } // global histroy change listener $(window).bind("hash", function(e, h) { if (h) { links.filter(function() { var href = $(this).attr("href"); return href == h || href == h.replace("#", ""); }).trigger("history", [h]); } else { links.eq(0).trigger("history", [h]); } hash = h; }); // jQuery plugin implementation $.fn.history = function(fn) { $.tools.history.init(this); // return jQuery return this.bind("history", fn); }; })(jQuery); /** * @license * jQuery Tools 1.2.5 Mousewheel * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/toolbox/mousewheel.html * * based on jquery.event.wheel.js ~ rev 1 ~ * Copyright (c) 2008, Three Dub Media * http://threedubmedia.com * * Since: Mar 2010 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { $.fn.mousewheel = function( fn ){ return this[ fn ? "bind" : "trigger" ]( "wheel", fn ); }; // special event config $.event.special.wheel = { setup: function() { $.event.add( this, wheelEvents, wheelHandler, {} ); }, teardown: function(){ $.event.remove( this, wheelEvents, wheelHandler ); } }; // events to bind ( browser sniffed... ) var wheelEvents = !$.browser.mozilla ? "mousewheel" : // IE, opera, safari "DOMMouseScroll"+( $.browser.version<"1.9" ? " mousemove" : "" ); // firefox // shared event handler function wheelHandler( event ) { switch ( event.type ) { // FF2 has incorrect event positions case "mousemove": return $.extend( event.data, { // store the correct properties clientX: event.clientX, clientY: event.clientY, pageX: event.pageX, pageY: event.pageY }); // firefox case "DOMMouseScroll": $.extend( event, event.data ); // fix event properties in FF2 event.delta = -event.detail / 3; // normalize delta break; // IE, opera, safari case "mousewheel": event.delta = event.wheelDelta / 120; break; } event.type = "wheel"; // hijack the event return $.event.handle.call( this, event, event.delta ); } })(jQuery); /** * @license * jQuery Tools 1.2.5 / Flashembed - New wave Flash embedding * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/toolbox/flashembed.html * * Since : March 2008 * Date : Thu May 15 10:43:37 CEST 2014 */ (function() { var IE = document.all, URL = 'http://www.adobe.com/go/getflashplayer', JQUERY = typeof jQuery == 'function', RE = /(\d+)[^\d]+(\d+)[^\d]*(\d*)/, GLOBAL_OPTS = { // very common opts width: '100%', height: '100%', id: "_" + ("" + Math.random()).slice(9), // flashembed defaults allowfullscreen: true, allowscriptaccess: 'always', quality: 'high', // flashembed specific options version: [3, 0], onFail: null, expressInstall: null, w3c: false, cachebusting: false }; // version 9 bugfix: (http://blog.deconcept.com/2006/07/28/swfobject-143-released/) if (window.attachEvent) { window.attachEvent("onbeforeunload", function() { __flash_unloadHandler = function() {}; __flash_savedUnloadHandler = function() {}; }); } // simple extend function extend(to, from) { if (from) { for (var key in from) { if (from.hasOwnProperty(key)) { to[key] = from[key]; } } } return to; } // used by asString method function map(arr, func) { var newArr = []; for (var i in arr) { if (arr.hasOwnProperty(i)) { newArr[i] = func(arr[i]); } } return newArr; } window.flashembed = function(root, opts, conf) { // root must be found / loaded if (typeof root == 'string') { root = document.getElementById(root.replace("#", "")); } // not found if (!root) { return; } if (typeof opts == 'string') { opts = {src: opts}; } return new Flash(root, extend(extend({}, GLOBAL_OPTS), opts), conf); }; // flashembed "static" API var f = extend(window.flashembed, { conf: GLOBAL_OPTS, getVersion: function() { var fo, ver; try { ver = navigator.plugins["Shockwave Flash"].description.slice(16); } catch(e) { try { fo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); ver = fo && fo.GetVariable("$version"); } catch(err) { try { fo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); ver = fo && fo.GetVariable("$version"); } catch(err2) { } } } ver = RE.exec(ver); return ver ? [ver[1], ver[3]] : [0, 0]; }, asString: function(obj) { if (obj === null || obj === undefined) { return null; } var type = typeof obj; if (type == 'object' && obj.push) { type = 'array'; } switch (type){ case 'string': obj = obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1'); // flash does not handle %- characters well. transforms "50%" to "50pct" (a dirty hack, I admit) obj = obj.replace(/^\s?(\d+\.?\d+)%/, "$1pct"); return '"' +obj+ '"'; case 'array': return '['+ map(obj, function(el) { return f.asString(el); }).join(',') +']'; case 'function': return '"function()"'; case 'object': var str = []; for (var prop in obj) { if (obj.hasOwnProperty(prop)) { str.push('"'+prop+'":'+ f.asString(obj[prop])); } } return '{'+str.join(',')+'}'; } // replace ' --> " and remove spaces return String(obj).replace(/\s/g, " ").replace(/\'/g, "\""); }, getHTML: function(opts, conf) { opts = extend({}, opts); /******* OBJECT tag and it's attributes *******/ var html = '<object width="' + opts.width + '" height="' + opts.height + '" id="' + opts.id + '" name="' + opts.id + '"'; if (opts.cachebusting) { opts.src += ((opts.src.indexOf("?") != -1 ? "&" : "?") + Math.random()); } if (opts.w3c || !IE) { html += ' data="' +opts.src+ '" type="application/x-shockwave-flash"'; } else { html += ' classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'; } html += '>'; /******* nested PARAM tags *******/ if (opts.w3c || IE) { html += '<param name="movie" value="' +opts.src+ '" />'; } // not allowed params opts.width = opts.height = opts.id = opts.w3c = opts.src = null; opts.onFail = opts.version = opts.expressInstall = null; for (var key in opts) { if (opts[key]) { html += '<param name="'+ key +'" value="'+ opts[key] +'" />'; } } /******* FLASHVARS *******/ var vars = ""; if (conf) { for (var k in conf) { if (conf[k]) { var val = conf[k]; vars += k +'='+ (/function|object/.test(typeof val) ? f.asString(val) : val) + '&'; } } vars = vars.slice(0, -1); html += '<param name="flashvars" value=\'' + vars + '\' />'; } html += "</object>"; return html; }, isSupported: function(ver) { return VERSION[0] > ver[0] || VERSION[0] == ver[0] && VERSION[1] >= ver[1]; } }); var VERSION = f.getVersion(); function Flash(root, opts, conf) { // version is ok if (f.isSupported(opts.version)) { root.innerHTML = f.getHTML(opts, conf); // express install } else if (opts.expressInstall && f.isSupported([6, 65])) { root.innerHTML = f.getHTML(extend(opts, {src: opts.expressInstall}), { MMredirectURL: location.href, MMplayerType: 'PlugIn', MMdoctitle: document.title }); } else { // fail #2.1 custom content inside container if (!root.innerHTML.replace(/\s/g, '')) { root.innerHTML = "<h2>Flash version " + opts.version + " or greater is required</h2>" + "<h3>" + (VERSION[0] > 0 ? "Your version is " + VERSION : "You have no flash plugin installed") + "</h3>" + (root.tagName == 'A' ? "<p>Click here to download latest version</p>" : "<p>Download latest version from <a href='" + URL + "'>here</a></p>"); if (root.tagName == 'A') { root.onclick = function() { location.href = URL; }; } } // onFail if (opts.onFail) { var ret = opts.onFail.call(this); if (typeof ret == 'string') { root.innerHTML = ret; } } } // http://flowplayer.org/forum/8/18186#post-18593 if (IE) { window[opts.id] = document.getElementById(opts.id); } // API methods for callback extend(this, { getRoot: function() { return root; }, getOptions: function() { return opts; }, getConf: function() { return conf; }, getApi: function() { return root.firstChild; } }); } // setup jquery support if (JQUERY) { // tools version number jQuery.tools = jQuery.tools || {version: '1.2.5'}; jQuery.tools.flashembed = { conf: GLOBAL_OPTS }; jQuery.fn.flashembed = function(opts, conf) { return this.each(function() { $(this).data("flashembed", flashembed(this, opts, conf)); }); }; } })(); /** * @license * jQuery Tools 1.2.5 / Expose - Dim the lights * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/toolbox/expose.html * * Since: Mar 2010 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { // static constructs $.tools = $.tools || {version: '1.2.5'}; var tool; tool = $.tools.expose = { conf: { maskId: 'exposeMask', loadSpeed: 'slow', closeSpeed: 'fast', closeOnClick: true, closeOnEsc: true, // css settings zIndex: 9998, opacity: 0.8, startOpacity: 0, color: '#fff', // callbacks onLoad: null, onClose: null } }; /* one of the greatest headaches in the tool. finally made it */ function viewport() { // the horror case if ($.browser.msie) { // if there are no scrollbars then use window.height var d = $(document).height(), w = $(window).height(); return [ window.innerWidth || // ie7+ document.documentElement.clientWidth || // ie6 document.body.clientWidth, // ie6 quirks mode d - w < 20 ? w : d ]; } // other well behaving browsers return [$(document).width(), $(document).height()]; } function call(fn) { if (fn) { return fn.call($.mask); } } var mask, exposed, loaded, config, overlayIndex; $.mask = { load: function(conf, els) { // already loaded ? if (loaded) { return this; } // configuration if (typeof conf == 'string') { conf = {color: conf}; } // use latest config conf = conf || config; config = conf = $.extend($.extend({}, tool.conf), conf); // get the mask mask = $("#" + conf.maskId); // or create it if (!mask.length) { mask = $('<div/>').attr("id", conf.maskId); $("body").append(mask); } // set position and dimensions var size = viewport(); mask.css({ position:'absolute', top: 0, left: 0, width: size[0], height: size[1], display: 'none', opacity: conf.startOpacity, zIndex: conf.zIndex }); if (conf.color) { mask.css("backgroundColor", conf.color); } // onBeforeLoad if (call(conf.onBeforeLoad) === false) { return this; } // esc button if (conf.closeOnEsc) { $(document).bind("keydown.mask", function(e) { if (e.keyCode == 27) { $.mask.close(e); } }); } // mask click closes if (conf.closeOnClick) { mask.bind("click.mask", function(e) { $.mask.close(e); }); } // resize mask when window is resized $(window).bind("resize.mask", function() { $.mask.fit(); }); // exposed elements if (els && els.length) { overlayIndex = els.eq(0).css("zIndex"); // make sure element is positioned absolutely or relatively $.each(els, function() { var el = $(this); if (!/relative|absolute|fixed/i.test(el.css("position"))) { el.css("position", "relative"); } }); // make elements sit on top of the mask exposed = els.css({ zIndex: Math.max(conf.zIndex + 1, overlayIndex == 'auto' ? 0 : overlayIndex)}); } // reveal mask mask.css({display: 'block'}).fadeTo(conf.loadSpeed, conf.opacity, function() { $.mask.fit(); call(conf.onLoad); loaded = "full"; }); loaded = true; return this; }, close: function() { if (loaded) { // onBeforeClose if (call(config.onBeforeClose) === false) { return this; } mask.fadeOut(config.closeSpeed, function() { call(config.onClose); if (exposed) { exposed.css({zIndex: overlayIndex}); } loaded = false; }); // unbind various event listeners $(document).unbind("keydown.mask"); mask.unbind("click.mask"); $(window).unbind("resize.mask"); } return this; }, fit: function() { if (loaded) { var size = viewport(); mask.css({width: size[0], height: size[1]}); } }, getMask: function() { return mask; }, isLoaded: function(fully) { return fully ? loaded == 'full' : loaded; }, getConf: function() { return config; }, getExposed: function() { return exposed; } }; $.fn.mask = function(conf) { $.mask.load(conf); return this; }; $.fn.expose = function(conf) { $.mask.load(conf, this); return this; }; })(jQuery); /** * @license * jQuery Tools 1.2.5 Dateinput - <input type="date" /> for humans * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/form/dateinput/ * * Since: Mar 2010 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { /* TODO: preserve today highlighted */ $.tools = $.tools || {version: '1.2.5'}; var instances = [], tool, // h=72, j=74, k=75, l=76, down=40, left=37, up=38, right=39 KEYS = [75, 76, 38, 39, 74, 72, 40, 37], LABELS = {}; tool = $.tools.dateinput = { conf: { format: 'mm/dd/yy', selectors: false, yearRange: [-5, 5], lang: 'en', offset: [0, 0], speed: 0, firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... min: undefined, max: undefined, trigger: false, css: { prefix: 'cal', input: 'date', // ids root: 0, head: 0, title: 0, prev: 0, next: 0, month: 0, year: 0, days: 0, body: 0, weeks: 0, today: 0, current: 0, // classnames week: 0, off: 0, sunday: 0, focus: 0, disabled: 0, trigger: 0 } }, localize: function(language, labels) { $.each(labels, function(key, val) { labels[key] = val.split(","); }); LABELS[language] = labels; } }; tool.localize("en", { months: 'January,February,March,April,May,June,July,August,September,October,November,December', shortMonths: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec', days: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday', shortDays: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat' }); //{{{ private functions // @return amount of days in certain month function dayAm(year, month) { return 32 - new Date(year, month, 32).getDate(); } function zeropad(val, len) { val = '' + val; len = len || 2; while (val.length < len) { val = "0" + val; } return val; } // thanks: http://stevenlevithan.com/assets/misc/date.format.js var Re = /d{1,4}|m{1,4}|yy(?:yy)?|"[^"]*"|'[^']*'/g, tmpTag = $("<a/>"); function format(date, fmt, lang) { var d = date.getDate(), D = date.getDay(), m = date.getMonth(), y = date.getFullYear(), flags = { d: d, dd: zeropad(d), ddd: LABELS[lang].shortDays[D], dddd: LABELS[lang].days[D], m: m + 1, mm: zeropad(m + 1), mmm: LABELS[lang].shortMonths[m], mmmm: LABELS[lang].months[m], yy: String(y).slice(2), yyyy: y }; var ret = fmt.replace(Re, function ($0) { return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1); }); // a small trick to handle special characters return tmpTag.html(ret).html(); } function integer(val) { return parseInt(val, 10); } function isSameDay(d1, d2) { return d1.getFullYear() === d2.getFullYear() && d1.getMonth() == d2.getMonth() && d1.getDate() == d2.getDate(); } function parseDate(val) { if (!val) { return; } if (val.constructor == Date) { return val; } if (typeof val == 'string') { // rfc3339? var els = val.split("-"); if (els.length == 3) { return new Date(integer(els[0]), integer(els[1]) -1, integer(els[2])); } // invalid offset if (!/^-?\d+$/.test(val)) { return; } // convert to integer val = integer(val); } var date = new Date(); date.setDate(date.getDate() + val); return date; } //}}} function Dateinput(input, conf) { // variables var self = this, now = new Date(), css = conf.css, labels = LABELS[conf.lang], root = $("#" + css.root), title = root.find("#" + css.title), trigger, pm, nm, currYear, currMonth, currDay, value = input.attr("data-value") || conf.value || input.val(), min = input.attr("min") || conf.min, max = input.attr("max") || conf.max, opened; // zero min is not undefined if (min === 0) { min = "0"; } // use sane values for value, min & max value = parseDate(value) || now; min = parseDate(min || conf.yearRange[0] * 365); max = parseDate(max || conf.yearRange[1] * 365); // check that language exists if (!labels) { throw "Dateinput: invalid language: " + conf.lang; } // Replace built-in date input: NOTE: input.attr("type", "text") throws exception by the browser if (input.attr("type") == 'date') { var tmp = $("<input/>"); $.each("class,disabled,id,maxlength,name,readonly,required,size,style,tabindex,title,value".split(","), function(i, attr) { tmp.attr(attr, input.attr(attr)); }); input.replaceWith(tmp); input = tmp; } input.addClass(css.input); var fire = input.add(self); // construct layout if (!root.length) { // root root = $('<div><div><a/><div/><a/></div><div><div/><div/></div></div>') .hide().css({position: 'absolute'}).attr("id", css.root); // elements root.children() .eq(0).attr("id", css.head).end() .eq(1).attr("id", css.body).children() .eq(0).attr("id", css.days).end() .eq(1).attr("id", css.weeks).end().end().end() .find("a").eq(0).attr("id", css.prev).end().eq(1).attr("id", css.next); // title title = root.find("#" + css.head).find("div").attr("id", css.title); // year & month selectors if (conf.selectors) { var monthSelector = $("<select/>").attr("id", css.month), yearSelector = $("<select/>").attr("id", css.year); title.html(monthSelector.add(yearSelector)); } // day titles var days = root.find("#" + css.days); // days of the week for (var d = 0; d < 7; d++) { days.append($("<span/>").text(labels.shortDays[(d + conf.firstDay) % 7])); } $("body").append(root); } // trigger icon if (conf.trigger) { trigger = $("<a/>").attr("href", "#").addClass(css.trigger).click(function(e) { self.show(); return e.preventDefault(); }).insertAfter(input); } // layout elements var weeks = root.find("#" + css.weeks); yearSelector = root.find("#" + css.year); monthSelector = root.find("#" + css.month); //{{{ pick function select(date, conf, e) { // current value value = date; currYear = date.getFullYear(); currMonth = date.getMonth(); currDay = date.getDate(); // change e = e || $.Event("api"); e.type = "change"; fire.trigger(e, [date]); if (e.isDefaultPrevented()) { return; } // formatting input.val(format(date, conf.format, conf.lang)); // store value into input input.data("date", date); self.hide(e); } //}}} //{{{ onShow function onShow(ev) { ev.type = "onShow"; fire.trigger(ev); $(document).bind("keydown.d", function(e) { if (e.ctrlKey) { return true; } var key = e.keyCode; // backspace clears the value if (key == 8) { input.val(""); return self.hide(e); } // esc key if (key == 27) { return self.hide(e); } if ($(KEYS).index(key) >= 0) { if (!opened) { self.show(e); return e.preventDefault(); } var days = $("#" + css.weeks + " a"), el = $("." + css.focus), index = days.index(el); el.removeClass(css.focus); if (key == 74 || key == 40) { index += 7; } else if (key == 75 || key == 38) { index -= 7; } else if (key == 76 || key == 39) { index += 1; } else if (key == 72 || key == 37) { index -= 1; } if (index > 41) { self.addMonth(); el = $("#" + css.weeks + " a:eq(" + (index-42) + ")"); } else if (index < 0) { self.addMonth(-1); el = $("#" + css.weeks + " a:eq(" + (index+42) + ")"); } else { el = days.eq(index); } el.addClass(css.focus); return e.preventDefault(); } // pageUp / pageDown if (key == 34) { return self.addMonth(); } if (key == 33) { return self.addMonth(-1); } // home if (key == 36) { return self.today(); } // enter if (key == 13) { if (!$(e.target).is("select")) { $("." + css.focus).click(); } } return $([16, 17, 18, 9]).index(key) >= 0; }); // click outside dateinput $(document).bind("click.d", function(e) { var el = e.target; if (!$(el).parents("#" + css.root).length && el != input[0] && (!trigger || el != trigger[0])) { self.hide(e); } }); } //}}} $.extend(self, { //{{{ show show: function(e) { if (input.attr("readonly") || input.attr("disabled") || opened) { return; } // onBeforeShow e = e || $.Event(); e.type = "onBeforeShow"; fire.trigger(e); if (e.isDefaultPrevented()) { return; } $.each(instances, function() { this.hide(); }); opened = true; // month selector monthSelector.unbind("change").change(function() { self.setValue(yearSelector.val(), $(this).val()); }); // year selector yearSelector.unbind("change").change(function() { self.setValue($(this).val(), monthSelector.val()); }); // prev / next month pm = root.find("#" + css.prev).unbind("click").click(function(e) { if (!pm.hasClass(css.disabled)) { self.addMonth(-1); } return false; }); nm = root.find("#" + css.next).unbind("click").click(function(e) { if (!nm.hasClass(css.disabled)) { self.addMonth(); } return false; }); // set date self.setValue(value); // show calendar var pos = input.offset(); // iPad position fix if (/iPad/i.test(navigator.userAgent)) { pos.top -= $(window).scrollTop(); } root.css({ top: pos.top + input.outerHeight({margins: true}) + conf.offset[0], left: pos.left + conf.offset[1] }); if (conf.speed) { root.show(conf.speed, function() { onShow(e); }); } else { root.show(); onShow(e); } return self; }, //}}} //{{{ setValue setValue: function(year, month, day) { var date = integer(month) >= -1 ? new Date(integer(year), integer(month), integer(day || 1)) : year || value ; if (date < min) { date = min; } else if (date > max) { date = max; } year = date.getFullYear(); month = date.getMonth(); day = date.getDate(); // roll year & month if (month == -1) { month = 11; year--; } else if (month == 12) { month = 0; year++; } if (!opened) { select(date, conf); return self; } currMonth = month; currYear = year; // variables var tmp = new Date(year, month, 1 - conf.firstDay), begin = tmp.getDay(), days = dayAm(year, month), prevDays = dayAm(year, month - 1), week; // selectors if (conf.selectors) { // month selector monthSelector.empty(); $.each(labels.months, function(i, m) { if (min < new Date(year, i + 1, -1) && max > new Date(year, i, 0)) { monthSelector.append($("<option/>").html(m).attr("value", i)); } }); // year selector yearSelector.empty(); var yearNow = now.getFullYear(); for (var i = yearNow + conf.yearRange[0]; i < yearNow + conf.yearRange[1]; i++) { if (min <= new Date(i + 1, -1, 1) && max > new Date(i, 0, 0)) { yearSelector.append($("<option/>").text(i)); } } monthSelector.val(month); yearSelector.val(year); // title } else { title.html(labels.months[month] + " " + year); } // populate weeks weeks.empty(); pm.add(nm).removeClass(css.disabled); // !begin === "sunday" for (var j = !begin ? -7 : 0, a, num; j < (!begin ? 35 : 42); j++) { a = $("<a/>"); if (j % 7 === 0) { week = $("<div/>").addClass(css.week); weeks.append(week); } if (j < begin) { a.addClass(css.off); num = prevDays - begin + j + 1; date = new Date(year, month-1, num); } else if (j >= begin + days) { a.addClass(css.off); num = j - days - begin + 1; date = new Date(year, month+1, num); } else { num = j - begin + 1; date = new Date(year, month, num); // current date if (isSameDay(value, date)) { a.attr("id", css.current).addClass(css.focus); // today } else if (isSameDay(now, date)) { a.attr("id", css.today); } } // disabled if (min && date < min) { a.add(pm).addClass(css.disabled); } if (max && date > max) { a.add(nm).addClass(css.disabled); } a.attr("href", "#" + num).text(num).data("date", date); week.append(a); } // date picking weeks.find("a").click(function(e) { var el = $(this); if (!el.hasClass(css.disabled)) { $("#" + css.current).removeAttr("id"); el.attr("id", css.current); select(el.data("date"), conf, e); } return false; }); // sunday if (css.sunday) { weeks.find(css.week).each(function() { var beg = conf.firstDay ? 7 - conf.firstDay : 0; $(this).children().slice(beg, beg + 1).addClass(css.sunday); }); } return self; }, //}}} setMin: function(val, fit) { min = parseDate(val); if (fit && value < min) { self.setValue(min); } return self; }, setMax: function(val, fit) { max = parseDate(val); if (fit && value > max) { self.setValue(max); } return self; }, today: function() { return self.setValue(now); }, addDay: function(amount) { return this.setValue(currYear, currMonth, currDay + (amount || 1)); }, addMonth: function(amount) { return this.setValue(currYear, currMonth + (amount || 1), currDay); }, addYear: function(amount) { return this.setValue(currYear + (amount || 1), currMonth, currDay); }, hide: function(e) { if (opened) { // onHide e = $.Event(); e.type = "onHide"; fire.trigger(e); $(document).unbind("click.d").unbind("keydown.d"); // cancelled ? if (e.isDefaultPrevented()) { return; } // do the hide root.hide(); opened = false; } return self; }, getConf: function() { return conf; }, getInput: function() { return input; }, getCalendar: function() { return root; }, getValue: function(dateFormat) { return dateFormat ? format(value, dateFormat, conf.lang) : value; }, isOpen: function() { return opened; } }); // callbacks $.each(['onBeforeShow','onShow','change','onHide'], function(i, name) { // configuration if ($.isFunction(conf[name])) { $(self).bind(name, conf[name]); } // API methods self[name] = function(fn) { if (fn) { $(self).bind(name, fn); } return self; }; }); // show dateinput & assign keyboard shortcuts input.bind("focus click", self.show).keydown(function(e) { var key = e.keyCode; // open dateinput with navigation keyw if (!opened && $(KEYS).index(key) >= 0) { self.show(e); return e.preventDefault(); } // allow tab return e.shiftKey || e.ctrlKey || e.altKey || key == 9 ? true : e.preventDefault(); }); // initial value if (parseDate(input.val())) { select(value, conf); } } $.expr[':'].date = function(el) { var type = el.getAttribute("type"); return type && type == 'date' || !!$(el).data("dateinput"); }; $.fn.dateinput = function(conf) { // already instantiated if (this.data("dateinput")) { return this; } // configuration conf = $.extend(true, {}, tool.conf, conf); // CSS prefix $.each(conf.css, function(key, val) { if (!val && key != 'prefix') { conf.css[key] = (conf.css.prefix || '') + (val || key); } }); var els; this.each(function() { var el = new Dateinput($(this), conf); instances.push(el); var input = el.getInput().data("dateinput", el); els = els ? els.add(input) : input; }); return els ? els : this; }; }) (jQuery); /** * @license * jQuery Tools 1.2.5 Tabs- The basics of UI design. * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/tabs/ * * Since: November 2008 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { // static constructs $.tools = $.tools || {version: '1.2.5'}; $.tools.tabs = { conf: { tabs: 'a', current: 'current', onBeforeClick: null, onClick: null, effect: 'default', initialIndex: 0, event: 'click', rotate: false, // 1.2 history: false }, addEffect: function(name, fn) { effects[name] = fn; } }; var effects = { // simple "toggle" effect 'default': function(i, done) { this.getPanes().hide().eq(i).show(); done.call(); }, /* configuration: - fadeOutSpeed (positive value does "crossfading") - fadeInSpeed */ fade: function(i, done) { var conf = this.getConf(), speed = conf.fadeOutSpeed, panes = this.getPanes(); if (speed) { panes.fadeOut(speed); } else { panes.hide(); } panes.eq(i).fadeIn(conf.fadeInSpeed, done); }, // for basic accordions slide: function(i, done) { this.getPanes().slideUp(200); this.getPanes().eq(i).slideDown(400, done); }, /** * AJAX effect */ ajax: function(i, done) { this.getPanes().eq(0).load(this.getTabs().eq(i).attr("href"), done); } }; var w; /** * Horizontal accordion * * @deprecated will be replaced with a more robust implementation */ $.tools.tabs.addEffect("horizontal", function(i, done) { // store original width of a pane into memory if (!w) { w = this.getPanes().eq(0).width(); } // set current pane's width to zero this.getCurrentPane().animate({width: 0}, function() { $(this).hide(); }); // grow opened pane to it's original width this.getPanes().eq(i).animate({width: w}, function() { $(this).show(); done.call(); }); }); function Tabs(root, paneSelector, conf) { var self = this, trigger = root.add(this), tabs = root.find(conf.tabs), panes = paneSelector.jquery ? paneSelector : root.children(paneSelector), current; // make sure tabs and panes are found if (!tabs.length) { tabs = root.children(); } if (!panes.length) { panes = root.parent().find(paneSelector); } if (!panes.length) { panes = $(paneSelector); } // public methods $.extend(this, { click: function(i, e) { var tab = tabs.eq(i); if (typeof i == 'string' && i.replace("#", "")) { tab = tabs.filter("[href*=" + i.replace("#", "") + "]"); i = Math.max(tabs.index(tab), 0); } if (conf.rotate) { var last = tabs.length -1; if (i < 0) { return self.click(last, e); } if (i > last) { return self.click(0, e); } } if (!tab.length) { if (current >= 0) { return self; } i = conf.initialIndex; tab = tabs.eq(i); } // current tab is being clicked if (i === current) { return self; } // possibility to cancel click action e = e || $.Event(); e.type = "onBeforeClick"; trigger.trigger(e, [i]); if (e.isDefaultPrevented()) { return; } // call the effect effects[conf.effect].call(self, i, function() { // onClick callback e.type = "onClick"; trigger.trigger(e, [i]); }); // default behaviour current = i; tabs.removeClass(conf.current); tab.addClass(conf.current); return self; }, getConf: function() { return conf; }, getTabs: function() { return tabs; }, getPanes: function() { return panes; }, getCurrentPane: function() { return panes.eq(current); }, getCurrentTab: function() { return tabs.eq(current); }, getIndex: function() { return current; }, next: function() { return self.click(current + 1); }, prev: function() { return self.click(current - 1); }, destroy: function() { tabs.unbind(conf.event).removeClass(conf.current); panes.find("a[href^=#]").unbind("click.T"); return self; } }); // callbacks $.each("onBeforeClick,onClick".split(","), function(i, name) { // configuration if ($.isFunction(conf[name])) { $(self).bind(name, conf[name]); } // API self[name] = function(fn) { if (fn) { $(self).bind(name, fn); } return self; }; }); if (conf.history && $.fn.history) { $.tools.history.init(tabs); conf.event = 'history'; } // setup click actions for each tab tabs.each(function(i) { $(this).bind(conf.event, function(e) { self.click(i, e); return e.preventDefault(); }); }); // cross tab anchor link panes.find("a[href^=#]").bind("click.T", function(e) { self.click($(this).attr("href"), e); }); // open initial tab if (location.hash && conf.tabs == "a" && root.find("[href=" +location.hash+ "]").length) { self.click(location.hash); } else { if (conf.initialIndex === 0 || conf.initialIndex > 0) { self.click(conf.initialIndex); } } } // jQuery plugin implementation $.fn.tabs = function(paneSelector, conf) { // return existing instance var el = this.data("tabs"); if (el) { el.destroy(); this.removeData("tabs"); } if ($.isFunction(conf)) { conf = {onBeforeClick: conf}; } // setup conf conf = $.extend({}, $.tools.tabs.conf, conf); this.each(function() { el = new Tabs($(this), paneSelector, conf); $(this).data("tabs", el); }); return conf.api ? el: this; }; }) (jQuery); /** * @license * jQuery Tools 1.2.5 Slideshow - Extend it. * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/tabs/slideshow.html * * Since: September 2009 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { var tool; tool = $.tools.tabs.slideshow = { conf: { next: '.forward', prev: '.backward', disabledClass: 'disabled', autoplay: false, autopause: true, interval: 3000, clickable: true, api: false } }; function Slideshow(root, conf) { var self = this, fire = root.add(this), tabs = root.data("tabs"), timer, stopped = true; // next / prev buttons function find(query) { var el = $(query); return el.length < 2 ? el : root.parent().find(query); } var nextButton = find(conf.next).click(function() { tabs.next(); }); var prevButton = find(conf.prev).click(function() { tabs.prev(); }); // extend the Tabs API with slideshow methods $.extend(self, { // return tabs API getTabs: function() { return tabs; }, getConf: function() { return conf; }, play: function() { // do not start additional timer if already exists if (timer) { return self; } // onBeforePlay var e = $.Event("onBeforePlay"); fire.trigger(e); if (e.isDefaultPrevented()) { return self; } // construct new timer timer = setInterval(tabs.next, conf.interval); stopped = false; // onPlay fire.trigger("onPlay"); return self; }, pause: function() { if (!timer) { return self; } // onBeforePause var e = $.Event("onBeforePause"); fire.trigger(e); if (e.isDefaultPrevented()) { return self; } timer = clearInterval(timer); // onPause fire.trigger("onPause"); return self; }, // when stopped - mouseover won't restart stop: function() { self.pause(); stopped = true; } }); // callbacks $.each("onBeforePlay,onPlay,onBeforePause,onPause".split(","), function(i, name) { // configuration if ($.isFunction(conf[name])) { $(self).bind(name, conf[name]); } // API methods self[name] = function(fn) { return $(self).bind(name, fn); }; }); /* when mouse enters, slideshow stops */ if (conf.autopause) { tabs.getTabs().add(nextButton).add(prevButton).add(tabs.getPanes()).hover(self.pause, function() { if (!stopped) { self.play(); } }); } if (conf.autoplay) { self.play(); } if (conf.clickable) { tabs.getPanes().click(function() { tabs.next(); }); } // manage disabling of next/prev buttons if (!tabs.getConf().rotate) { var disabled = conf.disabledClass; if (!tabs.getIndex()) { prevButton.addClass(disabled); } tabs.onBeforeClick(function(e, i) { prevButton.toggleClass(disabled, !i); nextButton.toggleClass(disabled, i == tabs.getTabs().length -1); }); } } // jQuery plugin implementation $.fn.slideshow = function(conf) { // return existing instance var el = this.data("slideshow"); if (el) { return el; } conf = $.extend({}, tool.conf, conf); this.each(function() { el = new Slideshow($(this), conf); $(this).data("slideshow", el); }); return conf.api ? el : this; }; })(jQuery); /** * @license * jQuery Tools 1.2.5 / Scrollable Navigator * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/scrollable/navigator.html * * Since: September 2009 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { var t = $.tools.scrollable; t.navigator = { conf: { navi: '.navi', naviItem: null, activeClass: 'active', indexed: false, idPrefix: null, // 1.2 history: false } }; function find(root, query) { var el = $(query); return el.length < 2 ? el : root.parent().find(query); } // jQuery plugin implementation $.fn.navigator = function(conf) { // configuration if (typeof conf == 'string') { conf = {navi: conf}; } conf = $.extend({}, t.navigator.conf, conf); var ret; this.each(function() { var api = $(this).data("scrollable"), navi = conf.navi.jquery ? conf.navi : find(api.getRoot(), conf.navi), buttons = api.getNaviButtons(), cls = conf.activeClass, history = conf.history && $.fn.history; // @deprecated stuff if (api) { ret = api; } api.getNaviButtons = function() { return buttons.add(navi); }; function doClick(el, i, e) { api.seekTo(i); if (history) { if (location.hash) { location.hash = el.attr("href").replace("#", ""); } } else { return e.preventDefault(); } } function els() { return navi.find(conf.naviItem || '> *'); } function addItem(i) { var item = $("<" + (conf.naviItem || 'a') + "/>").click(function(e) { doClick($(this), i, e); }).attr("href", "#" + i); // index number / id attribute if (i === 0) { item.addClass(cls); } if (conf.indexed) { item.text(i + 1); } if (conf.idPrefix) { item.attr("id", conf.idPrefix + i); } return item.appendTo(navi); } // generate navigator if (els().length) { els().each(function(i) { $(this).click(function(e) { doClick($(this), i, e); }); }); } else { $.each(api.getItems(), function(i) { addItem(i); }); } // activate correct entry api.onBeforeSeek(function(e, index) { setTimeout(function() { if (!e.isDefaultPrevented()) { var el = els().eq(index); if (!e.isDefaultPrevented() && el.length) { els().removeClass(cls).eq(index).addClass(cls); } } }, 1); }); function doHistory(evt, hash) { var el = els().eq(hash.replace("#", "")); if (!el.length) { el = els().filter("[href=" + hash + "]"); } el.click(); } // new item being added api.onAddItem(function(e, item) { item = addItem(api.getItems().index(item)); if (history) { item.history(doHistory); } }); if (history) { els().history(doHistory); } }); return conf.api ? ret : this; }; })(jQuery); /** * @license * jQuery Tools 1.2.5 Scrollable - New wave UI design * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/scrollable.html * * Since: March 2008 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { // static constructs $.tools = $.tools || {version: '1.2.5'}; $.tools.scrollable = { conf: { activeClass: 'active', circular: false, clonedClass: 'cloned', disabledClass: 'disabled', easing: 'swing', initialIndex: 0, item: null, items: '.items', keyboard: true, mousewheel: false, next: '.next', prev: '.prev', speed: 400, vertical: false, touch: true, wheelSpeed: 0 } }; // get hidden element's width or height even though it's hidden function dim(el, key) { var v = parseInt(el.css(key), 10); if (v) { return v; } var s = el[0].currentStyle; return s && s.width && parseInt(s.width, 10); } function find(root, query) { var el = $(query); return el.length < 2 ? el : root.parent().find(query); } var current; // constructor function Scrollable(root, conf) { // current instance var self = this, fire = root.add(self), itemWrap = root.children(), index = 0, vertical = conf.vertical; if (!current) { current = self; } if (itemWrap.length > 1) { itemWrap = $(conf.items, root); } // methods $.extend(self, { getConf: function() { return conf; }, getIndex: function() { return index; }, getSize: function() { return self.getItems().size(); }, getNaviButtons: function() { return prev.add(next); }, getRoot: function() { return root; }, getItemWrap: function() { return itemWrap; }, getItems: function() { return itemWrap.children(conf.item).not("." + conf.clonedClass); }, move: function(offset, time) { return self.seekTo(index + offset, time); }, next: function(time) { return self.move(1, time); }, prev: function(time) { return self.move(-1, time); }, begin: function(time) { return self.seekTo(0, time); }, end: function(time) { return self.seekTo(self.getSize() -1, time); }, focus: function() { current = self; return self; }, addItem: function(item) { item = $(item); if (!conf.circular) { itemWrap.append(item); } else { itemWrap.children("." + conf.clonedClass + ":last").before(item); itemWrap.children("." + conf.clonedClass + ":first").replaceWith(item.clone().addClass(conf.clonedClass)); } fire.trigger("onAddItem", [item]); return self; }, /* all seeking functions depend on this */ seekTo: function(i, time, fn) { // ensure numeric index if (!i.jquery) { i *= 1; } // avoid seeking from end clone to the beginning if (conf.circular && i === 0 && index == -1 && time !== 0) { return self; } // check that index is sane if (!conf.circular && i < 0 || i > self.getSize() || i < -1) { return self; } var item = i; if (i.jquery) { i = self.getItems().index(i); } else { item = self.getItems().eq(i); } // onBeforeSeek var e = $.Event("onBeforeSeek"); if (!fn) { fire.trigger(e, [i, time]); if (e.isDefaultPrevented() || !item.length) { return self; } } var props = vertical ? {top: -item.position().top} : {left: -item.position().left}; index = i; current = self; if (time === undefined) { time = conf.speed; } itemWrap.animate(props, time, conf.easing, fn || function() { fire.trigger("onSeek", [i]); }); return self; } }); // callbacks $.each(['onBeforeSeek', 'onSeek', 'onAddItem'], function(i, name) { // configuration if ($.isFunction(conf[name])) { $(self).bind(name, conf[name]); } self[name] = function(fn) { if (fn) { $(self).bind(name, fn); } return self; }; }); // circular loop if (conf.circular) { var cloned1 = self.getItems().slice(-1).clone().prependTo(itemWrap), cloned2 = self.getItems().eq(1).clone().appendTo(itemWrap); cloned1.add(cloned2).addClass(conf.clonedClass); self.onBeforeSeek(function(e, i, time) { if (e.isDefaultPrevented()) { return; } /* 1. animate to the clone without event triggering 2. seek to correct position with 0 speed */ if (i == -1) { self.seekTo(cloned1, time, function() { self.end(0); }); return e.preventDefault(); } else if (i == self.getSize()) { self.seekTo(cloned2, time, function() { self.begin(0); }); } }); // seek over the cloned item self.seekTo(0, 0, function() {}); } // next/prev buttons var prev = find(root, conf.prev).click(function() { self.prev(); }), next = find(root, conf.next).click(function() { self.next(); }); if (!conf.circular && self.getSize() > 1) { self.onBeforeSeek(function(e, i) { setTimeout(function() { if (!e.isDefaultPrevented()) { prev.toggleClass(conf.disabledClass, i <= 0); next.toggleClass(conf.disabledClass, i >= self.getSize() -1); } }, 1); }); if (!conf.initialIndex) { prev.addClass(conf.disabledClass); } } // mousewheel support if (conf.mousewheel && $.fn.mousewheel) { root.mousewheel(function(e, delta) { if (conf.mousewheel) { self.move(delta < 0 ? 1 : -1, conf.wheelSpeed || 50); return false; } }); } // touch event if (conf.touch) { var touch = {}; itemWrap[0].ontouchstart = function(e) { var t = e.touches[0]; touch.x = t.clientX; touch.y = t.clientY; }; itemWrap[0].ontouchmove = function(e) { // only deal with one finger if (e.touches.length == 1 && !itemWrap.is(":animated")) { var t = e.touches[0], deltaX = touch.x - t.clientX, deltaY = touch.y - t.clientY; self[vertical && deltaY > 0 || !vertical && deltaX > 0 ? 'next' : 'prev'](); e.preventDefault(); } }; } if (conf.keyboard) { $(document).bind("keydown.scrollable", function(evt) { // skip certain conditions if (!conf.keyboard || evt.altKey || evt.ctrlKey || $(evt.target).is(":input")) { return; } // does this instance have focus? if (conf.keyboard != 'static' && current != self) { return; } var key = evt.keyCode; if (vertical && (key == 38 || key == 40)) { self.move(key == 38 ? -1 : 1); return evt.preventDefault(); } if (!vertical && (key == 37 || key == 39)) { self.move(key == 37 ? -1 : 1); return evt.preventDefault(); } }); } // initial index if (conf.initialIndex) { self.seekTo(conf.initialIndex, 0, function() {}); } } // jQuery plugin implementation $.fn.scrollable = function(conf) { // already constructed --> return API var el = this.data("scrollable"); if (el) { return el; } conf = $.extend({}, $.tools.scrollable.conf, conf); this.each(function() { el = new Scrollable($(this), conf); $(this).data("scrollable", el); }); return conf.api ? el: this; }; })(jQuery); /** * @license * jQuery Tools 1.2.5 / Scrollable Autoscroll * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/scrollable/autoscroll.html * * Since: September 2009 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { var t = $.tools.scrollable; t.autoscroll = { conf: { autoplay: true, interval: 3000, autopause: true } }; // jQuery plugin implementation $.fn.autoscroll = function(conf) { if (typeof conf == 'number') { conf = {interval: conf}; } var opts = $.extend({}, t.autoscroll.conf, conf), ret; this.each(function() { var api = $(this).data("scrollable"); if (api) { ret = api; } // interval stuff var timer, stopped = true; api.play = function() { // do not start additional timer if already exists if (timer) { return; } stopped = false; // construct new timer timer = setInterval(function() { api.next(); }, opts.interval); }; api.pause = function() { timer = clearInterval(timer); }; // when stopped - mouseover won't restart api.stop = function() { api.pause(); stopped = true; }; /* when mouse enters, autoscroll stops */ if (opts.autopause) { api.getRoot().add(api.getNaviButtons()).hover(api.pause, api.play); } if (opts.autoplay) { api.play(); } }); return opts.api ? ret : this; }; })(jQuery); /** * @license * jQuery Tools Validator 1.2.5 - HTML5 is here. Now use it. * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/form/validator/ * * Since: Mar 2010 * Date: Thu May 15 10:43:37 CEST 2014 */ /*jslint evil: true */ (function($) { $.tools = $.tools || {version: '1.2.5'}; // globals var typeRe = /\[type=([a-z]+)\]/, numRe = /^-?[0-9]*(\.[0-9]+)?$/, dateInput = $.tools.dateinput, // http://net.tutsplus.com/tutorials/other/8-regular-expressions-you-should-know/ emailRe = /^([a-z0-9_\.\-\+]+)@([\da-z\.\-]+)\.([a-z\.]{2,6})$/i, urlRe = /^(https?:\/\/)?[\da-z\.\-]+\.[a-z\.]{2,6}[#&+_\?\/\w \.\-=]*$/i, v; v = $.tools.validator = { conf: { grouped: false, // show all error messages at once inside the container effect: 'default', // show/hide effect for error message. only 'default' is built-in errorClass: 'invalid', // input field class name in case of validation error // when to check for validity? inputEvent: null, // change, blur, keyup, null errorInputEvent: 'keyup', // change, blur, keyup, null formEvent: 'submit', // submit, null lang: 'en', // default language for error messages message: '<div/>', messageAttr: 'data-message', // name of the attribute for overridden error message messageClass: 'error', // error message element's class name offset: [0, 0], position: 'center right', singleError: false, // validate all inputs at once speed: 'normal' // message's fade-in speed }, /* The Error Messages */ messages: { "*": { en: "Please correct this value" } }, localize: function(lang, messages) { $.each(messages, function(key, msg) { v.messages[key] = v.messages[key] || {}; v.messages[key][lang] = msg; }); }, localizeFn: function(key, messages) { v.messages[key] = v.messages[key] || {}; $.extend(v.messages[key], messages); }, /** * Adds a new validator */ fn: function(matcher, msg, fn) { // no message supplied if ($.isFunction(msg)) { fn = msg; // message(s) on second argument } else { if (typeof msg == 'string') { msg = {en: msg}; } this.messages[matcher.key || matcher] = msg; } // check for "[type=xxx]" (not supported by jQuery) var test = typeRe.exec(matcher); if (test) { matcher = isType(test[1]); } // add validator to the arsenal fns.push([matcher, fn]); }, /* Add new show/hide effect */ addEffect: function(name, showFn, closeFn) { effects[name] = [showFn, closeFn]; } }; /* calculate error message position relative to the input */ function getPosition(trigger, el, conf) { // get origin top/left position var top = trigger.offset().top, left = trigger.offset().left, pos = conf.position.split(/,?\s+/), y = pos[0], x = pos[1]; top -= el.outerHeight() - conf.offset[0]; left += trigger.outerWidth() + conf.offset[1]; // iPad position fix if (/iPad/i.test(navigator.userAgent)) { top -= $(window).scrollTop(); } // adjust Y var height = el.outerHeight() + trigger.outerHeight(); if (y == 'center') { top += height / 2; } if (y == 'bottom') { top += height; } // adjust X var width = trigger.outerWidth(); if (x == 'center') { left -= (width + el.outerWidth()) / 2; } if (x == 'left') { left -= width; } return {top: top, left: left}; } // $.is("[type=xxx]") or $.filter("[type=xxx]") not working in jQuery 1.3.2 or 1.4.2 function isType(type) { function fn() { return this.getAttribute("type") == type; } fn.key = "[type=" + type + "]"; return fn; } var fns = [], effects = { 'default' : [ // show errors function function(errs) { var conf = this.getConf(); // loop errors $.each(errs, function(i, err) { // add error class var input = err.input; input.addClass(conf.errorClass); // get handle to the error container var msg = input.data("msg.el"); // create it if not present if (!msg) { msg = $(conf.message).addClass(conf.messageClass).appendTo(document.body); input.data("msg.el", msg); } // clear the container msg.css({visibility: 'hidden'}).find("p").remove(); // populate messages $.each(err.messages, function(i, m) { $("<p/>").html(m).appendTo(msg); }); // make sure the width is not full body width so it can be positioned correctly if (msg.outerWidth() == msg.parent().width()) { msg.add(msg.find("p")).css({display: 'inline'}); } // insert into correct position (relative to the field) var pos = getPosition(input, msg, conf); msg.css({ visibility: 'visible', position: 'absolute', top: pos.top, left: pos.left }) .fadeIn(conf.speed); }); // hide errors function }, function(inputs) { var conf = this.getConf(); inputs.removeClass(conf.errorClass).each(function() { var msg = $(this).data("msg.el"); if (msg) { msg.css({visibility: 'hidden'}); } }); } ] }; /* sperial selectors */ $.each("email,url,number".split(","), function(i, key) { $.expr[':'][key] = function(el) { return el.getAttribute("type") === key; }; }); /* oninvalid() jQuery plugin. Usage: $("input:eq(2)").oninvalid(function() { ... }); */ $.fn.oninvalid = function( fn ){ return this[fn ? "bind" : "trigger"]("OI", fn); }; /******* built-in HTML5 standard validators *********/ v.fn(":email", "Please enter a valid email address", function(el, v) { return !v || emailRe.test(v); }); v.fn(":url", "Please enter a valid URL", function(el, v) { return !v || urlRe.test(v); }); v.fn(":number", "Please enter a numeric value.", function(el, v) { return numRe.test(v); }); v.fn("[max]", "Please enter a value smaller than $1", function(el, v) { // skip empty values and dateinputs if (v === '' || dateInput && el.is(":date")) { return true; } var max = el.attr("max"); return parseFloat(v) <= parseFloat(max) ? true : [max]; }); v.fn("[min]", "Please enter a value larger than $1", function(el, v) { // skip empty values and dateinputs if (v === '' || dateInput && el.is(":date")) { return true; } var min = el.attr("min"); return parseFloat(v) >= parseFloat(min) ? true : [min]; }); v.fn("[required]", "Please complete this mandatory field.", function(el, v) { if (el.is(":checkbox")) { return el.is(":checked"); } return !!v; }); v.fn("[pattern]", function(el) { var p = new RegExp("^" + el.attr("pattern") + "$"); return p.test(el.val()); }); function Validator(inputs, form, conf) { // private variables var self = this, fire = form.add(self); // make sure there are input fields available inputs = inputs.not(":button, :image, :reset, :submit"); // utility function function pushMessage(to, matcher, returnValue) { // only one message allowed if (!conf.grouped && to.length) { return; } // the error message var msg; // substitutions are returned if (returnValue === false || $.isArray(returnValue)) { msg = v.messages[matcher.key || matcher] || v.messages["*"]; msg = msg[conf.lang] || v.messages["*"].en; // substitution var matches = msg.match(/\$\d/g); if (matches && $.isArray(returnValue)) { $.each(matches, function(i) { msg = msg.replace(this, returnValue[i]); }); } // error message is returned directly } else { msg = returnValue[conf.lang] || returnValue; } to.push(msg); } // API methods $.extend(self, { getConf: function() { return conf; }, getForm: function() { return form; }, getInputs: function() { return inputs; }, reflow: function() { inputs.each(function() { var input = $(this), msg = input.data("msg.el"); if (msg) { var pos = getPosition(input, msg, conf); msg.css({ top: pos.top, left: pos.left }); } }); return self; }, /* @param e - for internal use only */ invalidate: function(errs, e) { // errors are given manually: { fieldName1: 'message1', fieldName2: 'message2' } if (!e) { var errors = []; $.each(errs, function(key, val) { var input = inputs.filter("[name='" + key + "']"); if (input.length) { // trigger HTML5 ininvalid event input.trigger("OI", [val]); errors.push({ input: input, messages: [val]}); } }); errs = errors; e = $.Event(); } // onFail callback e.type = "onFail"; fire.trigger(e, [errs]); // call the effect if (!e.isDefaultPrevented()) { effects[conf.effect][0].call(self, errs, e); } return self; }, reset: function(els) { els = els || inputs; els.removeClass(conf.errorClass).each(function() { var msg = $(this).data("msg.el"); if (msg) { msg.remove(); $(this).data("msg.el", null); } }).unbind(conf.errorInputEvent || ''); return self; }, destroy: function() { form.unbind(conf.formEvent + ".V").unbind("reset.V"); inputs.unbind(conf.inputEvent + ".V").unbind("change.V"); return self.reset(); }, //{{{ checkValidity() - flesh and bone of this tool /* @returns boolean */ checkValidity: function(els, e) { els = els || inputs; els = els.not(":disabled"); if (!els.length) { return true; } e = e || $.Event(); // onBeforeValidate e.type = "onBeforeValidate"; fire.trigger(e, [els]); if (e.isDefaultPrevented()) { return e.result; } // container for errors var errs = []; // loop trough the inputs els.not(":radio:not(:checked)").each(function() { // field and it's error message container var msgs = [], el = $(this).data("messages", msgs), event = dateInput && el.is(":date") ? "onHide.v" : conf.errorInputEvent + ".v"; // cleanup previous validation event el.unbind(event); // loop all validator functions $.each(fns, function() { var fn = this, match = fn[0]; // match found if (el.filter(match).length) { // execute a validator function var returnValue = fn[1].call(self, el, el.val()); // validation failed. multiple substitutions can be returned with an array if (returnValue !== true) { // onBeforeFail e.type = "onBeforeFail"; fire.trigger(e, [el, match]); if (e.isDefaultPrevented()) { return false; } // overridden custom message var msg = el.attr(conf.messageAttr); if (msg) { msgs = [msg]; return false; } else { pushMessage(msgs, match, returnValue); } } } }); if (msgs.length) { errs.push({input: el, messages: msgs}); // trigger HTML5 ininvalid event el.trigger("OI", [msgs]); // begin validating upon error event type (such as keyup) if (conf.errorInputEvent) { el.bind(event, function(e) { self.checkValidity(el, e); }); } } if (conf.singleError && errs.length) { return false; } }); // validation done. now check that we have a proper effect at hand var eff = effects[conf.effect]; if (!eff) { throw "Validator: cannot find effect \"" + conf.effect + "\""; } // errors found if (errs.length) { self.invalidate(errs, e); return false; // no errors } else { // call the effect eff[1].call(self, els, e); // onSuccess callback e.type = "onSuccess"; fire.trigger(e, [els]); els.unbind(conf.errorInputEvent + ".v"); } return true; } //}}} }); // callbacks $.each("onBeforeValidate,onBeforeFail,onFail,onSuccess".split(","), function(i, name) { // configuration if ($.isFunction(conf[name])) { $(self).bind(name, conf[name]); } // API methods self[name] = function(fn) { if (fn) { $(self).bind(name, fn); } return self; }; }); // form validation if (conf.formEvent) { form.bind(conf.formEvent + ".V", function(e) { if (!self.checkValidity(null, e)) { return e.preventDefault(); } }); } // form reset form.bind("reset.V", function() { self.reset(); }); // disable browser's default validation mechanism if (inputs[0] && inputs[0].validity) { inputs.each(function() { this.oninvalid = function() { return false; }; }); } // Web Forms 2.0 compatibility if (form[0]) { form[0].checkValidity = self.checkValidity; } // input validation if (conf.inputEvent) { inputs.bind(conf.inputEvent + ".V", function(e) { self.checkValidity($(this), e); }); } // checkboxes, selects and radios are checked separately inputs.filter(":checkbox, select").filter("[required]").bind("change.V", function(e) { var el = $(this); if (this.checked || (el.is("select") && $(this).val())) { effects[conf.effect][1].call(self, el, e); } }); var radios = inputs.filter(":radio").change(function(e) { self.checkValidity(radios, e); }); // reposition tooltips when window is resized $(window).resize(function() { self.reflow(); }); } // jQuery plugin initialization $.fn.validator = function(conf) { var instance = this.data("validator"); // destroy existing instance if (instance) { instance.destroy(); this.removeData("validator"); } // configuration conf = $.extend(true, {}, v.conf, conf); // selector is a form if (this.is("form")) { return this.each(function() { var form = $(this); instance = new Validator(form.find(":input"), form, conf); form.data("validator", instance); }); } else { instance = new Validator(this, this.eq(0).closest("form"), conf); return this.data("validator", instance); } }; })(jQuery); /** * @license * jQuery Tools 1.2.5 Overlay - Overlay base. Extend it. * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/overlay/ * * Since: March 2008 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { // static constructs $.tools = $.tools || {version: '1.2.5'}; $.tools.overlay = { addEffect: function(name, loadFn, closeFn) { effects[name] = [loadFn, closeFn]; }, conf: { close: null, closeOnClick: true, closeOnEsc: true, closeSpeed: 'fast', effect: 'default', // since 1.2. fixed positioning not supported by IE6 fixed: !$.browser.msie || $.browser.version > 6, left: 'center', load: false, // 1.2 mask: null, oneInstance: true, speed: 'normal', target: null, // target element to be overlayed. by default taken from [rel] top: '10%' } }; var instances = [], effects = {}; // the default effect. nice and easy! $.tools.overlay.addEffect('default', /* onLoad/onClose functions must be called otherwise none of the user supplied callback methods won't be called */ function(pos, onLoad) { var conf = this.getConf(), w = $(window); if (!conf.fixed) { pos.top += w.scrollTop(); pos.left += w.scrollLeft(); } pos.position = conf.fixed ? 'fixed' : 'absolute'; this.getOverlay().css(pos).fadeIn(conf.speed, onLoad); }, function(onClose) { this.getOverlay().fadeOut(this.getConf().closeSpeed, onClose); } ); function Overlay(trigger, conf) { // private variables var self = this, fire = trigger.add(self), w = $(window), closers, overlay, opened, maskConf = $.tools.expose && (conf.mask || conf.expose), uid = Math.random().toString().slice(10); // mask configuration if (maskConf) { if (typeof maskConf == 'string') { maskConf = {color: maskConf}; } maskConf.closeOnClick = maskConf.closeOnEsc = false; } // get overlay and triggerr var jq = conf.target || trigger.attr("rel"); overlay = jq ? $(jq) : null || trigger; // overlay not found. cannot continue if (!overlay.length) { throw "Could not find Overlay: " + jq; } // trigger's click event if (trigger && trigger.index(overlay) == -1) { trigger.click(function(e) { self.load(e); return e.preventDefault(); }); } // API methods $.extend(self, { load: function(e) { // can be opened only once if (self.isOpened()) { return self; } // find the effect var eff = effects[conf.effect]; if (!eff) { throw "Overlay: cannot find effect : \"" + conf.effect + "\""; } // close other instances? if (conf.oneInstance) { $.each(instances, function() { this.close(e); }); } // onBeforeLoad e = e || $.Event(); e.type = "onBeforeLoad"; fire.trigger(e); if (e.isDefaultPrevented()) { return self; } // opened opened = true; // possible mask effect if (maskConf) { $(overlay).expose(maskConf); } // position & dimensions var top = conf.top, left = conf.left, oWidth = overlay.outerWidth({margin:true}), oHeight = overlay.outerHeight({margin:true}); if (typeof top == 'string') { top = top == 'center' ? Math.max((w.height() - oHeight) / 2, 0) : parseInt(top, 10) / 100 * w.height(); } if (left == 'center') { left = Math.max((w.width() - oWidth) / 2, 0); } // load effect eff[0].call(self, {top: top, left: left}, function() { if (opened) { e.type = "onLoad"; fire.trigger(e); } }); // mask.click closes overlay if (maskConf && conf.closeOnClick) { $.mask.getMask().one("click", self.close); } // when window is clicked outside overlay, we close if (conf.closeOnClick) { $(document).bind("click." + uid, function(e) { if (!$(e.target).parents(overlay).length) { self.close(e); } }); } // keyboard::escape if (conf.closeOnEsc) { // one callback is enough if multiple instances are loaded simultaneously $(document).bind("keydown." + uid, function(e) { if (e.keyCode == 27) { self.close(e); } }); } return self; }, close: function(e) { if (!self.isOpened()) { return self; } e = e || $.Event(); e.type = "onBeforeClose"; fire.trigger(e); if (e.isDefaultPrevented()) { return; } opened = false; // close effect effects[conf.effect][1].call(self, function() { e.type = "onClose"; fire.trigger(e); }); // unbind the keyboard / clicking actions $(document).unbind("click." + uid).unbind("keydown." + uid); if (maskConf) { $.mask.close(); } return self; }, getOverlay: function() { return overlay; }, getTrigger: function() { return trigger; }, getClosers: function() { return closers; }, isOpened: function() { return opened; }, // manipulate start, finish and speeds getConf: function() { return conf; } }); // callbacks $.each("onBeforeLoad,onStart,onLoad,onBeforeClose,onClose".split(","), function(i, name) { // configuration if ($.isFunction(conf[name])) { $(self).bind(name, conf[name]); } // API self[name] = function(fn) { if (fn) { $(self).bind(name, fn); } return self; }; }); // close button closers = overlay.find(conf.close || ".close"); if (!closers.length && !conf.close) { closers = $('<a class="close"></a>'); overlay.prepend(closers); } closers.click(function(e) { self.close(e); }); // autoload if (conf.load) { self.load(); } } // jQuery plugin initialization $.fn.overlay = function(conf) { // already constructed --> return API var el = this.data("overlay"); if (el) { return el; } if ($.isFunction(conf)) { conf = {onBeforeLoad: conf}; } conf = $.extend(true, {}, $.tools.overlay.conf, conf); this.each(function() { el = new Overlay($(this), conf); instances.push(el); $(this).data("overlay", el); }); return conf.api ? el: this; }; })(jQuery); /** * @license * jQuery Tools 1.2.5 / Overlay Apple effect. * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. * * http://flowplayer.org/tools/overlay/apple.html * * Since: July 2009 * Date: Thu May 15 10:43:37 CEST 2014 */ (function($) { // version number var t = $.tools.overlay, w = $(window); // extend global configuragion with effect specific defaults $.extend(t.conf, { start: { top: null, left: null }, fadeInSpeed: 'fast', zIndex: 9999 }); // utility function function getPosition(el) { var p = el.offset(); return { top: p.top + el.height() / 2, left: p.left + el.width() / 2 }; } //{{{ load var loadEffect = function(pos, onLoad) { var overlay = this.getOverlay(), conf = this.getConf(), trigger = this.getTrigger(), self = this, oWidth = overlay.outerWidth({margin:true}), img = overlay.data("img"), position = conf.fixed ? 'fixed' : 'absolute'; // growing image is required. if (!img) { var bg = overlay.css("backgroundImage"); if (!bg) { throw "background-image CSS property not set for overlay"; } // url("bg.jpg") --> bg.jpg bg = bg.slice(bg.indexOf("(") + 1, bg.indexOf(")")).replace(/\"/g, ""); overlay.css("backgroundImage", "none"); img = $('<img src="' + bg + '"/>'); img.css({border:0, display:'none'}).width(oWidth); $('body').append(img); overlay.data("img", img); } // initial top & left var itop = conf.start.top || Math.round(w.height() / 2), ileft = conf.start.left || Math.round(w.width() / 2); if (trigger) { var p = getPosition(trigger); itop = p.top; ileft = p.left; } // put overlay into final position if (conf.fixed) { itop -= w.scrollTop(); ileft -= w.scrollLeft(); } else { pos.top += w.scrollTop(); pos.left += w.scrollLeft(); } // initialize background image and make it visible img.css({ position: 'absolute', top: itop, left: ileft, width: 0, zIndex: conf.zIndex }).show(); pos.position = position; overlay.css(pos); // begin growing img.animate({ top: overlay.css("top"), left: overlay.css("left"), width: oWidth}, conf.speed, function() { // set close button and content over the image overlay.css("zIndex", conf.zIndex + 1).fadeIn(conf.fadeInSpeed, function() { if (self.isOpened() && !$(this).index(overlay)) { onLoad.call(); } else { overlay.hide(); } }); }).css("position", position); }; //}}} var closeEffect = function(onClose) { // variables var overlay = this.getOverlay().hide(), conf = this.getConf(), trigger = this.getTrigger(), img = overlay.data("img"), css = { top: conf.start.top, left: conf.start.left, width: 0 }; // trigger position if (trigger) { $.extend(css, getPosition(trigger)); } // change from fixed to absolute position if (conf.fixed) { img.css({position: 'absolute'}) .animate({ top: "+=" + w.scrollTop(), left: "+=" + w.scrollLeft()}, 0); } // shrink image img.animate(css, conf.closeSpeed, onClose); }; // add overlay effect t.addEffect("apple", loadEffect, closeEffect); })(jQuery);