 
var MooTools={version:'1.11'
};
function $defined(obj){return (obj !=undefined);};
function $type(obj){if (!$defined(obj)) return false;
if (obj.htmlElement) return 'element';
var type=typeof obj;
if (type=='object' && obj.nodeName){switch(obj.nodeType){case 1: return 'element';
case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' :'whitespace';}}
if (type=='object' || type=='function'){switch(obj.constructor){case Array: return 'array';
case RegExp: return 'regexp';
case Class: return 'class';}
if (typeof obj.length=='number'){if (obj.item) return 'collection';
if (obj.callee) return 'arguments';}}
return type;};
function $merge(){var mix={};
for (var i=0; i < arguments.length; i++){for (var property in arguments[i]){var ap=arguments[i][property];
var mp=mix[property];
if (mp && $type(ap)=='object' && $type(mp)=='object') mix[property]=$merge(mp, ap);
else mix[property]=ap;}}
return mix;};
var $extend=function(){var args=arguments;
if (!args[1]) args=[this, args[0]];
for (var property in args[1]) args[0][property]=args[1][property];
return args[0];};
var $native=function(){for (var i=0, l=arguments.length; i < l; i++){arguments[i].extend=function(props){for (var prop in props){if (!this.prototype[prop]) this.prototype[prop]=props[prop];
if (!this[prop]) this[prop]=$native.generic(prop);}};}};
$native.generic=function(prop){return function(bind){return this.prototype[prop].apply(bind, Array.prototype.slice.call(arguments, 1));};};
$native(Function, Array, String, Number);
function $chk(obj){return !!(obj || obj===0);};
function $pick(obj, picked){return $defined(obj) ? obj : picked;};
function $random(min, max){return Math.floor(Math.random() * (max - min+1)+min);};
function $time(){return new Date().getTime();};
function $clear(timer){clearTimeout(timer);
clearInterval(timer);
return null;};
var Abstract=function(obj){obj=obj ||{};
obj.extend=$extend;
return obj;};
var Window=new Abstract(window);
var Document=new Abstract(document);
document.head=document.getElementsByTagName('head')[0];
window.xpath=!!(document.evaluate);
if (window.ActiveXObject) window.ie=window[window.XMLHttpRequest ? 'ie7' :'ie6']=true;
else if (document.childNodes && !document.all && !navigator.taintEnabled) window.webkit=window[window.xpath ? 'webkit420' :'webkit419']=true;
else if (document.getBoxObjectFor !=null) window.gecko=true;
window.khtml=window.webkit;
Object.extend=$extend;
if (typeof HTMLElement=='undefined'){var HTMLElement=function(){};
if (window.webkit) document.createElement("iframe");
HTMLElement.prototype=(window.webkit) ? window["[[DOMElement.prototype]]"] :{};}
HTMLElement.prototype.htmlElement=function(){};
if (window.ie6) try{document.execCommand("BackgroundImageCache", false, true);}catch(e){};
var Class=function(properties){var klass=function(){return (arguments[0] !==null && this.initialize && $type(this.initialize)=='function') ? this.initialize.apply(this, arguments) : this;};
$extend(klass, this);
klass.prototype=properties;
klass.constructor=Class;
return klass;};
Class.empty=function(){};
Class.prototype={extend: function(properties){var proto=new this(null);
for (var property in properties){var pp=proto[property];
proto[property]=Class.Merge(pp, properties[property]);}
return new Class(proto);},
implement: function(){for (var i=0, l=arguments.length; i < l; i++) $extend(this.prototype, arguments[i]);}};
Class.Merge=function(previous, current){if (previous && previous !=current){var type=$type(current);
if (type !=$type(previous)) return current;
switch(type){case 'function':
var merged=function(){this.parent=arguments.callee.parent;
return current.apply(this, arguments);};
merged.parent=previous;
return merged;
case 'object': return $merge(previous, current);}}
return current;};
var Chain=new Class({chain: function(fn){this.chains=this.chains || [];
this.chains.push(fn);
return this;},
callChain: function(){if (this.chains && this.chains.length) this.chains.shift().delay(10, this);},
clearChain: function(){this.chains=[];}});
var Events=new Class({addEvent: function(type, fn){if (fn !=Class.empty){this.$events=this.$events ||{};
this.$events[type]=this.$events[type] || [];
this.$events[type].include(fn);}
return this;},
fireEvent: function(type, args, delay){if (this.$events && this.$events[type]){this.$events[type].each(function(fn){fn.create({'bind': this, 'delay': delay, 'arguments': args})();}, this);}
return this;},
removeEvent: function(type, fn){if (this.$events && this.$events[type]) this.$events[type].remove(fn);
return this;}});
var Options=new Class({setOptions: function(){this.options=$merge.apply(null, [this.options].extend(arguments));
if (this.addEvent){for (var option in this.options){if ($type(this.options[option]=='function') && (/^on[A-Z]/).test(option)) this.addEvent(option, this.options[option]);}}
return this;}});
Array.extend({forEach: function(fn, bind){for (var i=0, j=this.length; i < j; i++) fn.call(bind, this[i], i, this);},
filter: function(fn, bind){var results=[];
for (var i=0, j=this.length; i < j; i++){if (fn.call(bind, this[i], i, this)) results.push(this[i]);}
return results;},
map: function(fn, bind){var results=[];
for (var i=0, j=this.length; i < j; i++) results[i]=fn.call(bind, this[i], i, this);
return results;},
every: function(fn, bind){for (var i=0, j=this.length; i < j; i++){if (!fn.call(bind, this[i], i, this)) return false;}
return true;},
some: function(fn, bind){for (var i=0, j=this.length; i < j; i++){if (fn.call(bind, this[i], i, this)) return true;}
return false;},
indexOf: function(item, from){var len=this.length;
for (var i=(from < 0) ? Math.max(0, len+from) : from || 0; i < len; i++){if (this[i]===item) return i;}
return -1;},
copy: function(start, length){start=start || 0;
if (start < 0) start=this.length+start;
length=length || (this.length - start);
var newArray=[];
for (var i=0; i < length; i++) newArray[i]=this[start++];
return newArray;},
remove: function(item){var i=0;
var len=this.length;
while (i < len){if (this[i]===item){this.splice(i, 1);
len--;}else{i++;}}
return this;},
contains: function(item, from){return this.indexOf(item, from) !=-1;},
associate: function(keys){var obj={}, length=Math.min(this.length, keys.length);
for (var i=0; i < length; i++) obj[keys[i]]=this[i];
return obj;},
extend: function(array){for (var i=0, j=array.length; i < j; i++) this.push(array[i]);
return this;},
merge: function(array){for (var i=0, l=array.length; i < l; i++) this.include(array[i]);
return this;},
include: function(item){if (!this.contains(item)) this.push(item);
return this;},
getRandom: function(){return this[$random(0, this.length - 1)] || null;},
getLast: function(){return this[this.length - 1] || null;}});
Array.prototype.each=Array.prototype.forEach;
Array.each=Array.forEach;
function $A(array){return Array.copy(array);};
function $each(iterable, fn, bind){if (iterable && typeof iterable.length=='number' && $type(iterable) !='object'){Array.forEach(iterable, fn, bind);}else{for (var name in iterable) fn.call(bind || iterable, iterable[name], name);}};
Array.prototype.test=Array.prototype.contains;
String.extend({test: function(regex, params){return (($type(regex)=='string') ? new RegExp(regex, params) : regex).test(this);},
toInt: function(){return parseInt(this, 10);},
toFloat: function(){return parseFloat(this);},
camelCase: function(){return this.replace(/-\D/g, function(match){return match.charAt(1).toUpperCase();});},
hyphenate: function(){return this.replace(/\w[A-Z]/g, function(match){return (match.charAt(0)+'-'+match.charAt(1).toLowerCase());});},
capitalize: function(){return this.replace(/\b[a-z]/g, function(match){return match.toUpperCase();});},
trim: function(){return this.replace(/^\s+|\s+$/g, '');},
clean: function(){return this.replace(/\s{2,}/g, ' ').trim();},
rgbToHex: function(array){var rgb=this.match(/\d{1,3}/g);
return (rgb) ? rgb.rgbToHex(array) : false;},
hexToRgb: function(array){var hex=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
return (hex) ? hex.slice(1).hexToRgb(array) : false;},
contains: function(string, s){return (s) ? (s+this+s).indexOf(s+string+s) > -1 : this.indexOf(string) > -1;},
escapeRegExp: function(){return this.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');}});
Array.extend({rgbToHex: function(array){if (this.length < 3) return false;
if (this.length==4 && this[3]==0 && !array) return 'transparent';
var hex=[];
for (var i=0; i < 3; i++){var bit=(this[i] - 0).toString(16);
hex.push((bit.length==1) ? '0'+bit : bit);}
return array ? hex :'#'+hex.join('');},
hexToRgb: function(array){if (this.length !=3) return false;
var rgb=[];
for (var i=0; i < 3; i++){rgb.push(parseInt((this[i].length==1) ? this[i]+this[i] : this[i], 16));}
return array ? rgb :'rgb('+rgb.join(',')+')';}});
Function.extend({create: function(options){var fn=this;
options=$merge({'bind': fn,
'event': false,
'arguments': null,
'delay': false,
'periodical': false,
'attempt': false
}, options);
if ($chk(options.arguments) && $type(options.arguments) !='array') options.arguments=[options.arguments];
return function(event){var args;
if (options.event){event=event || window.event;
args=[(options.event===true) ? event : new options.event(event)];
if (options.arguments) args.extend(options.arguments);}
else args=options.arguments || arguments;
var returns=function(){return fn.apply($pick(options.bind, fn), args);};
if (options.delay) return setTimeout(returns, options.delay);
if (options.periodical) return setInterval(returns, options.periodical);
if (options.attempt) try{return returns();}catch(err){return false;};
return returns();};},
pass: function(args, bind){return this.create({'arguments': args, 'bind': bind});},
attempt: function(args, bind){return this.create({'arguments': args, 'bind': bind, 'attempt': true})();},
bind: function(bind, args){return this.create({'bind': bind, 'arguments': args});},
bindAsEventListener: function(bind, args){return this.create({'bind': bind, 'event': true, 'arguments': args});},
delay: function(delay, bind, args){return this.create({'delay': delay, 'bind': bind, 'arguments': args})();},
periodical: function(interval, bind, args){return this.create({'periodical': interval, 'bind': bind, 'arguments': args})();}});
Number.extend({toInt: function(){return parseInt(this);},
toFloat: function(){return parseFloat(this);},
limit: function(min, max){return Math.min(max, Math.max(min, this));},
round: function(precision){precision=Math.pow(10, precision || 0);
return Math.round(this * precision) / precision;},
times: function(fn){for (var i=0; i < this; i++) fn(i);}});
var Element=new Class({initialize: function(el, props){if ($type(el)=='string'){if (window.ie && props && (props.name || props.type)){var name=(props.name) ? ' name="'+props.name+'"' :'';
var type=(props.type) ? ' type="'+props.type+'"' :'';
delete props.name;
delete props.type;
el='<'+el+name+type+'>';}
el=document.createElement(el);}
el=$(el);
return (!props || !el) ? el : el.set(props);}});
var Elements=new Class({initialize: function(elements){return (elements) ? $extend(elements, this) : this;}});
Elements.extend=function(props){for (var prop in props){this.prototype[prop]=props[prop];
this[prop]=$native.generic(prop);}};
function $(el){if (!el) return null;
if (el.htmlElement) return Garbage.collect(el);
if ([window, document].contains(el)) return el;
var type=$type(el);
if (type=='string'){el=document.getElementById(el);
type=(el) ? 'element' : false;}
if (type !='element') return null;
if (el.htmlElement) return Garbage.collect(el);
if (['object', 'embed'].contains(el.tagName.toLowerCase())) return el;
$extend(el, Element.prototype);
el.htmlElement=function(){};
return Garbage.collect(el);};
document.getElementsBySelector=document.getElementsByTagName;
function $$(){var elements=[];
for (var i=0, j=arguments.length; i < j; i++){var selector=arguments[i];
switch($type(selector)){case 'element': elements.push(selector);
case 'boolean': break;
case false: break;
case 'string': selector=document.getElementsBySelector(selector, true);
default: elements.extend(selector);}}
return $$.unique(elements);};
$$.unique=function(array){var elements=[];
for (var i=0, l=array.length; i < l; i++){if (array[i].$included) continue;
var element=$(array[i]);
if (element && !element.$included){element.$included=true;
elements.push(element);}}
for (var n=0, d=elements.length; n < d; n++) elements[n].$included=null;
return new Elements(elements);};
Elements.Multi=function(property){return function(){var args=arguments;
var items=[];
var elements=true;
for (var i=0, j=this.length, returns; i < j; i++){returns=this[i][property].apply(this[i], args);
if ($type(returns) !='element') elements=false;
items.push(returns);};
return (elements) ? $$.unique(items) : items;};};
Element.extend=function(properties){for (var property in properties){HTMLElement.prototype[property]=properties[property];
Element.prototype[property]=properties[property];
Element[property]=$native.generic(property);
var elementsProperty=(Array.prototype[property]) ? property+'Elements' : property;
Elements.prototype[elementsProperty]=Elements.Multi(property);}};
Element.extend({set: function(props){for (var prop in props){var val=props[prop];
switch(prop){case 'styles': this.setStyles(val); break;
case 'events': if (this.addEvents) this.addEvents(val); break;
case 'properties': this.setProperties(val); break;
default: this.setProperty(prop, val);}}
return this;},
inject: function(el, where){el=$(el);
switch(where){case 'before': el.parentNode.insertBefore(this, el); break;
case 'after':
var next=el.getNext();
if (!next) el.parentNode.appendChild(this);
else el.parentNode.insertBefore(this, next);
break;
case 'top':
var first=el.firstChild;
if (first){el.insertBefore(this, first);
break;}
default: el.appendChild(this);}
return this;},
injectBefore: function(el){return this.inject(el, 'before');},
injectAfter: function(el){return this.inject(el, 'after');},
injectInside: function(el){return this.inject(el, 'bottom');},
injectTop: function(el){return this.inject(el, 'top');},
adopt: function(){var elements=[];
$each(arguments, function(argument){elements=elements.concat(argument);});
$$(elements).inject(this);
return this;},
remove: function(){return this.parentNode.removeChild(this);},
clone: function(contents){var el=$(this.cloneNode(contents !==false));
if (!el.$events) return el;
el.$events={};
for (var type in this.$events) el.$events[type]={'keys': $A(this.$events[type].keys),
'values': $A(this.$events[type].values)
};
return el.removeEvents();},
replaceWith: function(el){el=$(el);
this.parentNode.replaceChild(el, this);
return el;},
appendText: function(text){this.appendChild(document.createTextNode(text));
return this;},
hasClass: function(className){return this.className.contains(className, ' ');},
addClass: function(className){if (!this.hasClass(className)) this.className=(this.className+' '+className).clean();
return this;},
removeClass: function(className){this.className=this.className.replace(new RegExp('(^|\\s)'+className+'(?:\\s|$)'), '$1').clean();
return this;},
toggleClass: function(className){return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);},
setStyle: function(property, value){switch(property){case 'opacity': return this.setOpacity(parseFloat(value));
case 'float': property=(window.ie) ? 'styleFloat' :'cssFloat';}
property=property.camelCase();
switch($type(value)){case 'number': if (!['zIndex', 'zoom'].contains(property)) value+='px'; break;
case 'array': value='rgb('+value.join(',')+')';}
this.style[property]=value;
return this;},
setStyles: function(source){switch($type(source)){case 'object': Element.setMany(this, 'setStyle', source); break;
case 'string': this.style.cssText=source;}
return this;},
setOpacity: function(opacity){if (opacity==0){if (this.style.visibility !="hidden") this.style.visibility="hidden";}else{if (this.style.visibility !="visible") this.style.visibility="visible";}
if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom=1;
if (window.ie) this.style.filter=(opacity==1) ? '' : "alpha(opacity="+opacity * 100+")";
this.style.opacity=this.$tmp.opacity=opacity;
return this;},
getStyle: function(property){property=property.camelCase();
var result=this.style[property];
if (!$chk(result)){if (property=='opacity') return this.$tmp.opacity;
result=[];
for (var style in Element.Styles){if (property==style){Element.Styles[style].each(function(s){var style=this.getStyle(s);
result.push(parseInt(style) ? style :'0px');}, this);
if (property=='border'){var every=result.every(function(bit){return (bit==result[0]);});
return (every) ? result[0] : false;}
return result.join(' ');}}
if (property.contains('border')){if (Element.Styles.border.contains(property)){return ['Width', 'Style', 'Color'].map(function(p){return this.getStyle(property+p);}, this).join(' ');}else if (Element.borderShort.contains(property)){return ['Top', 'Right', 'Bottom', 'Left'].map(function(p){return this.getStyle('border'+p+property.replace('border', ''));}, this).join(' ');}}
if (document.defaultView) result=document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate());
else if (this.currentStyle) result=this.currentStyle[property];}
if (window.ie) result=Element.fixStyle(property, result, this);
if (result && property.test(/color/i) && result.contains('rgb')){return result.split('rgb').splice(1,4).map(function(color){return color.rgbToHex();}).join(' ');}
return result;},
getStyles: function(){return Element.getMany(this, 'getStyle', arguments);},
walk: function(brother, start){brother+='Sibling';
var el=(start) ? this[start] : this[brother];
while (el && $type(el) !='element') el=el[brother];
return $(el);},
getPrevious: function(){return this.walk('previous');},
getNext: function(){return this.walk('next');},
getFirst: function(){return this.walk('next', 'firstChild');},
getLast: function(){return this.walk('previous', 'lastChild');},
getParent: function(){return $(this.parentNode);},
getChildren: function(){return $$(this.childNodes);},
hasChild: function(el){return !!$A(this.getElementsByTagName('*')).contains(el);},
getProperty: function(property){var index=Element.Properties[property];
if (index) return this[index];
var flag=Element.PropertiesIFlag[property] || 0;
if (!window.ie || flag) return this.getAttribute(property, flag);
var node=this.attributes[property];
return (node) ? node.nodeValue : null;},
removeProperty: function(property){var index=Element.Properties[property];
if (index) this[index]='';
else this.removeAttribute(property);
return this;},
getProperties: function(){return Element.getMany(this, 'getProperty', arguments);},
setProperty: function(property, value){var index=Element.Properties[property];
if (index) this[index]=value;
else this.setAttribute(property, value);
return this;},
setProperties: function(source){return Element.setMany(this, 'setProperty', source);},
setHTML: function(){this.innerHTML=$A(arguments).join('');
return this;},
setText: function(text){var tag=this.getTag();
if (['style', 'script'].contains(tag)){if (window.ie){if (tag=='style') this.styleSheet.cssText=text;
else if (tag=='script') this.setProperty('text', text);
return this;}else{this.removeChild(this.firstChild);
return this.appendText(text);}}
this[$defined(this.innerText) ? 'innerText' :'textContent']=text;
return this;},
getText: function(){var tag=this.getTag();
if (['style', 'script'].contains(tag)){if (window.ie){if (tag=='style') return this.styleSheet.cssText;
else if (tag=='script') return this.getProperty('text');}else{return this.innerHTML;}}
return ($pick(this.innerText, this.textContent));},
getTag: function(){return this.tagName.toLowerCase();},
empty: function(){Garbage.trash(this.getElementsByTagName('*'));
return this.setHTML('');}});
Element.fixStyle=function(property, result, element){if ($chk(parseInt(result))) return result;
if (['height', 'width'].contains(property)){var values=(property=='width') ? ['left', 'right'] : ['top', 'bottom'];
var size=0;
values.each(function(value){size+=element.getStyle('border-'+value+'-width').toInt()+element.getStyle('padding-'+value).toInt();});
return element['offset'+property.capitalize()] - size+'px';}else if (property.test(/border(.+)Width|margin|padding/)){return '0px';}
return result;};
Element.Styles={'border': [], 'padding': [], 'margin': []};
['Top', 'Right', 'Bottom', 'Left'].each(function(direction){for (var style in Element.Styles) Element.Styles[style].push(style+direction);});
Element.borderShort=['borderWidth', 'borderStyle', 'borderColor'];
Element.getMany=function(el, method, keys){var result={};
$each(keys, function(key){result[key]=el[method](key);});
return result;};
Element.setMany=function(el, method, pairs){for (var key in pairs) el[method](key, pairs[key]);
return el;};
Element.Properties=new Abstract({'class':'className', 'for':'htmlFor', 'colspan':'colSpan', 'rowspan':'rowSpan',
'accesskey':'accessKey', 'tabindex':'tabIndex', 'maxlength':'maxLength',
'readonly':'readOnly', 'frameborder':'frameBorder', 'value':'value',
'disabled':'disabled', 'checked':'checked', 'multiple':'multiple', 'selected':'selected'
});
Element.PropertiesIFlag={'href': 2, 'src': 2
};
Element.Methods={Listeners:{addListener: function(type, fn){if (this.addEventListener) this.addEventListener(type, fn, false);
else this.attachEvent('on'+type, fn);
return this;},
removeListener: function(type, fn){if (this.removeEventListener) this.removeEventListener(type, fn, false);
else this.detachEvent('on'+type, fn);
return this;}}};
window.extend(Element.Methods.Listeners);
document.extend(Element.Methods.Listeners);
Element.extend(Element.Methods.Listeners);
var Garbage={elements: [],
collect: function(el){if (!el.$tmp){Garbage.elements.push(el);
el.$tmp={'opacity': 1};}
return el;},
trash: function(elements){for (var i=0, j=elements.length, el; i < j; i++){if (!(el=elements[i]) || !el.$tmp) continue;
if (el.$events) el.fireEvent('trash').removeEvents();
for (var p in el.$tmp) el.$tmp[p]=null;
for (var d in Element.prototype) el[d]=null;
Garbage.elements[Garbage.elements.indexOf(el)]=null;
el.htmlElement=el.$tmp=el=null;}
Garbage.elements.remove(null);},
empty: function(){Garbage.collect(window);
Garbage.collect(document);
Garbage.trash(Garbage.elements);}};
window.addListener('beforeunload', function(){window.addListener('unload', Garbage.empty);
if (window.ie) window.addListener('unload', CollectGarbage);});
var Event=new Class({initialize: function(event){if (event && event.$extended) return event;
this.$extended=true;
event=event || window.event;
this.event=event;
this.type=event.type;
this.target=event.target || event.srcElement;
if (this.target.nodeType==3) this.target=this.target.parentNode;
this.shift=event.shiftKey;
this.control=event.ctrlKey;
this.alt=event.altKey;
this.meta=event.metaKey;
if (['DOMMouseScroll', 'mousewheel'].contains(this.type)){this.wheel=(event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;}else if (this.type.contains('key')){this.code=event.which || event.keyCode;
for (var name in Event.keys){if (Event.keys[name]==this.code){this.key=name;
break;}}
if (this.type=='keydown'){var fKey=this.code - 111;
if (fKey > 0 && fKey < 13) this.key='f'+fKey;}
this.key=this.key || String.fromCharCode(this.code).toLowerCase();}else if (this.type.test(/(click|mouse|menu)/)){this.page={'x': event.pageX || event.clientX+document.documentElement.scrollLeft,
'y': event.pageY || event.clientY+document.documentElement.scrollTop
};
this.client={'x': event.pageX ? event.pageX - window.pageXOffset : event.clientX,
'y': event.pageY ? event.pageY - window.pageYOffset : event.clientY
};
this.rightClick=(event.which==3) || (event.button==2);
switch(this.type){case 'mouseover': this.relatedTarget=event.relatedTarget || event.fromElement; break;
case 'mouseout': this.relatedTarget=event.relatedTarget || event.toElement;}
this.fixRelatedTarget();}
return this;},
stop: function(){return this.stopPropagation().preventDefault();},
stopPropagation: function(){if (this.event.stopPropagation) this.event.stopPropagation();
else this.event.cancelBubble=true;
return this;},
preventDefault: function(){if (this.event.preventDefault) this.event.preventDefault();
else this.event.returnValue=false;
return this;}});
Event.fix={relatedTarget: function(){if (this.relatedTarget && this.relatedTarget.nodeType==3) this.relatedTarget=this.relatedTarget.parentNode;},
relatedTargetGecko: function(){try{Event.fix.relatedTarget.call(this);}catch(e){this.relatedTarget=this.target;}}};
Event.prototype.fixRelatedTarget=(window.gecko) ? Event.fix.relatedTargetGecko : Event.fix.relatedTarget;
Event.keys=new Abstract({'enter': 13,
'up': 38,
'down': 40,
'left': 37,
'right': 39,
'esc': 27,
'space': 32,
'backspace': 8,
'tab': 9,
'delete': 46
});
Element.Methods.Events={addEvent: function(type, fn){this.$events=this.$events ||{};
this.$events[type]=this.$events[type] ||{'keys': [], 'values': []};
if (this.$events[type].keys.contains(fn)) return this;
this.$events[type].keys.push(fn);
var realType=type;
var custom=Element.Events[type];
if (custom){if (custom.add) custom.add.call(this, fn);
if (custom.map) fn=custom.map;
if (custom.type) realType=custom.type;}
if (!this.addEventListener) fn=fn.create({'bind': this, 'event': true});
this.$events[type].values.push(fn);
return (Element.NativeEvents.contains(realType)) ? this.addListener(realType, fn) : this;},
removeEvent: function(type, fn){if (!this.$events || !this.$events[type]) return this;
var pos=this.$events[type].keys.indexOf(fn);
if (pos==-1) return this;
var key=this.$events[type].keys.splice(pos,1)[0];
var value=this.$events[type].values.splice(pos,1)[0];
var custom=Element.Events[type];
if (custom){if (custom.remove) custom.remove.call(this, fn);
if (custom.type) type=custom.type;}
return (Element.NativeEvents.contains(type)) ? this.removeListener(type, value) : this;},
addEvents: function(source){return Element.setMany(this, 'addEvent', source);},
removeEvents: function(type){if (!this.$events) return this;
if (!type){for (var evType in this.$events) this.removeEvents(evType);
this.$events=null;}else if (this.$events[type]){this.$events[type].keys.each(function(fn){this.removeEvent(type, fn);}, this);
this.$events[type]=null;}
return this;},
fireEvent: function(type, args, delay){if (this.$events && this.$events[type]){this.$events[type].keys.each(function(fn){fn.create({'bind': this, 'delay': delay, 'arguments': args})();}, this);}
return this;},
cloneEvents: function(from, type){if (!from.$events) return this;
if (!type){for (var evType in from.$events) this.cloneEvents(from, evType);}else if (from.$events[type]){from.$events[type].keys.each(function(fn){this.addEvent(type, fn);}, this);}
return this;}};
window.extend(Element.Methods.Events);
document.extend(Element.Methods.Events);
Element.extend(Element.Methods.Events);
Element.Events=new Abstract({'mouseenter':{type:'mouseover',
map: function(event){event=new Event(event);
if (event.relatedTarget !=this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseenter', event);}},
'mouseleave':{type:'mouseout',
map: function(event){event=new Event(event);
if (event.relatedTarget !=this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseleave', event);}},
'mousewheel':{type: (window.gecko) ? 'DOMMouseScroll' :'mousewheel'
}});
Element.NativeEvents=[
'click', 'dblclick', 'mouseup', 'mousedown',
'mousewheel', 'DOMMouseScroll',
'mouseover', 'mouseout', 'mousemove',
'keydown', 'keypress', 'keyup',
'load', 'unload', 'beforeunload', 'resize', 'move',
'focus', 'blur', 'change', 'submit', 'reset', 'select',
'error', 'abort', 'contextmenu', 'scroll'
];
Function.extend({bindWithEvent: function(bind, args){return this.create({'bind': bind, 'arguments': args, 'event': Event});}});
Element.Events.domready={add: function(fn){if (window.loaded){fn.call(this);
return;}
var domReady=function(){if (window.loaded) return;
window.loaded=true;
window.timer=$clear(window.timer);
this.fireEvent('domready');}.bind(this);
if (document.readyState && window.webkit){window.timer=function(){if (['loaded','complete'].contains(document.readyState)) domReady();}.periodical(50);}else if (document.readyState && window.ie){if (!$('ie_ready')){var src=(window.location.protocol=='https:') ? '://0' :'javascript:void(0)';
document.write('<script id="ie_ready" defer src="'+src+'"><\/script>');
$('ie_ready').onreadystatechange=function(){if (this.readyState=='complete') domReady();};}}else{window.addListener("load", domReady);
document.addListener("DOMContentLoaded", domReady);}}};
window.onDomReady=function(fn){return this.addEvent('domready', fn);};
window.extend({getWidth: function(){if (this.webkit419) return this.innerWidth;
if (this.opera) return document.body.clientWidth;
return document.documentElement.clientWidth;},
getHeight: function(){if (this.webkit419) return this.innerHeight;
if (this.opera) return document.body.clientHeight;
return document.documentElement.clientHeight;},
getScrollWidth: function(){if (this.ie) return Math.max(document.documentElement.offsetWidth, document.documentElement.scrollWidth);
if (this.webkit) return document.body.scrollWidth;
return document.documentElement.scrollWidth;},
getScrollHeight: function(){if (this.ie) return Math.max(document.documentElement.offsetHeight, document.documentElement.scrollHeight);
if (this.webkit) return document.body.scrollHeight;
return document.documentElement.scrollHeight;},
getScrollLeft: function(){return this.pageXOffset || document.documentElement.scrollLeft;},
getScrollTop: function(){return this.pageYOffset || document.documentElement.scrollTop;},
getSize: function(){return{'size':{'x': this.getWidth(), 'y': this.getHeight()},
'scrollSize':{'x': this.getScrollWidth(), 'y': this.getScrollHeight()},
'scroll':{'x': this.getScrollLeft(), 'y': this.getScrollTop()}};},
getPosition: function(){return{'x': 0, 'y': 0};}});
var Fx={};
Fx.Base=new Class({options:{onStart: Class.empty,
onComplete: Class.empty,
onCancel: Class.empty,
transition: function(p){return -(Math.cos(Math.PI * p) - 1) / 2;},
duration: 500,
unit:'px',
wait: true,
fps: 50
},
initialize: function(options){this.element=this.element || null;
this.setOptions(options);
if (this.options.initialize) this.options.initialize.call(this);},
step: function(){var time=$time();
if (time < this.time+this.options.duration){this.delta=this.options.transition((time - this.time) / this.options.duration);
this.setNow();
this.increase();}else{this.stop(true);
this.set(this.to);
this.fireEvent('onComplete', this.element, 10);
this.callChain();}},
set: function(to){this.now=to;
this.increase();
return this;},
setNow: function(){this.now=this.compute(this.from, this.to);},
compute: function(from, to){return (to - from) * this.delta+from;},
start: function(from, to){if (!this.options.wait) this.stop();
else if (this.timer) return this;
this.from=from;
this.to=to;
this.change=this.to - this.from;
this.time=$time();
this.timer=this.step.periodical(Math.round(1000 / this.options.fps), this);
this.fireEvent('onStart', this.element);
return this;},
stop: function(end){if (!this.timer) return this;
this.timer=$clear(this.timer);
if (!end) this.fireEvent('onCancel', this.element);
return this;}/*compatibility*/,
custom: function(from, to){return this.start(from, to);},
clearTimer: function(end){return this.stop(end);}});
Fx.Base.implement(new Chain, new Events, new Options);
Fx.CSS={select: function(property, to){if (property.test(/color/i)) return this.Color;
var type=$type(to);
if ((type=='array') || (type=='string' && to.contains(' '))) return this.Multi;
return this.Single;},
parse: function(el, property, fromTo){if (!fromTo.push) fromTo=[fromTo];
var from=fromTo[0], to=fromTo[1];
if (!$chk(to)){to=from;
from=el.getStyle(property);}
var css=this.select(property, to);
return{'from': css.parse(from), 'to': css.parse(to), 'css': css};}};
Fx.CSS.Single={parse: function(value){return parseFloat(value);},
getNow: function(from, to, fx){return fx.compute(from, to);},
getValue: function(value, unit, property){if (unit=='px' && property !='opacity') value=Math.round(value);
return value+unit;}};
Fx.CSS.Multi={parse: function(value){return value.push ? value : value.split(' ').map(function(v){return parseFloat(v);});},
getNow: function(from, to, fx){var now=[];
for (var i=0; i < from.length; i++) now[i]=fx.compute(from[i], to[i]);
return now;},
getValue: function(value, unit, property){if (unit=='px' && property !='opacity') value=value.map(Math.round);
return value.join(unit+' ')+unit;}};
Fx.CSS.Color={parse: function(value){return value.push ? value : value.hexToRgb(true);},
getNow: function(from, to, fx){var now=[];
for (var i=0; i < from.length; i++) now[i]=Math.round(fx.compute(from[i], to[i]));
return now;},
getValue: function(value){return 'rgb('+value.join(',')+')';}};
Fx.Style=Fx.Base.extend({initialize: function(el, property, options){this.element=$(el);
this.property=property;
this.parent(options);},
hide: function(){return this.set(0);},
setNow: function(){this.now=this.css.getNow(this.from, this.to, this);},
set: function(to){this.css=Fx.CSS.select(this.property, to);
return this.parent(this.css.parse(to));},
start: function(from, to){if (this.timer && this.options.wait) return this;
var parsed=Fx.CSS.parse(this.element, this.property, [from, to]);
this.css=parsed.css;
return this.parent(parsed.from, parsed.to);},
increase: function(){this.element.setStyle(this.property, this.css.getValue(this.now, this.options.unit, this.property));}});
Element.extend({effect: function(property, options){return new Fx.Style(this, property, options);}});
Fx.Styles=Fx.Base.extend({initialize: function(el, options){this.element=$(el);
this.parent(options);},
setNow: function(){for (var p in this.from) this.now[p]=this.css[p].getNow(this.from[p], this.to[p], this);},
set: function(to){var parsed={};
this.css={};
for (var p in to){this.css[p]=Fx.CSS.select(p, to[p]);
parsed[p]=this.css[p].parse(to[p]);}
return this.parent(parsed);},
start: function(obj){if (this.timer && this.options.wait) return this;
this.now={};
this.css={};
var from={}, to={};
for (var p in obj){var parsed=Fx.CSS.parse(this.element, p, obj[p]);
from[p]=parsed.from;
to[p]=parsed.to;
this.css[p]=parsed.css;}
return this.parent(from, to);},
increase: function(){for (var p in this.now) this.element.setStyle(p, this.css[p].getValue(this.now[p], this.options.unit, p));}});
Element.extend({effects: function(options){return new Fx.Styles(this, options);}});
Fx.Transition=function(transition, params){params=params || [];
if ($type(params) !='array') params=[params];
return $extend(transition,{easeIn: function(pos){return transition(pos, params);},
easeOut: function(pos){return 1 - transition(1 - pos, params);},
easeInOut: function(pos){return (pos <=0.5) ? transition(2 * pos, params) / 2 : (2 - transition(2 * (1 - pos), params)) / 2;}});};
Fx.Transitions=new Abstract({linear: function(p){return p;}});
Fx.Transitions.extend=function(transitions){for (var transition in transitions){Fx.Transitions[transition]=new Fx.Transition(transitions[transition]);
Fx.Transitions.compat(transition);}};
Fx.Transitions.compat=function(transition){['In', 'Out', 'InOut'].each(function(easeType){Fx.Transitions[transition.toLowerCase()+easeType]=Fx.Transitions[transition]['ease'+easeType];});};
Fx.Transitions.extend({Pow: function(p, x){return Math.pow(p, x[0] || 6);},
Expo: function(p){return Math.pow(2, 8 * (p - 1));},
Circ: function(p){return 1 - Math.sin(Math.acos(p));},
Sine: function(p){return 1 - Math.sin((1 - p) * Math.PI / 2);},
Back: function(p, x){x=x[0] || 1.618;
return Math.pow(p, 2) * ((x+1) * p - x);},
Bounce: function(p){var value;
for (var a=0, b=1; 1; a+=b, b /=2){if (p >=(7 - 4 * a) / 11){value=- Math.pow((11 - 6 * a - 11 * p) / 4, 2)+b * b;
break;}}
return value;},
Elastic: function(p, x){return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3);}});
['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){Fx.Transitions[transition]=new Fx.Transition(function(p){return Math.pow(p, [i+2]);});
Fx.Transitions.compat(transition);});
var Lightbox={init: function(options){this.options=$extend({resizeDuration: 400,
resizeTransition: false,
initialWidth: 250,
initialHeight: 250,
animateCaption: true,
showCounter: true
}, options ||{});
this.anchors=[];
$each(document.links, function(el){if (el.rel && el.rel.test(/^lightbox/i)){el.onclick=this.click.pass(el, this);
this.anchors.push(el);}}, this);
this.eventKeyDown=this.keyboardListener.bindAsEventListener(this);
this.eventPosition=this.position.bind(this);
this.overlay=new Element('div',{'id':'lbOverlay'}).injectInside(document.body);
this.center=new Element('div',{'id':'lbCenter', 'styles':{'width': this.options.initialWidth, 'height': this.options.initialHeight, 'marginLeft': -(this.options.initialWidth/2), 'display':'none'}}).injectInside(document.body);
this.image=new Element('div',{'id':'lbImage'}).injectInside(this.center);
this.prevLink=new Element('a',{'id':'lbPrevLink', 'href':'#', 'styles':{'display':'none'}}).injectInside(this.image);
this.nextLink=this.prevLink.clone().setProperty('id', 'lbNextLink').injectInside(this.image);
this.prevLink.onclick=this.previous.bind(this);
this.nextLink.onclick=this.next.bind(this);
this.bottomContainer=new Element('div',{'id':'lbBottomContainer', 'styles':{'display':'none'}}).injectInside(document.body);
this.bottom=new Element('div',{'id':'lbBottom'}).injectInside(this.bottomContainer);
new Element('a',{'id':'lbCloseLink', 'href':'#'}).injectInside(this.bottom).onclick=this.overlay.onclick=this.close.bind(this);
this.caption=new Element('div',{'id':'lbCaption'}).injectInside(this.bottom);
this.number=new Element('div',{'id':'lbNumber'}).injectInside(this.bottom);
new Element('div',{'styles':{'clear':'both'}}).injectInside(this.bottom);
var nextEffect=this.nextEffect.bind(this);
this.fx={overlay: this.overlay.effect('opacity',{duration: 500}).hide(),
resize: this.center.effects($extend({duration: this.options.resizeDuration, onComplete: nextEffect}, this.options.resizeTransition ?{transition: this.options.resizeTransition}:{})),
image: this.image.effect('opacity',{duration: 500, onComplete: nextEffect}),
bottom: this.bottom.effect('margin-top',{duration: 400, onComplete: nextEffect})
};
this.preloadPrev=new Image();
this.preloadNext=new Image();},
click: function(link){if (link.rel.length==8) return this.show(link.href, link.title);
var j, imageNum, images=[];
this.anchors.each(function(el){if (el.rel==link.rel){for (j=0; j < images.length; j++) if(images[j][0]==el.href) break;
if (j==images.length){images.push([el.href, el.title]);
if (el.href==link.href) imageNum=j;}}}, this);
return this.open(images, imageNum);},
show: function(url, title){return this.open([[url, title]], 0);},
open: function(images, imageNum){this.images=images;
this.position();
this.setup(true);
this.top=window.getScrollTop()+(window.getHeight() / 15);
this.center.setStyles({top: this.top, display:''});
this.fx.overlay.start(0.8);
return this.changeImage(imageNum);},
position: function(){this.overlay.setStyles({'top': window.getScrollTop(), 'height': window.getHeight()});},
setup: function(open){var elements=$A(document.getElementsByTagName('object'));
elements.extend(document.getElementsByTagName(window.ie ? 'select' :'embed'));
elements.each(function(el){if (open) el.lbBackupStyle=el.style.visibility;
el.style.visibility=open ? 'hidden' : el.lbBackupStyle;});
var fn=open ? 'addEvent' :'removeEvent';
window[fn]('scroll', this.eventPosition)[fn]('resize', this.eventPosition);
document[fn]('keydown', this.eventKeyDown);
this.step=0;},
keyboardListener: function(event){switch (event.keyCode){case 27: case 88: case 67: this.close(); break;
case 37: case 80: this.previous(); break;
case 39: case 78: this.next();}},
previous: function(){return this.changeImage(this.activeImage-1);},
next: function(){return this.changeImage(this.activeImage+1);},
changeImage: function(imageNum){if (this.step || (imageNum < 0) || (imageNum >=this.images.length)) return false;
this.step=1;
this.activeImage=imageNum;
this.bottomContainer.style.display=this.prevLink.style.display=this.nextLink.style.display='none';
this.fx.image.hide();
this.center.className='lbLoading';
this.preload=new Image();
this.preload.onload=this.nextEffect.bind(this);
this.preload.src=this.images[imageNum][0];
return false;},
nextEffect: function(){switch (this.step++){case 1:
this.center.className='';
this.image.style.backgroundImage='url('+this.images[this.activeImage][0]+')';
this.image.style.width=this.bottom.style.width=this.preload.width+'px';
this.image.style.height=this.prevLink.style.height=this.nextLink.style.height=this.preload.height+'px';
this.caption.setHTML(this.images[this.activeImage][1] || '');
this.number.setHTML((!this.options.showCounter || (this.images.length==1)) ? '' :'Image '+(this.activeImage+1)+' of '+this.images.length);
if (this.activeImage) this.preloadPrev.src=this.images[this.activeImage-1][0];
if (this.activeImage !=(this.images.length - 1)) this.preloadNext.src=this.images[this.activeImage+1][0];
if (this.center.clientHeight !=this.image.offsetHeight){this.fx.resize.start({height: this.image.offsetHeight});
break;}
this.step++;
case 2:
if (this.center.clientWidth !=this.image.offsetWidth){this.fx.resize.start({width: this.image.offsetWidth, marginLeft: -this.image.offsetWidth/2});
break;}
this.step++;
case 3:
this.bottomContainer.setStyles({top: this.top+this.center.clientHeight, height: 0, marginLeft: this.center.style.marginLeft, display:''});
this.fx.image.start(1);
break;
case 4:
if (this.options.animateCaption){this.fx.bottom.set(-this.bottom.offsetHeight);
this.bottomContainer.style.height='';
this.fx.bottom.start(0);
break;}
this.bottomContainer.style.height='';
case 5:
if (this.activeImage) this.prevLink.style.display='';
if (this.activeImage !=(this.images.length - 1)) this.nextLink.style.display='';
this.step=0;}},
close: function(){if (this.step < 0) return;
this.step=-1;
if (this.preload){this.preload.onload=Class.empty;
this.preload=null;}
for (var f in this.fx) this.fx[f].stop();
this.center.style.display=this.bottomContainer.style.display='none';
this.fx.overlay.chain(this.setup.pass(false, this)).start(0);
return false;}};
window.addEvent('domready', Lightbox.init.bind(Lightbox));
