//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2008 G.Montesano, <http://www.googlerank.it>.

var MooTools={version:"1.11"};function $defined(A){return(A!=undefined);}function $type(B){if(!$defined(B)){return false;}if(B.htmlElement){return"element";
}var A=typeof B;if(A=="object"&&B.nodeName){switch(B.nodeType){case 1:return"element";case 3:return(/\S/).test(B.nodeValue)?"textnode":"whitespace";}}if(A=="object"||A=="function"){switch(B.constructor){case Array:return"array";
case RegExp:return"regexp";case Class:return"class";}if(typeof B.length=="number"){if(B.item){return"collection";}if(B.callee){return"arguments";}}}return A;
}function $merge(){var C={};for(var B=0;B<arguments.length;B++){for(var E in arguments[B]){var A=arguments[B][E];var D=C[E];if(D&&$type(A)=="object"&&$type(D)=="object"){C[E]=$merge(D,A);
}else{C[E]=A;}}}return C;}var $extend=function(){var A=arguments;if(!A[1]){A=[this,A[0]];}for(var B in A[1]){A[0][B]=A[1][B];}return A[0];};var $native=function(){for(var B=0,A=arguments.length;
B<A;B++){arguments[B].extend=function(C){for(var D in C){if(!this.prototype[D]){this.prototype[D]=C[D];}if(!this[D]){this[D]=$native.generic(D);}}};}};
$native.generic=function(A){return function(B){return this.prototype[A].apply(B,Array.prototype.slice.call(arguments,1));};};$native(Function,Array,String,Number);
function $chk(A){return !!(A||A===0);}function $pick(B,A){return $defined(B)?B:A;}function $random(B,A){return Math.floor(Math.random()*(A-B+1)+B);}function $time(){return new Date().getTime();
}function $clear(A){clearTimeout(A);clearInterval(A);return null;}var Abstract=function(A){A=A||{};A.extend=$extend;return A;};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(B){var A=function(){return(arguments[0]!==null&&this.initialize&&$type(this.initialize)=="function")?this.initialize.apply(this,arguments):this;
};$extend(A,this);A.prototype=B;A.constructor=Class;return A;};Class.empty=function(){};Class.prototype={extend:function(B){var C=new this(null);for(var D in B){var A=C[D];
C[D]=Class.Merge(A,B[D]);}return new Class(C);},implement:function(){for(var B=0,A=arguments.length;B<A;B++){$extend(this.prototype,arguments[B]);}}};Class.Merge=function(C,D){if(C&&C!=D){var B=$type(D);
if(B!=$type(C)){return D;}switch(B){case"function":var A=function(){this.parent=arguments.callee.parent;return D.apply(this,arguments);};A.parent=C;return A;
case"object":return $merge(C,D);}}return D;};var Chain=new Class({chain:function(A){this.chains=this.chains||[];this.chains.push(A);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(B,A){if(A!=Class.empty){this.$events=this.$events||{};this.$events[B]=this.$events[B]||[];
this.$events[B].include(A);}return this;},fireEvent:function(C,B,A){if(this.$events&&this.$events[C]){this.$events[C].each(function(D){D.create({bind:this,delay:A,"arguments":B})();
},this);}return this;},removeEvent:function(B,A){if(this.$events&&this.$events[B]){this.$events[B].remove(A);}return this;}});var Options=new Class({setOptions:function(){this.options=$merge.apply(null,[this.options].extend(arguments));
if(this.addEvent){for(var A in this.options){if($type(this.options[A]=="function")&&(/^on[A-Z]/).test(A)){this.addEvent(A,this.options[A]);}}}return this;
}});Array.extend({forEach:function(C,D){for(var B=0,A=this.length;B<A;B++){C.call(D,this[B],B,this);}},filter:function(D,E){var C=[];for(var B=0,A=this.length;
B<A;B++){if(D.call(E,this[B],B,this)){C.push(this[B]);}}return C;},map:function(D,E){var C=[];for(var B=0,A=this.length;B<A;B++){C[B]=D.call(E,this[B],B,this);
}return C;},every:function(C,D){for(var B=0,A=this.length;B<A;B++){if(!C.call(D,this[B],B,this)){return false;}}return true;},some:function(C,D){for(var B=0,A=this.length;
B<A;B++){if(C.call(D,this[B],B,this)){return true;}}return false;},indexOf:function(C,D){var A=this.length;for(var B=(D<0)?Math.max(0,A+D):D||0;B<A;B++){if(this[B]===C){return B;
}}return -1;},copy:function(D,C){D=D||0;if(D<0){D=this.length+D;}C=C||(this.length-D);var A=[];for(var B=0;B<C;B++){A[B]=this[D++];}return A;},remove:function(C){var B=0;
var A=this.length;while(B<A){if(this[B]===C){this.splice(B,1);A--;}else{B++;}}return this;},contains:function(A,B){return this.indexOf(A,B)!=-1;},associate:function(C){var D={},B=Math.min(this.length,C.length);
for(var A=0;A<B;A++){D[C[A]]=this[A];}return D;},extend:function(C){for(var B=0,A=C.length;B<A;B++){this.push(C[B]);}return this;},merge:function(C){for(var B=0,A=C.length;
B<A;B++){this.include(C[B]);}return this;},include:function(A){if(!this.contains(A)){this.push(A);}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(A){return Array.copy(A);
}function $each(C,B,D){if(C&&typeof C.length=="number"&&$type(C)!="object"){Array.forEach(C,B,D);}else{for(var A in C){B.call(D||C,C[A],A);}}}Array.prototype.test=Array.prototype.contains;
String.extend({test:function(A,B){return(($type(A)=="string")?new RegExp(A,B):A).test(this);},toInt:function(){return parseInt(this,10);},toFloat:function(){return parseFloat(this);
},camelCase:function(){return this.replace(/-\D/g,function(A){return A.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/\w[A-Z]/g,function(A){return(A.charAt(0)+"-"+A.charAt(1).toLowerCase());
});},capitalize:function(){return this.replace(/\b[a-z]/g,function(A){return A.toUpperCase();});},trim:function(){return this.replace(/^\s+|\s+$/g,"");
},clean:function(){return this.replace(/\s{2,}/g," ").trim();},rgbToHex:function(B){var A=this.match(/\d{1,3}/g);return(A)?A.rgbToHex(B):false;},hexToRgb:function(B){var A=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
return(A)?A.slice(1).hexToRgb(B):false;},contains:function(A,B){return(B)?(B+this+B).indexOf(B+A+B)>-1:this.indexOf(A)>-1;},escapeRegExp:function(){return this.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1");
}});Array.extend({rgbToHex:function(D){if(this.length<3){return false;}if(this.length==4&&this[3]==0&&!D){return"transparent";}var B=[];for(var A=0;A<3;
A++){var C=(this[A]-0).toString(16);B.push((C.length==1)?"0"+C:C);}return D?B:"#"+B.join("");},hexToRgb:function(C){if(this.length!=3){return false;}var A=[];
for(var B=0;B<3;B++){A.push(parseInt((this[B].length==1)?this[B]+this[B]:this[B],16));}return C?A:"rgb("+A.join(",")+")";}});Function.extend({create:function(A){var B=this;
A=$merge({bind:B,event:false,"arguments":null,delay:false,periodical:false,attempt:false},A);if($chk(A.arguments)&&$type(A.arguments)!="array"){A.arguments=[A.arguments];
}return function(E){var C;if(A.event){E=E||window.event;C=[(A.event===true)?E:new A.event(E)];if(A.arguments){C.extend(A.arguments);}}else{C=A.arguments||arguments;
}var F=function(){return B.apply($pick(A.bind,B),C);};if(A.delay){return setTimeout(F,A.delay);}if(A.periodical){return setInterval(F,A.periodical);}if(A.attempt){try{return F();
}catch(D){return false;}}return F();};},pass:function(A,B){return this.create({"arguments":A,bind:B});},attempt:function(A,B){return this.create({"arguments":A,bind:B,attempt:true})();
},bind:function(B,A){return this.create({bind:B,"arguments":A});},bindAsEventListener:function(B,A){return this.create({bind:B,event:true,"arguments":A});
},delay:function(B,C,A){return this.create({delay:B,bind:C,"arguments":A})();},periodical:function(A,C,B){return this.create({periodical:A,bind:C,"arguments":B})();
}});Number.extend({toInt:function(){return parseInt(this);},toFloat:function(){return parseFloat(this);},limit:function(B,A){return Math.min(A,Math.max(B,this));
},round:function(A){A=Math.pow(10,A||0);return Math.round(this*A)/A;},times:function(B){for(var A=0;A<this;A++){B(A);}}});var Element=new Class({initialize:function(D,C){if($type(D)=="string"){if(window.ie&&C&&(C.name||C.type)){var A=(C.name)?' name="'+C.name+'"':"";
var B=(C.type)?' type="'+C.type+'"':"";delete C.name;delete C.type;D="<"+D+A+B+">";}D=document.createElement(D);}D=$(D);return(!C||!D)?D:D.set(C);}});var Elements=new Class({initialize:function(A){return(A)?$extend(A,this):this;
}});Elements.extend=function(A){for(var B in A){this.prototype[B]=A[B];this[B]=$native.generic(B);}};function $(B){if(!B){return null;}if(B.htmlElement){return Garbage.collect(B);
}if([window,document].contains(B)){return B;}var A=$type(B);if(A=="string"){B=document.getElementById(B);A=(B)?"element":false;}if(A!="element"){return null;
}if(B.htmlElement){return Garbage.collect(B);}if(["object","embed"].contains(B.tagName.toLowerCase())){return B;}$extend(B,Element.prototype);B.htmlElement=function(){};
return Garbage.collect(B);}document.getElementsBySelector=document.getElementsByTagName;function $$(){var D=[];for(var C=0,B=arguments.length;C<B;C++){var A=arguments[C];
switch($type(A)){case"element":D.push(A);case"boolean":break;case false:break;case"string":A=document.getElementsBySelector(A,true);default:D.extend(A);
}}return $$.unique(D);}$$.unique=function(G){var D=[];for(var C=0,A=G.length;C<A;C++){if(G[C].$included){continue;}var B=$(G[C]);if(B&&!B.$included){B.$included=true;
D.push(B);}}for(var F=0,E=D.length;F<E;F++){D[F].$included=null;}return new Elements(D);};Elements.Multi=function(A){return function(){var D=arguments;
var B=[];var G=true;for(var E=0,C=this.length,F;E<C;E++){F=this[E][A].apply(this[E],D);if($type(F)!="element"){G=false;}B.push(F);}return(G)?$$.unique(B):B;
};};Element.extend=function(A){for(var B in A){HTMLElement.prototype[B]=A[B];Element.prototype[B]=A[B];Element[B]=$native.generic(B);var C=(Array.prototype[B])?B+"Elements":B;
Elements.prototype[C]=Elements.Multi(B);}};Element.extend({set:function(A){for(var C in A){var B=A[C];switch(C){case"styles":this.setStyles(B);break;case"events":if(this.addEvents){this.addEvents(B);
}break;case"properties":this.setProperties(B);break;default:this.setProperty(C,B);}}return this;},inject:function(C,A){C=$(C);switch(A){case"before":C.parentNode.insertBefore(this,C);
break;case"after":var B=C.getNext();if(!B){C.parentNode.appendChild(this);}else{C.parentNode.insertBefore(this,B);}break;case"top":var D=C.firstChild;if(D){C.insertBefore(this,D);
break;}default:C.appendChild(this);}return this;},injectBefore:function(A){return this.inject(A,"before");},injectAfter:function(A){return this.inject(A,"after");
},injectInside:function(A){return this.inject(A,"bottom");},injectTop:function(A){return this.inject(A,"top");},adopt:function(){var A=[];$each(arguments,function(B){A=A.concat(B);
});$$(A).inject(this);return this;},remove:function(){return this.parentNode.removeChild(this);},clone:function(C){var B=$(this.cloneNode(C!==false));if(!B.$events){return B;
}B.$events={};for(var A in this.$events){B.$events[A]={keys:$A(this.$events[A].keys),values:$A(this.$events[A].values)};}return B.removeEvents();},replaceWith:function(A){A=$(A);
this.parentNode.replaceChild(A,this);return A;},appendText:function(A){this.appendChild(document.createTextNode(A));return this;},hasClass:function(A){return this.className.contains(A," ");
},addClass:function(A){if(!this.hasClass(A)){this.className=(this.className+" "+A).clean();}return this;},removeClass:function(A){this.className=this.className.replace(new RegExp("(^|\\s)"+A+"(?:\\s|$)"),"$1").clean();
return this;},toggleClass:function(A){return this.hasClass(A)?this.removeClass(A):this.addClass(A);},setStyle:function(B,A){switch(B){case"opacity":return this.setOpacity(parseFloat(A));
case"float":B=(window.ie)?"styleFloat":"cssFloat";}B=B.camelCase();switch($type(A)){case"number":if(!["zIndex","zoom"].contains(B)){A+="px";}break;case"array":A="rgb("+A.join(",")+")";
}this.style[B]=A;return this;},setStyles:function(A){switch($type(A)){case"object":Element.setMany(this,"setStyle",A);break;case"string":this.style.cssText=A;
}return this;},setOpacity:function(A){if(A==0){if(this.style.visibility!="hidden"){this.style.visibility="hidden";}}else{if(this.style.visibility!="visible"){this.style.visibility="visible";
}}if(!this.currentStyle||!this.currentStyle.hasLayout){this.style.zoom=1;}if(window.ie){this.style.filter=(A==1)?"":"alpha(opacity="+A*100+")";}this.style.opacity=this.$tmp.opacity=A;
return this;},getStyle:function(C){C=C.camelCase();var A=this.style[C];if(!$chk(A)){if(C=="opacity"){return this.$tmp.opacity;}A=[];for(var B in Element.Styles){if(C==B){Element.Styles[B].each(function(F){var E=this.getStyle(F);
A.push(parseInt(E)?E:"0px");},this);if(C=="border"){var D=A.every(function(E){return(E==A[0]);});return(D)?A[0]:false;}return A.join(" ");}}if(C.contains("border")){if(Element.Styles.border.contains(C)){return["Width","Style","Color"].map(function(E){return this.getStyle(C+E);
},this).join(" ");}else{if(Element.borderShort.contains(C)){return["Top","Right","Bottom","Left"].map(function(E){return this.getStyle("border"+E+C.replace("border",""));
},this).join(" ");}}}if(document.defaultView){A=document.defaultView.getComputedStyle(this,null).getPropertyValue(C.hyphenate());}else{if(this.currentStyle){A=this.currentStyle[C];
}}}if(window.ie){A=Element.fixStyle(C,A,this);}if(A&&C.test(/color/i)&&A.contains("rgb")){return A.split("rgb").splice(1,4).map(function(E){return E.rgbToHex();
}).join(" ");}return A;},getStyles:function(){return Element.getMany(this,"getStyle",arguments);},walk:function(A,C){A+="Sibling";var B=(C)?this[C]:this[A];
while(B&&$type(B)!="element"){B=B[A];}return $(B);},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(A){return !!$A(this.getElementsByTagName("*")).contains(A);},getProperty:function(D){var B=Element.Properties[D];if(B){return this[B];
}var A=Element.PropertiesIFlag[D]||0;if(!window.ie||A){return this.getAttribute(D,A);}var C=this.attributes[D];return(C)?C.nodeValue:null;},removeProperty:function(B){var A=Element.Properties[B];
if(A){this[A]="";}else{this.removeAttribute(B);}return this;},getProperties:function(){return Element.getMany(this,"getProperty",arguments);},setProperty:function(C,B){var A=Element.Properties[C];
if(A){this[A]=B;}else{this.setAttribute(C,B);}return this;},setProperties:function(A){return Element.setMany(this,"setProperty",A);},setHTML:function(){this.innerHTML=$A(arguments).join("");
return this;},setText:function(B){var A=this.getTag();if(["style","script"].contains(A)){if(window.ie){if(A=="style"){this.styleSheet.cssText=B;}else{if(A=="script"){this.setProperty("text",B);
}}return this;}else{this.removeChild(this.firstChild);return this.appendText(B);}}this[$defined(this.innerText)?"innerText":"textContent"]=B;return this;
},getText:function(){var A=this.getTag();if(["style","script"].contains(A)){if(window.ie){if(A=="style"){return this.styleSheet.cssText;}else{if(A=="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(E,A,D){if($chk(parseInt(A))){return A;}if(["height","width"].contains(E)){var B=(E=="width")?["left","right"]:["top","bottom"];
var C=0;B.each(function(F){C+=D.getStyle("border-"+F+"-width").toInt()+D.getStyle("padding-"+F).toInt();});return D["offset"+E.capitalize()]-C+"px";}else{if(E.test(/border(.+)Width|margin|padding/)){return"0px";
}}return A;};Element.Styles={border:[],padding:[],margin:[]};["Top","Right","Bottom","Left"].each(function(B){for(var A in Element.Styles){Element.Styles[A].push(A+B);
}});Element.borderShort=["borderWidth","borderStyle","borderColor"];Element.getMany=function(B,D,C){var A={};$each(C,function(E){A[E]=B[D](E);});return A;
};Element.setMany=function(B,D,C){for(var A in C){B[D](A,C[A]);}return B;};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(B,A){if(this.addEventListener){this.addEventListener(B,A,false);
}else{this.attachEvent("on"+B,A);}return this;},removeListener:function(B,A){if(this.removeEventListener){this.removeEventListener(B,A,false);}else{this.detachEvent("on"+B,A);
}return this;}}};window.extend(Element.Methods.Listeners);document.extend(Element.Methods.Listeners);Element.extend(Element.Methods.Listeners);var Garbage={elements:[],collect:function(A){if(!A.$tmp){Garbage.elements.push(A);
A.$tmp={opacity:1};}return A;},trash:function(D){for(var B=0,A=D.length,C;B<A;B++){if(!(C=D[B])||!C.$tmp){continue;}if(C.$events){C.fireEvent("trash").removeEvents();
}for(var E in C.$tmp){C.$tmp[E]=null;}for(var F in Element.prototype){C[F]=null;}Garbage.elements[Garbage.elements.indexOf(C)]=null;C.htmlElement=C.$tmp=C=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(C){if(C&&C.$extended){return C;}this.$extended=true;
C=C||window.event;this.event=C;this.type=C.type;this.target=C.target||C.srcElement;if(this.target.nodeType==3){this.target=this.target.parentNode;}this.shift=C.shiftKey;
this.control=C.ctrlKey;this.alt=C.altKey;this.meta=C.metaKey;if(["DOMMouseScroll","mousewheel"].contains(this.type)){this.wheel=(C.wheelDelta)?C.wheelDelta/120:-(C.detail||0)/3;
}else{if(this.type.contains("key")){this.code=C.which||C.keyCode;for(var B in Event.keys){if(Event.keys[B]==this.code){this.key=B;break;}}if(this.type=="keydown"){var A=this.code-111;
if(A>0&&A<13){this.key="f"+A;}}this.key=this.key||String.fromCharCode(this.code).toLowerCase();}else{if(this.type.test(/(click|mouse|menu)/)){this.page={x:C.pageX||C.clientX+document.documentElement.scrollLeft,y:C.pageY||C.clientY+document.documentElement.scrollTop};
this.client={x:C.pageX?C.pageX-window.pageXOffset:C.clientX,y:C.pageY?C.pageY-window.pageYOffset:C.clientY};this.rightClick=(C.which==3)||(C.button==2);
switch(this.type){case"mouseover":this.relatedTarget=C.relatedTarget||C.fromElement;break;case"mouseout":this.relatedTarget=C.relatedTarget||C.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(A){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(C,B){this.$events=this.$events||{};
this.$events[C]=this.$events[C]||{keys:[],values:[]};if(this.$events[C].keys.contains(B)){return this;}this.$events[C].keys.push(B);var A=C;var D=Element.Events[C];
if(D){if(D.add){D.add.call(this,B);}if(D.map){B=D.map;}if(D.type){A=D.type;}}if(!this.addEventListener){B=B.create({bind:this,event:true});}this.$events[C].values.push(B);
return(Element.NativeEvents.contains(A))?this.addListener(A,B):this;},removeEvent:function(C,B){if(!this.$events||!this.$events[C]){return this;}var F=this.$events[C].keys.indexOf(B);
if(F==-1){return this;}var A=this.$events[C].keys.splice(F,1)[0];var E=this.$events[C].values.splice(F,1)[0];var D=Element.Events[C];if(D){if(D.remove){D.remove.call(this,B);
}if(D.type){C=D.type;}}return(Element.NativeEvents.contains(C))?this.removeListener(C,E):this;},addEvents:function(A){return Element.setMany(this,"addEvent",A);
},removeEvents:function(A){if(!this.$events){return this;}if(!A){for(var B in this.$events){this.removeEvents(B);}this.$events=null;}else{if(this.$events[A]){this.$events[A].keys.each(function(C){this.removeEvent(A,C);
},this);this.$events[A]=null;}}return this;},fireEvent:function(C,B,A){if(this.$events&&this.$events[C]){this.$events[C].keys.each(function(D){D.create({bind:this,delay:A,"arguments":B})();
},this);}return this;},cloneEvents:function(C,A){if(!C.$events){return this;}if(!A){for(var B in C.$events){this.cloneEvents(C,B);}}else{if(C.$events[A]){C.$events[A].keys.each(function(D){this.addEvent(A,D);
},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(A){A=new Event(A);
if(A.relatedTarget!=this&&!this.hasChild(A.relatedTarget)){this.fireEvent("mouseenter",A);}}},mouseleave:{type:"mouseout",map:function(A){A=new Event(A);
if(A.relatedTarget!=this&&!this.hasChild(A.relatedTarget)){this.fireEvent("mouseleave",A);}}},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(B,A){return this.create({bind:B,"arguments":A,event:Event});}});Elements.extend({filterByTag:function(A){return new Elements(this.filter(function(B){return(Element.getTag(B)==A);
}));},filterByClass:function(A,C){var B=this.filter(function(D){return(D.className&&D.className.contains(A," "));});return(C)?B:new Elements(B);},filterById:function(C,B){var A=this.filter(function(D){return(D.id==C);
});return(B)?A:new Elements(A);},filterByAttribute:function(B,A,D,E){var C=this.filter(function(F){var G=Element.getProperty(F,B);if(!G){return false;}if(!A){return true;
}switch(A){case"=":return(G==D);case"*=":return(G.contains(D));case"^=":return(G.substr(0,D.length)==D);case"$=":return(G.substr(G.length-D.length)==D);
case"!=":return(G!=D);case"~=":return G.contains(D," ");}return false;});return(E)?C:new Elements(C);}});function $E(A,B){return($(B)||document).getElement(A);
}function $ES(A,B){return($(B)||document).getElementsBySelector(A);}$$.shared={regexp:/^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/,xpath:{getParam:function(B,D,E,C){var A=[D.namespaceURI?"xhtml:":"",E[1]];
if(E[2]){A.push('[@id="',E[2],'"]');}if(E[3]){A.push('[contains(concat(" ", @class, " "), " ',E[3],' ")]');}if(E[4]){if(E[5]&&E[6]){switch(E[5]){case"*=":A.push("[contains(@",E[4],', "',E[6],'")]');
break;case"^=":A.push("[starts-with(@",E[4],', "',E[6],'")]');break;case"$=":A.push("[substring(@",E[4],", string-length(@",E[4],") - ",E[6].length,' + 1) = "',E[6],'"]');
break;case"=":A.push("[@",E[4],'="',E[6],'"]');break;case"!=":A.push("[@",E[4],'!="',E[6],'"]');}}else{A.push("[@",E[4],"]");}}B.push(A.join(""));return B;
},getItems:function(B,E,G){var F=[];var A=document.evaluate(".//"+B.join("//"),E,$$.shared.resolver,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);for(var D=0,C=A.snapshotLength;
D<C;D++){F.push(A.snapshotItem(D));}return(G)?F:new Elements(F.map($));}},normal:{getParam:function(A,C,E,B){if(B==0){if(E[2]){var D=C.getElementById(E[2]);
if(!D||((E[1]!="*")&&(Element.getTag(D)!=E[1]))){return false;}A=[D];}else{A=$A(C.getElementsByTagName(E[1]));}}else{A=$$.shared.getElementsByTagName(A,E[1]);
if(E[2]){A=Elements.filterById(A,E[2],true);}}if(E[3]){A=Elements.filterByClass(A,E[3],true);}if(E[4]){A=Elements.filterByAttribute(A,E[4],E[5],E[6],true);
}return A;},getItems:function(A,B,C){return(C)?A:$$.unique(A);}},resolver:function(A){return(A=="xhtml")?"http://www.w3.org/1999/xhtml":false;},getElementsByTagName:function(D,C){var E=[];
for(var B=0,A=D.length;B<A;B++){E.extend(D[B].getElementsByTagName(C));}return E;}};$$.shared.method=(window.xpath)?"xpath":"normal";Element.Methods.Dom={getElements:function(A,H){var C=[];
A=A.trim().split(" ");for(var E=0,D=A.length;E<D;E++){var F=A[E];var G=F.match($$.shared.regexp);if(!G){break;}G[1]=G[1]||"*";var B=$$.shared[$$.shared.method].getParam(C,this,G,E);
if(!B){break;}C=B;}return $$.shared[$$.shared.method].getItems(C,this,H);},getElement:function(A){return $(this.getElements(A,true)[0]||false);},getElementsBySelector:function(A,E){var D=[];
A=A.split(",");for(var C=0,B=A.length;C<B;C++){D=D.concat(this.getElements(A[C],true));}return(E)?D:$$.unique(D);}};Element.extend({getElementById:function(C){var B=document.getElementById(C);
if(!B){return false;}for(var A=B.parentNode;A!=this;A=A.parentNode){if(!A){return false;}}return B;},getElementsByClassName:function(A){return this.getElements("."+A);
}});document.extend(Element.Methods.Dom);Element.extend(Element.Methods.Dom);Element.extend({getValue:function(){switch(this.getTag()){case"select":var A=[];
$each(this.options,function(B){if(B.selected){A.push($pick(B.value,B.text));}});return(this.multiple)?A:A[0];case"input":if(!(this.checked&&["checkbox","radio"].contains(this.type))&&!["hidden","text","password"].contains(this.type)){break;
}case"textarea":return this.value;}return false;},getFormElements:function(){return $$(this.getElementsByTagName("input"),this.getElementsByTagName("select"),this.getElementsByTagName("textarea"));
},toQueryString:function(){var A=[];this.getFormElements().each(function(D){var C=D.name;var E=D.getValue();if(E===false||!C||D.disabled){return ;}var B=function(F){A.push(C+"="+encodeURIComponent(F));
};if($type(E)=="array"){E.each(B);}else{B(E);}});return A.join("&");}});Element.extend({scrollTo:function(A,B){this.scrollLeft=A;this.scrollTop=B;},getSize:function(){return{scroll:{x:this.scrollLeft,y:this.scrollTop},size:{x:this.offsetWidth,y:this.offsetHeight},scrollSize:{x:this.scrollWidth,y:this.scrollHeight}};
},getPosition:function(A){A=A||[];var B=this,D=0,C=0;do{D+=B.offsetLeft||0;C+=B.offsetTop||0;B=B.offsetParent;}while(B);A.each(function(E){D-=E.scrollLeft||0;
C-=E.scrollTop||0;});return{x:D,y:C};},getTop:function(A){return this.getPosition(A).y;},getLeft:function(A){return this.getPosition(A).x;},getCoordinates:function(B){var A=this.getPosition(B);
var C={width:this.offsetWidth,height:this.offsetHeight,left:A.x,top:A.y};C.right=C.left+C.width;C.bottom=C.top+C.height;return C;}});Element.Events.domready={add:function(B){if(window.loaded){B.call(this);
return ;}var A=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)){A();
}}.periodical(50);}else{if(document.readyState&&window.ie){if(!$("ie_ready")){var C=(window.location.protocol=="https:")?"://0":"javascript:void(0)";document.write('<script id="ie_ready" defer src="'+C+'"><\/script>');
$("ie_ready").onreadystatechange=function(){if(this.readyState=="complete"){A();}};}}else{window.addListener("load",A);document.addListener("DOMContentLoaded",A);
}}}};window.onDomReady=function(A){return this.addEvent("domready",A);};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(A){return -(Math.cos(Math.PI*A)-1)/2;
},duration:500,unit:"px",wait:true,fps:50},initialize:function(A){this.element=this.element||null;this.setOptions(A);if(this.options.initialize){this.options.initialize.call(this);
}},step:function(){var A=$time();if(A<this.time+this.options.duration){this.delta=this.options.transition((A-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(A){this.now=A;this.increase();
return this;},setNow:function(){this.now=this.compute(this.from,this.to);},compute:function(B,A){return(A-B)*this.delta+B;},start:function(B,A){if(!this.options.wait){this.stop();
}else{if(this.timer){return this;}}this.from=B;this.to=A;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(A){if(!this.timer){return this;}this.timer=$clear(this.timer);if(!A){this.fireEvent("onCancel",this.element);
}return this;},custom:function(B,A){return this.start(B,A);},clearTimer:function(A){return this.stop(A);}});Fx.Base.implement(new Chain,new Events,new Options);
Fx.CSS={select:function(B,C){if(B.test(/color/i)){return this.Color;}var A=$type(C);if((A=="array")||(A=="string"&&C.contains(" "))){return this.Multi;
}return this.Single;},parse:function(C,D,A){if(!A.push){A=[A];}var F=A[0],E=A[1];if(!$chk(E)){E=F;F=C.getStyle(D);}var B=this.select(D,E);return{from:B.parse(F),to:B.parse(E),css:B};
}};Fx.CSS.Single={parse:function(A){return parseFloat(A);},getNow:function(C,B,A){return A.compute(C,B);},getValue:function(C,A,B){if(A=="px"&&B!="opacity"){C=Math.round(C);
}return C+A;}};Fx.CSS.Multi={parse:function(A){return A.push?A:A.split(" ").map(function(B){return parseFloat(B);});},getNow:function(E,D,C){var A=[];for(var B=0;
B<E.length;B++){A[B]=C.compute(E[B],D[B]);}return A;},getValue:function(C,A,B){if(A=="px"&&B!="opacity"){C=C.map(Math.round);}return C.join(A+" ")+A;}};
Fx.CSS.Color={parse:function(A){return A.push?A:A.hexToRgb(true);},getNow:function(E,D,C){var A=[];for(var B=0;B<E.length;B++){A[B]=Math.round(C.compute(E[B],D[B]));
}return A;},getValue:function(A){return"rgb("+A.join(",")+")";}};Fx.Style=Fx.Base.extend({initialize:function(B,C,A){this.element=$(B);this.property=C;
this.parent(A);},hide:function(){return this.set(0);},setNow:function(){this.now=this.css.getNow(this.from,this.to,this);},set:function(A){this.css=Fx.CSS.select(this.property,A);
return this.parent(this.css.parse(A));},start:function(C,B){if(this.timer&&this.options.wait){return this;}var A=Fx.CSS.parse(this.element,this.property,[C,B]);
this.css=A.css;return this.parent(A.from,A.to);},increase:function(){this.element.setStyle(this.property,this.css.getValue(this.now,this.options.unit,this.property));
}});Element.extend({effect:function(B,A){return new Fx.Style(this,B,A);}});Fx.Elements=Fx.Base.extend({initialize:function(B,A){this.elements=$$(B);this.parent(A);
},setNow:function(){for(var C in this.from){var F=this.from[C],E=this.to[C],B=this.css[C],A=this.now[C]={};for(var D in F){A[D]=B[D].getNow(F[D],E[D],this);
}}},set:function(G){var B={};this.css={};for(var D in G){var F=G[D],C=this.css[D]={},A=B[D]={};for(var E in F){C[E]=Fx.CSS.select(E,F[E]);A[E]=C[E].parse(F[E]);
}}return this.parent(B);},start:function(D){if(this.timer&&this.options.wait){return this;}this.now={};this.css={};var I={},J={};for(var E in D){var G=D[E],A=I[E]={},H=J[E]={},C=this.css[E]={};
for(var B in G){var F=Fx.CSS.parse(this.elements[E],B,G[B]);A[B]=F.from;H[B]=F.to;C[B]=F.css;}}return this.parent(I,J);},increase:function(){for(var C in this.now){var A=this.now[C],B=this.css[C];
for(var D in A){this.elements[C].setStyle(D,B[D].getValue(A[D],this.options.unit,D));}}}});Fx.Slide=Fx.Base.extend({options:{mode:"vertical"},initialize:function(B,A){this.element=$(B);
this.wrapper=new Element("div",{styles:$extend(this.element.getStyles("margin"),{overflow:"hidden"})}).injectAfter(this.element).adopt(this.element);this.element.setStyle("margin",0);
this.setOptions(A);this.now=[];this.parent(this.options);this.open=true;this.addEvent("onComplete",function(){this.open=(this.now[0]===0);});if(window.webkit419){this.addEvent("onComplete",function(){if(this.open){this.element.remove().inject(this.wrapper);
}});}},setNow:function(){for(var A=0;A<2;A++){this.now[A]=this.compute(this.from[A],this.to[A]);}},vertical:function(){this.margin="margin-top";this.layout="height";
this.offset=this.element.offsetHeight;},horizontal:function(){this.margin="margin-left";this.layout="width";this.offset=this.element.offsetWidth;},slideIn:function(A){this[A||this.options.mode]();
return this.start([this.element.getStyle(this.margin).toInt(),this.wrapper.getStyle(this.layout).toInt()],[0,this.offset]);},slideOut:function(A){this[A||this.options.mode]();
return this.start([this.element.getStyle(this.margin).toInt(),this.wrapper.getStyle(this.layout).toInt()],[-this.offset,0]);},hide:function(A){this[A||this.options.mode]();
this.open=false;return this.set([-this.offset,0]);},show:function(A){this[A||this.options.mode]();this.open=true;return this.set([0,this.offset]);},toggle:function(A){if(this.wrapper.offsetHeight==0||this.wrapper.offsetWidth==0){return this.slideIn(A);
}return this.slideOut(A);},increase:function(){this.element.setStyle(this.margin,this.now[0]+this.options.unit);this.wrapper.setStyle(this.layout,this.now[1]+this.options.unit);
}});var Drag={};Drag.Base=new Class({options:{handle:false,unit:"px",onStart:Class.empty,onBeforeStart:Class.empty,onComplete:Class.empty,onSnap:Class.empty,onDrag:Class.empty,limit:false,modifiers:{x:"left",y:"top"},grid:false,snap:6},initialize:function(B,A){this.setOptions(A);
this.element=$(B);this.handle=$(this.options.handle)||this.element;this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.bound={start:this.start.bindWithEvent(this),check:this.check.bindWithEvent(this),drag:this.drag.bindWithEvent(this),stop:this.stop.bind(this)};
this.attach();if(this.options.initialize){this.options.initialize.call(this);}},attach:function(){this.handle.addEvent("mousedown",this.bound.start);return this;
},detach:function(){this.handle.removeEvent("mousedown",this.bound.start);return this;},start:function(C){this.fireEvent("onBeforeStart",this.element);
this.mouse.start=C.page;var A=this.options.limit;this.limit={x:[],y:[]};for(var D in this.options.modifiers){if(!this.options.modifiers[D]){continue;}this.value.now[D]=this.element.getStyle(this.options.modifiers[D]).toInt();
this.mouse.pos[D]=C.page[D]-this.value.now[D];if(A&&A[D]){for(var B=0;B<2;B++){if($chk(A[D][B])){this.limit[D][B]=($type(A[D][B])=="function")?A[D][B]():A[D][B];
}}}}if($type(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid};}document.addListener("mousemove",this.bound.check);
document.addListener("mouseup",this.bound.stop);this.fireEvent("onStart",this.element);C.stop();},check:function(A){var B=Math.round(Math.sqrt(Math.pow(A.page.x-this.mouse.start.x,2)+Math.pow(A.page.y-this.mouse.start.y,2)));
if(B>this.options.snap){document.removeListener("mousemove",this.bound.check);document.addListener("mousemove",this.bound.drag);this.drag(A);this.fireEvent("onSnap",this.element);
}A.stop();},drag:function(A){this.out=false;this.mouse.now=A.page;for(var B in this.options.modifiers){if(!this.options.modifiers[B]){continue;}this.value.now[B]=this.mouse.now[B]-this.mouse.pos[B];
if(this.limit[B]){if($chk(this.limit[B][1])&&(this.value.now[B]>this.limit[B][1])){this.value.now[B]=this.limit[B][1];this.out=true;}else{if($chk(this.limit[B][0])&&(this.value.now[B]<this.limit[B][0])){this.value.now[B]=this.limit[B][0];
this.out=true;}}}if(this.options.grid[B]){this.value.now[B]-=(this.value.now[B]%this.options.grid[B]);}this.element.setStyle(this.options.modifiers[B],this.value.now[B]+this.options.unit);
}this.fireEvent("onDrag",this.element);A.stop();},stop:function(){document.removeListener("mousemove",this.bound.check);document.removeListener("mousemove",this.bound.drag);
document.removeListener("mouseup",this.bound.stop);this.fireEvent("onComplete",this.element);}});Drag.Base.implement(new Events,new Options);Element.extend({makeResizable:function(A){return new Drag.Base(this,$merge({modifiers:{x:"width",y:"height"}},A));
}});Drag.Move=Drag.Base.extend({options:{droppables:[],container:false,overflown:[]},initialize:function(B,A){this.setOptions(A);this.element=$(B);this.droppables=$$(this.options.droppables);
this.container=$(this.options.container);this.position={element:this.element.getStyle("position"),container:false};if(this.container){this.position.container=this.container.getStyle("position");
}if(!["relative","absolute","fixed"].contains(this.position.element)){this.position.element="absolute";}var D=this.element.getStyle("top").toInt();var C=this.element.getStyle("left").toInt();
if(this.position.element=="absolute"&&!["relative","absolute","fixed"].contains(this.position.container)){D=$chk(D)?D:this.element.getTop(this.options.overflown);
C=$chk(C)?C:this.element.getLeft(this.options.overflown);}else{D=$chk(D)?D:0;C=$chk(C)?C:0;}this.element.setStyles({top:D,left:C,position:this.position.element});
this.parent(this.element);},start:function(C){this.overed=null;if(this.container){var A=this.container.getCoordinates();var B=this.element.getCoordinates();
if(this.position.element=="absolute"&&!["relative","absolute","fixed"].contains(this.position.container)){this.options.limit={x:[A.left,A.right-B.width],y:[A.top,A.bottom-B.height]};
}else{this.options.limit={y:[0,A.height-B.height],x:[0,A.width-B.width]};}}this.parent(C);},drag:function(A){this.parent(A);var B=this.out?false:this.droppables.filter(this.checkAgainst,this).getLast();
if(this.overed!=B){if(this.overed){this.overed.fireEvent("leave",[this.element,this]);}this.overed=B?B.fireEvent("over",[this.element,this]):null;}return this;
},checkAgainst:function(B){B=B.getCoordinates(this.options.overflown);var A=this.mouse.now;return(A.x>B.left&&A.x<B.right&&A.y<B.bottom&&A.y>B.top);},stop:function(){if(this.overed&&!this.out){this.overed.fireEvent("drop",[this.element,this]);
}else{this.element.fireEvent("emptydrop",this);}this.parent();return this;}});Element.extend({makeDraggable:function(A){return new Drag.Move(this,A);}});
var XHR=new Class({options:{method:"post",async:true,onRequest:Class.empty,onSuccess:Class.empty,onFailure:Class.empty,urlEncoded:true,encoding:"utf-8",autoCancel:false,headers:{}},setTransport:function(){this.transport=(window.XMLHttpRequest)?new XMLHttpRequest():(window.ie?new ActiveXObject("Microsoft.XMLHTTP"):false);
return this;},initialize:function(A){this.setTransport().setOptions(A);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers={};if(this.options.urlEncoded&&this.options.method=="post"){var B=(this.options.encoding)?"; charset="+this.options.encoding:"";
this.setHeader("Content-type","application/x-www-form-urlencoded"+B);}if(this.options.initialize){this.options.initialize.call(this);}},onStateChange:function(){if(this.transport.readyState!=4||!this.running){return ;
}this.running=false;var A=0;try{A=this.transport.status;}catch(B){}if(this.options.isSuccess.call(this,A)){this.onSuccess();}else{this.onFailure();}this.transport.onreadystatechange=Class.empty;
},isSuccess:function(A){return((A>=200)&&(A<300));},onSuccess:function(){this.response={text:this.transport.responseText,xml:this.transport.responseXML};
this.fireEvent("onSuccess",[this.response.text,this.response.xml]);this.callChain();},onFailure:function(){this.fireEvent("onFailure",this.transport);},setHeader:function(A,B){this.headers[A]=B;
return this;},send:function(A,C){if(this.options.autoCancel){this.cancel();}else{if(this.running){return this;}}this.running=true;if(C&&this.options.method=="get"){A=A+(A.contains("?")?"&":"?")+C;
C=null;}this.transport.open(this.options.method.toUpperCase(),A,this.options.async);this.transport.onreadystatechange=this.onStateChange.bind(this);if((this.options.method=="post")&&this.transport.overrideMimeType){this.setHeader("Connection","close");
}$extend(this.headers,this.options.headers);for(var B in this.headers){try{this.transport.setRequestHeader(B,this.headers[B]);}catch(D){}}this.fireEvent("onRequest");
this.transport.send($pick(C,null));return this;},cancel:function(){if(!this.running){return this;}this.running=false;this.transport.abort();this.transport.onreadystatechange=Class.empty;
this.setTransport();this.fireEvent("onCancel");return this;}});XHR.implement(new Chain,new Events,new Options);var Ajax=XHR.extend({options:{data:null,update:null,onComplete:Class.empty,evalScripts:false,evalResponse:false},initialize:function(B,A){this.addEvent("onSuccess",this.onComplete);
this.setOptions(A);this.options.data=this.options.data||this.options.postBody;if(!["post","get"].contains(this.options.method)){this._method="_method="+this.options.method;
this.options.method="post";}this.parent();this.setHeader("X-Requested-With","XMLHttpRequest");this.setHeader("Accept","text/javascript, text/html, application/xml, text/xml, */*");
this.url=B;},onComplete:function(){if(this.options.update){$(this.options.update).empty().setHTML(this.response.text);}if(this.options.evalScripts||this.options.evalResponse){this.evalScripts();
}this.fireEvent("onComplete",[this.response.text,this.response.xml],20);},request:function(A){A=A||this.options.data;switch($type(A)){case"element":A=$(A).toQueryString();
break;case"object":A=Object.toQueryString(A);}if(this._method){A=(A)?[this._method,A].join("&"):this._method;}return this.send(this.url,A);},evalScripts:function(){var B,A;
if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){A=this.response.text;}else{A=[];var C=/<script[^>]*>([\s\S]*?)<\/script>/gi;
while((B=C.exec(this.response.text))){A.push(B[1]);}A=A.join("\n");}if(A){(window.execScript)?window.execScript(A):window.setTimeout(A,0);}},getHeader:function(A){try{return this.transport.getResponseHeader(A);
}catch(B){}return null;}});Object.toQueryString=function(B){var C=[];for(var A in B){C.push(encodeURIComponent(A)+"="+encodeURIComponent(B[A]));}return C.join("&");
};Element.extend({send:function(A){return new Ajax(this.getProperty("action"),$merge({data:this.toQueryString()},A,{method:"post"})).request();}});var Cookie=new Abstract({options:{domain:false,path:false,duration:false,secure:false},set:function(C,D,B){B=$merge(this.options,B);
D=encodeURIComponent(D);if(B.domain){D+="; domain="+B.domain;}if(B.path){D+="; path="+B.path;}if(B.duration){var A=new Date();A.setTime(A.getTime()+B.duration*24*60*60*1000);
D+="; expires="+A.toGMTString();}if(B.secure){D+="; secure";}document.cookie=C+"="+D;return $extend(B,{key:C,value:D});},get:function(A){var B=document.cookie.match("(?:^|;)\\s*"+A.escapeRegExp()+"=([^;]*)");
return B?decodeURIComponent(B[1]):false;},remove:function(B,A){if($type(B)=="object"){this.set(B.key,"",$merge(B,{duration:-1}));}else{this.set(B,"",$merge(A,{duration:-1}));
}}});var Json={toString:function(C){switch($type(C)){case"string":return'"'+C.replace(/(["\\])/g,"\\$1")+'"';case"array":return"["+C.map(Json.toString).join(",")+"]";
case"object":var A=[];for(var B in C){A.push(Json.toString(B)+":"+Json.toString(C[B]));}return"{"+A.join(",")+"}";case"number":if(isFinite(C)){break;}case false:return"null";
}return String(C);},evaluate:function(str,secure){return(($type(str)!="string")||(secure&&!str.test(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/)))?null:eval("("+str+")");
}};Json.Remote=XHR.extend({initialize:function(B,A){this.url=B;this.addEvent("onSuccess",this.onComplete);this.parent(A);this.setHeader("X-Request","JSON");
},send:function(A){return this.parent(this.url,"json="+Json.toString(A));},onComplete:function(){this.fireEvent("onComplete",[Json.evaluate(this.response.text,this.options.secure)]);
}});var Asset=new Abstract({javascript:function(C,B){B=$merge({onload:Class.empty},B);var A=new Element("script",{src:C}).addEvents({load:B.onload,readystatechange:function(){if(this.readyState=="complete"){this.fireEvent("load");
}}});delete B.onload;return A.setProperties(B).inject(document.head);},css:function(B,A){return new Element("link",$merge({rel:"stylesheet",media:"screen",type:"text/css",href:B},A)).inject(document.head);
},image:function(C,B){B=$merge({onload:Class.empty,onabort:Class.empty,onerror:Class.empty},B);var D=new Image();D.src=C;var A=new Element("img",{src:C});
["load","abort","error"].each(function(E){var F=B["on"+E];delete B["on"+E];A.addEvent(E,function(){this.removeEvent(E,arguments.callee);F.call(this);});
});if(D.width&&D.height){A.fireEvent("load",A,1);}return A.setProperties(B);},images:function(D,C){C=$merge({onComplete:Class.empty,onProgress:Class.empty},C);
if(!D.push){D=[D];}var A=[];var B=0;D.each(function(F){var E=new Asset.image(F,{onload:function(){C.onProgress.call(this,B);B++;if(B==D.length){C.onComplete();
}}});A.push(E);});return new Elements(A);}});var Accordion=Fx.Elements.extend({options:{onActive:Class.empty,onBackground:Class.empty,display:0,show:false,height:true,width:false,opacity:true,fixedHeight:false,fixedWidth:false,wait:false,alwaysHide:false},initialize:function(){var C,E,F,B;
$each(arguments,function(I,H){switch($type(I)){case"object":C=I;break;case"element":B=$(I);break;default:var G=$$(I);if(!E){E=G;}else{F=G;}}});this.togglers=E||[];
this.elements=F||[];this.container=$(B);this.setOptions(C);this.previous=-1;if(this.options.alwaysHide){this.options.wait=true;}if($chk(this.options.show)){this.options.display=false;
this.previous=this.options.show;}if(this.options.start){this.options.display=false;this.options.show=false;}this.effects={};if(this.options.opacity){this.effects.opacity="fullOpacity";
}if(this.options.width){this.effects.width=this.options.fixedWidth?"fullWidth":"offsetWidth";}if(this.options.height){this.effects.height=this.options.fixedHeight?"fullHeight":"scrollHeight";
}for(var D=0,A=this.togglers.length;D<A;D++){this.addSection(this.togglers[D],this.elements[D]);}this.elements.each(function(H,G){if(this.options.show===G){this.fireEvent("onActive",[this.togglers[G],H]);
}else{for(var I in this.effects){H.setStyle(I,0);}}},this);this.parent(this.elements);if($chk(this.options.display)){this.display(this.options.display);
}},addSection:function(E,C,G){E=$(E);C=$(C);var F=this.togglers.contains(E);var B=this.togglers.length;this.togglers.include(E);this.elements.include(C);
if(B&&(!F||G)){G=$pick(G,B-1);E.injectBefore(this.togglers[G]);C.injectAfter(E);}else{if(this.container&&!F){E.inject(this.container);C.inject(this.container);
}}var A=this.togglers.indexOf(E);E.addEvent("click",this.display.bind(this,A));if(this.options.height){C.setStyles({"padding-top":0,"border-top":"none","padding-bottom":0,"border-bottom":"none"});
}if(this.options.width){C.setStyles({"padding-left":0,"border-left":"none","padding-right":0,"border-right":"none"});}C.fullOpacity=1;if(this.options.fixedWidth){C.fullWidth=this.options.fixedWidth;
}if(this.options.fixedHeight){C.fullHeight=this.options.fixedHeight;}C.setStyle("overflow","hidden");if(!F){for(var D in this.effects){C.setStyle(D,0);
}}return this;},display:function(A){A=($type(A)=="element")?this.elements.indexOf(A):A;if((this.timer&&this.options.wait)||(A===this.previous&&!this.options.alwaysHide)){return this;
}this.previous=A;var B={};this.elements.each(function(E,D){B[D]={};var C=(D!=A)||(this.options.alwaysHide&&(E.offsetHeight>0));this.fireEvent(C?"onBackground":"onActive",[this.togglers[D],E]);
for(var F in this.effects){B[D][F]=C?0:E[this.effects[F]];}},this);return this.start(B);},showThisHideOpen:function(A){return this.display(A);}});Fx.Accordion=Accordion;

Function.extend({
  // same as delay, but FF 1.0 has issues with the name delay
	invokeLater: function(delay, bind, args){
		return this.create({'delay': delay, 'bind': bind, 'arguments': args})();
	}
});

var Observer = new Class({

	options: {
		periodical: false,
		delay: 1000
	},

	initialize: function(el, onFired, options){
		this.setOptions(options);
		this.addEvent('onFired', onFired);
		this.element = $(el);
		this.listener = this.fired.bind(this);
		this.value = this.element.getValue();
		if (this.options.periodical) this.timer = this.listener.periodical(this.options.periodical);
		else this.element.addEvent('keyup', this.listener);
	},

	fired: function() {
		var value = this.element.getValue();
		if (this.value == value) return;
		this.clear();
		this.value = value;
		this.timeout = this.fireEvent.invokeLater(this.options.delay, this, ['onFired', [value]]);
	},

	clear: function() {
		$clear(this.timeout);
		return this;
	}
});

Observer.implement(new Options);
Observer.implement(new Events);


var Autocompleter = {};

Autocompleter.Base = new Class({

	options: {
		minLength: 1,
		useSelection: true,
		markQuery: true,
		inheritWidth: true,
		maxChoices: 10,
		injectChoice: null,
		onSelect: Class.empty,
		onShow: Class.empty,
		onHide: Class.empty,
		customTarget: null,
		className: 'autocompleter-choices',
		zIndex: 42,
		observerOptions: {},
		fxOptions: {},
		overflown: []
	},

	initialize: function(el, options) {
		this.setOptions(options);
		this.element = $(el);
		this.build();
		this.observer = new Observer(this.element, this.prefetch.bind(this), $merge({
			delay: 400
		}, this.options.observerOptions));
		this.value = this.observer.value;
		this.queryValue = null;
	},

	
	build: function() {
		if ($(this.options.customTarget)) this.choices = this.options.customTarget;
		else {
			this.choices = new Element('ul', {
				'class': this.options.className,
				styles: {zIndex: this.options.zIndex}
			}).injectInside(document.body);
			this.fix = new OverlayFix(this.choices);
		}
		this.fx = this.choices.effect('opacity', $merge({
			wait: false,
			duration: 200
		}, this.options.fxOptions))
			.addEvent('onStart', function() {
				if (this.fx.now) return;
				this.choices.setStyle('display', '');
				this.fix.show();
			}.bind(this))
			.addEvent('onComplete', function() {
				if (this.fx.now) return;
				this.choices.setStyle('display', 'none');
				this.fix.hide();
			}.bind(this)).set(0)
      .addEvent('onShow', function() {
				this.fix.show();
      }.bind(this));
		this.element.setProperty('autocomplete', 'off')
			.addEvent(window.ie6 ? 'keydown' : 'keypress', this.onCommand.bindWithEvent(this))
			.addEvent('mousedown', this.onCommand.bindWithEvent(this, [true]))
			.addEvent('focus', this.toggleFocus.bind(this, [true]))
			.addEvent('blur', this.toggleFocus.bind(this, [false]))
			.addEvent('trash', this.destroy.bind(this));
	},

	destroy: function() {
		this.choices.remove();
	},

	toggleFocus: function(state) {
		this.focussed = state;
		if (!state) this.hideChoices();
	},

	onCommand: function(e, mouse) {
		if (mouse && this.focussed) this.prefetch();
		if (e.key && !e.shift) switch (e.key) {
			case 'enter':
				if (this.selected && this.visible) {
					this.choiceSelect(this.selected);
					e.stop();
				} return;
			case 'up': case 'down':
				if (this.observer.value != (this.value || this.queryValue)) this.prefetch();
				else if (this.queryValue === null) break;
				else if (!this.visible) this.showChoices();
				else {
					this.choiceOver((e.key == 'up')
						? this.selected.getPrevious() || this.choices.getLast()
						: this.selected.getNext() || this.choices.getFirst() );
					this.setSelection();
				}
				e.stop(); return;
			case 'esc': this.hideChoices(); return;
		}
		this.value = false;
	},

	setSelection: function() {
		if (!this.options.useSelection) return;
		var startLength = this.queryValue.length;
		if (this.element.value.indexOf(this.queryValue) != 0) return;
		var insert = this.selected.inputValue.substr(startLength);
		if (document.getSelection) {
			this.element.value = this.queryValue + insert;
			this.element.selectionStart = startLength;
			this.element.selectionEnd = this.element.value.length;
		} else if (document.selection) {
			var sel = document.selection.createRange();
			sel.text = insert;
			sel.move("character", - insert.length);
			sel.findText(insert);
			sel.select();
		}
		this.value = this.observer.value = this.element.value;
	},

	hideChoices: function() {
		if (!this.visible) return;
		this.visible = this.value = false;
		this.observer.clear();
		this.fx.start(0);
		this.fireEvent('onHide', [this.element, this.choices]);
	},

	showChoices: function() {
		if (this.visible || !this.choices.getFirst()) return;
		this.visible = true;
		var pos = this.element.getCoordinates(this.options.overflown);
		this.choices.setStyles({
			left: pos.left,
			top: pos.bottom
		});
		if (this.options.inheritWidth) this.choices.setStyle('width', pos.width);
		this.fx.start(1);
		this.choiceOver(this.choices.getFirst());
		this.fireEvent('onShow', [this.element, this.choices]);
	},

	prefetch: function() {
		if (this.element.value.length < this.options.minLength) this.hideChoices();
		else if (this.element.value == this.queryValue) this.showChoices();
		else this.query();
	},

	updateChoices: function(choices) {
		this.choices.empty();
		this.selected = null;
		if (!choices || !choices.length) return;
		if (this.options.maxChoices < choices.length) choices.length = this.options.maxChoices;
		choices.each(this.options.injectChoice || function(choice, i){
			var el = new Element('li').setHTML(this.markQueryValue(choice));
			el.inputValue = choice;
			this.addChoiceEvents(el).injectInside(this.choices);
		}, this);
		this.showChoices();
	},

	choiceOver: function(el) {
		if (this.selected) this.selected.removeClass('autocompleter-selected');
		this.selected = el.addClass('autocompleter-selected');
	},

	choiceSelect: function(el) {
		this.observer.value = this.element.value = el.inputValue;
		this.hideChoices();
		this.fireEvent('onSelect', [this.element], 20);
	},

	/**
	 * markQueryValue
	 *
	 * Marks the queried word in the given string with <span class="autocompleter-queried">*</span>
	 * Call this i.e. from your custom parseChoices, same for addChoiceEvents
	 *
	 * @param		{String} Text
	 * @return		{String} Text
	 */
	markQueryValue: function(txt) {
		return (this.options.markQuery && this.queryValue) ? txt.replace(new RegExp('^(' + this.queryValue.escapeRegExp() + ')', 'i'), '<span class="autocompleter-queried">$1</span>') : txt;
	},

	/**
	 * addChoiceEvents
	 *
	 * Appends the needed event handlers for a choice-entry to the given element.
	 *
	 * @param		{Element} Choice entry
	 * @return		{Element} Choice entry
	 */
	addChoiceEvents: function(el) {
		return el.addEvents({
			mouseover: this.choiceOver.bind(this, [el]),
			mousedown: this.choiceSelect.bind(this, [el])
		});
	}
});

Autocompleter.Base.implement(new Events);
Autocompleter.Base.implement(new Options);

Autocompleter.Local = Autocompleter.Base.extend({

	options: {
		minLength: 0,
		filterTokens : null
	},

	initialize: function(el, tokens, options) {
		this.parent(el, options);
		this.tokens = tokens;
		if (this.options.filterTokens) this.filterTokens = this.options.filterTokens.bind(this);
	},

	query: function() {
		this.hideChoices();
		this.queryValue = this.element.value;
		this.updateChoices(this.filterTokens());
	},

	filterTokens: function(token) {
		var regex = new RegExp('^' + this.queryValue.escapeRegExp(), 'i');
		return this.tokens.filter(function(token) {
			return regex.test(token);
		});
	}

});

Autocompleter.Ajax = {};

Autocompleter.Ajax.Base = Autocompleter.Base.extend({

	options: {
		postVar: 'value',
		postData: {},
		ajaxOptions: {},
		onRequest: Class.empty,
		onComplete: Class.empty
	},

	initialize: function(el, url, options) {
		this.parent(el, options);
		this.ajax = new Ajax(url, $merge({
			autoCancel: true
		}, this.options.ajaxOptions));
		this.ajax.addEvent('onComplete', this.queryResponse.bind(this));
		this.ajax.addEvent('onFailure', this.queryResponse.bind(this, [false]));
	},

	query: function(){
		var data = $extend({}, this.options.postData);
		data[this.options.postVar] = this.element.value;
		this.fireEvent('onRequest', [this.element, this.ajax]);
		this.ajax.request(data);
	},

	/**
	 * queryResponse - abstract
	 *
	 * Inherated classes have to extend this function and use this.parent(resp)
	 *
	 * @param		{String} Response
	 */
	queryResponse: function(resp) {
		this.value = this.queryValue = this.element.value;
		this.selected = false;
		this.hideChoices();
		this.fireEvent(resp ? 'onComplete' : 'onFailure', [this.element, this.ajax], 20);
	}

});

Autocompleter.Ajax.Json = Autocompleter.Ajax.Base.extend({

	queryResponse: function(resp) {
		this.parent(resp);
		var choices = Json.evaluate(resp || false);
		if (!choices || !choices.length) return;
		this.updateChoices(choices);
	}

});

Autocompleter.Ajax.Xhtml = Autocompleter.Ajax.Base.extend({

	options: {
		parseChoices: null
	},

	queryResponse: function(resp) {
		this.parent(resp);
		if (!resp) return;
		this.choices.setHTML(resp).getChildren().each(this.options.parseChoices || this.parseChoices, this);
		this.showChoices();
	},

	parseChoices: function(el) {
		var value = el.innerHTML;
		el.inputValue = value;
		el.setHTML(this.markQueryValue(value));
	}

});


var OverlayFix = new Class({

	initialize: function(el) {
		this.element = $(el);
		if (window.ie6){
			this.element.addEvent('trash', this.destroy.bind(this));
			this.fix = new Element('iframe', {
				properties: {
					frameborder: '0',
					scrolling: 'no',
					src: 'javascript:false;'
				},
				styles: {
					position: 'absolute',
					border: 'none',
					display: 'none',
					filter: 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)'
				}
			}).injectAfter(this.element);
		}
	},

	show: function() {
		if (this.fix) this.fix.setStyles($extend(
			this.element.getCoordinates(), {
				display: '',
				zIndex: (this.element.getStyle('zIndex') || 1) - 1
			}));
		return this;
	},

	hide: function() {
		if (this.fix) this.fix.setStyle('display', 'none');
		return this;
	},

	destroy: function() {
		this.fix.remove();
	}

});


var StringBuffer = new Class({
  initialize: function(str) {
    this.strings = new Array();
    if (str) this.append(str);
  },

  append: function(str) {
    this.strings.push(str);
    return this;
  },

  toString: function() {
    return this.strings.join('');
  },

  isEmpty: function () {
    return this.strings.length == 0;
  }
});

Cookie.extend({
	set: function(key, value, options){
		options = $merge(this.options, options);
		value = encodeURIComponent(value);
		if (options.domain) value += '; domain=' + options.domain;
		if (options.path) value += '; path=' + options.path;
		if (options.duration){
			var date = new Date();
			date.setTime(date.getTime() + options.duration * 24 * 60 * 60 * 1000);
			value += '; expires=' + date.toGMTString();
		}
		if (options.time){
			var date = new Date();
			date.setTime(date.getTime() + options.time * 1000);
			value += '; expires=' + date.toGMTString();
		}
		if (options.secure) value += '; secure';
		document.cookie = key + '=' + value;
		return $extend(options, {'key': key, 'value': value});
	},

	exist: function(key){
		return document.cookie.match('(?:^|;)\\s*' + key.escapeRegExp() + '=([^;]*)') != null;
	}
});

Element.extend({
  getParents: function(selector){
    return $$(selector || '').filter(function(el){
      return (el.hasChild(this));}, this).reverse();
  },

  getParent: function(selector){
    if (!selector) return $(this.parentNode);
    return this.getParents(selector)[0] || this;
  },

  getLastElement: function(selector){
    return $(this.getElements(selector, true).reverse()[0] || false);
  },

  centerOnScreen: function(){
    var s = this.getCoordinates();
    this.style.left = Math.round((Window.getWidth() - s.width) / 2) + Window.getScrollLeft() + 'px';
    this.style.top  = Math.round((Window.getHeight() - s.height) / 2) + Window.getScrollTop() + 'px';
  },

  contains: function(evnt){
    evnt = new Event(evnt);
    var s = this.getCoordinates();
    return (evnt.page.y >= s.top &&
            evnt.page.y <= s.bottom &&
            evnt.page.x >= s.left &&
            evnt.page.x <= s.right);
  },

  overlaps: function(elmt){
    var c = this.getCoordinates();
    var e = elmt.getCoordinates();
    var inH = (e.left > c.left && e.left < c.right) || (e.right > c.left && e.right < c.right);
    var top = e.top > c.top && e.top < c.bottom;
    var btm = e.bottom > c.top && e.bottom < c.bottom;
    return (top && inH) || (btm && inH);
  },

  linkify: function(){
    return this.replaceWith(new Element('a', {'class': this.className, href: 'javascript:;'})).setHTML(this.innerHTML);
  },

  setContent: function(content) {
    if (content instanceof Array) content.each( function(v) { this.adopt($(v)); }, this );
    // IDs are case insensitive in IE
    // don't get an element by id, just check if its already an element
    else if ($type(content) == 'element') this.adopt($(content));
    else this.setHTML(content);
    return this;
  },

  hidden: function() {
    return this.getStyle('display') == 'none';
  },

  show: function() {
    return this.setStyle('display', 'block');
  },

  hide: function() {
    return this.setStyle('display', 'none');
  },

  inDocument: function() {
    return this.parentNode != null && this.parentNode.nodeType != 11;
  }
});

/*
Class: Table

Options:
  properties - (object) properties to set on the table
  rows - (array) table contents
*/
// TODO should this extend element with overrides so it can be injected and so forth?
var Table = new Class({
  options: {
    properties: {
      cellpadding: 0,
      cellspacing: 0,
      border: 0
    },
    rows: []
  },

  initialize: function(options) {
    this.setOptions(options);
    this.table = new Element('table').setProperties(this.options.properties);
    this.tbody = new Element('tbody').injectInside(this.table);
    this.options.rows.each(this.push.bind(this));
  },

  /*
  Property: push
    Add contents to a section of the table.

  Arguments:
    row - (array) content to be added. Each item is a cell.
    section - thead or tfoot, defaults to tbody
    head - (boolean) true to use th instead of td, default is false
  */
  push: function(row, section, head) {
    var tr = new Element('tr').injectInside(section || this.tbody);
    row.each(function (v) {
      var td = new Element(head ? 'th' : 'td').injectInside(tr);
      if (v.properties) td.setProperties(v.properties);
      if (v.content)    td.setContent(v.content);
      else              td.setContent(v);
    });
    return this;
  },

  /*
  Property: pushHead
    Add a row of content to the thead. Uses TRs instead of TDs.

  Arguments:
    row - (array) content to be added. Each item is a cell.
  */
  pushHead: function(row) {
    if (!this.thead) this.thead = new Element('thead').injectTop(this.table);
    this.push(row, this.thead, true);
    return this;
  },

  /*
  Property: pushFoot
    Add a row of content to the tfoot.

  Arguments:
    row - (array) content to be added. Each item is a cell.
  */
  pushFoot: function(row) {
    if (!this.tfoot) this.tfoot = new Element('tfoot').injectInside(this.table);
    this.push(row, this.tfoot);
    return this;
  },

  /*
  Property: pushCaption
  */
  // TODO should be set caption and only allow one
  pushCaption: function(content) {
    new Element('caption').setContent(content).injectTop(this.table);
    return this;
  }
});
Table.implement(new Options);

/*
Class: Autocompleter.Ajax.Json2
  Modified version of Autocompleter.Ajax.Json that uses objects for the response
  instead of a string array.
*/
Autocompleter.Ajax.Json2 = Autocompleter.Ajax.Json.extend({
  updateChoices: function(choices) {
    this.choices.empty();
    this.selected = null;
    if (!choices || !choices.length) return;
    if (this.options.maxChoices < choices.length) choices.length = this.options.maxChoices;
    choices.each(this.options.injectChoice || function(choice, i){
      var el = new Element('li').setHTML(this.markQueryValue(choice.name));
      el.responseObj = choice;
      el.inputValue = choice.name;
      this.addChoiceEvents(el).injectInside(this.choices);
    }, this);
    this.showChoices();
  },

  choiceSelect: function(el) {
    if (el.responseObj.notFound) { this.hideChoices(); return; }
    this.observer.value = this.element.value = el.inputValue;
    this.hideChoices();
    this.fireEvent('onSelect', [this.element, el.responseObj], 20);
  },

  queryResponse: function(resp) {
    this.value = this.queryValue = this.element.value;
    this.selected = false;
    this.hideChoices();
    this.fireEvent(resp ? 'onComplete' : 'onFailure', [this.element, this.ajax], 20);
    var choices = Json.evaluate(resp || false);
    if (!choices || !choices.length) {
      choices = [{ name : JS_location_not_found, value: JS_location_not_found, notFound: true}];
    }
    this.updateChoices(choices);
  }
});

/*
Class: TabSet
  The TabSet class creates a group of elements that are toggled when their handles are clicked. When one element toggles in, the others toggle back.

Arguments:
  togglers - required, a collection of elements, the elements handlers that will be clickable.
  elements - required, a collection of elements the transitions will be applied to.
  options - optional, see options below, and <Fx.Base> options and events.

Options:
  show - integer, the Index of the element to show at start.

Events:
  onActive - function to execute when an element starts to show
  onBackground - function to execute when an element starts to hide
*/
var TabSet = new Class({
  options: {
    onActive: Class.empty,
    onBackground: Class.empty,
    show: 0
  },

  initialize: function() {
    var options, togglers, elements;
    $each(arguments, function(argument, i){
      switch($type(argument)){
        case 'object': options = argument; break;
        default:
          var temp = $$(argument);
          if (!togglers) togglers = temp;
          else elements = temp;
      }
    });
    this.togglers = togglers || [];
    this.elements = elements || [];
    this.setOptions(options);
    this.elements.each(function(el, i){
      this.togglers[i].addEvent('click', this.display.bind(this, i));
      if (this.options.show === i){
        el.show();
        this.previous = i;
        this.fireEvent('onActive', [this.togglers[i], el]);
      } else {
        el.hide();
      }
    }, this);
  },

  /*
  Property: display
    Shows a specific section and hides all others. Useful when triggering a tab from outside.

  Arguments:
    index - integer, the index of the item to show, or the actual element to show.
  */

  display: function(index) {
    if (this.previous || this.previous === 0) {
      this.fireEvent('onBackground', [this.togglers[this.previous], this.elements[this.previous]]);
      this.elements[this.previous].hide();
    }
    this.previous = index;
    this.fireEvent('onActive', [this.togglers[index], this.elements[index]]);
    this.elements[index].show();
    return this;
  }
});
TabSet.implement(new Events, new Options);




var Slider = new Class({

	options: {
		onChange: Class.empty,
		onComplete: Class.empty,
		onTick: function(pos){
			this.knob.setStyle(this.p, pos);
		},
		mode: 'horizontal',
		steps: 100,
		offset: 0
	},

	initialize: function(el, knob, options){
		this.element = $(el);
		this.knob = $(knob);
		this.setOptions(options);
		this.previousChange = -1;
		this.previousEnd = -1;
		this.step = -1;
		this.element.addEvent('mousedown', this.clickedElement.bindWithEvent(this));
		var mod, offset;
		switch(this.options.mode){
			case 'horizontal':
				this.z = 'x';
				this.p = 'left';
				mod = {'x': 'left', 'y': false};
				offset = 'offsetWidth';
				break;
			case 'vertical':
				this.z = 'y';
				this.p = 'top';
				mod = {'x': false, 'y': 'top'};
				offset = 'offsetHeight';
		}
		this.max = this.element[offset] - this.knob[offset] + (this.options.offset * 2);
		this.half = this.knob[offset]/2;
		this.getPos = this.element['get' + this.p.capitalize()].bind(this.element);
		this.knob.setStyle('position', 'relative').setStyle(this.p, - this.options.offset);
		var lim = {};
		lim[this.z] = [- this.options.offset, this.max - this.options.offset];
		this.drag = new Drag.Base(this.knob, {
			limit: lim,
			modifiers: mod,
			snap: 0,
			onStart: function(){
				this.draggedKnob();
			}.bind(this),
			onDrag: function(){
				this.draggedKnob();
			}.bind(this),
			onComplete: function(){
				this.draggedKnob();
				this.end();
			}.bind(this)
		});
		if (this.options.initialize) this.options.initialize.call(this);
	},

	/*
	Property: set
		The slider will get the step you pass.

	Arguments:
		step - one integer
	*/

	set: function(step){
		this.step = step.limit(0, this.options.steps);
		this.checkStep();
		this.end();
		this.fireEvent('onTick', this.toPosition(this.step));
		return this;
	},
	
	setDefault: function(step){
		if (step > this.options.steps) step = this.options.steps;
		else if (step < 0) step = 0;
		this.step = step;
		//this.checkStep();
		this.end();
		this.knob.setStyle(this.p, this.toPosition(this.step)+'px');
		return this;
	},

	scrolledElement: function(event){
		if (event.wheel < 0) this.set(this.step + 1);
		else if (event.wheel > 0) this.set(this.step - 1);
		event.stop();
	},

	clickedElement: function(event){
		var position = event.page[this.z] - this.getPos() - this.half;
		position = position.limit(-this.options.offset, this.max -this.options.offset);
		this.step = this.toStep(position);
		this.checkStep();
		this.end();
		//this.fireEvent('onTick', position);
		this.set(this.step);
	},

	draggedKnob: function(){
		this.step = this.toStep(this.drag.value.now[this.z]);
		this.checkStep();
		this.setDefault(this.step);
	},

	checkStep: function(){
		if (this.previousChange != this.step){
			this.previousChange = this.step;
			this.fireEvent('onChange', this.step);
		}
	},

	end: function(){
		if (this.previousEnd !== this.step){
			this.previousEnd = this.step;
			this.fireEvent('onComplete', this.step + '');
		}
	},

	toStep: function(position){
		return Math.round((position + this.options.offset) / this.max * this.options.steps);
	},

	toPosition: function(step){
		return this.max * step / this.options.steps;
	}

});

Slider.implement(new Events);
Slider.implement(new Options);
/*
Script: Behavior.js
  Behavior rules and related functions.
  Contains: <Behavior>
*/

var rules = {};

/*
Class: Behavior
  Custom class to help manage behavior stylish rules. Use register to register
  rules at page loading. Use reload to re-apply rules on element updated after
  an AJAX update.
 */
var Behavior = new Class({
  /*
  Property: register
    Applies the rules to the current DOM.

  Arguments:
    rules - (array) map of selectors to the functions that operate on them
  */
  register: function(rules){
    this.rules = rules;
    for (var i in this.rules) {
      this.reload(i);
    }
    return this;
  },

  /*
  Property: reload
    Applies a single rule to the current DOM

  Arguments:
    rule - (string) selector that should be applied
  */
  reload: function(rule){
    elements = $$(rule);
    for(y=0;y<elements.length;y++){
      this.rules[rule](elements[y]);
    }
  },

  apply: function(elmt){

    // Process links - don't use rules[] because it is too slow for links.
    processLinks(elmt);

    for (var rule in this.rules) {
      window.applyLastRule = rule;
      elmt.getElements(rule).each(function(e){
        this.rules[rule](e);
      }, this);
    }
  }
});


// func: doCookieCheck
//   Checks that none of the newsletter cookies are set.
//
// Returns:
//   true if none of the cookies are set, false otherwise
//
function doCookieCheck()
{
    if(Cookie.get('NLPB'))    { return false; }
    if(Cookie.get('NLPS'))    { return false; }
    if(Cookie.get('NLPP'))    { return false; }

    // Session cookies not accepted
    Cookie.set('NLPS', 'true', {duration: 0});
    if(!Cookie.get('NLPS'))    { return false; }
    Cookie.set('NLPP', 'true', {duration: 1/2});
    return true;
}

window.addEvent('load', function() {
  Cookie.remove('NPID');
  if (window.showPopup) showPopup();
  if (typeof showRedesignPopup != "undefined") {
      showRedesignPopup();
  }

  var c = Cookie.get('ajaxAction');
  if (c) {
    Cookie.remove('ajaxAction', {domain:cookieDomain, path:"/"});
    c = c.split('|');
    window[c[0]](c[1]);// 0 - function to call, 1 - parameter as a string
  }

  // Firefox and Safari calculate the scroll offset before content is collapsed
  // so make sure to scroll to the proper place once everything is loaded
  if (window.gecko || window.webkit) { 
    var id = window.location.hash;
    if (id.length > 1) id = id.substring(1);
    var t = $(id);
    if (t && t.getTop() != window.getScrollTop()) window.scrollTo(0, t.getTop());
  }
});

// Define the ready event - the point at which to load the behavior.
// This may need to be load instead of domready with cerain badly-behaving ads.
TAReadyEvent = window.TAReadyEvent || "domready";

// apply the rules when the DOM is ready.
window.addEvent(TAReadyEvent, behaviorFunction);

function behaviorFunction()
{
  // hide some elements
  if (window.hideOnLoad) $A(hideOnLoad).each(function(v){ var x = $(v); if (x) x.hide(); });

  // Process links - don't use rules[] because it is too slow for links.
  processLinks(document);

  // register the rules
  window.behavior = new Behavior().register(rules);

  // setup a tab set if need be
  var initTab = 0;
  if (window.location.hash && (hash = window.location.hash.match(/t(\d)/))) initTab = parseInt(hash[1]);
  var tabs = $$('#HOMEPAGE .perfecttrip .tabs h2');
  if ( tabs.length > 0 ) {
    var elmts = $$('#HOMEPAGE .perfecttrip .tripforms .interior');
    new TabSet(tabs, elmts, {
      show: initTab,
      onActive: function(toggler, element) {

        // fetch content via AJAX
        var t = element.getElement('a.src');
        if (t) 
        {
         // Set content to placeholder graphic
          var imgCntr = new Element('div', { 'class': 'progresstab' } );
          (new Asset.image(img_loop)).injectInside(imgCntr);
          imgCntr.injectInside(element);

          // Make AJAX call to get content.
          new Ajax(t.href, {
            onComplete: function(txt, xml) { 
                element.empty();
                element.innerHTML = txt;
                window.behavior.apply(element); 
              } // apply any defined behavior
            }).request();
        }

        toggler.addClass('current');
      },
      onBackground: function(toggler, element) {
        toggler.removeClass('current');
      }
    });
  }
  
  // setup the accordion(s) if need be
  var elmts = $$('#DEST_HOME #DEST_ACCORDION .pane');
  if ( elmts.length > 0 ) {
    window.accordion = new Accordion('#DEST_ACCORDION .window', elmts, {
      show: -1, // element to show by default
      //display: 0, // element to show by default w/ transition - requires onload instead of domready
      //fixedHeight: true, // force fixed height
      //fixedWidth: true, // force fixed width
      //height: false, // use height transition
      opacity: false, // use opacity transition
      //alwaysHide: true, // allow to hide all elements
      onActive: function(toggler, element) {
        var d = element.getElement('.preview');
        if (d) {d.remove();}// in case the user clicks the dt and not the preview layer
        toggler.addClass('active');
        element.addClass('active');
      },
      onBackground: function(toggler, element) {
        toggler.removeClass('active');
        element.removeClass('active');
      }
    });

    // setup 'preview' state
    window.accordion.preview = true;
    window.accordion.hovers = [];
    elmts.each(function(elmt, x) {
      // add hover layer
      var c = elmt.getCoordinates();
      var d = new Element('div', {
        'class': 'preview',
        events: {
          click: function(e) {
            // this click doesn't propagate to catch flyouts apparently...
            if (window.flyout) window.flyout.hide();
            if (window.ie6) elmt.getElements('select').setStyle('visibility', 'visible');
            window.accordion.hovers.each( function(elmt) {elmt.remove();} );
            window.accordion.display(x);
          },
          mouseenter: function() {
            if (window.ie6) elmt.getElements('select').setStyle('visibility', 'hidden');
            this.setOpacity(0.6).addClass('hover');// bloody IE6...
          },
          mouseleave: function() {
            if (window.ie6) elmt.getElements('select').setStyle('visibility', 'visible');
            this.setOpacity(0.01).removeClass('hover');
          }
        }
      }).setOpacity(0.01).setHTML('<span>' + JS_click_to_expand + '</span>').injectInside(elmt);
      window.accordion.hovers.push(d); 
      c = d.getCoordinates();
      elmt.setStyles({
        height: c.height + 'px',// let the CSS control the preview height
        // have to set these explicitly on the element because the Accordion JS does, too.
        visibility: 'visible'
      });
    });
  }
  
  // setup SIS Accordion ( no preview )
  // this needs to happen after the preview accordion above for IE6 to render correctly
  var sisAccordionElements = $$('#SIS_ACCORDION .pane');
  if ( sisAccordionElements.length > 0 )
  {
	
	// get the orignal heights of each pane
  	var overflowElements = {};
  	sisAccordionElements.each(function(elmt,x){
  		overflowElements[x] = elmt.getStyle('height').toInt();
	});
	
	// show the first pane with content
	var showIndex = 0;
	for (var i=0; i<sisAccordionElements.length; i++)
	{
		if (sisAccordionElements[i].getElement('.sisContribution'))
		{
			showIndex = i;
			break;			
		}
	}

	window.sisAccordion = new Accordion('#SIS_ACCORDION .window', sisAccordionElements, {
	  show: showIndex,
      opacity: false, // use opacity transition
      fixedHeight: 160,
      onActive: function(toggler, element) {
        toggler.addClass('active');
        element.addClass('active');
      },
      onBackground: function(toggler, element) {
        toggler.removeClass('active');
        element.removeClass('active');
      }
    });
	
	// Change overflow and height dynamically
	window.sisAccordion.elements.each(function(elmt,x){
		// give it a scroll bar
		if (overflowElements[x] > window.sisAccordion.options.fixedHeight)
		{
			elmt.setStyle('overflow-y', 'auto');
			elmt.setStyle('overflow-x', 'hidden');
		}
		// make the height the size of the content
		else
		{
			elmt.fullHeight = overflowElements[x];
		}
		
		// make sure the initial pane is the right height
		if (x == window.sisAccordion.options.show)
		{
			elmt.setStyle('height', elmt.fullHeight);
		}
		
		// BUG 22422
		// IE6 sucks so we have to apply the offset after the DEST_HOME accordion
		// or else it doesn't refresh the preview pane for some elements.
		// Even accessing the offsetTop property earlier than this causes this bug	
		var flyoutsL = $$('#SIS_ACCORDION .flyoutL');
		flyoutsL.each(function(f,i){
			f.flyout.setOptions({offsets: {x:0, y:-1*f.offsetTop-16}});
		});
		
		var flyouts = $$('#SIS_ACCORDION .flyout');
		flyouts.each(function(f,i){
			f.flyout.setOptions({offsets: {x:4, y:-1*f.offsetTop-16}});
		});
	});
	
	// pad if we're in the left nav and have overflow
	var sisPaddingElements = $$('#LEFTNAV #SIS_ACCORDION .pane');
	sisPaddingElements.each(function(elmt, x){
		if (overflowElements[x] > window.sisAccordion.options.fixedHeight)
		{
			elmt.setStyle('width', '166px');
			var sisPaddingNums = elmt.getElements('.num');
			sisPaddingNums.each(function(num, i)
			{
				num.setStyle('padding-right', '20px');
			});
		}
 	});

  }
}

/*
Function: popup
  Show a poup window. The event target (or one of its ancestors) should be a
  link. The href of the link will be used as the URL of the popup

Arguments:
  e       - the event
  width   - width of the popup
  height  - height of the popup
  x       - horizontal screen offset
  y       - vertical screen offset
 */
var popupIndex = 0;
function popup(e, name, width, height, x, y, noScroll, buildUrl, allOptions)
{
  new Event(e).preventDefault();
  var ops = "";
  if (sz = this.className.match(/sz(\d+)x(\d+)/)) {
    width = sz[1];
    height = sz[2];
  }
  if (width) ops += ",width="+width;
  if (height) ops += ",height="+height;
  if (x) ops += ",screenX="+x+",left="+x;
  if (y) ops += ",screenY="+y+",top="+y;
  if (ops != "") {
    if (allOptions) {
      ops = "toolbar=1,resizable=1,menubar=1,location=1,status=1,scrollbars=1" + ops;
    }
    else {
      ops = "toolbar=0,resizable=1,menubar=0,location=0,status=0,scrollbars=" + (noScroll ? 0 : 1) + ops;
    }
  }
  var w = window.open(buildUrl ? buildUrl : this.href, name || "p"+window.name+(popupIndex++), ops);
  if (w != null)
  {
    w.opener = self;
    w.focus();
  }
}

// 'this' is the element
function formSubmit(e)
{
  new Event(e).preventDefault();
  this.click();
}

function unobf(uri)
{
  return (uri.substring(0,8) == "NOFOLLOW" ? "http://" + uri.substring(8) : "/" + uri) + ".html";
}

/*
Function: toggle
  Toggle the class (default: 'off') of the element this function is bound to.
*/
function toggle(e) {new Event(e).preventDefault(); this.toggleClass('off');}

/* Some generic rules
   ---------------------------------------------------------------------------------------------- */

function addPIDOnclick(elmt, pid) {elmt.addEvent('click', function() {Cookie.set('NPID', pid, {time:5});});}

/* All Link rules in one function for performance */
function processLinks(root) 
{
  var aTags = root.getElementsByTagName('a');
  for(i = 0; i < aTags.length; i++) 
  { 
    var element = aTags[i]; 

    // Skip links with no class attribute or one without behavior.
    if (element.className == '') { continue; }
    if (element.className == 'src') { continue; }

    var classes = element.className.split(' ');
    var elmt = false;
    for(var j = 0; j < classes.length; j++) {
      // Check pids
      if (classes[j].length > 3 && (classes[j].substring(0, 3) == 'pid')) {
        var pid = classes[j].substring(3);
        if (!elmt) { elmt = $(element) };
        addPIDOnclick(elmt, pid);
      }
      else {
        var f = linkMap[classes[j]];
        if (f) { 
          if (!elmt) { elmt = $(element) };
          f(elmt);
        }
      }
    }
  }
}

var linkMap = {};

linkMap['close'] = function(elmt) { 
  elmt.addEvent('click', function() {$(elmt.rel).style.display = 'none'});
};

linkMap['dhtmlclose'] = function(elmt) { 
  elmt.addEvent('click', function() {$('DHTMLPOPUP').remove(); if($('dhtmlPopupIframe'))$('dhtmlPopupIframe').remove();});
};

// submit forms via AJAX
linkMap['ajaxSubmit'] = function(elmt) {
  var uri = elmt.href;
  var form = elmt.className.match(/\bform_(\w+)\b/);
  if (!form) return;
  form = $(form[1]);
  elmt.addEvent('click', function(e) {
      new Event(e).preventDefault();
      new Ajax(uri, {
        data: form,
            onComplete: showInLightbox,
            onFailure: function(e) { alert(e.status + "\n" + e.responseText); }
        }).request();
    });
};

linkMap['ajax'] = function(elmt) {
  elmt.addEvent('click', function(e) {
      new Event(e).preventDefault();
      if (!(tgt = elmt.className.match(/\btgt_(\w+)\b/))) return;// target is required
      tgt = $(tgt[1]);
      new Ajax(elmt.href, {
        update: tgt,
            onFailure: function(e) { alert(e.status + "\n" + e.responseText); }
        }).request();
    });
};

// like 'ajax', but expected to log-in first
linkMap['ajaxlogin'] = function(elmt) {
  elmt.addEvent('click', function(e) {
      new Event(e).preventDefault();
      if (!(tgt = elmt.className.match(/\btgt_(\w+)\b/))) return;// target is required
      var alHref = elmt.href;
      tgt = $(tgt[1]);
      new Ajax(elmt.href, {
            onComplete: function(txt, xml) {
                var bWasLoggedIn = (txt.indexOf('<!--nologin-->')<0);
                if(!bWasLoggedIn)
                {
                    login(['tt','ajax','returnTo', alHref + "&rd=1", 'greeting', 'showuserreviews_vote_25ee' ]);
                }
                else
                {
                    tgt.innerHTML = txt;
                }
            },
            onFailure: function(e) { alert(e.status + "\n" + e.responseText); }
        }).request();
    });
};


linkMap['ajaxMsg'] = function(elmt) {
  elmt.addEvent('click', ajaxMsg.bindAsEventListener(elmt));
};

linkMap['ajaxReport'] = function(elmt) {
  elmt.addEvent('click', ajaxReport.bindAsEventListener(elmt));
};

// open links in popups of various sizes
linkMap['popup'] = function(elmt) {  elmt.addEvent('click', popup.bindAsEventListener(elmt));};
linkMap['popNoScroll'] = function(elmt) {  elmt.addEvent('click', popup.bindAsEventListener(elmt, [null, null, null, null, null, true]));};
linkMap['popCR'] = function(elmt) {  elmt.addEvent('click', popup.bindAsEventListener(elmt, ['cr',          245, 610, 5, 5]));};
linkMap['email'] = function(elmt) {  elmt.addEvent('click', popup.bindAsEventListener(elmt, ['email',       580, 460, 30, 25]));};
linkMap['terms'] = function(elmt) {  elmt.addEvent('click', popup.bindAsEventListener(elmt, ['terms',       300, 300, 30, 25]));};
linkMap['popReview'] = function(elmt) { elmt.addEvent('click', popup.bindAsEventListener(elmt, ['review',      550, 395, 30, 25]));};
linkMap['popPhoto'] = function(elmt) { elmt.addEvent('click', popup.bindAsEventListener(elmt, ['photo',       650, 350]));};
linkMap['popGallery'] = function(elmt) { elmt.addEvent('click', popup.bindAsEventListener(elmt, ['media',       780, 705]));};
linkMap['popDMO'] = function(elmt) { elmt.addEvent('click', popup.bindAsEventListener(elmt, ['dmo',         400, 400]));};
linkMap['popNxTall'] = function(elmt) { elmt.addEvent('click', popup.bindAsEventListener(elmt, [               330, 680]));};
linkMap['popNxWide'] = function(elmt) { elmt.addEvent('click', popup.bindAsEventListener(elmt, [               730, 380]));};
linkMap['popDestGd'] = function(elmt) { elmt.addEvent('click', popup.bindAsEventListener(elmt, ['dest_guide',  545, 680, (screen.width-700)/2, (screen.height-600)/2]));};

linkMap['popSmall'] = function(elmt) {
  if (screen.width > 1024)     { elmt.addEvent('click', popup.bindAsEventListener(elmt, [null, 800, 600, 240, 5, false, false, true])); }
  else if (screen.width > 800) { elmt.addEvent('click', popup.bindAsEventListener(elmt, [null, 620, 500, 240, 5, false, false, true])); }
  else                         { elmt.addEvent('click', popup.bindAsEventListener(elmt, [null, 475, 390, 210, 5, false, false, true])); }
};

linkMap['popRef'] = function(elmt) {
  if (!(classInfo = elmt.className.match(/\bg(\d+)\b\s+\br(\d+)\b\s+\bd(\d+)\b/))) return;
  geoId = parseInt(classInfo[1]);
  locId = parseInt(classInfo[2]);
  detId = parseInt(classInfo[3]);
    
  if (classInfoCommerce = elmt.className.match(/\s+\ba(\w+)\b/))
  {
    comId = classInfoCommerce[1];
  }
  comText = typeof comId != "undefined" ? "-a_area."+comId : "";
  buildUrl = '/ShowUrl-g' + geoId + '-r' + locId + '-d' + detId + comText +'.html';
  var w = 475;
  var h = 390;
  var x = 210;
  if (screen.width > 1024) { w = 800; h = 600; x = 240; }
  else if (screen.width > 800) { w = 620; h = 500; x = 240; }
  elmt.addEvent('click', popup.bindAsEventListener(elmt, [null, w, h, x, 5, null, buildUrl, true]));
};

linkMap['notImpl'] = function(elmt) {
  elmt.addEvent('click',
                function(e) {
                  var e = new Event(e); e.preventDefault();
                  alert("This feature has not yet been implemented:\n\n"+elmt.title);
                }
                );
};

linkMap['noTAPD'] = function(elmt) { elmt.addEvent('click', function() {Cookie.remove('TAPD', {domain: cookieDomain});});};

linkMap['modifySub'] = function(elmt) { elmt.addEvent('click', modifySub.bindAsEventListener(elmt));};

linkMap['delay'] = function(elmt) {
  if (!(ms = elmt.className.match(/\b(\d+)ms\b/))) return;
  ms = parseInt(ms[1]);
  elmt.fireEvent('click', null, ms);
};

// TODO: remove this once the new dhtml popup framework gets out of pool testing
linkMap['figsSurveyLink']=function(elmt) {
  elmt.addEvent('click', function() {
  	Cookie.set('TAPanelSurveyPopup', '-1', {domain:cookieDomain, path:"/", duration:365});
  });	
}

// submit buttons get reworked to look like other buttons
// <div class="button"><div><span><b><a></a></b></span></div></div>
rules['input[type=submit]'] = function(elmt) {
  var b = new Element('div', {'class': 'button'});
  new Element('a', {href: 'javascript:;',
    events:{'click': formSubmit.bindAsEventListener(elmt)}
    }).injectInside(
    new Element('b').injectInside(
      new Element('span').injectInside(
        new Element('div').injectInside(b)))).innerHTML = elmt.value;
  b.injectAfter(elmt);
  elmt.hide();
}

// text elements with class 'focusClear' have their value cleared on focus if it is the default value
rules['input.focusClear[type=text]'] = function(elmt) {
  elmt.addEvent('focus', function() {if (elmt.value == elmt.defaultValue) elmt.value = '';});
}

// text elements with class 'haltIfEmpty' cause form submission to fail if the value is empty
rules['input.haltIfEmpty[type=text]'] = function(elmt) {
  $(elmt.form).addEvent('submit', function(e) {if (elmt.value == '') (new Event(e)).stop();});
}

// text elements with class 'alertIfEmpty' cause form submission to fail and an alert to be shown if the value is empty
rules['input.alertIfEmpty[type=text]'] = function(elmt) {
  $(elmt.form).addEvent('submit', function(e) { if (elmt.value == '') {
     if(msg = elmt.className.match(/\bmsg_([\w\d]+)\b/)) {
        alert(window[msg[1]]);
     } else {
        alert('The field can not be empty'); // input fields should instead use a localization key
     }
     (new Event(e)).stop();
   }});
}

rules['input.haltIfUnchanged[type=text]'] = function(elmt) {
  $(elmt.form).addEvent('submit', function(e) {if (elmt.value == '' || elmt.value == elmt.defaultValue) (new Event(e)).stop();});
}

rules['select.submitOnChange'] = function(elmt) {
  elmt.addEvent('change', function() {elmt.form.submit();});
}

rules['span.dsrc'] = function(elmt) 
{ 
  var elmtP = elmt.getParent();
  // Make AJAX call to get content -delay it 10ms to let IE process the rest of the JS first.
  (function () {
    new Ajax('/' + elmt.innerHTML + '.html', {
      update: elmtP,
      onComplete: function(txt, xml) { window.behavior.apply(elmtP);  } // apply any defined behavior
      }).request();
  }).delay(10);
}

// call bound to a SELECT
var openValueInNew = function(e) {
  var uri = this.options[this.selectedIndex].value;
  if (uri.length == 0) return;
  var parts = uri.match(/(\d+):(.*)/);
  if (parts) {
    setPID(parseInt(parts[1]));
    uri = parts[2];
  }
  var w = window.open(uri, "p"+window.name+(popupIndex++));
  if (w != null)
  {
    w.opener = self;
    w.focus();
  }
}

rules['select.redirOnChange'] = function(elmt) {
  elmt.addEvent('change', openValueInNew.bindAsEventListener(elmt));
}

// clicking the 'search within' checkbox should set the 'exc' form field to 'n' when selected, 'y' otherwise
//rules['.navSrch input#geo'] = function(elmt) {
//  elmt.addEvent('change', function() {$('exc').value = elmt.checked ? 'n' : 'y';});
//}

// collapsible content - hide initially
rules['div.toggle'] = function(elmt) {
  elmt.toggleClass('off');
  // convert show/hide spans to links
  elmt.getElement('.show').linkify().addEvent('click', toggle.bindAsEventListener(elmt));
  elmt.getElements('.hide').each(function(v){v.linkify().addEvent('click', toggle.bindAsEventListener(elmt))});
}

// Nexus - subscribe/unsubscribe
var modifySub = function(e) {
  (new Event(e)).preventDefault();
  var elmt = this;
  new Json.Remote(this.href, {
    onFailure: function(e) { alert(e.status + "\n" + e.responseText); },
    onComplete: function(rslt) {
      if (rslt && rslt.debug && rslt.editErrorTag)
        alert("Error during ajax call, \nTag: " + rslt.editErrorTag + "\nMsg: " + rslt.editErrorMessage + "\nContent: " + data.editErrorContent);
      else if (rslt.readonly) document.location = rslt.maintenanceUrl;
      else if (rslt.loginUrl) document.location = rslt.loginUrl;
      else {
        var i = elmt.getParent().id;
        if (/^un/.test(i)) i = i.substring(2);
        else i = "un" + i;
        elmt.getParent().hide();
        $(i).show();
      }
    }
  }).send();
}

// type ahead
rules['input.typeAhead[type=text]'] = function(elmt) {
  if (action = elmt.className.match(/\bact(\w+)\b/)) {
    new Autocompleter.Ajax.Json2(elmt, "/TypeAheadJson?action="+action[1], {
      ajaxOptions: {method:'get'},
      postVar: 'query',
      inheritWidth: false
    });
  }
}
rules['input.flightTypeAhead[type=text]'] = function(elmt) {
  if (action = elmt.className.match(/\bact(\w+)\b/)) {
    new Autocompleter.Ajax.Json2(elmt, "/TypeAheadJson?action="+action[1], {
      ajaxOptions: {method:'get'},
      postVar: 'query',
      className: 'autocompleter-choices flights',
      inheritWidth: false,
      onSelect: function(elmt, resObj) {elmt.value = resObj.value}
    });
  }
}
rules['input.attractionTypeAhead'] = function(elmt) {
  if (action = elmt.className.match(/\bact(\w+)\b/)) {
    new Autocompleter.Ajax.Json2(elmt, "/TypeAheadJson?action="+action[1], {
      ajaxOptions: {method:'get'},
      postVar: 'query',
      inheritWidth: false,
      onSelect: function(elmt, resObj) {
        $('attractionCityGeoId').value = resObj.value;
        updateAttractionCategory(resObj.broad);
      }
    });
  }
}

rules['#ATTRACTION_FORM'] = function(elmt) {
  elmt.addEvent('submit', function(e) {
    if (!attractionFormOnSubmit()) { (new Event(e)).stop(); }
  });
}

rules['#CRUISE_CRITIC_REVIEWS_FORM'] = function(elmt) {
  elmt.addEvent('submit', function(e) {
    if (!cruiseCriticReviewFormOnSubmit()) { (new Event(e)).stop(); }
  });
}

rules['#PM_UNBLOCK'] = function(elmt) {
  elmt.addEvent('submit', function(e) {
    new Event(e).stop();
    var form = $('PM_UNBLOCK');
    if (form.unblock.value == '1') {
      new Ajax('/SendMessageRD', {
        data: form,
        onComplete: showInLightbox,
        onFailure: function(e) { alert(e.status + "\n" + e.responseText); }
      }).request();
    }
    else {
      $('unblock-intercept').hide();
      $('blockedreply').show();
      form.unblock.value = '1';
    }
  });
}

var showInLightbox = function(txt) {
  // hide any flyout that's open
  if (window.flyout) window.flyout.hide();
  // if there is a currently visible lightbox, use it
  if (window.lightbox && window.lightbox.inner) {
    window.lightbox.inner.setContent(txt);
    window.lightbox.actions();
  } else {
    new Lightbox(txt).activate();
  }
}

function enableCommunity(callback, noHandle)
{
  var res = callback;
  if (!noHandle) res = function(r) {enableCommunityResponse(r, callback);}
  new Ajax("/CommunityAjax?action=CommunitySet&set=on", {
    onComplete: res,
    onFailure: function(e) { alert(e.status + "\n" + e.responseText); }
  });
}

function enableCommunityResponse(res, callback) {
  var in_data = eval("(" + res.responseText + ")");
  if (in_data.error) {
    document.getElementById('inviteStatusField').innerHTML = in_data.error;
    document.getElementById('inviteStatusField').style.display='block';
  } else if (in_data.response) {
    document.getElementById('inviteStatusField').innerHTML = in_data.response;
    document.getElementById('inviteStatusField').style.display='block';
    //setTimeout(function() {hide('confirmBubble'); callback();}, 1000);
  }
}

var communityLightbox = function(uri) {
  if (!userLoggedIn || migrationMember) return;
  if (!communityEnabled) {
    var callback = function() {communityEnabled = true; window.lightbox.deactivate(); communityLightbox(uri);};
    var aSMC = new StringBuffer();
    aSMC.append('<p id="inviteStatusField" style="display: none; color: red;"></p>');
    aSMC.append('<p>'+JS_mem_travelnet_friends_disabledM2M+'.</p>'); // You have disabled member-to-member communications
    aSMC.append('<p><a href="javascript:void(0)" onclick="enableCommunity(callback, true); return false;">'+JS_common_Clickhere+'</a> '+JS_mem_travelnet_friends_turnOn+'.</p>'); // Click here to turn the feature back on and send your message
    showInLightbox(aSMC);
    return;
  }
  new Ajax(uri, {
    onComplete: showInLightbox,
    onFailure: function(e) { alert(e.status + "\n" + e.responseText); }
  }).request();
}

function getRelativeURL() {
  return window.location.pathname + window.location.search + (window.location.hash.length > 0 ? '#' : '') + window.location.hash;
}

var ajaxMsg = function(e) {
  new Event(e).preventDefault();
  if (!userLoggedIn || migrationMember) {
    if (!(ops = this.className.match(/\bpm(\d)([A-F0-9]+)\b/))) return;
    var msgType = parseInt(ops[1]) == 1 ? "cc" : "cm";
    var greeting = msgType == "cm" ? "m2m_singin_greeting_d99" : "";
    var uid = ops[2];
    Cookie.set('ajaxAction', "communityLightbox|" + this.href, {domain:cookieDomain, path:"/"});
    var func = !userLoggedIn ? login : migrate;
    func(['tt',msgType,'greeting',greeting,'returnTo', getRelativeURL()]);
    return;
  }
  communityLightbox(this.href);
}

var ajaxLightbox = function(uri) {
  new Ajax(uri, {
    onComplete: showInLightbox,
    onFailure: function(e) { alert(e.status + "\n" + e.responseText); }
  }).request();
	
}

var ajaxReport = function(e) {
  new Event(e).preventDefault();
  ajaxLightbox(this.href);
}

rules['#REVIEWS .fkLnk,#PERSPECTIVES .fkLnk,#TOURISM_REVIEWS .fkLnk'] = function(elmt) {
  var id = elmt.className.match(/\bt([\w\d]+)\b/);
  if (!id) return;
  elmt.linkify().setProperty('href', $(id[1]).href);
}

rules['#sheraton area'] = function(elmt) {
  var pid = elmt.className.match(/\bpid(\d+)\b/)
  if (pid) elmt.addEvent('click', function() {Cookie.set('NPID', pid[1], {time:5});});
  if (elmt.hasClass('popup')) {elmt.addEvent('click', popup.bindAsEventListener(elmt));}
}

rules['#dhtmlPopupClose']=function(elmt) {
  elmt.addEvent('click', function() {
  	 $('DHTMLPOPUP').remove();
     $('dhtmlPopupIframe').remove();
   });
}

var reviewRating = new Class(
{
	initialize: function(userId, rating) 
	{
		this.userId = userId;
		this.rating = rating;
	}
});

// creates a "How useful was this translation?" slider. when the value of this slider
// is changed, it adds the (userid, value) pair to ratingsToSubmit, to be submitted
// when the user leaves the page
var ratingsToSubmit = {}; 
rules['.usefulReview'] = function(elmt) 
{
	var containerDiv = elmt.getElement('.usefulReviewContainer');
	var sliderDiv = elmt.getElement('.usefulReviewSlider');
	var srcSpan = elmt.getElement('.userfulReviewSrc');
	var userIdSpan = elmt.getElement('.userfulReviewUserId');
	var thankYouDiv = elmt.getElement('.usefulReviewThankYou');
	if (containerDiv && sliderDiv && srcSpan && userIdSpan && thankYouDiv)
	{
		var src = srcSpan.innerHTML;
		var userId = userIdSpan.innerHTML;
		var slider = new Slider(containerDiv, sliderDiv,
								{ 
									onChange: function(val)
												{
													var value = new reviewRating(userId, val + 1);
													ratingsToSubmit[src] = value;
													thankYouDiv.style.display = 'block';
												},
									steps: 4,
									offset: 10
								}
								);
		slider.setDefault(2);						
	}		
}

// used to submit the page when the user toggles "Original in <language>" or "Automatic Translation" radio buttons
// have to use the onclick event because IE6 doesn't handle onChange properly with radio buttons
rules['input.submitOnClick[type=radio]'] = function(elmt)
{
  elmt.addEvent('click', function() 
  	{
  		elmt.form.submit();
  	});
}

// adds the submitRatings function to the unload event handler
var rateUrl = null;
rules['input.sliderRatingUrlClass'] = function(elmt)
{
	rateUrl = $(elmt).value; 
	window.addEvent('unload', submitRatings);
}

// submits the ratings for any sliders a user moved
function submitRatings()
{
	if (ratingsToSubmit && rateUrl)
	{
		var ratings = '';
		$each(ratingsToSubmit, function(idAndRating, src)
		{
			ratings += src + ',' + idAndRating.userId + ',' + idAndRating.rating + '-';
		});
			
		if (ratings != '')
		{
			// submit the ratings
			rateUrl += ratings;
  			new Ajax(rateUrl).request();		
		}
		
		// reset the map
		ratingsToSubmit = {};		
	}
}

rules['input.memberUpdateEmail[type=text]']=function(elmt) {
  $('memberUpdatesEmailDefault').hide();
  $(elmt.form).addEvent('submit', function(e) {
  	if(elmt.value == $('memberUpdatesEmailDefault').innerHTML)
  	{
  		elmt.value = ""; 		
  	}
  });
}

// Name of the cookie used to track the distance units for "Nearby Locations"
var distanceUnitsCookieName = "TAdistanceCookie";

// Shows distances in km for "Nearby Locations"
function showKm()
{
	$$('#NEARBY .kmOption').each(function(item, index)
	{
		item.checked = true;
	});
	
	$$('#NEARBY .milesLabel').each(function(item, index)
	{
		$(item).removeClass('selected');
	});

	$$('#NEARBY .kmLabel').each(function(item, index)
	{
		$(item).addClass('selected');
	});	
	
	$$('#NEARBY .distanceMiles').hide();
	$$('#NEARBY .distanceKm').show();
	
	Cookie.set(distanceUnitsCookieName, 1);
}

// Shows distances in mi for "Nearby Locations"
function showMi()
{
	$$('#NEARBY .milesOption').each(function(item, index)
	{
		item.checked = true;
	});

	$$('#NEARBY .milesLabel').each(function(item, index)
	{
		$(item).addClass('selected');
	});

	$$('#NEARBY .kmLabel').each(function(item, index)
	{
		$(item).removeClass('selected');
	});

	$$('#NEARBY .distanceMiles').show();
	$$('#NEARBY .distanceKm').hide();
	
	Cookie.set(distanceUnitsCookieName, 0);		
}

// Selects the proper distance unit based on the value of the hidden form element (0 is miles, 1 is km)
rules['#NEARBY #nearbyDistanceUnits']=function(elmt) 
{
	if ($(elmt).value == 0)
	{
		showMi();
	}
	else
	{
		showKm();
	} 
}

// Hides the "booking" section under a review if it is empty
rules['#REVIEWS .booking']=function(elmt)
{
	var showBookingInput = $(elmt).getElement('input.showBookingInput');
	if (showBookingInput)
	{
		var sShowBooking = showBookingInput.value;
		if (sShowBooking == "false")
		{
			elmt.hide();
		}
	}
}
/*
Script: flyout.js
  Flyout class and related behavior rules.
  Contains: <Flyout>
*/

var POS = {TOP:0, RIGHT:1, BOTTOM:2, LEFT:3};

/*
Class: Flyout
  Spawns a flyout on the page from a target. If the element has a child with the class
  'flyoutContents', its contents will be used for the flyout. Otherwise, the href of the
  first 'A' child will be used to request the content via AJAX. By default flyouts are
  triggered on click. Clicking the spawning element a second time, or anywhere outside
  the flyout, will close the flyout. If the bound option is set, flyouts instead show on
  mouse enter, and disappear when the mouse leaves either the element or the flyout.

Arguments:
  elmt - required, the element that should spawn the flyout.
	options - optional, see options below.
  content - optional, content to use in the flyout (overrides flyoutContents and AJAX request).

Options:
  offsets - (array) x and y offsets, default: [0,0]
  arrowPosition - one of: POS.TOP, POS.RIGHT, POS.BOTTOM, POS.LEFT, default: POS.TOP
  showClose - (boolean) whether or not to show the close link in the flyout, default: true
  bound - (boolean) if true, the flyout is on mouseenter and hidden when the mouse leaves the
    spawning elements or the flyout, default: false
  showArrow - (boolean) whether or not to show the arrow, default: true
  autoSpawn - (boolean) whether or not events should be added to cause the flyout to show and hide.
    Note if this is set to false, you will have to manually call show and hide.
  centerArrow - (boolean) true to center the arrow, otherwise defaults to top/left
*/
var Flyout = new Class({
  options: {
    offsets: {x:0, y:0},
    arrowPosition: 2,
    showClose: true,
    bound: false,
    showArrow: true,
    arrowClass: 'arrow',
    autoSpawn: true,
    flyoutClass: null,
    limit: 0,
    centerArrow: false
  },

  initialize: function(elmt, options, content) {
    this.elmt = elmt;
    this.setOptions(options);

    if (pos = elmt.className.match(/\bpos(Left|Right|Top|Bottom)\b/)) {
      this.options.arrowPosition = POS[pos[1].toUpperCase()];
      // reset offsets if overriding position
      this.options.offsets = {x:0, y:0};
    }
    if (off = elmt.className.match(/\bol(-?\d+)/)) this.options.offsets.x = parseInt(off[1]);
    if (off = elmt.className.match(/\bot(-?\d+)/)) this.options.offsets.y = parseInt(off[1]);

    if (!options.arrowClass && this.options.arrowPosition != POS.BOTTOM) {
      if (this.options.arrowPosition == POS.RIGHT) this.options.arrowClass = 'arrowLeft';
      else if (this.options.arrowPosition == POS.TOP) this.options.arrowClass = 'arrowBottom';
      else this.options.arrowClass = 'arrowRight';
    }

    if (content) this.content = content;
    else {
      this.content = this.elmt.getElement('.flyoutContents');
      if (this.content) this.content = this.content.getChildren().remove();
      else {
        // fetch content via AJAX
        var t = this.elmt.getElement('a.src');
        if (t) {
          // set content to placeholder graphic
          this.remoteContent = t.href;
        }
        else if (window[elmt.id]) {
          this.callback = window[elmt.id];
        }
        else {return;}
      }
    }

    // Build container when requested.
    this.container = false; 

    if (this.options.autoSpawn) {
      this.documentListener = this.hide.bindAsEventListener(this);
      if (this.options.bound) {
        this.eventType = 'mousemove';
        this.elmt.addEvent('mouseenter', this.toggle.bindAsEventListener(this));
        this.elmt.addEvent('mouseleave', this.abort.bindAsEventListener(this));
      }
      else {
        this.eventType = 'click';
        this.elmt.addEvent('click', this.toggle.bindAsEventListener(this));
      }
    }

    // Be sure to cleanup 
    this.elmt.addEvent('trash', this.destroy.bindAsEventListener(this));
  },

  buildContainer: function() { 

    if (this.remoteContent) {
      this.content = new Asset.image(img_loop);
      this.content.style.height = "40px";
      this.content.style.width = "40px";
    }

    this.container = new Element('div', {
      styles: {
        position: 'absolute',
        left: '-999em',
        display: 'block',
        zIndex: 9999
      },
      id: 'FLYOUT',
      'class': this.options.flyoutClass
    });

    // rounded corners
    this.top  = new Element('div', {'class': 'cnrR5 top'}).injectInside(this.container);
    this.tl   = new Element('div', {'class': 'lft'}).setContent("<!--Lft Corner-->").injectInside(this.top);
    this.tm   = new Element('div', {'class': 'mid'}).setContent("<!--Mid Border-->").injectInside(this.top);
    this.tr   = new Element('div', {'class': 'rgt'}).setContent("<!--Rgt Corner-->").injectInside(this.top);
    this.btm  = new Element('div', {'class': 'cnrR5 btm'}).injectInside(this.container);
    this.bl   = new Element('div', {'class': 'lft'}).setContent("<!--Lft Corner-->").injectInside(this.btm);
    this.bm   = new Element('div', {'class': 'mid'}).setContent("<!--Mid Border-->").injectInside(this.btm);
    this.br   = new Element('div', {'class': 'rgt'}).setContent("<!--Rgt Corner-->").injectInside(this.btm);

    if (this.options.showArrow)
      this.point = new Element('span', {'class': this.options.arrowClass}).setContent('&#x20').injectInside(this.container);

    if (this.options.showClose) {
      var div   = new Element('div', {'class': 'close'}).injectInside(this.container);
      new Element('span', {'class': 'cnrL'}).injectInside(div);
      new Element('span', {'class': 'cnrB'}).injectInside(div);
      new Element('span', {'class': 'cnrBL'}).injectInside(div);
      this.closeLink  = new Element('a', {href: 'javascript: void(0)', 'class': 'close'}).setContent(lang_Close).injectInside(div);
    }

    this.inner = new Element('div', {'class': 'inner'}).setContent(this.content).injectInside(this.container);
  },

  position: function() {
    var c = this.container.getCoordinates();
    var sC = this.elmt.getCoordinates();
    // Safari can't calculate positions for TRs correctly, so use the first cell instead
    if (window.webkit419 && this.elmt.getTag() == "tr") sC = this.elmt.getElement('td').getCoordinates();
    // make sure flyout is within bounds of PAGE element
    var page = $('PAGE').getCoordinates();
    var rightLimit = page.right - 14 - this.options.limit;

    // default to top-left corner
    this.container.setStyle('top', sC.top + this.options.offsets.y + 'px');

    if (this.options.arrowPosition == POS.BOTTOM) { // deafult
      var l = sC.left + this.options.offsets.x;
      if (this.point && !this.pointOrigLeft) this.pointOrigLeft = parseInt(this.point.getStyle('left').replace(/px/,''));
      if (this.point) l -= this.pointOrigLeft;
      if (l + c.width > rightLimit) {
        l = rightLimit - c.width;
        if (this.point) this.point.setStyle('left', sC.left - l + "px");
      }
      this.container.setStyle('left', l + 'px');
      this.container.setStyle('top', sC.bottom + this.options.offsets.y + "px");
      if (this.options.centerArrow && this.point) { // move the arrow to the right half-way across the source elmt
        this.point.setStyle('left', sC.left + Math.floor(sC.width / 2) - l - Math.floor(this.point.getCoordinates().width / 2) + "px");
      }
    }
    else if (this.options.arrowPosition == POS.RIGHT) {
      // Safari can't calculate positions for TRs correctly, so use the last call instead
      if (window.webkit419 && this.elmt.getTag() == "tr") sC = this.elmt.getLastElement('td').getCoordinates();
      this.container.setStyle('left', (sC.right + this.options.offsets.x) + 'px');
    }
    else if (this.options.arrowPosition == POS.LEFT) {
      // Safari can't calculate positions for TR/TDs correctly, so use the table for left position instead
      // note: if trying to do this for any TD after the first, will also need to add the left position of the TD
      if (window.webkit419 && this.elmt.getTag() == "tr") sC = this.elmt.getParent('table').getCoordinates();
      this.container.setStyle('left', (sC.left - c.width + this.options.offsets.x) + 'px');
    }
    else if (this.options.arrowPosition == POS.TOP) {}

    this.positionCorners();
    return this;
  },

  positionCorners: function() {
    var c = this.container.getCoordinates();
    this.top.setStyle('width', c.width + 'px');
    this.btm.setStyle('width', c.width + 'px');
    var tm = c.width - this.tl.getCoordinates().width - this.tr.getCoordinates().width;
    var bm = c.width - this.bl.getCoordinates().width - this.br.getCoordinates().width;
    this.tm.setStyle('width', (tm > 0 ? tm : 0) + "px");
    this.bm.setStyle('width', (bm > 0 ? bm : 0) + "px");

    if (this.options.autoSpawn && this.options.bound) { // set bounds for pass-thru
      var sC = this.elmt.getCoordinates();
      if (this.options.arrowPosition == POS.BOTTOM) { // deafult
        this.passThruBounds = {top:sC.bottom, bottom:c.top, left:sC.left, right:sC.right};
      }
      else if (this.options.arrowPosition == POS.RIGHT) {
        this.passThruBounds = {top:c.top, bottom:c.bottom, left:c.right, right:sC.left};
      }
      else if (this.options.arrowPosition == POS.LEFT) {
        this.passThruBounds = {top:c.top, bottom:c.bottom, left:sC.right, right:c.right};
      }
      else if (this.options.arrowPosition == POS.TOP) {
        this.passThruBounds = {top:c.bottom, bottom:sC.top, left:sC.left, right:sC.right};
      }
    }
  },

  setAJAXContent: function(txt, xml) {
    this.content = txt;
    if (this.options.arrowPosition == POS.LEFT) this.container.setStyle('left', '-999em');
    this.inner.setContent(this.content);
    this.remoteContent = null;
    if (this.options.arrowPosition == POS.LEFT) {
      var c = this.container.getCoordinates();
      var sC = this.elmt.getCoordinates();
      // Safari can't calculate positions for TR/TDs correctly, so use the table for left position instead
      // note: if trying to do this for any TD after the first, will also need to add the left position of the TD
      if (window.webkit419 && this.elmt.getTag() == "tr") sC = this.elmt.getParent('table').getCoordinates();
      this.container.setStyle('left', (sC.left - c.width + this.options.offsets.x) + 'px');
    }
    this.positionCorners();
    this.hideSelects();
    window.behavior.apply(this.inner);// apply any defined behavior
  },

  hideSelects: function() {
    if (window.ie6) {
      var contained = this.container.getElements('select');
      var covered = [];
      $$('select').each(function(s){
        if (!contained.contains(s) && this.container.overlaps(s)) {
          covered.push(s);
          s.setStyle('visibility', 'hidden');
        }
      }, this);
      this.covered = new Elements(covered);
    }
  },

  toggle: function(e) {
    new Event(e).stop();

    if (!this.options.bound && this.container && this.container.inDocument()) {
      if (window.ie6) $$('select').setStyle('visibility', 'visible');
      this.hide();
    }
    else {this.options.bound ? this._show() : this.show();}
  },

  show: function() {
    // If the container hasn't been built, then build it.
    var containerBuilt = false;
    if (!this.container) { containerBuilt = true; this.buildContainer(); }

    if (this.container.inDocument()) return;
    if (this.remoteContent) {
      new Ajax(this.remoteContent, {
        onComplete: this.setAJAXContent.bind(this),
        onFailure: function(e) { alert(e.status + "\n" + e.responseText); }
      }).request();
    }
    if (this.callback) {
      this.inner.setContent(this.callback(this));
      this.positionCorners();
    }
    if (window.flyout) window.flyout.hide();
    window.flyout = this;
    this.container.setStyle('left', '-999em');
    this.add();

    // if showing close link, reposition contents lower
    if (containerBuilt) {
      if (this.closeLink) this.inner.style.paddingTop = parseInt(this.inner.getStyle("paddingTop").replace(/px/,'')) + this.closeLink.getCoordinates().height + "px";
    }
    this.position();

    this.hideSelects();
    if (this.options.autoSpawn) document.addEvent(this.eventType, this.documentListener);
    return this;
  },

  _show: function() {
    this.showDelay = this.show.delay(200, this);
  },

  abort: function(e) {
    $clear(this.showDelay);
  },

  /*
  Property: hide
    Called either on mousemove or click by document events.
  */
  hide: function(e) {
    // If the container hasn't been built, then bail.
    if (this.container == false) { return; }
    if (!this.container.inDocument()) return;

    if (e) {
      e = new Event(e);
      if (this.options.bound) {
        // mouse is still inside the flyout or the spawning element
        if (this.container.contains(e) || this.elmt.contains(e)) return;
        if (e.page.x > this.passThruBounds.left && e.page.x < this.passThruBounds.right &&
            e.page.y > this.passThruBounds.top && e.page.y < this.passThruBounds.bottom) return;
      }
      else {
        if ($(e.target).getTag() == 'option') return; // clicked on an open select dropdown

        if (window.ie && $(e.target).getTag() == 'select' && this.container.getElements('select').contains(e.target)) return;

        // user clicked inside the flyout but not on the close button
        if (this.container.contains(e) && !this.closeLink.contains(e)) return;

        // FF: button version of submit button causes flyout to close after an alert
        if (e.page.x == 0 && e.page.y == 0 && e.target.getTag() == 'a' && this.container.getElements('a').contains(e.target)) return;
      }
      e.preventDefault();
    }
    if (this.options.autoSpawn) document.removeEvent(this.eventType, this.documentListener);
    if (this.covered) this.covered.setStyle('visibility', 'visible');
    this.remove();
  },

  /*
  Property: add
    Add the flyout container to the DOM.
  */
  add: function() { this.container.injectInside(document.body); },

  /*
  Property: remove
    Remove the flyout container from the DOM.
  */
  remove: function() 
  {
    if (this.container == false) { return; }
    if (this.container.inDocument()) this.container.remove(); 
  },

  /*
    Discards the flyout on page unload.
  */
  destroy: function() 
  {
    this.remove();
    this.elmt = null;
    this.content = null;
    this.container = null;
  }

});
Flyout.implement(new Options);

rules['li.flyout']            = function(elmt) {new Flyout(elmt, {offsets: {x:-1, y:8}});}
rules['li.flyoutFun']            = function(elmt) {new Flyout(elmt, {offsets: {x:14, y:16}});}
rules['li.flyoutR'] = function(elmt) {new Flyout(elmt, {arrowPosition: POS.RIGHT, offsets: {x:4, y:-16}});}
rules['#COMMUNITY_BOX tr.flyout']   = function(elmt) { elmt.flyout = new Flyout(elmt, {arrowPosition: POS.RIGHT, offsets: {x:0, y:0}});}
rules['#COMMUNITY_BOX tr.flyoutL']  = function(elmt) { elmt.flyout = new Flyout(elmt, {arrowPosition: POS.LEFT, offsets: {x:0, y:0}});}
rules['div.thumbnails li']       = function(elmt) {new Flyout(elmt, {offsets: {x:4, y:9}, limit:14, showClose: false, bound: true, flyoutClass: 'mediaBox', centerArrow: true});}
rules['li.flyoutMap']         = function(elmt) {elmt.getElement('span').linkify(); new Flyout(elmt, {offsets: {x:12, y:14}, flyoutClass: 'flyoutMapContents'});}
rules['li.flyoutAward'] = function(elmt) {new Flyout(elmt, {offsets: {x:-374, y:30}, flyoutClass: 'flyoutAwardContents'});}
rules['li.nofly']             = function(elmt) {
  elmt.removeClass('nofly');
  elmt.addClass('flyout');
  elmt.getElement('span').linkify();
  new Flyout(elmt, {offsets: {x:12, y:14}});
}

function funStuffPop(elem)
{
	new Ajax('/vpages/funStuffFly.html', {
        onComplete: elem.setAJAXContent.bind(elem),
        onFailure: function(e) { alert(e.status + "\n" + e.responseText); }
      }).request();
    return new Asset.image(img_loop);  
}

//German Award - Reise & Preise
function reisePop(elem)
{
  new Ajax('/vpages/reise.html', {
   onComplete: elem.setAJAXContent.bind(elem),
   onFailure: function(e) { alert(e.status + "\n" + e.responseText); }
  }).request();
  return new Asset.image(img_loop);  
}/*
Script: calendar.js
  Contains <Calendar>

License:
  not free for public use
*/

var daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
/*
Class: Calendar
  A scrolling, multi-month calendar.

Arguments:
  elmt - required, the element that should spawn the flyout.
	options - optional, see options below.

Options:
  calendarClass - (string) class name to give the calendar
  todayClass - (string) class name for the table cell representing today
  selectedClass - (string) class name for the table cell representing the selected day
  disabledClass - (string) class name for disabled dates
  weekStart - (integer) days from Sunday on which to start the week (1 for Monday, etc.)
  selectedDate - (Date) the currently selected date (default: null)
  firstDate - (Date) first valid date of calendar (anything before it will be disabled)
  lastDate - (Date) last valid date of calendar (anything after it will be disabled)
  showOtherDates - (boolean) if false the padding days around a month aren't shown
  dualCalendar - (boolean) if true two months are shown instead of just one
  show - (function) function to be called in order to show the calendar (here for overriding)
    The function will be bound to the calendar as event listener.
  hide - (function) same as show, but called when that calendar should be hidden

Events:
  onSelect - called when the user selects a date
  onRequest - called just before the calendar is shown
*/
var Calendar = new Class({
  options: {
    calendarClass: "calendar",
    todayClass: "today",
    selectedClass: "selected",
    disabledClass: "disabled",
    otherMonthClass: "other",
    controlsClass: "navCal",
    weekStart: 0,
    selectedDate: null,
    firstDate: null,
    lastDate: null,
    showOtherDates: true,
    dualCalendar: false,
    show: null,
    hide: null
  },

  initialize: function(elmt, options) {
    this.source = elmt;
    this.setOptions(options);

    this.today = new Date();
    this.selectedDate = this.options.selectedDate;

    // force Dates to midnight for easier comparison
    this.today.setHours(0,0,0,0);
    if (this.options.firstDate) this.options.firstDate.setHours(0,0,0,0);
    if (this.options.lastDate)  this.options.lastDate.setHours(0,0,0,0);
    if (this.selectedDate)      this.selectedDate.setHours(0,0,0,0);

    if (!this.options.show) this.options.show = this.show;
    if (!this.options.hide) this.options.hide = this.hide;

    this.container = new Element('div', {'class': this.options.calendarClass});

    this.controls = new Element('div', {'class': this.options.controlsClass}).injectInside(this.container);
    this.prev = new Element('a', {events: {'click': this.prev.bindAsEventListener(this)}})
      .setContent('Previous Month').injectInside(new Element('span', {'class': 'prev'}).injectInside(this.controls));
    this.next = new Element('a', {events: {'click': this.next.bindAsEventListener(this)}})
      .setContent('Next Month').injectInside(new Element('span', {'class': 'next'}).injectInside(this.controls));

    this.source.addEvent('focus', this.options.show.bindAsEventListener(this));
    this.source.addEvent('click', this.options.show.bindAsEventListener(this));
    document.addEvent('click', this.options.hide.bindAsEventListener(this));

    // Be sure to cleanup 
    this.source.addEvent('trash', this.destroy.bindAsEventListener(this));
  },

  /*
    Discards the flyout on page unload.
  */
  destroy: function() 
  {
    this.source.calendar = null;
    this.source = null;
    this.container = null;
    this.controls = null;
    this.prev = null;
    this.next = null;
    this.after = null;
    this.before = null;
  },

  /*
  Property: update
    Update the month(s) shown by the calendar. Should be called whenever the date is changed externally.
  */
  update: function() {
  	if (this.currentMonth) this.removeTable(null, this.currentMonth);
    if (this.nextMonth) this.removeTable(null, this.nextMonth);

    this.currentMonth = this.createMonth(this.selectedDate || this.today);
    this.currentMonth.elmt.table.injectInside(this.container);
    if (this.options.dualCalendar) {
      var d = new Date(this.currentMonth.date); 
      var day = d.getDate();
      var nextMonth = d.getMonth()+1;
      if (day > daysInMonth[nextMonth]) { day = daysInMonth[nextMonth]; }
      d.setMonth(nextMonth, day);
      this.nextMonth = this.createMonth(d);
      this.nextMonth.elmt.table.injectInside(this.container);
    }

    return this;
  },

  /*
  Property: show
    Default show function.
  */
  show: function(e) {
    this.fireEvent('onRequest');
    
    if (!this.container) this.build();
    else this.update();
    if (!this.container.inDocument()) this.container.injectInside(document.body);
  },

  /*
  Property: hide
    Default hide function.
  */
  hide: function(e) {
  	if (!this.container.inDocument()) return;
    if (this.source.contains(e)) return;
    if (this.container.contains(e)) return;
    var e = new Event(e).stop();
    this.container.remove();
  },

  /*
  Property: createMonth
    Creates a month object; including start/end dates and the Table object.

  Argumnets:
    d - (Date) any date in the month
  */
  createMonth: function(d) {
    var month = {date: d};

    month.start = new Date(d);
    month.start.setDate(1);
    if (this.options.weekStart > 0 && month.start.getDay() == 0) {
      month.start.setDate(this.options.weekStart-6);
    }
    else {
      month.start.setDate(this.options.weekStart - month.start.getDay() + 1);
    }

    month.end   = new Date(d);
    month.end.setDate(daysInMonth[month.end.getMonth()]);
    if (month.end.getDay() >= this.options.weekStart)
      month.end.setDate(month.end.getDate() + 7 + this.options.weekStart - month.end.getDay());
    else
      month.end.setDate(month.end.getDate() + this.options.weekStart - month.end.getDay());

    month.elmt = new Table()
      .pushHead([{properties:{colspan:7, 'class':'caption'}, content:jsGlobalMonths[d.getMonth()]+' '+d.getFullYear()}])
      .pushHead(jsGlobalDaysShort);
    var week  = new Array;
    for (var d = new Date(month.start); d < month.end; d.setDate(d.getDate()+1)) {
      var c = {properties: {}};
      if (d.getMonth() != month.date.getMonth()) {
        c.properties['class'] = this.options.otherMonthClass;
        if (!this.options.showOtherDates) c.content = '&nbsp;';
      }
      else if ((this.options.firstDate && d < this.options.firstDate) || (this.options.lastDate && d > this.options.lastDate)) {
        c.properties['class'] = this.options.disabledClass;
        c.content = d.getDate();
      }
      else {
        c.content = new Element('a', {href:'javascript:void(0);',events:{click:this.select.bindAsEventListener(this,[new Date(d)])}}).setContent(d.getDate());
      }
      if (d.getTime() == this.today.getTime()) c.properties['class'] = this.options.todayClass;
      if (this.selectedDate && d.getTime() == this.selectedDate.getTime()) c.properties['class'] = this.options.selectedClass;
      week.push(c);
      if (week.length == 7) {
        month.elmt.push(week);
        week = new Array;
      }
    }
    month.elmt.table = new Element('div', {'class': 'month'}).setContent(month.elmt.table);
    return month;
  },

  /*
  Property: prev
    Moves the calendar back one month.
  */
  prev: function() {
    if (this.animating) return;
    this.animating = true;
    var d = new Date(this.currentMonth.date); 
    var month = d.getMonth()-1;
    if(month < 0){
    	month = month + 12;
    	d.setFullYear(d.getFullYear() - 1);
    }
    var day = d.getDate();
    if (day > daysInMonth[month]) { day = daysInMonth[month]; }
    d.setMonth(month, day);
    var m = this.createMonth(d);
    m.elmt.table.injectInside(this.container);
    var w = this.currentMonth.elmt.table.getCoordinates().width;

    var elmts = $$(m.elmt.table, this.currentMonth.elmt.table);
    var opts = {'0': {left: [-w,0]}, '1': {left: [w]}};
    if (this.nextMonth) {
      elmts.push($(this.nextMonth.elmt.table));
      opts['2'] = {left: [w*2]};
    }
    var fx = new Fx.Elements(elmts, {
      onComplete: this.doneAnimating.bindAsEventListener(this, [this.nextMonth || this.currentMonth])
    });
    if (this.nextMonth) this.nextMonth = this.currentMonth;
    this.currentMonth = m;

	if (this.options.firstDate && this.currentMonth.date.getMonth() == this.options.firstDate.getMonth())
      this.prev.setStyle('display', 'none');
    if (this.options.lastDate && (this.nextMonth || this.currentMonth).date.getMonth() == this.nearbyMonth(this.options.lastDate.getMonth(), -2))
      this.next.setStyle('display', 'block');
    fx.start(opts);
  },

  /*
  Property: next
    Moves the calendar forward one month.
  */
  next: function() {
    if (this.animating) return;
    this.animating = true;
    var d = new Date(this.currentMonth.date); 
    var month = d.getMonth() + (this.options.dualCalendar ? 2 : 1);
    if(month > 12){
    	month = month - 12;
    	d.setFullYear(d.getFullYear() + 1);
    }
    var day = d.getDate();
    if (day > daysInMonth[month]) { day = daysInMonth[month]; }
    d.setMonth(month, day);
    var m = this.createMonth(d);
    m.elmt.table.injectInside(this.container);
    var w = this.currentMonth.elmt.table.getCoordinates().width;

    var elmts = $$(m.elmt.table, this.currentMonth.elmt.table);
    var opts = {'0': {left: [w,0]}, '1': {left: [-w]}};
    if (this.nextMonth) {
      elmts.push($(this.nextMonth.elmt.table));
      opts['0'].left = [w*2,w];
      opts['2'] = {left: [0]};
    }
    var fx = new Fx.Elements(elmts, {
      onComplete: this.doneAnimating.bindAsEventListener(this, [this.currentMonth])
    });
    this.currentMonth = this.nextMonth || m;
    if (this.nextMonth) this.nextMonth = m;

    if (this.options.lastDate && (this.nextMonth || this.currentMonth).date.getMonth() == this.nearbyMonth(this.options.lastDate.getMonth(), -1))
      this.next.setStyle('display', 'none');
    if (this.options.firstDate && this.currentMonth.date.getMonth() == this.nearbyMonth(this.options.firstDate.getMonth(), 1))
      this.prev.setStyle('display', 'block');
    fx.start(opts);
  },

  /*
  Property: removeTable
    Removes the table from the container. Used by prev/next as a bound event listener for when
    the animation completes.

  Arguments:
    e - (event) the event object, unused
    t - (month object) the month to be removed
  */
  removeTable: function(e, t) {
    t.elmt.table.remove();
  },

  doneAnimating: function(e, t) {
    this.removeTable(e, t);
    this.animating = false;
  },

  /*
  Property: select
    Called when the user selects a date. Fires any onSelect events.

  Arguments:
    e - (event) the event object, unused
    d - (Date) the date the user selected
  */
  select: function(e, d) {
    this.selectedDate = d;
    this.fireEvent('onSelect', e);
  },

  /*
  Property: nearbyMonth
    Convenience method to get a month near a given month. Checks for boundary conditions.

  Arguments:
    month - (integer) starting month
    mod - (integer) amount to alter the number by (positive or negative)
  */
  nearbyMonth: function(month, mod) {
    var d = month + mod;
    if (d > 11) d -= 11;
    else if (d < 0) d += 11;
    return d;
  }
});
Calendar.implement(new Events, new Options);

var buildDate = function(cal) {
  var d = parseInt(cal.dayField.value.replace(/^0/,''));
  var m = cal.monthField.value.split(/\//);
  var y = parseInt(m[1]);
  m = parseInt(m[0].replace(/^0/,''));
  cal.selectedDate = new Date(y,m-1,d);
  return d;
}

/*
Function: showCalendar
  Bound to a Calendar and called when the user requests the calendar. Sets the selected date
  and updates the calendar so it can't get out of sync with the form fields. Also uses the
  flyout to contain the calendar.
*/
var showCalendar = function(e) {
  new Event(e).stop();
  var d = buildDate(this);

  if (this.toggler && this.toggler.checked) {
    this.toggler.setProperty('checked', '');
    this.source.value = formatDate(d, this.selectedDate.getMonth(), this.selectedDate.getFullYear());
    var oC = (this.after || this.before).calendar;
    d = buildDate(oC);
    oC.source.value = formatDate(d, oC.selectedDate.getMonth(), oC.selectedDate.getFullYear());
  }

  this.update();

  this.currentMonth.elmt.table.setStyle('left', '0px');
  this.flyout.show();
  if (this.options.dualCalendar) {
    this.nextMonth.elmt.table.setStyle('left', this.currentMonth.elmt.table.getCoordinates().width + 'px');
  }
  window.calendar = this;
}

/*
Function: hideCalendar
  Bound to a Calendar and called when the user clicks anywhere on the document. Will remove the flyout if
  the click was anywhere outside of it.
*/
var hideCalendar = function(e) {
  if ((this.flyout.container == false) || !this.flyout.container.inDocument()) return;
  e = new Event(e).stop();
  if (this.source.contains(e)) return;
  if (this.flyout.container.contains(e) && !this.flyout.closeLink.contains(e)) return;
  // re-show the select fields
  if (window.ie6) $$('select').setStyle('visibility', 'visible');
  this.flyout.remove();
}

var updateFields = function(cal) {
  var m = cal.selectedDate.getMonth() + 1; if (m < 10) m = "0" + m;
  cal.dayField.value   = cal.selectedDate.getDate();
  cal.monthField.value = m + "/" + cal.selectedDate.getFullYear();
  cal.source.value     = formatDate(cal.selectedDate.getDate(), cal.selectedDate.getMonth(), cal.selectedDate.getFullYear());
}

/*
Function: calendarSelect
  Bound to a Calendar and called when the user selects a date. Hides the flyout and updates the form.
*/
var calendarSelect = function(e) {
  new Event(e).stop();
  // re-show the select fields
  if (window.ie6) $(this.source.form).getElements('select').setStyle('visibility', 'visible');
  this.flyout.remove();
  updateFields(this);

  if (this.after && this.after.calendar.selectedDate > this.selectedDate) {
    var before = new Date(this.selectedDate);
    before.setDate(before.getDate() - 1);
    this.after.calendar.selectedDate = before;
    updateFields(this.after.calendar);
  }
  else if (this.before && this.before.calendar.selectedDate < this.selectedDate) {
    var after = new Date(this.selectedDate);
    after.setDate(after.getDate() + 1);
    this.before.calendar.selectedDate = after;
    updateFields(this.before.calendar);
  }
}

var validateDate = function(cal) {
  var d = cal.selectedDate.getDate();
  var m = cal.selectedDate.getMonth() + 1;
  var y = cal.selectedDate.getFullYear();
  var r = cal.source.value.match(DATE_FORMAT.pattern);
  if (r) {
    var nd = parseInt(r[DATE_FORMAT.date].replace(/^0/,''));
    var nm = parseInt(r[DATE_FORMAT.month].replace(/^0/,''));
    var ny = parseInt(r[DATE_FORMAT.year].replace(/^0/,''));
    //if (d != nd || m != nm || y != ny) {
    if (nd > 0 && nd < 32 && nm > 0 && nm < 13) {
      if (nd < 10) nd = '0' + nd;
      if (nm < 10) nm = '0' + nm;
      if (ny < 100) ny += 2000;
      cal.dayField.value = nd;
      cal.monthField.value = nm + "/" + ny;
      buildDate(cal);
    }
    else { return sInvalidDates; } // number out of range
  }
  else { return sInvalidDates; } // invalid format
  return null;
}

var validateDates = function(e) {
  var valid = true;
  var msg;
  if ((msg = validateDate(this.checkIn.calendar)) != null || (msg = validateDate(this.checkOut.calendar)) != null) {
    valid = false;
    this.getElement('span.error_msg').setContent(msg).show();
  }
  else if (!(this.checkOut.calendar.selectedDate > this.checkIn.calendar.selectedDate)) {
    valid = false;
    this.getElement('span.error_msg').setContent(sInvalidDates).show();
  }
  if (!valid && e) new Event(e).stop();
  return valid;
}

rules['#HAC_FORM'] = function(elmt) {elmt.addEvent('submit', validateDates.bindAsEventListener(elmt));}
rules['#FLIGHT_FORM'] = function(elmt) {elmt.addEvent('submit', validateDates.bindAsEventListener(elmt));}

rules['#BODYCON span.cal,#HOMEPAGE span.cal'] = function(elmt) {
  var end = new Date();
  end.setYear(end.getFullYear()+1);
  end.setMonth(end.getMonth()-1, 1);

  var src = elmt.getElement('input[type=text]');
  var cal = new Calendar(src, {
    firstDate: new Date(),
    lastDate: end,
    showOtherDates: false,
    dualCalendar: true,
    onSelect: calendarSelect,
    show: showCalendar,
    hide: hideCalendar,
    weekStart: jsGlobalDayOffset
  });
  cal.dayField = elmt.getElement('.day');
  cal.monthField = elmt.getElement('.month');
  cal.flyout = new Flyout(cal.source, {offsets: {x:0, y:28}, showArrow: false, autoSpawn: false}, cal.container);
  cal.wrapper = elmt;
  cal.toggler = $('searchAll');
  elmt.getElement('.icn').addEvent('click', showCalendar.bindAsEventListener(cal));
  if (src.id == 'checkIn')    cal.before = src.form.checkOut; // use name instead of byID (multiple forms)
  if (src.id == 'qcCheckIn')  cal.before = $('qcCheckOut');
  if (src.id == 'checkOut')   cal.after = src.form.checkIn;
  if (src.id == 'qcCheckOut') cal.after = $('qcCheckIn');
  src.calendar = cal;
  buildDate(cal);
}

// HAC calendar 	 
rules['#searchAll'] = function(elmt) { 	 
  elmt.addEvent('click', function() { 	 
    if (elmt.checked) {
      $$('#HAC_FORM input[type=text]').each(function(e){
        e.value = JS_Any_Date;
      });
    }
    else {
      $$('#HAC_FORM input[type=text]').each(function(e){
        var d = buildDate(e.calendar);
        e.calendar.source.value = formatDate(d, e.calendar.selectedDate.getMonth(), e.calendar.selectedDate.getFullYear());
      });
    }
  }); 	 
}
/*
 http://www.huddletogether.com/projects/lightbox/
*/

var Lightbox = new Class({

  initialize: function(ctrl) {
    if (typeof(ctrl) == "string") {
      this.content = ctrl;
    }
    else {
      this.source = ctrl.href;
      ctrl.addEvent('click', this.activate.bindAsEventListener(this));
    }
  },
	
  // Turn everything on - mainly the IE fixes
  activate: function(e){
    if (e) new Event(e).stop();// can be activated progamatically
    if ( ! $('overlay') ) this.addLightboxMarkup();
    if (window.ie6){
      $('overlay').setStyle('height', window.getHeight() + 'px');
      $$('select').setStyle('visibility', 'hidden');
    }
    this.displayLightbox("block");
    window.lightbox = this;
    return this;
  },
	
  // Add in markup necessary to make this work. Basically two divs:
  // Overlay holds the shadow
  // Lightbox is the centered square that the content is put into.
  addLightboxMarkup: function() {
    overlay = document.createElement('div');
    overlay.id = 'overlay';
    lb = document.createElement('div');
    lb.id = 'lightbox';
    lb.className = 'loading';
    lb.innerHTML = '<div id="lbLoadMessage"><p>Loading</p></div>';
    document.body.appendChild(overlay);
    document.body.appendChild(lb);
  },

  displayLightbox: function(display){
    $('overlay').setStyle('display', display);
    $('lightbox').setStyle('display', display);
    if(display != 'none') this.loadInfo();
    return this;
  },
	
	loadInfo: function() {
    if (this.content) return this.processInfo(this.content);
		var myAjax = new Ajax(this.source, {
      onComplete: this.processInfo.bindAsEventListener(this)
    }).request();
    return this;
	},
	
	processInfo: function(response){
    $('overlay').setStyle('top', window.getScrollTop() + "px");

    this.info = new Element('div', {id: 'lbContent'})

    // rounded corners
    this.top  = new Element('div', {'class': 'cnrR5 top'}).injectInside(this.info);
    this.tl   = new Element('div', {'class': 'lft'}).setContent("<!--Lft Corner-->").injectInside(this.top);
    this.tm   = new Element('div', {'class': 'mid'}).setContent("<!--Mid Border-->").injectInside(this.top);
    this.tr   = new Element('div', {'class': 'rgt'}).setContent("<!--Rgt Corner-->").injectInside(this.top);
    this.btm  = new Element('div', {'class': 'cnrR5 btm'}).injectInside(this.info);
    this.bl   = new Element('div', {'class': 'lft'}).setContent("<!--Lft Corner-->").injectInside(this.btm);
    this.bm   = new Element('div', {'class': 'mid'}).setContent("<!--Mid Border-->").injectInside(this.btm);
    this.br   = new Element('div', {'class': 'rgt'}).setContent("<!--Rgt Corner-->").injectInside(this.btm);

    var div   = new Element('div', {'class': 'close'}).injectInside(this.info);
    new Element('span', {'class': 'cnrL'}).injectInside(div);
    new Element('span', {'class': 'cnrB'}).injectInside(div);
    new Element('span', {'class': 'cnrBL'}).injectInside(div);
    this.closeLink  = new Element('a', {'class':'lbAction', rel:'deactivate', href:''}).setContent(lang_Close).injectInside(div);

    this.inner = new Element('div', {'class': 'inner'}).setContent(response).injectInside(this.info);
    this.info.injectBefore($('lbLoadMessage'));
    $('lightbox').setProperty('class', 'done').centerOnScreen();
    this.positionCorners();
		this.actions();			
    return this;
	},

  positionCorners: function() {
    var c = this.info.getCoordinates();
    this.top.setStyle('width', c.width + 'px');
    this.btm.setStyle('width', c.width + 'px');
    var tm = c.width - this.tl.getCoordinates().width - this.tr.getCoordinates().width;
    var bm = c.width - this.bl.getCoordinates().width - this.br.getCoordinates().width;
    this.tm.setStyle('width', (tm > 0 ? tm : 0) + "px");
    this.bm.setStyle('width', (bm > 0 ? bm : 0) + "px");
  },
	
	// Search through new links within the lightbox, and attach click event
	actions: function(){
		this.info.getElements('a.lbAction').each(function(v){
			v.addEvent('click', this[v.rel].bindAsEventListener(this));
		}, this);
    window.behavior.apply(this.info);
	},

  // Example of creating your own functionality once lightbox is initiated
  insert: function(e){
    if (e) new Event(e).stop();
    link = Event.element(e).parentNode;
    Element.remove(this.info);
    var myAjax = new Ajax(link.href,
      {onComplete: this.processInfo.bindAsEventListener(this)}
    ).request();
    return this;
  },

  // Example of creating your own functionality once lightbox is initiated
  deactivate: function(e){
    if (e) new Event(e).stop();
    if (!this.info.inDocument()) return false;
    Element.remove(this.info);
    if (window.ie) $$('select').setStyle('visibility', 'visible');
    this.displayLightbox("none");
    window.lightbox = null;
    return this;
  }
});

/*-----------------------------------------------------------------------------------------------*/



function registerOnLoad(fn) {
  window.addEvent('load', fn);
}
function registerOnUnload(fn) {
  window.addEvent('unload', fn);
}

//func: getScrollOffset
function getScrollOffset()
{
  return [ window.getScrollLeft(), window.getScrollTop() ];
}

function isIn(eventPos, ele, bounds)
{
  var off = getScrollOffset();

  ele = $(ele);
  var pos = findPos(ele);
  // calculate element bounts
  var l = pos[0] - off[0];
  var t = pos[1] - off[1];
  var r = l + ele.clientWidth;
  var b = t + ele.clientHeight;

  if (bounds) {
    if (typeof(bounds) == "number") {
      l = l - bounds;
      t = t - bounds;
      r = r + bounds;
      b = b + bounds;
    }
    else if (bounds instanceof Array && (bounds.length == 2 || bounds.length == 4)) {
      t = t - bounds[0];
      r = r + bounds[1];
      l = l - (bounds.length == 4 ? bounds[3] : bounds[1]);
      b = b + (bounds.length == 4 ? bounds[2] : bounds[0]);
    }
  }

  return (eventPos[0] >= l && eventPos[0] <= r && eventPos[1] >= t && eventPos[1] <= b);
}

function setDetails(event, title, category, space) {
  new Event(event).stop();
  $('title').value = title;
  $('category').value = category;
  $('space').value = space;
  $('newPage').submit();
}
