var displayKeyboard = false;

function loadShadowbox(){
	Shadowbox.loadSkin('classic', shop.url + '/css/shadowBox');
	Shadowbox.loadLanguage(shop.selectedLanguageInitials, shop.commonTemplatePath + '/js/shadowBox/language');
	Shadowbox.loadPlayer(['html', 'img', 'ajax', 'iframe'],  shop.commonTemplatePath + '/js/shadowBox/player');
	$(window).addEvent('domready', function(){Shadowbox.init({overlayOpacity:shop.overlayOpacity, overlayColor:shop.overlayColor});});
}

var MooTools={version:"1.2.0",build:""};var Native=function(J){J=J||{};var F=J.afterImplement||function(){};var G=J.generics;G=(G!==false);var H=J.legacy;
var E=J.initialize;var B=J.protect;var A=J.name;var C=E||H;C.constructor=Native;C.$family={name:"native"};if(H&&E){C.prototype=H.prototype;}C.prototype.constructor=C;
if(A){var D=A.toLowerCase();C.prototype.$family={name:D};Native.typize(C,D);}var I=function(M,K,N,L){if(!B||L||!M.prototype[K]){M.prototype[K]=N;}if(G){Native.genericize(M,K,B);
}F.call(M,K,N);return M;};C.implement=function(L,K,N){if(typeof L=="string"){return I(this,L,K,N);}for(var M in L){I(this,M,L[M],K);}return this;};C.alias=function(M,K,N){if(typeof M=="string"){M=this.prototype[M];
if(M){I(this,K,M,N);}}else{for(var L in M){this.alias(L,M[L],K);}}return this;};return C;};Native.implement=function(D,C){for(var B=0,A=D.length;B<A;B++){D[B].implement(C);
}};Native.genericize=function(B,C,A){if((!A||!B[C])&&typeof B.prototype[C]=="function"){B[C]=function(){var D=Array.prototype.slice.call(arguments);return B.prototype[C].apply(D.shift(),D);
};}};Native.typize=function(A,B){if(!A.type){A.type=function(C){return($type(C)===B);};}};Native.alias=function(E,B,A,F){for(var D=0,C=E.length;D<C;D++){E[D].alias(B,A,F);
}};(function(B){for(var A in B){Native.typize(B[A],A);}})({"boolean":Boolean,"native":Native,object:Object});(function(B){for(var A in B){new Native({name:A,initialize:B[A],protect:true});
}})({String:String,Function:Function,Number:Number,Array:Array,RegExp:RegExp,Date:Date});(function(B,A){for(var C=A.length;C--;C){Native.genericize(B,A[C],true);
}return arguments.callee;})(Array,["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice","toString","valueOf","indexOf","lastIndexOf"])(String,["charAt","charCodeAt","concat","indexOf","lastIndexOf","match","replace","search","slice","split","substr","substring","toLowerCase","toUpperCase","valueOf"]);
function $chk(A){return !!(A||A===0);}function $clear(A){clearTimeout(A);clearInterval(A);return null;}function $defined(A){return(A!=undefined);}function $empty(){}function $arguments(A){return function(){return arguments[A];
};}function $lambda(A){return(typeof A=="function")?A:function(){return A;};}function $extend(C,A){for(var B in (A||{})){C[B]=A[B];}return C;}function $unlink(C){var B;
switch($type(C)){case"object":B={};for(var E in C){B[E]=$unlink(C[E]);}break;case"hash":B=$unlink(C.getClean());break;case"array":B=[];for(var D=0,A=C.length;
D<A;D++){B[D]=$unlink(C[D]);}break;default:return C;}return B;}function $merge(){var E={};for(var D=0,A=arguments.length;D<A;D++){var B=arguments[D];if($type(B)!="object"){continue;
}for(var C in B){var G=B[C],F=E[C];E[C]=(F&&$type(G)=="object"&&$type(F)=="object")?$merge(F,G):$unlink(G);}}return E;}function $pick(){for(var B=0,A=arguments.length;
B<A;B++){if(arguments[B]!=undefined){return arguments[B];}}return null;}function $random(B,A){return Math.floor(Math.random()*(A-B+1)+B);}function $splat(B){var A=$type(B);
return(A)?((A!="array"&&A!="arguments")?[B]:B):[];}var $time=Date.now||function(){return new Date().getTime();};function $try(){for(var B=0,A=arguments.length;
B<A;B++){try{return arguments[B]();}catch(C){}}return null;}function $type(A){if(A==undefined){return false;}if(A.$family){return(A.$family.name=="number"&&!isFinite(A))?false:A.$family.name;
}if(A.nodeName){switch(A.nodeType){case 1:return"element";case 3:return(/\S/).test(A.nodeValue)?"textnode":"whitespace";}}else{if(typeof A.length=="number"){if(A.callee){return"arguments";
}else{if(A.item){return"collection";}}}}return typeof A;}var Hash=new Native({name:"Hash",initialize:function(A){if($type(A)=="hash"){A=$unlink(A.getClean());
}for(var B in A){this[B]=A[B];}return this;}});Hash.implement({getLength:function(){var B=0;for(var A in this){if(this.hasOwnProperty(A)){B++;}}return B;
},forEach:function(B,C){for(var A in this){if(this.hasOwnProperty(A)){B.call(C,this[A],A,this);}}},getClean:function(){var B={};for(var A in this){if(this.hasOwnProperty(A)){B[A]=this[A];
}}return B;}});Hash.alias("forEach","each");function $H(A){return new Hash(A);}Array.implement({forEach:function(C,D){for(var B=0,A=this.length;B<A;B++){C.call(D,this[B],B,this);
}}});Array.alias("forEach","each");function $A(C){if(C.item){var D=[];for(var B=0,A=C.length;B<A;B++){D[B]=C[B];}return D;}return Array.prototype.slice.call(C);
}function $each(C,B,D){var A=$type(C);((A=="arguments"||A=="collection"||A=="array")?Array:Hash).each(C,B,D);}var Browser=new Hash({Engine:{name:"unknown",version:""},Platform:{name:(navigator.platform.match(/mac|win|linux/i)||["other"])[0].toLowerCase()},Features:{xpath:!!(document.evaluate),air:!!(window.runtime)},Plugins:{}});
if(window.opera){Browser.Engine={name:"presto",version:(document.getElementsByClassName)?950:925};}else{if(window.ActiveXObject){Browser.Engine={name:"trident",version:(window.XMLHttpRequest)?5:4};
}else{if(!navigator.taintEnabled){Browser.Engine={name:"webkit",version:(Browser.Features.xpath)?420:419};}else{if(document.getBoxObjectFor!=null){Browser.Engine={name:"gecko",version:(document.getElementsByClassName)?19:18};
}}}}Browser.Engine[Browser.Engine.name]=Browser.Engine[Browser.Engine.name+Browser.Engine.version]=true;if(window.orientation!=undefined){Browser.Platform.name="ipod";
}Browser.Platform[Browser.Platform.name]=true;Browser.Request=function(){return $try(function(){return new XMLHttpRequest();},function(){return new ActiveXObject("MSXML2.XMLHTTP");
});};Browser.Features.xhr=!!(Browser.Request());Browser.Plugins.Flash=(function(){var A=($try(function(){return navigator.plugins["Shockwave Flash"].description;
},function(){return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version");})||"0 r0").match(/\d+/g);return{version:parseInt(A[0]||0+"."+A[1]||0),build:parseInt(A[2]||0)};
})();function $exec(B){if(!B){return B;}if(window.execScript){window.execScript(B);}else{var A=document.createElement("script");A.setAttribute("type","text/javascript");
A.text=B;document.head.appendChild(A);document.head.removeChild(A);}return B;}Native.UID=1;var $uid=(Browser.Engine.trident)?function(A){return(A.uid||(A.uid=[Native.UID++]))[0];
}:function(A){return A.uid||(A.uid=Native.UID++);};var Window=new Native({name:"Window",legacy:(Browser.Engine.trident)?null:window.Window,initialize:function(A){$uid(A);
if(!A.Element){A.Element=$empty;if(Browser.Engine.webkit){A.document.createElement("iframe");}A.Element.prototype=(Browser.Engine.webkit)?window["[[DOMElement.prototype]]"]:{};
}return $extend(A,Window.Prototype);},afterImplement:function(B,A){window[B]=Window.Prototype[B]=A;}});Window.Prototype={$family:{name:"window"}};new Window(window);
var Document=new Native({name:"Document",legacy:(Browser.Engine.trident)?null:window.Document,initialize:function(A){$uid(A);A.head=A.getElementsByTagName("head")[0];
A.html=A.getElementsByTagName("html")[0];A.window=A.defaultView||A.parentWindow;if(Browser.Engine.trident4){$try(function(){A.execCommand("BackgroundImageCache",false,true);
});}return $extend(A,Document.Prototype);},afterImplement:function(B,A){document[B]=Document.Prototype[B]=A;}});Document.Prototype={$family:{name:"document"}};
new Document(document);Array.implement({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;
},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;},clean:function(){return this.filter($defined);
},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;},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;},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;},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;},link:function(C){var A={};
for(var E=0,B=this.length;E<B;E++){for(var D in C){if(C[D](this[E])){A[D]=this[E];delete C[D];break;}}}return A;},contains:function(A,B){return this.indexOf(A,B)!=-1;
},extend:function(C){for(var B=0,A=C.length;B<A;B++){this.push(C[B]);}return this;},getLast:function(){return(this.length)?this[this.length-1]:null;},getRandom:function(){return(this.length)?this[$random(0,this.length-1)]:null;
},include:function(A){if(!this.contains(A)){this.push(A);}return this;},combine:function(C){for(var B=0,A=C.length;B<A;B++){this.include(C[B]);}return this;
},erase:function(B){for(var A=this.length;A--;A){if(this[A]===B){this.splice(A,1);}}return this;},empty:function(){this.length=0;return this;},flatten:function(){var D=[];
for(var B=0,A=this.length;B<A;B++){var C=$type(this[B]);if(!C){continue;}D=D.concat((C=="array"||C=="collection"||C=="arguments")?Array.flatten(this[B]):this[B]);
}return D;},hexToRgb:function(B){if(this.length!=3){return null;}var A=this.map(function(C){if(C.length==1){C+=C;}return C.toInt(16);});return(B)?A:"rgb("+A+")";
},rgbToHex:function(D){if(this.length<3){return null;}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("");}});Function.implement({extend:function(A){for(var B in A){this[B]=A[B];}return this;},create:function(B){var A=this;
B=B||{};return function(D){var C=B.arguments;C=(C!=undefined)?$splat(C):Array.slice(arguments,(B.event)?1:0);if(B.event){C=[D||window.event].extend(C);
}var E=function(){return A.apply(B.bind||null,C);};if(B.delay){return setTimeout(E,B.delay);}if(B.periodical){return setInterval(E,B.periodical);}if(B.attempt){return $try(E);
}return E();};},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});},bindWithEvent: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})();},run:function(A,B){return this.apply(B,$splat(A));}});Number.implement({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,C){for(var A=0;A<this;A++){B.call(C,A,this);}},toFloat:function(){return parseFloat(this);
},toInt:function(A){return parseInt(this,A||10);}});Number.alias("times","each");(function(B){var A={};B.each(function(C){if(!Number[C]){A[C]=function(){return Math[C].apply(null,[this].concat($A(arguments)));
};}});Number.implement(A);})(["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","max","min","pow","sin","sqrt","tan"]);String.implement({test:function(A,B){return((typeof A=="string")?new RegExp(A,B):A).test(this);
},contains:function(A,B){return(B)?(B+this+B).indexOf(B+A+B)>-1:this.indexOf(A)>-1;},trim:function(){return this.replace(/^\s+|\s+$/g,"");},clean:function(){return this.replace(/\s+/g," ").trim();
},camelCase:function(){return this.replace(/-\D/g,function(A){return A.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/[A-Z]/g,function(A){return("-"+A.charAt(0).toLowerCase());
});},capitalize:function(){return this.replace(/\b[a-z]/g,function(A){return A.toUpperCase();});},escapeRegExp:function(){return this.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1");
},toInt:function(A){return parseInt(this,A||10);},toFloat:function(){return parseFloat(this);},hexToRgb:function(B){var A=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
return(A)?A.slice(1).hexToRgb(B):null;},rgbToHex:function(B){var A=this.match(/\d{1,3}/g);return(A)?A.rgbToHex(B):null;},stripScripts:function(B){var A="";
var C=this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi,function(){A+=arguments[1]+"\n";return"";});if(B===true){$exec(A);}else{if($type(B)=="function"){B(A,C);
}}return C;},substitute:function(A,B){return this.replace(B||(/\\?\{([^}]+)\}/g),function(D,C){if(D.charAt(0)=="\\"){return D.slice(1);}return(A[C]!=undefined)?A[C]:"";
});}});Hash.implement({has:Object.prototype.hasOwnProperty,keyOf:function(B){for(var A in this){if(this.hasOwnProperty(A)&&this[A]===B){return A;}}return null;
},hasValue:function(A){return(Hash.keyOf(this,A)!==null);},extend:function(A){Hash.each(A,function(C,B){Hash.set(this,B,C);},this);return this;},combine:function(A){Hash.each(A,function(C,B){Hash.include(this,B,C);
},this);return this;},erase:function(A){if(this.hasOwnProperty(A)){delete this[A];}return this;},get:function(A){return(this.hasOwnProperty(A))?this[A]:null;
},set:function(A,B){if(!this[A]||this.hasOwnProperty(A)){this[A]=B;}return this;},empty:function(){Hash.each(this,function(B,A){delete this[A];},this);
return this;},include:function(B,C){var A=this[B];if(A==undefined){this[B]=C;}return this;},map:function(B,C){var A=new Hash;Hash.each(this,function(E,D){A.set(D,B.call(C,E,D,this));
},this);return A;},filter:function(B,C){var A=new Hash;Hash.each(this,function(E,D){if(B.call(C,E,D,this)){A.set(D,E);}},this);return A;},every:function(B,C){for(var A in this){if(this.hasOwnProperty(A)&&!B.call(C,this[A],A)){return false;
}}return true;},some:function(B,C){for(var A in this){if(this.hasOwnProperty(A)&&B.call(C,this[A],A)){return true;}}return false;},getKeys:function(){var A=[];
Hash.each(this,function(C,B){A.push(B);});return A;},getValues:function(){var A=[];Hash.each(this,function(B){A.push(B);});return A;},toQueryString:function(A){var B=[];
Hash.each(this,function(F,E){if(A){E=A+"["+E+"]";}var D;switch($type(F)){case"object":D=Hash.toQueryString(F,E);break;case"array":var C={};F.each(function(H,G){C[G]=H;
});D=Hash.toQueryString(C,E);break;default:D=E+"="+encodeURIComponent(F);}if(F!=undefined){B.push(D);}});return B.join("&");}});Hash.alias({keyOf:"indexOf",hasValue:"contains"});
var Event=new Native({name:"Event",initialize:function(A,F){F=F||window;var K=F.document;A=A||F.event;if(A.$extended){return A;}this.$extended=true;var J=A.type;
var G=A.target||A.srcElement;while(G&&G.nodeType==3){G=G.parentNode;}if(J.test(/key/)){var B=A.which||A.keyCode;var M=Event.Keys.keyOf(B);if(J=="keydown"){var D=B-111;
if(D>0&&D<13){M="f"+D;}}M=M||String.fromCharCode(B).toLowerCase();}else{if(J.match(/(click|mouse|menu)/i)){K=(!K.compatMode||K.compatMode=="CSS1Compat")?K.html:K.body;
var I={x:A.pageX||A.clientX+K.scrollLeft,y:A.pageY||A.clientY+K.scrollTop};var C={x:(A.pageX)?A.pageX-F.pageXOffset:A.clientX,y:(A.pageY)?A.pageY-F.pageYOffset:A.clientY};
if(J.match(/DOMMouseScroll|mousewheel/)){var H=(A.wheelDelta)?A.wheelDelta/120:-(A.detail||0)/3;}var E=(A.which==3)||(A.button==2);var L=null;if(J.match(/over|out/)){switch(J){case"mouseover":L=A.relatedTarget||A.fromElement;
break;case"mouseout":L=A.relatedTarget||A.toElement;}if(!(function(){while(L&&L.nodeType==3){L=L.parentNode;}return true;}).create({attempt:Browser.Engine.gecko})()){L=false;
}}}}return $extend(this,{event:A,type:J,page:I,client:C,rightClick:E,wheel:H,relatedTarget:L,target:G,code:B,key:M,shift:A.shiftKey,control:A.ctrlKey,alt:A.altKey,meta:A.metaKey});
}});Event.Keys=new Hash({enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46});Event.implement({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;}});var Class=new Native({name:"Class",initialize:function(B){B=B||{};var A=function(E){for(var D in this){this[D]=$unlink(this[D]);
}for(var F in Class.Mutators){if(!this[F]){continue;}Class.Mutators[F](this,this[F]);delete this[F];}this.constructor=A;if(E===$empty){return this;}var C=(this.initialize)?this.initialize.apply(this,arguments):this;
if(this.options&&this.options.initialize){this.options.initialize.call(this);}return C;};$extend(A,this);A.constructor=Class;A.prototype=B;return A;}});
Class.implement({implement:function(){Class.Mutators.Implements(this.prototype,Array.slice(arguments));return this;}});Class.Mutators={Implements:function(A,B){$splat(B).each(function(C){$extend(A,($type(C)=="class")?new C($empty):C);
});},Extends:function(self,klass){var instance=new klass($empty);delete instance.parent;delete instance.parentOf;for(var key in instance){var current=self[key],previous=instance[key];
if(current==undefined){self[key]=previous;continue;}var ctype=$type(current),ptype=$type(previous);if(ctype!=ptype){continue;}switch(ctype){case"function":if(!arguments.callee.caller){self[key]=eval("("+String(current).replace(/\bthis\.parent\(\s*(\))?/g,function(full,close){return"arguments.callee._parent_.call(this"+(close||", ");
})+")");}self[key]._parent_=previous;break;case"object":self[key]=$merge(previous,current);}}self.parent=function(){return arguments.callee.caller._parent_.apply(this,arguments);
};self.parentOf=function(descendant){return descendant._parent_.apply(this,Array.slice(arguments,1));};}};var Chain=new Class({chain:function(){this.$chain=(this.$chain||[]).extend(arguments);
return this;},callChain:function(){return(this.$chain&&this.$chain.length)?this.$chain.shift().apply(this,arguments):false;},clearChain:function(){if(this.$chain){this.$chain.empty();
}return this;}});var Events=new Class({addEvent:function(C,B,A){C=Events.removeOn(C);if(B!=$empty){this.$events=this.$events||{};this.$events[C]=this.$events[C]||[];
this.$events[C].include(B);if(A){B.internal=true;}}return this;},addEvents:function(A){for(var B in A){this.addEvent(B,A[B]);}return this;},fireEvent:function(C,B,A){C=Events.removeOn(C);
if(!this.$events||!this.$events[C]){return this;}this.$events[C].each(function(D){D.create({bind:this,delay:A,"arguments":B})();},this);return this;},removeEvent:function(B,A){B=Events.removeOn(B);
if(!this.$events||!this.$events[B]){return this;}if(!A.internal){this.$events[B].erase(A);}return this;},removeEvents:function(C){for(var D in this.$events){if(C&&C!=D){continue;
}var B=this.$events[D];for(var A=B.length;A--;A){this.removeEvent(D,B[A]);}}return this;}});Events.removeOn=function(A){return A.replace(/^on([A-Z])/,function(B,C){return C.toLowerCase();
});};var Options=new Class({setOptions:function(){this.options=$merge.run([this.options].extend(arguments));if(!this.addEvent){return this;}for(var A in this.options){if($type(this.options[A])!="function"||!(/^on[A-Z]/).test(A)){continue;
}this.addEvent(A,this.options[A]);delete this.options[A];}return this;}});Document.implement({newElement:function(A,B){if(Browser.Engine.trident&&B){["name","type","checked"].each(function(C){if(!B[C]){return ;
}A+=" "+C+'="'+B[C]+'"';if(C!="checked"){delete B[C];}});A="<"+A+">";}return $.element(this.createElement(A)).set(B);},newTextNode:function(A){return this.createTextNode(A);
},getDocument:function(){return this;},getWindow:function(){return this.defaultView||this.parentWindow;},purge:function(){var C=this.getElementsByTagName("*");
for(var B=0,A=C.length;B<A;B++){Browser.freeMem(C[B]);}}});var Element=new Native({name:"Element",legacy:window.Element,initialize:function(A,B){var C=Element.Constructors.get(A);
if(C){return C(B);}if(typeof A=="string"){return document.newElement(A,B);}return $(A).set(B);},afterImplement:function(A,B){if(!Array[A]){Elements.implement(A,Elements.multi(A));
}Element.Prototype[A]=B;}});Element.Prototype={$family:{name:"element"}};Element.Constructors=new Hash;var IFrame=new Native({name:"IFrame",generics:false,initialize:function(){var E=Array.link(arguments,{properties:Object.type,iframe:$defined});
var C=E.properties||{};var B=$(E.iframe)||false;var D=C.onload||$empty;delete C.onload;C.id=C.name=$pick(C.id,C.name,B.id,B.name,"IFrame_"+$time());B=new Element(B||"iframe",C);
var A=function(){var F=$try(function(){return B.contentWindow.location.host;});if(F&&F==window.location.host){var H=new Window(B.contentWindow);var G=new Document(B.contentWindow.document);
$extend(H.Element.prototype,Element.Prototype);}D.call(B.contentWindow,B.contentWindow.document);};(!window.frames[C.id])?B.addListener("load",A):A();return B;
}});var Elements=new Native({initialize:function(F,B){B=$extend({ddup:true,cash:true},B);F=F||[];if(B.ddup||B.cash){var G={},E=[];for(var C=0,A=F.length;
C<A;C++){var D=$.element(F[C],!B.cash);if(B.ddup){if(G[D.uid]){continue;}G[D.uid]=true;}E.push(D);}F=E;}return(B.cash)?$extend(F,this):F;}});Elements.implement({filter:function(A,B){if(!A){return this;
}return new Elements(Array.filter(this,(typeof A=="string")?function(C){return C.match(A);}:A,B));}});Elements.multi=function(A){return function(){var B=[];
var F=true;for(var D=0,C=this.length;D<C;D++){var E=this[D][A].apply(this[D],arguments);B.push(E);if(F){F=($type(E)=="element");}}return(F)?new Elements(B):B;
};};Window.implement({$:function(B,C){if(B&&B.$family&&B.uid){return B;}var A=$type(B);return($[A])?$[A](B,C,this.document):null;},$$:function(A){if(arguments.length==1&&typeof A=="string"){return this.document.getElements(A);
}var F=[];var C=Array.flatten(arguments);for(var D=0,B=C.length;D<B;D++){var E=C[D];switch($type(E)){case"element":E=[E];break;case"string":E=this.document.getElements(E,true);
break;default:E=false;}if(E){F.extend(E);}}return new Elements(F);},getDocument:function(){return this.document;},getWindow:function(){return this;}});
$.string=function(C,B,A){C=A.getElementById(C);return(C)?$.element(C,B):null;};$.element=function(A,D){$uid(A);if(!D&&!A.$family&&!(/^object|embed$/i).test(A.tagName)){var B=Element.Prototype;
for(var C in B){A[C]=B[C];}}return A;};$.object=function(B,C,A){if(B.toElement){return $.element(B.toElement(A),C);}return null;};$.textnode=$.whitespace=$.window=$.document=$arguments(0);
Native.implement([Element,Document],{getElement:function(A,B){return $(this.getElements(A,true)[0]||null,B);},getElements:function(A,D){A=A.split(",");
var C=[];var B=(A.length>1);A.each(function(E){var F=this.getElementsByTagName(E.trim());(B)?C.extend(F):C=F;},this);return new Elements(C,{ddup:B,cash:!D});
}});Element.Storage={get:function(A){return(this[A]||(this[A]={}));}};Element.Inserters=new Hash({before:function(B,A){if(A.parentNode){A.parentNode.insertBefore(B,A);
}},after:function(B,A){if(!A.parentNode){return ;}var C=A.nextSibling;(C)?A.parentNode.insertBefore(B,C):A.parentNode.appendChild(B);},bottom:function(B,A){A.appendChild(B);
},top:function(B,A){var C=A.firstChild;(C)?A.insertBefore(B,C):A.appendChild(B);}});Element.Inserters.inside=Element.Inserters.bottom;Element.Inserters.each(function(C,B){var A=B.capitalize();
Element.implement("inject"+A,function(D){C(this,$(D,true));return this;});Element.implement("grab"+A,function(D){C($(D,true),this);return this;});});Element.implement({getDocument:function(){return this.ownerDocument;
},getWindow:function(){return this.ownerDocument.getWindow();},getElementById:function(D,C){var B=this.ownerDocument.getElementById(D);if(!B){return null;
}for(var A=B.parentNode;A!=this;A=A.parentNode){if(!A){return null;}}return $.element(B,C);},set:function(D,B){switch($type(D)){case"object":for(var C in D){this.set(C,D[C]);
}break;case"string":var A=Element.Properties.get(D);(A&&A.set)?A.set.apply(this,Array.slice(arguments,1)):this.setProperty(D,B);}return this;},get:function(B){var A=Element.Properties.get(B);
return(A&&A.get)?A.get.apply(this,Array.slice(arguments,1)):this.getProperty(B);},erase:function(B){var A=Element.Properties.get(B);(A&&A.erase)?A.erase.apply(this,Array.slice(arguments,1)):this.removeProperty(B);
return this;},match:function(A){return(!A||Element.get(this,"tag")==A);},inject:function(B,A){Element.Inserters.get(A||"bottom")(this,$(B,true));return this;
},wraps:function(B,A){B=$(B,true);return this.replaces(B).grab(B,A);},grab:function(B,A){Element.Inserters.get(A||"bottom")($(B,true),this);return this;
},appendText:function(B,A){return this.grab(this.getDocument().newTextNode(B),A);},adopt:function(){Array.flatten(arguments).each(function(A){A=$(A,true);
if(A){this.appendChild(A);}},this);return this;},dispose:function(){return(this.parentNode)?this.parentNode.removeChild(this):this;},clone:function(D,C){switch($type(this)){case"element":var H={};
for(var G=0,E=this.attributes.length;G<E;G++){var B=this.attributes[G],L=B.nodeName.toLowerCase();if(Browser.Engine.trident&&(/input/i).test(this.tagName)&&(/width|height/).test(L)){continue;
}var K=(L=="style"&&this.style)?this.style.cssText:B.nodeValue;if(!$chk(K)||L=="uid"||(L=="id"&&!C)){continue;}if(K!="inherit"&&["string","number"].contains($type(K))){H[L]=K;
}}var J=new Element(this.nodeName.toLowerCase(),H);if(D!==false){for(var I=0,F=this.childNodes.length;I<F;I++){var A=Element.clone(this.childNodes[I],true,C);
if(A){J.grab(A);}}}return J;case"textnode":return document.newTextNode(this.nodeValue);}return null;},replaces:function(A){A=$(A,true);A.parentNode.replaceChild(this,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);
},getComputedStyle:function(B){if(this.currentStyle){return this.currentStyle[B.camelCase()];}var A=this.getWindow().getComputedStyle(this,null);return(A)?A.getPropertyValue([B.hyphenate()]):null;
},empty:function(){$A(this.childNodes).each(function(A){Browser.freeMem(A);Element.empty(A);Element.dispose(A);},this);return this;},destroy:function(){Browser.freeMem(this.empty().dispose());
return null;},getSelected:function(){return new Elements($A(this.options).filter(function(A){return A.selected;}));},toQueryString:function(){var A=[];
this.getElements("input, select, textarea").each(function(B){if(!B.name||B.disabled){return ;}var C=(B.tagName.toLowerCase()=="select")?Element.getSelected(B).map(function(D){return D.value;
}):((B.type=="radio"||B.type=="checkbox")&&!B.checked)?null:B.value;$splat(C).each(function(D){if(D){A.push(B.name+"="+encodeURIComponent(D));}});});return A.join("&");
},getProperty:function(C){var B=Element.Attributes,A=B.Props[C];var D=(A)?this[A]:this.getAttribute(C,2);return(B.Bools[C])?!!D:(A)?D:D||null;},getProperties:function(){var A=$A(arguments);
return A.map(function(B){return this.getProperty(B);},this).associate(A);},setProperty:function(D,E){var C=Element.Attributes,B=C.Props[D],A=$defined(E);
if(B&&C.Bools[D]){E=(E||!A)?true:false;}else{if(!A){return this.removeProperty(D);}}(B)?this[B]=E:this.setAttribute(D,E);return this;},setProperties:function(A){for(var B in A){this.setProperty(B,A[B]);
}return this;},removeProperty:function(D){var C=Element.Attributes,B=C.Props[D],A=(B&&C.Bools[D]);(B)?this[B]=(A)?false:"":this.removeAttribute(D);return this;
},removeProperties:function(){Array.each(arguments,this.removeProperty,this);return this;}});(function(){var A=function(D,B,I,C,F,H){var E=D[I||B];var G=[];
while(E){if(E.nodeType==1&&(!C||Element.match(E,C))){G.push(E);if(!F){break;}}E=E[B];}return(F)?new Elements(G,{ddup:false,cash:!H}):$(G[0],H);};Element.implement({getPrevious:function(B,C){return A(this,"previousSibling",null,B,false,C);
},getAllPrevious:function(B,C){return A(this,"previousSibling",null,B,true,C);},getNext:function(B,C){return A(this,"nextSibling",null,B,false,C);},getAllNext:function(B,C){return A(this,"nextSibling",null,B,true,C);
},getFirst:function(B,C){return A(this,"nextSibling","firstChild",B,false,C);},getLast:function(B,C){return A(this,"previousSibling","lastChild",B,false,C);
},getParent:function(B,C){return A(this,"parentNode",null,B,false,C);},getParents:function(B,C){return A(this,"parentNode",null,B,true,C);},getChildren:function(B,C){return A(this,"nextSibling","firstChild",B,true,C);
},hasChild:function(B){B=$(B,true);return(!!B&&$A(this.getElementsByTagName(B.tagName)).contains(B));}});})();Element.Properties=new Hash;Element.Properties.style={set:function(A){this.style.cssText=A;
},get:function(){return this.style.cssText;},erase:function(){this.style.cssText="";}};Element.Properties.tag={get:function(){return this.tagName.toLowerCase();
}};Element.Properties.href={get:function(){return(!this.href)?null:this.href.replace(new RegExp("^"+document.location.protocol+"//"+document.location.host),"");
}};Element.Properties.html={set:function(){return this.innerHTML=Array.flatten(arguments).join("");}};Native.implement([Element,Window,Document],{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;},retrieve:function(B,A){var D=Element.Storage.get(this.uid);var C=D[B];if($defined(A)&&!$defined(C)){C=D[B]=A;}return $pick(C);},store:function(B,A){var C=Element.Storage.get(this.uid);
C[B]=A;return this;},eliminate:function(A){var B=Element.Storage.get(this.uid);delete B[A];return this;}});Element.Attributes=new Hash({Props:{html:"innerHTML","class":"className","for":"htmlFor",text:(Browser.Engine.trident)?"innerText":"textContent"},Bools:["compact","nowrap","ismap","declare","noshade","checked","disabled","readonly","multiple","selected","noresize","defer"],Camels:["value","accessKey","cellPadding","cellSpacing","colSpan","frameBorder","maxLength","readOnly","rowSpan","tabIndex","useMap"]});
Browser.freeMem=function(A){if(!A){return ;}if(Browser.Engine.trident&&(/object/i).test(A.tagName)){for(var B in A){if(typeof A[B]=="function"){A[B]=$empty;
}}Element.dispose(A);}if(A.uid&&A.removeEvents){A.removeEvents();}};(function(B){var C=B.Bools,A=B.Camels;B.Bools=C=C.associate(C);Hash.extend(Hash.combine(B.Props,C),A.associate(A.map(function(D){return D.toLowerCase();
})));B.erase("Camels");})(Element.Attributes);window.addListener("unload",function(){window.removeListener("unload",arguments.callee);document.purge();
if(Browser.Engine.trident){CollectGarbage();}});Element.Properties.events={set:function(A){this.addEvents(A);}};Native.implement([Element,Window,Document],{addEvent:function(E,G){var H=this.retrieve("events",{});
H[E]=H[E]||{keys:[],values:[]};if(H[E].keys.contains(G)){return this;}H[E].keys.push(G);var F=E,A=Element.Events.get(E),C=G,I=this;if(A){if(A.onAdd){A.onAdd.call(this,G);
}if(A.condition){C=function(J){if(A.condition.call(this,J)){return G.call(this,J);}return false;};}F=A.base||F;}var D=function(){return G.call(I);};var B=Element.NativeEvents[F]||0;
if(B){if(B==2){D=function(J){J=new Event(J,I.getWindow());if(C.call(I,J)===false){J.stop();}};}this.addListener(F,D);}H[E].values.push(D);return this;},removeEvent:function(D,C){var B=this.retrieve("events");
if(!B||!B[D]){return this;}var G=B[D].keys.indexOf(C);if(G==-1){return this;}var A=B[D].keys.splice(G,1)[0];var F=B[D].values.splice(G,1)[0];var E=Element.Events.get(D);
if(E){if(E.onRemove){E.onRemove.call(this,C);}D=E.base||D;}return(Element.NativeEvents[D])?this.removeListener(D,F):this;},addEvents:function(A){for(var B in A){this.addEvent(B,A[B]);
}return this;},removeEvents:function(B){var A=this.retrieve("events");if(!A){return this;}if(!B){for(var C in A){this.removeEvents(C);}A=null;}else{if(A[B]){while(A[B].keys[0]){this.removeEvent(B,A[B].keys[0]);
}A[B]=null;}}return this;},fireEvent:function(D,B,A){var C=this.retrieve("events");if(!C||!C[D]){return this;}C[D].keys.each(function(E){E.create({bind:this,delay:A,"arguments":B})();
},this);return this;},cloneEvents:function(D,A){D=$(D);var C=D.retrieve("events");if(!C){return this;}if(!A){for(var B in C){this.cloneEvents(D,B);}}else{if(C[A]){C[A].keys.each(function(E){this.addEvent(A,E);
},this);}}return this;}});Element.NativeEvents={click:2,dblclick:2,mouseup:2,mousedown:2,contextmenu:2,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:1,unload:1,beforeunload:2,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1};
(function(){var A=function(B){var C=B.relatedTarget;if(C==undefined){return true;}if(C===false){return false;}return($type(this)!="document"&&C!=this&&C.prefix!="xul"&&!this.hasChild(C));
};Element.Events=new Hash({mouseenter:{base:"mouseover",condition:A},mouseleave:{base:"mouseout",condition:A},mousewheel:{base:(Browser.Engine.gecko)?"DOMMouseScroll":"mousewheel"}});
})();Element.Properties.styles={set:function(A){this.setStyles(A);}};Element.Properties.opacity={set:function(A,B){if(!B){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(Browser.Engine.trident){this.style.filter=(A==1)?"":"alpha(opacity="+A*100+")";
}this.style.opacity=A;this.store("opacity",A);},get:function(){return this.retrieve("opacity",1);}};Element.implement({setOpacity:function(A){return this.set("opacity",A,true);
},getOpacity:function(){return this.get("opacity");},setStyle:function(B,A){switch(B){case"opacity":return this.set("opacity",parseFloat(A));case"float":B=(Browser.Engine.trident)?"styleFloat":"cssFloat";
}B=B.camelCase();if($type(A)!="string"){var C=(Element.Styles.get(B)||"@").split(" ");A=$splat(A).map(function(E,D){if(!C[D]){return"";}return($type(E)=="number")?C[D].replace("@",Math.round(E)):E;
}).join(" ");}else{if(A==String(Number(A))){A=Math.round(A);}}this.style[B]=A;return this;},getStyle:function(G){switch(G){case"opacity":return this.get("opacity");
case"float":G=(Browser.Engine.trident)?"styleFloat":"cssFloat";}G=G.camelCase();var A=this.style[G];if(!$chk(A)){A=[];for(var F in Element.ShortStyles){if(G!=F){continue;
}for(var E in Element.ShortStyles[F]){A.push(this.getStyle(E));}return A.join(" ");}A=this.getComputedStyle(G);}if(A){A=String(A);var C=A.match(/rgba?\([\d\s,]+\)/);
if(C){A=A.replace(C[0],C[0].rgbToHex());}}if(Browser.Engine.presto||(Browser.Engine.trident&&!$chk(parseInt(A)))){if(G.test(/^(height|width)$/)){var B=(G=="width")?["left","right"]:["top","bottom"],D=0;
B.each(function(H){D+=this.getStyle("border-"+H+"-width").toInt()+this.getStyle("padding-"+H).toInt();},this);return this["offset"+G.capitalize()]-D+"px";
}if(Browser.Engine.presto&&String(A).test("px")){return A;}if(G.test(/(border(.+)Width|margin|padding)/)){return"0px";}}return A;},setStyles:function(B){for(var A in B){this.setStyle(A,B[A]);
}return this;},getStyles:function(){var A={};Array.each(arguments,function(B){A[B]=this.getStyle(B);},this);return A;}});Element.Styles=new Hash({left:"@px",top:"@px",bottom:"@px",right:"@px",width:"@px",height:"@px",maxWidth:"@px",maxHeight:"@px",minWidth:"@px",minHeight:"@px",backgroundColor:"rgb(@, @, @)",backgroundPosition:"@px @px",color:"rgb(@, @, @)",fontSize:"@px",letterSpacing:"@px",lineHeight:"@px",clip:"rect(@px @px @px @px)",margin:"@px @px @px @px",padding:"@px @px @px @px",border:"@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",borderWidth:"@px @px @px @px",borderStyle:"@ @ @ @",borderColor:"rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",zIndex:"@",zoom:"@",fontWeight:"@",textIndent:"@px",opacity:"@"});
Element.ShortStyles={margin:{},padding:{},border:{},borderWidth:{},borderStyle:{},borderColor:{}};["Top","Right","Bottom","Left"].each(function(G){var F=Element.ShortStyles;
var B=Element.Styles;["margin","padding"].each(function(H){var I=H+G;F[H][I]=B[I]="@px";});var E="border"+G;F.border[E]=B[E]="@px @ rgb(@, @, @)";var D=E+"Width",A=E+"Style",C=E+"Color";
F[E]={};F.borderWidth[D]=F[E][D]=B[D]="@px";F.borderStyle[A]=F[E][A]=B[A]="@";F.borderColor[C]=F[E][C]=B[C]="rgb(@, @, @)";});(function(){Element.implement({scrollTo:function(H,I){if(B(this)){this.getWindow().scrollTo(H,I);
}else{this.scrollLeft=H;this.scrollTop=I;}return this;},getSize:function(){if(B(this)){return this.getWindow().getSize();}return{x:this.offsetWidth,y:this.offsetHeight};
},getScrollSize:function(){if(B(this)){return this.getWindow().getScrollSize();}return{x:this.scrollWidth,y:this.scrollHeight};},getScroll:function(){if(B(this)){return this.getWindow().getScroll();
}return{x:this.scrollLeft,y:this.scrollTop};},getScrolls:function(){var I=this,H={x:0,y:0};while(I&&!B(I)){H.x+=I.scrollLeft;H.y+=I.scrollTop;I=I.parentNode;
}return H;},getOffsetParent:function(){var H=this;if(B(H)){return null;}if(!Browser.Engine.trident){return H.offsetParent;}while((H=H.parentNode)&&!B(H)){if(D(H,"position")!="static"){return H;
}}return null;},getOffsets:function(){var I=this,H={x:0,y:0};if(B(this)){return H;}while(I&&!B(I)){H.x+=I.offsetLeft;H.y+=I.offsetTop;if(Browser.Engine.gecko){if(!F(I)){H.x+=C(I);
H.y+=G(I);}var J=I.parentNode;if(J&&D(J,"overflow")!="visible"){H.x+=C(J);H.y+=G(J);}}else{if(I!=this&&(Browser.Engine.trident||Browser.Engine.webkit)){H.x+=C(I);
H.y+=G(I);}}I=I.offsetParent;if(Browser.Engine.trident){while(I&&!I.currentStyle.hasLayout){I=I.offsetParent;}}}if(Browser.Engine.gecko&&!F(this)){H.x-=C(this);
H.y-=G(this);}return H;},getPosition:function(K){if(B(this)){return{x:0,y:0};}var L=this.getOffsets(),I=this.getScrolls();var H={x:L.x-I.x,y:L.y-I.y};var J=(K&&(K=$(K)))?K.getPosition():{x:0,y:0};
return{x:H.x-J.x,y:H.y-J.y};},getCoordinates:function(J){if(B(this)){return this.getWindow().getCoordinates();}var H=this.getPosition(J),I=this.getSize();
var K={left:H.x,top:H.y,width:I.x,height:I.y};K.right=K.left+K.width;K.bottom=K.top+K.height;return K;},computePosition:function(H){return{left:H.x-E(this,"margin-left"),top:H.y-E(this,"margin-top")};
},position:function(H){return this.setStyles(this.computePosition(H));}});Native.implement([Document,Window],{getSize:function(){var I=this.getWindow();
if(Browser.Engine.presto||Browser.Engine.webkit){return{x:I.innerWidth,y:I.innerHeight};}var H=A(this);return{x:H.clientWidth,y:H.clientHeight};},getScroll:function(){var I=this.getWindow();
var H=A(this);return{x:I.pageXOffset||H.scrollLeft,y:I.pageYOffset||H.scrollTop};},getScrollSize:function(){var I=A(this);var H=this.getSize();return{x:Math.max(I.scrollWidth,H.x),y:Math.max(I.scrollHeight,H.y)};
},getPosition:function(){return{x:0,y:0};},getCoordinates:function(){var H=this.getSize();return{top:0,left:0,bottom:H.y,right:H.x,height:H.y,width:H.x};
}});var D=Element.getComputedStyle;function E(H,I){return D(H,I).toInt()||0;}function F(H){return D(H,"-moz-box-sizing")=="border-box";}function G(H){return E(H,"border-top-width");
}function C(H){return E(H,"border-left-width");}function B(H){return(/^(?:body|html)$/i).test(H.tagName);}function A(H){var I=H.getDocument();return(!I.compatMode||I.compatMode=="CSS1Compat")?I.html:I.body;
}})();Native.implement([Window,Document,Element],{getHeight:function(){return this.getSize().y;},getWidth:function(){return this.getSize().x;},getScrollTop:function(){return this.getScroll().y;
},getScrollLeft:function(){return this.getScroll().x;},getScrollHeight:function(){return this.getScrollSize().y;},getScrollWidth:function(){return this.getScrollSize().x;
},getTop:function(){return this.getPosition().y;},getLeft:function(){return this.getPosition().x;}});Native.implement([Document,Element],{getElements:function(H,G){H=H.split(",");
var C,E={};for(var D=0,B=H.length;D<B;D++){var A=H[D],F=Selectors.Utils.search(this,A,E);if(D!=0&&F.item){F=$A(F);}C=(D==0)?F:(C.item)?$A(C).concat(F):C.concat(F);
}return new Elements(C,{ddup:(H.length>1),cash:!G});}});Element.implement({match:function(B){if(!B){return true;}var D=Selectors.Utils.parseTagAndID(B);
var A=D[0],E=D[1];if(!Selectors.Filters.byID(this,E)||!Selectors.Filters.byTag(this,A)){return false;}var C=Selectors.Utils.parseSelector(B);return(C)?Selectors.Utils.filter(this,C,{}):true;
}});var Selectors={Cache:{nth:{},parsed:{}}};Selectors.RegExps={id:(/#([\w-]+)/),tag:(/^(\w+|\*)/),quick:(/^(\w+|\*)$/),splitter:(/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g),combined:(/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)["']?(.*?)["']?)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g)};
Selectors.Utils={chk:function(B,C){if(!C){return true;}var A=$uid(B);if(!C[A]){return C[A]=true;}return false;},parseNthArgument:function(F){if(Selectors.Cache.nth[F]){return Selectors.Cache.nth[F];
}var C=F.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/);if(!C){return false;}var E=parseInt(C[1]);var B=(E||E===0)?E:1;var D=C[2]||false;var A=parseInt(C[3])||0;
if(B!=0){A--;while(A<1){A+=B;}while(A>=B){A-=B;}}else{B=A;D="index";}switch(D){case"n":C={a:B,b:A,special:"n"};break;case"odd":C={a:2,b:0,special:"n"};
break;case"even":C={a:2,b:1,special:"n"};break;case"first":C={a:0,special:"index"};break;case"last":C={special:"last-child"};break;case"only":C={special:"only-child"};
break;default:C={a:(B-1),special:"index"};}return Selectors.Cache.nth[F]=C;},parseSelector:function(E){if(Selectors.Cache.parsed[E]){return Selectors.Cache.parsed[E];
}var D,H={classes:[],pseudos:[],attributes:[]};while((D=Selectors.RegExps.combined.exec(E))){var I=D[1],G=D[2],F=D[3],B=D[4],C=D[5],J=D[6];if(I){H.classes.push(I);
}else{if(C){var A=Selectors.Pseudo.get(C);if(A){H.pseudos.push({parser:A,argument:J});}else{H.attributes.push({name:C,operator:"=",value:J});}}else{if(G){H.attributes.push({name:G,operator:F,value:B});
}}}}if(!H.classes.length){delete H.classes;}if(!H.attributes.length){delete H.attributes;}if(!H.pseudos.length){delete H.pseudos;}if(!H.classes&&!H.attributes&&!H.pseudos){H=null;
}return Selectors.Cache.parsed[E]=H;},parseTagAndID:function(B){var A=B.match(Selectors.RegExps.tag);var C=B.match(Selectors.RegExps.id);return[(A)?A[1]:"*",(C)?C[1]:false];
},filter:function(F,C,E){var D;if(C.classes){for(D=C.classes.length;D--;D){var G=C.classes[D];if(!Selectors.Filters.byClass(F,G)){return false;}}}if(C.attributes){for(D=C.attributes.length;
D--;D){var B=C.attributes[D];if(!Selectors.Filters.byAttribute(F,B.name,B.operator,B.value)){return false;}}}if(C.pseudos){for(D=C.pseudos.length;D--;D){var A=C.pseudos[D];
if(!Selectors.Filters.byPseudo(F,A.parser,A.argument,E)){return false;}}}return true;},getByTagAndID:function(B,A,D){if(D){var C=(B.getElementById)?B.getElementById(D,true):Element.getElementById(B,D,true);
return(C&&Selectors.Filters.byTag(C,A))?[C]:[];}else{return B.getElementsByTagName(A);}},search:function(J,I,O){var B=[];var C=I.trim().replace(Selectors.RegExps.splitter,function(Z,Y,X){B.push(Y);
return":)"+X;}).split(":)");var K,F,E,V;for(var U=0,Q=C.length;U<Q;U++){var T=C[U];if(U==0&&Selectors.RegExps.quick.test(T)){K=J.getElementsByTagName(T);
continue;}var A=B[U-1];var L=Selectors.Utils.parseTagAndID(T);var W=L[0],M=L[1];if(U==0){K=Selectors.Utils.getByTagAndID(J,W,M);}else{var D={},H=[];for(var S=0,R=K.length;
S<R;S++){H=Selectors.Getters[A](H,K[S],W,M,D);}K=H;}var G=Selectors.Utils.parseSelector(T);if(G){E=[];for(var P=0,N=K.length;P<N;P++){V=K[P];if(Selectors.Utils.filter(V,G,O)){E.push(V);
}}K=E;}}return K;}};Selectors.Getters={" ":function(H,G,I,A,E){var D=Selectors.Utils.getByTagAndID(G,I,A);for(var C=0,B=D.length;C<B;C++){var F=D[C];if(Selectors.Utils.chk(F,E)){H.push(F);
}}return H;},">":function(H,G,I,A,F){var C=Selectors.Utils.getByTagAndID(G,I,A);for(var E=0,D=C.length;E<D;E++){var B=C[E];if(B.parentNode==G&&Selectors.Utils.chk(B,F)){H.push(B);
}}return H;},"+":function(C,B,A,E,D){while((B=B.nextSibling)){if(B.nodeType==1){if(Selectors.Utils.chk(B,D)&&Selectors.Filters.byTag(B,A)&&Selectors.Filters.byID(B,E)){C.push(B);
}break;}}return C;},"~":function(C,B,A,E,D){while((B=B.nextSibling)){if(B.nodeType==1){if(!Selectors.Utils.chk(B,D)){break;}if(Selectors.Filters.byTag(B,A)&&Selectors.Filters.byID(B,E)){C.push(B);
}}}return C;}};Selectors.Filters={byTag:function(B,A){return(A=="*"||(B.tagName&&B.tagName.toLowerCase()==A));},byID:function(A,B){return(!B||(A.id&&A.id==B));
},byClass:function(B,A){return(B.className&&B.className.contains(A," "));},byPseudo:function(A,D,C,B){return D.call(A,C,B);},byAttribute:function(C,D,B,E){var A=Element.prototype.getProperty.call(C,D);
if(!A){return false;}if(!B||E==undefined){return true;}switch(B){case"=":return(A==E);case"*=":return(A.contains(E));case"^=":return(A.substr(0,E.length)==E);
case"$=":return(A.substr(A.length-E.length)==E);case"!=":return(A!=E);case"~=":return A.contains(E," ");case"|=":return A.contains(E,"-");}return false;
}};Selectors.Pseudo=new Hash({empty:function(){return !(this.innerText||this.textContent||"").length;},not:function(A){return !Element.match(this,A);},contains:function(A){return(this.innerText||this.textContent||"").contains(A);
},"first-child":function(){return Selectors.Pseudo.index.call(this,0);},"last-child":function(){var A=this;while((A=A.nextSibling)){if(A.nodeType==1){return false;
}}return true;},"only-child":function(){var B=this;while((B=B.previousSibling)){if(B.nodeType==1){return false;}}var A=this;while((A=A.nextSibling)){if(A.nodeType==1){return false;
}}return true;},"nth-child":function(G,E){G=(G==undefined)?"n":G;var C=Selectors.Utils.parseNthArgument(G);if(C.special!="n"){return Selectors.Pseudo[C.special].call(this,C.a,E);
}var F=0;E.positions=E.positions||{};var D=$uid(this);if(!E.positions[D]){var B=this;while((B=B.previousSibling)){if(B.nodeType!=1){continue;}F++;var A=E.positions[$uid(B)];
if(A!=undefined){F=A+F;break;}}E.positions[D]=F;}return(E.positions[D]%C.a==C.b);},index:function(A){var B=this,C=0;while((B=B.previousSibling)){if(B.nodeType==1&&++C>A){return false;
}}return(C==A);},even:function(B,A){return Selectors.Pseudo["nth-child"].call(this,"2n+1",A);},odd:function(B,A){return Selectors.Pseudo["nth-child"].call(this,"2n",A);
}});Element.Events.domready={onAdd:function(A){if(Browser.loaded){A.call(this);}}};(function(){var B=function(){if(Browser.loaded){return ;}Browser.loaded=true;
window.fireEvent("domready");document.fireEvent("domready");};switch(Browser.Engine.name){case"webkit":(function(){(["loaded","complete"].contains(document.readyState))?B():arguments.callee.delay(50);
})();break;case"trident":var A=document.createElement("div");(function(){($try(function(){A.doScroll("left");return $(A).inject(document.body).set("html","temp").dispose();
}))?B():arguments.callee.delay(50);})();break;default:window.addEvent("load",B);document.addEvent("DOMContentLoaded",B);}})();var Cookie=new Class({Implements:Options,options:{path:false,domain:false,duration:false,secure:false,document:document},initialize:function(B,A){this.key=B;
this.setOptions(A);},write:function(B){B=encodeURIComponent(B);if(this.options.domain){B+="; domain="+this.options.domain;}if(this.options.path){B+="; path="+this.options.path;
}if(this.options.duration){var A=new Date();A.setTime(A.getTime()+this.options.duration*24*60*60*1000);B+="; expires="+A.toGMTString();}if(this.options.secure){B+="; secure";
}this.options.document.cookie=this.key+"="+B;return this;},read:function(){var A=this.options.document.cookie.match("(?:^|;)\\s*"+this.key.escapeRegExp()+"=([^;]*)");
return(A)?decodeURIComponent(A[1]):null;},dispose:function(){new Cookie(this.key,$merge(this.options,{duration:-1})).write("");return this;}});Cookie.write=function(B,C,A){return new Cookie(B,A).write(C);
};Cookie.read=function(A){return new Cookie(A).read();};Cookie.dispose=function(B,A){return new Cookie(B,A).dispose();};var Swiff=new Class({Implements:[Options],options:{id:null,height:1,width:1,container:null,properties:{},params:{quality:"high",allowScriptAccess:"always",wMode:"transparent",swLiveConnect:true},callBacks:{},vars:{}},toElement:function(){return this.object;
},initialize:function(L,M){this.instance="Swiff_"+$time();this.setOptions(M);M=this.options;var B=this.id=M.id||this.instance;var A=$(M.container);Swiff.CallBacks[this.instance]={};
var E=M.params,G=M.vars,F=M.callBacks;var H=$extend({height:M.height,width:M.width},M.properties);var K=this;for(var D in F){Swiff.CallBacks[this.instance][D]=(function(N){return function(){return N.apply(K.object,arguments);
};})(F[D]);G[D]="Swiff.CallBacks."+this.instance+"."+D;}E.flashVars=Hash.toQueryString(G);if(Browser.Engine.trident){H.classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
E.movie=L;}else{H.type="application/x-shockwave-flash";H.data=L;}var J='<object id="'+B+'"';for(var I in H){J+=" "+I+'="'+H[I]+'"';}J+=">";for(var C in E){if(E[C]){J+='<param name="'+C+'" value="'+E[C]+'" />';
}}J+="</object>";this.object=((A)?A.empty():new Element("div")).set("html",J).firstChild;},replaces:function(A){A=$(A,true);A.parentNode.replaceChild(this.toElement(),A);
return this;},inject:function(A){$(A,true).appendChild(this.toElement());return this;},remote:function(){return Swiff.remote.apply(Swiff,[this.toElement()].extend(arguments));
}});Swiff.CallBacks={};Swiff.remote=function(obj,fn){var rs=obj.CallFunction('<invoke name="'+fn+'" returntype="javascript">'+__flash__argumentsToXML(arguments,2)+"</invoke>");
return eval(rs);};var Fx=new Class({Implements:[Chain,Events,Options],options:{fps:50,unit:false,duration:500,link:"ignore",transition:function(A){return -(Math.cos(Math.PI*A)-1)/2;
}},initialize:function(A){this.subject=this.subject||this;this.setOptions(A);this.options.duration=Fx.Durations[this.options.duration]||this.options.duration.toInt();
var B=this.options.wait;if(B===false){this.options.link="cancel";}},step:function(){var A=$time();if(A<this.time+this.options.duration){var B=this.options.transition((A-this.time)/this.options.duration);
this.set(this.compute(this.from,this.to,B));}else{this.set(this.compute(this.from,this.to,1));this.complete();}},set:function(A){return A;},compute:function(C,B,A){return Fx.compute(C,B,A);
},check:function(A){if(!this.timer){return true;}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(A.bind(this,Array.slice(arguments,1)));
return false;}return false;},start:function(B,A){if(!this.check(arguments.callee,B,A)){return this;}this.from=B;this.to=A;this.time=0;this.startTimer();
this.onStart();return this;},complete:function(){if(this.stopTimer()){this.onComplete();}return this;},cancel:function(){if(this.stopTimer()){this.onCancel();
}return this;},onStart:function(){this.fireEvent("start",this.subject);},onComplete:function(){this.fireEvent("complete",this.subject);if(!this.callChain()){this.fireEvent("chainComplete",this.subject);
}},onCancel:function(){this.fireEvent("cancel",this.subject).clearChain();},pause:function(){this.stopTimer();return this;},resume:function(){this.startTimer();
return this;},stopTimer:function(){if(!this.timer){return false;}this.time=$time()-this.time;this.timer=$clear(this.timer);return true;},startTimer:function(){if(this.timer){return false;
}this.time=$time()-this.time;this.timer=this.step.periodical(Math.round(1000/this.options.fps),this);return true;}});Fx.compute=function(C,B,A){return(B-C)*A+C;
};Fx.Durations={"short":250,normal:500,"long":1000};Fx.CSS=new Class({Extends:Fx,prepare:function(D,E,B){B=$splat(B);var C=B[1];if(!$chk(C)){B[1]=B[0];
B[0]=D.getStyle(E);}var A=B.map(this.parse);return{from:A[0],to:A[1]};},parse:function(A){A=$lambda(A)();A=(typeof A=="string")?A.split(" "):$splat(A);
return A.map(function(C){C=String(C);var B=false;Fx.CSS.Parsers.each(function(F,E){if(B){return ;}var D=F.parse(C);if($chk(D)){B={value:D,parser:F};}});
B=B||{value:C,parser:Fx.CSS.Parsers.String};return B;});},compute:function(D,C,B){var A=[];(Math.min(D.length,C.length)).times(function(E){A.push({value:D[E].parser.compute(D[E].value,C[E].value,B),parser:D[E].parser});
});A.$family={name:"fx:css:value"};return A;},serve:function(C,B){if($type(C)!="fx:css:value"){C=this.parse(C);}var A=[];C.each(function(D){A=A.concat(D.parser.serve(D.value,B));
});return A;},render:function(A,D,C,B){A.setStyle(D,this.serve(C,B));},search:function(A){if(Fx.CSS.Cache[A]){return Fx.CSS.Cache[A];}var B={};Array.each(document.styleSheets,function(E,D){var C=E.href;
if(C&&C.contains("://")&&!C.contains(document.domain)){return ;}var F=E.rules||E.cssRules;Array.each(F,function(I,G){if(!I.style){return ;}var H=(I.selectorText)?I.selectorText.replace(/^\w+/,function(J){return J.toLowerCase();
}):null;if(!H||!H.test("^"+A+"$")){return ;}Element.Styles.each(function(K,J){if(!I.style[J]||Element.ShortStyles[J]){return ;}K=String(I.style[J]);B[J]=(K.test(/^rgb/))?K.rgbToHex():K;
});});});return Fx.CSS.Cache[A]=B;}});Fx.CSS.Cache={};Fx.CSS.Parsers=new Hash({Color:{parse:function(A){if(A.match(/^#[0-9a-f]{3,6}$/i)){return A.hexToRgb(true);
}return((A=A.match(/(\d+),\s*(\d+),\s*(\d+)/)))?[A[1],A[2],A[3]]:false;},compute:function(C,B,A){return C.map(function(E,D){return Math.round(Fx.compute(C[D],B[D],A));
});},serve:function(A){return A.map(Number);}},Number:{parse:parseFloat,compute:Fx.compute,serve:function(B,A){return(A)?B+A:B;}},String:{parse:$lambda(false),compute:$arguments(1),serve:$arguments(0)}});
Fx.Tween=new Class({Extends:Fx.CSS,initialize:function(B,A){this.element=this.subject=$(B);this.parent(A);},set:function(B,A){if(arguments.length==1){A=B;
B=this.property||this.options.property;}this.render(this.element,B,A,this.options.unit);return this;},start:function(C,E,D){if(!this.check(arguments.callee,C,E,D)){return this;
}var B=Array.flatten(arguments);this.property=this.options.property||B.shift();var A=this.prepare(this.element,this.property,B);return this.parent(A.from,A.to);
}});Element.Properties.tween={set:function(A){var B=this.retrieve("tween");if(B){B.cancel();}return this.eliminate("tween").store("tween:options",$extend({link:"cancel"},A));
},get:function(A){if(A||!this.retrieve("tween")){if(A||!this.retrieve("tween:options")){this.set("tween",A);}this.store("tween",new Fx.Tween(this,this.retrieve("tween:options")));
}return this.retrieve("tween");}};Element.implement({tween:function(A,C,B){this.get("tween").start(arguments);return this;},fade:function(C){var E=this.get("tween"),D="opacity",A;
C=$pick(C,"toggle");switch(C){case"in":E.start(D,1);break;case"out":E.start(D,0);break;case"show":E.set(D,1);break;case"hide":E.set(D,0);break;case"toggle":var B=this.retrieve("fade:flag",this.get("opacity")==1);
E.start(D,(B)?0:1);this.store("fade:flag",!B);A=true;break;default:E.start(D,arguments);}if(!A){this.eliminate("fade:flag");}return this;},highlight:function(C,A){if(!A){A=this.retrieve("highlight:original",this.getStyle("background-color"));
A=(A=="transparent")?"#fff":A;}var B=this.get("tween");B.start("background-color",C||"#ffff88",A).chain(function(){this.setStyle("background-color",this.retrieve("highlight:original"));
B.callChain();}.bind(this));return this;}});Fx.Morph=new Class({Extends:Fx.CSS,initialize:function(B,A){this.element=this.subject=$(B);this.parent(A);},set:function(A){if(typeof A=="string"){A=this.search(A);
}for(var B in A){this.render(this.element,B,A[B],this.options.unit);}return this;},compute:function(E,D,C){var A={};for(var B in E){A[B]=this.parent(E[B],D[B],C);
}return A;},start:function(B){if(!this.check(arguments.callee,B)){return this;}if(typeof B=="string"){B=this.search(B);}var E={},D={};for(var C in B){var A=this.prepare(this.element,C,B[C]);
E[C]=A.from;D[C]=A.to;}return this.parent(E,D);}});Element.Properties.morph={set:function(A){var B=this.retrieve("morph");if(B){B.cancel();}return this.eliminate("morph").store("morph:options",$extend({link:"cancel"},A));
},get:function(A){if(A||!this.retrieve("morph")){if(A||!this.retrieve("morph:options")){this.set("morph",A);}this.store("morph",new Fx.Morph(this,this.retrieve("morph:options")));
}return this.retrieve("morph");}};Element.implement({morph:function(A){this.get("morph").start(A);return this;}});(function(){var A=Fx.prototype.initialize;
Fx.prototype.initialize=function(B){A.call(this,B);var C=this.options.transition;if(typeof C=="string"&&(C=C.split(":"))){var D=Fx.Transitions;D=D[C[0]]||D[C[0].capitalize()];
if(C[1]){D=D["ease"+C[1].capitalize()+(C[2]?C[2].capitalize():"")];}this.options.transition=D;}};})();Fx.Transition=function(B,A){A=$splat(A);return $extend(B,{easeIn:function(C){return B(C,A);
},easeOut:function(C){return 1-B(1-C,A);},easeInOut:function(C){return(C<=0.5)?B(2*C,A)/2:(2-B(2*(1-C),A))/2;}});};Fx.Transitions=new Hash({linear:$arguments(0)});
Fx.Transitions.extend=function(A){for(var B in A){Fx.Transitions[B]=new Fx.Transition(A[B]);}};Fx.Transitions.extend({Pow:function(B,A){return Math.pow(B,A[0]||6);
},Expo:function(A){return Math.pow(2,8*(A-1));},Circ:function(A){return 1-Math.sin(Math.acos(A));},Sine:function(A){return 1-Math.sin((1-A)*Math.PI/2);
},Back:function(B,A){A=A[0]||1.618;return Math.pow(B,2)*((A+1)*B-A);},Bounce:function(D){var C;for(var B=0,A=1;1;B+=A,A/=2){if(D>=(7-4*B)/11){C=-Math.pow((11-6*B-11*D)/4,2)+A*A;
break;}}return C;},Elastic:function(B,A){return Math.pow(2,10*--B)*Math.cos(20*B*Math.PI*(A[0]||1)/3);}});["Quad","Cubic","Quart","Quint"].each(function(B,A){Fx.Transitions[B]=new Fx.Transition(function(C){return Math.pow(C,[A+2]);
});});var Request=new Class({Implements:[Chain,Events,Options],options:{url:"",data:"",headers:{"X-Requested-With":"XMLHttpRequest",Accept:"text/javascript, text/html, application/xml, text/xml, */*"},async:true,format:false,method:"post",link:"ignore",isSuccess:null,emulation:true,urlEncoded:true,encoding:"utf-8",evalScripts:false,evalResponse:false},initialize:function(A){this.xhr=new Browser.Request();
this.setOptions(A);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers=new Hash(this.options.headers);},onStateChange:function(){if(this.xhr.readyState!=4||!this.running){return ;
}this.running=false;this.status=0;$try(function(){this.status=this.xhr.status;}.bind(this));if(this.options.isSuccess.call(this,this.status)){this.response={text:this.xhr.responseText,xml:this.xhr.responseXML};
this.success(this.response.text,this.response.xml);}else{this.response={text:null,xml:null};this.failure();}this.xhr.onreadystatechange=$empty;},isSuccess:function(){return((this.status>=200)&&(this.status<300));
},processScripts:function(A){if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){return $exec(A);}return A.stripScripts(this.options.evalScripts);
},success:function(B,A){this.onSuccess(this.processScripts(B),A);},onSuccess:function(){this.fireEvent("complete",arguments).fireEvent("success",arguments).callChain();
},failure:function(){this.onFailure();},onFailure:function(){this.fireEvent("complete").fireEvent("failure",this.xhr);},setHeader:function(A,B){this.headers.set(A,B);
return this;},getHeader:function(A){return $try(function(){return this.xhr.getResponseHeader(A);}.bind(this));},check:function(A){if(!this.running){return true;
}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(A.bind(this,Array.slice(arguments,1)));return false;}return false;
},send:function(I){if(!this.check(arguments.callee,I)){return this;}this.running=true;var G=$type(I);if(G=="string"||G=="element"){I={data:I};}var D=this.options;
I=$extend({data:D.data,url:D.url,method:D.method},I);var E=I.data,B=I.url,A=I.method;switch($type(E)){case"element":E=$(E).toQueryString();break;case"object":case"hash":E=Hash.toQueryString(E);
}if(this.options.format){var H="format="+this.options.format;E=(E)?H+"&"+E:H;}if(this.options.emulation&&["put","delete"].contains(A)){var F="_method="+A;
E=(E)?F+"&"+E:F;A="post";}if(this.options.urlEncoded&&A=="post"){var C=(this.options.encoding)?"; charset="+this.options.encoding:"";this.headers.set("Content-type","application/x-www-form-urlencoded"+C);
}if(E&&A=="get"){B=B+(B.contains("?")?"&":"?")+E;E=null;}this.xhr.open(A.toUpperCase(),B,this.options.async);this.xhr.onreadystatechange=this.onStateChange.bind(this);
this.headers.each(function(K,J){if(!$try(function(){this.xhr.setRequestHeader(J,K);return true;}.bind(this))){this.fireEvent("exception",[J,K]);}},this);
this.fireEvent("request");this.xhr.send(E);if(!this.options.async){this.onStateChange();}return this;},cancel:function(){if(!this.running){return this;
}this.running=false;this.xhr.abort();this.xhr.onreadystatechange=$empty;this.xhr=new Browser.Request();this.fireEvent("cancel");return this;}});(function(){var A={};
["get","post","put","delete","GET","POST","PUT","DELETE"].each(function(B){A[B]=function(){var C=Array.link(arguments,{url:String.type,data:$defined});
return this.send($extend(C,{method:B.toLowerCase()}));};});Request.implement(A);})();Element.Properties.send={set:function(A){var B=this.retrieve("send");
if(B){B.cancel();}return this.eliminate("send").store("send:options",$extend({data:this,link:"cancel",method:this.get("method")||"post",url:this.get("action")},A));
},get:function(A){if(A||!this.retrieve("send")){if(A||!this.retrieve("send:options")){this.set("send",A);}this.store("send",new Request(this.retrieve("send:options")));
}return this.retrieve("send");}};Element.implement({send:function(A){var B=this.get("send");B.send({data:this,url:A||B.options.url});return this;}});Request.HTML=new Class({Extends:Request,options:{update:false,evalScripts:true,filter:false},processHTML:function(C){var B=C.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
C=(B)?B[1]:C;var A=new Element("div");return $try(function(){var D="<root>"+C+"</root>",G;if(Browser.Engine.trident){G=new ActiveXObject("Microsoft.XMLDOM");
G.async=false;G.loadXML(D);}else{G=new DOMParser().parseFromString(D,"text/xml");}D=G.getElementsByTagName("root")[0];for(var F=0,E=D.childNodes.length;
F<E;F++){var H=Element.clone(D.childNodes[F],true,true);if(H){A.grab(H);}}return A;})||A.set("html",C);},success:function(D){var C=this.options,B=this.response;
B.html=D.stripScripts(function(E){B.javascript=E;});var A=this.processHTML(B.html);B.tree=A.childNodes;B.elements=A.getElements("*");if(C.filter){B.tree=B.elements.filter(C.filter);
}if(C.update){$(C.update).empty().adopt(B.tree);}if(C.evalScripts){$exec(B.javascript);}this.onSuccess(B.tree,B.elements,B.html,B.javascript);}});Element.Properties.load={set:function(A){var B=this.retrieve("load");
if(B){send.cancel();}return this.eliminate("load").store("load:options",$extend({data:this,link:"cancel",update:this,method:"get"},A));},get:function(A){if(A||!this.retrieve("load")){if(A||!this.retrieve("load:options")){this.set("load",A);
}this.store("load",new Request.HTML(this.retrieve("load:options")));}return this.retrieve("load");}};Element.implement({load:function(){this.get("load").send(Array.link(arguments,{data:Object.type,url:String.type}));
return this;}});

Request.JSON=new Class({Extends:Request,options:{secure:true},initialize:function(a){this.parent(a);this.headers.extend({Accept:"application/json","X-Request":"JSON"});},success:function(a){this.response.json=JSON.decode(a,this.options.secure);this.onSuccess(this.response.json,a);}});

var JSON=new Hash({encode:function(B){switch($type(B)){case"string":return'"'+B.replace(/[\x00-\x1f\\"]/g,JSON.$replaceChars)+'"';
case"array":return"["+String(B.map(JSON.encode).filter($defined))+"]";case"object":case"hash":var A=[];Hash.each(B,function(E,D){var C=JSON.encode(E);if(C){A.push(JSON.encode(D)+":"+C);
}});return"{"+A+"}";case"number":case"boolean":return String(B);case false:return"null";}return null;},$specialChars:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},$replaceChars:function(A){return JSON.$specialChars[A]||"\\u00"+Math.floor(A.charCodeAt()/16).toString(16)+(A.charCodeAt()%16).toString(16);
},decode:function(string,secure){if($type(string)!="string"||!string.length){return null;}if(secure&&!(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"/g,""))){return null;
}return eval("("+string+")");}});

Fx.Slide=new Class({Extends:Fx,options:{mode:"vertical"},initialize:function(B,A){this.addEvent("complete",function(){this.open=(this.wrapper["offset"+this.layout.capitalize()]!=0);
if(this.open&&Browser.Engine.webkit419){this.element.dispose().inject(this.wrapper);}},true);this.element=this.subject=$(B);this.parent(A);var C=this.element.retrieve("wrapper");
this.wrapper=C||new Element("div",{styles:$extend(this.element.getStyles("margin","position"),{overflow:"hidden"})}).wraps(this.element);this.element.store("wrapper",this.wrapper).setStyle("margin",0);
this.now=[];this.open=true;},vertical:function(){this.margin="margin-top";this.layout="height";this.offset=this.element.offsetHeight;},horizontal:function(){this.margin="margin-left";
this.layout="width";this.offset=this.element.offsetWidth;},set:function(A){this.element.setStyle(this.margin,A[0]);this.wrapper.setStyle(this.layout,A[1]);
return this;},compute:function(E,D,C){var B=[];var A=2;A.times(function(F){B[F]=Fx.compute(E[F],D[F],C);});return B;},start:function(B,E){if(!this.check(arguments.callee,B,E)){return this;
}this[E||this.options.mode]();var D=this.element.getStyle(this.margin).toInt();var C=this.wrapper.getStyle(this.layout).toInt();var A=[[D,C],[0,this.offset]];
var G=[[D,C],[-this.offset,0]];var F;switch(B){case"in":F=A;break;case"out":F=G;break;case"toggle":F=(this.wrapper["offset"+this.layout.capitalize()]==0)?A:G;
}return this.parent(F[0],F[1]);},slideIn:function(A){return this.start("in",A);},slideOut:function(A){return this.start("out",A);},hide:function(A){this[A||this.options.mode]();
this.open=false;return this.set([-this.offset,0]);},show:function(A){this[A||this.options.mode]();this.open=true;return this.set([0,this.offset]);},toggle:function(A){return this.start("toggle",A);
}});Element.Properties.slide={set:function(B){var A=this.retrieve("slide");if(A){A.cancel();}return this.eliminate("slide").store("slide:options",$extend({link:"cancel"},B));
},get:function(A){if(A||!this.retrieve("slide")){if(A||!this.retrieve("slide:options")){this.set("slide",A);}this.store("slide",new Fx.Slide(this,this.retrieve("slide:options")));
}return this.retrieve("slide");}};Element.implement({slide:function(D,E){D=D||"toggle";var B=this.get("slide"),A;switch(D){case"hide":B.hide(E);break;case"show":B.show(E);
break;case"toggle":var C=this.retrieve("slide:flag",B.open);B[(C)?"slideOut":"slideIn"](E);this.store("slide:flag",!C);A=true;break;default:B.start(D,E);
}if(!A){this.eliminate("slide:flag");}return this;}});Fx.Scroll=new Class({Extends:Fx,options:{offset:{x:0,y:0},wheelStops:true},initialize:function(B,A){this.element=this.subject=$(B);
this.parent(A);var D=this.cancel.bind(this,false);if($type(this.element)!="element"){this.element=$(this.element.getDocument().body);}var C=this.element;
if(this.options.wheelStops){this.addEvent("start",function(){C.addEvent("mousewheel",D);},true);this.addEvent("complete",function(){C.removeEvent("mousewheel",D);
},true);}},set:function(){var A=Array.flatten(arguments);this.element.scrollTo(A[0],A[1]);},compute:function(E,D,C){var B=[];var A=2;A.times(function(F){B.push(Fx.compute(E[F],D[F],C));
});return B;},start:function(C,H){if(!this.check(arguments.callee,C,H)){return this;}var E=this.element.getSize(),F=this.element.getScrollSize();var B=this.element.getScroll(),D={x:C,y:H};
for(var G in D){var A=F[G]-E[G];if($chk(D[G])){D[G]=($type(D[G])=="number")?D[G].limit(0,A):A;}else{D[G]=B[G];}D[G]+=this.options.offset[G];}return this.parent([B.x,B.y],[D.x,D.y]);
},toTop:function(){return this.start(false,0);},toLeft:function(){return this.start(0,false);},toRight:function(){return this.start("right",false);},toBottom:function(){return this.start(false,"bottom");
},toElement:function(B){var A=$(B).getPosition(this.element);return this.start(A.x,A.y);}});Fx.Elements=new Class({Extends:Fx.CSS,initialize:function(B,A){this.elements=this.subject=$$(B);
this.parent(A);},compute:function(G,H,I){var C={};for(var D in G){var A=G[D],E=H[D],F=C[D]={};for(var B in A){F[B]=this.parent(A[B],E[B],I);}}return C;
},set:function(B){for(var C in B){var A=B[C];for(var D in A){this.render(this.elements[C],D,A[D],this.options.unit);}}return this;},start:function(C){if(!this.check(arguments.callee,C)){return this;
}var H={},I={};for(var D in C){var F=C[D],A=H[D]={},G=I[D]={};for(var B in F){var E=this.prepare(this.elements[D],B,F[B]);A[B]=E.from;G[B]=E.to;}}return this.parent(H,I);
}});var Drag=new Class({Implements:[Events,Options],options:{snap:6,unit:"px",grid:false,style:true,limit:false,handle:false,invert:false,preventDefault:false,modifiers:{x:"left",y:"top"}},initialize:function(){var B=Array.link(arguments,{options:Object.type,element:$defined});
this.element=$(B.element);this.document=this.element.getDocument();this.setOptions(B.options||{});var A=$type(this.options.handle);this.handles=(A=="array"||A=="collection")?$$(this.options.handle):$(this.options.handle)||this.element;
this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.selection=(Browser.Engine.trident)?"selectstart":"mousedown";this.bound={start:this.start.bind(this),check:this.check.bind(this),drag:this.drag.bind(this),stop:this.stop.bind(this),cancel:this.cancel.bind(this),eventStop:$lambda(false)};
this.attach();},attach:function(){this.handles.addEvent("mousedown",this.bound.start);return this;},detach:function(){this.handles.removeEvent("mousedown",this.bound.start);
return this;},start:function(C){if(this.options.preventDefault){C.preventDefault();}this.fireEvent("beforeStart",this.element);this.mouse.start=C.page;
var A=this.options.limit;this.limit={x:[],y:[]};for(var D in this.options.modifiers){if(!this.options.modifiers[D]){continue;}if(this.options.style){this.value.now[D]=this.element.getStyle(this.options.modifiers[D]).toInt();
}else{this.value.now[D]=this.element[this.options.modifiers[D]];}if(this.options.invert){this.value.now[D]*=-1;}this.mouse.pos[D]=C.page[D]-this.value.now[D];
if(A&&A[D]){for(var B=2;B--;B){if($chk(A[D][B])){this.limit[D][B]=$lambda(A[D][B])();}}}}if($type(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid};
}this.document.addEvents({mousemove:this.bound.check,mouseup:this.bound.cancel});this.document.addEvent(this.selection,this.bound.eventStop);},check:function(A){if(this.options.preventDefault){A.preventDefault();
}var B=Math.round(Math.sqrt(Math.pow(A.page.x-this.mouse.start.x,2)+Math.pow(A.page.y-this.mouse.start.y,2)));if(B>this.options.snap){this.cancel();this.document.addEvents({mousemove:this.bound.drag,mouseup:this.bound.stop});
this.fireEvent("start",this.element).fireEvent("snap",this.element);}},drag:function(A){if(this.options.preventDefault){A.preventDefault();}this.mouse.now=A.page;
for(var B in this.options.modifiers){if(!this.options.modifiers[B]){continue;}this.value.now[B]=this.mouse.now[B]-this.mouse.pos[B];if(this.options.invert){this.value.now[B]*=-1;
}if(this.options.limit&&this.limit[B]){if($chk(this.limit[B][1])&&(this.value.now[B]>this.limit[B][1])){this.value.now[B]=this.limit[B][1];}else{if($chk(this.limit[B][0])&&(this.value.now[B]<this.limit[B][0])){this.value.now[B]=this.limit[B][0];
}}}if(this.options.grid[B]){this.value.now[B]-=(this.value.now[B]%this.options.grid[B]);}if(this.options.style){this.element.setStyle(this.options.modifiers[B],this.value.now[B]+this.options.unit);
}else{this.element[this.options.modifiers[B]]=this.value.now[B];}}this.fireEvent("drag",this.element);},cancel:function(A){this.document.removeEvent("mousemove",this.bound.check);
this.document.removeEvent("mouseup",this.bound.cancel);if(A){this.document.removeEvent(this.selection,this.bound.eventStop);this.fireEvent("cancel",this.element);
}},stop:function(A){this.document.removeEvent(this.selection,this.bound.eventStop);this.document.removeEvent("mousemove",this.bound.drag);this.document.removeEvent("mouseup",this.bound.stop);
if(A){this.fireEvent("complete",this.element);}}});Element.implement({makeResizable:function(A){return new Drag(this,$merge({modifiers:{x:"width",y:"height"}},A));
}});Drag.Move=new Class({Extends:Drag,options:{droppables:[],container:false},initialize:function(C,B){this.parent(C,B);this.droppables=$$(this.options.droppables);
this.container=$(this.options.container);if(this.container&&$type(this.container)!="element"){this.container=$(this.container.getDocument().body);}C=this.element;
var D=C.getStyle("position");var A=(D!="static")?D:"absolute";if(C.getStyle("left")=="auto"||C.getStyle("top")=="auto"){C.position(C.getPosition(C.offsetParent));
}C.setStyle("position",A);this.addEvent("start",function(){this.checkDroppables();},true);},start:function(B){if(this.container){var D=this.element,J=this.container,E=J.getCoordinates(D.offsetParent),F={},A={};
["top","right","bottom","left"].each(function(K){F[K]=J.getStyle("padding-"+K).toInt();A[K]=D.getStyle("margin-"+K).toInt();},this);var C=D.offsetWidth+A.left+A.right,I=D.offsetHeight+A.top+A.bottom;
var H=[E.left+F.left,E.right-F.right-C];var G=[E.top+F.top,E.bottom-F.bottom-I];this.options.limit={x:H,y:G};}this.parent(B);},checkAgainst:function(B){B=B.getCoordinates();
var A=this.mouse.now;return(A.x>B.left&&A.x<B.right&&A.y<B.bottom&&A.y>B.top);},checkDroppables:function(){var A=this.droppables.filter(this.checkAgainst,this).getLast();
if(this.overed!=A){if(this.overed){this.fireEvent("leave",[this.element,this.overed]);}if(A){this.overed=A;this.fireEvent("enter",[this.element,A]);}else{this.overed=null;
}}},drag:function(A){this.parent(A);if(this.droppables.length){this.checkDroppables();}},stop:function(A){this.checkDroppables();this.fireEvent("drop",[this.element,this.overed]);
this.overed=null;return this.parent(A);}});Element.implement({makeDraggable:function(A){return new Drag.Move(this,A);}});var Color=new Native({initialize:function(B,C){if(arguments.length>=3){C="rgb";
B=Array.slice(arguments,0,3);}else{if(typeof B=="string"){if(B.match(/rgb/)){B=B.rgbToHex().hexToRgb(true);}else{if(B.match(/hsb/)){B=B.hsbToRgb();}else{B=B.hexToRgb(true);
}}}}C=C||"rgb";switch(C){case"hsb":var A=B;B=B.hsbToRgb();B.hsb=A;break;case"hex":B=B.hexToRgb(true);break;}B.rgb=B.slice(0,3);B.hsb=B.hsb||B.rgbToHsb();
B.hex=B.rgbToHex();return $extend(B,this);}});Color.implement({mix:function(){var A=Array.slice(arguments);var C=($type(A.getLast())=="number")?A.pop():50;
var B=this.slice();A.each(function(D){D=new Color(D);for(var E=0;E<3;E++){B[E]=Math.round((B[E]/100*(100-C))+(D[E]/100*C));}});return new Color(B,"rgb");
},invert:function(){return new Color(this.map(function(A){return 255-A;}));},setHue:function(A){return new Color([A,this.hsb[1],this.hsb[2]],"hsb");},setSaturation:function(A){return new Color([this.hsb[0],A,this.hsb[2]],"hsb");
},setBrightness:function(A){return new Color([this.hsb[0],this.hsb[1],A],"hsb");}});function $RGB(C,B,A){return new Color([C,B,A],"rgb");}function $HSB(C,B,A){return new Color([C,B,A],"hsb");
}function $HEX(A){return new Color(A,"hex");}Array.implement({rgbToHsb:function(){var B=this[0],C=this[1],J=this[2];var G,F,H;var I=Math.max(B,C,J),E=Math.min(B,C,J);
var K=I-E;H=I/255;F=(I!=0)?K/I:0;if(F==0){G=0;}else{var D=(I-B)/K;var A=(I-C)/K;var L=(I-J)/K;if(B==I){G=L-A;}else{if(C==I){G=2+D-L;}else{G=4+A-D;}}G/=6;
if(G<0){G++;}}return[Math.round(G*360),Math.round(F*100),Math.round(H*100)];},hsbToRgb:function(){var C=Math.round(this[2]/100*255);if(this[1]==0){return[C,C,C];
}else{var A=this[0]%360;var E=A%60;var F=Math.round((this[2]*(100-this[1]))/10000*255);var D=Math.round((this[2]*(6000-this[1]*E))/600000*255);var B=Math.round((this[2]*(6000-this[1]*(60-E)))/600000*255);
switch(Math.floor(A/60)){case 0:return[C,B,F];case 1:return[D,C,F];case 2:return[F,C,B];case 3:return[F,D,C];case 4:return[B,F,C];case 5:return[C,F,D];
}}return false;}});String.implement({rgbToHsb:function(){var A=this.match(/\d{1,3}/g);return(A)?hsb.rgbToHsb():null;},hsbToRgb:function(){var A=this.match(/\d{1,3}/g);
return(A)?A.hsbToRgb():null;}});var Asset=new Hash({javascript:function(F,D){D=$extend({onload:$empty,document:document,check:$lambda(true)},D);var B=new Element("script",{src:F,type:"text/javascript"});
var E=D.onload.bind(B),A=D.check,G=D.document;delete D.onload;delete D.check;delete D.document;B.addEvents({load:E,readystatechange:function(){if(["loaded","complete"].contains(this.readyState)){E();
}}}).setProperties(D);if(Browser.Engine.webkit419){var C=(function(){if(!$try(A)){return ;}$clear(C);E();}).periodical(50);}return B.inject(G.head);},css:function(B,A){return new Element("link",$merge({rel:"stylesheet",media:"screen",type:"text/css",href:B},A)).inject(document.head);
},image:function(C,B){B=$merge({onload:$empty,onabort:$empty,onerror:$empty},B);var D=new Image();var A=$(D)||new Element("img");["load","abort","error"].each(function(E){var F="on"+E;
var G=B[F];delete B[F];D[F]=function(){if(!D){return ;}if(!A.parentNode){A.width=D.width;A.height=D.height;}D=D.onload=D.onabort=D.onerror=null;G.delay(1,A,A);
A.fireEvent(E,A,1);};});D.src=A.src=C;if(D&&D.complete){D.onload.delay(1);}return A.setProperties(B);},images:function(D,C){C=$merge({onComplete:$empty,onProgress:$empty},C);
if(!D.push){D=[D];}var A=[];var B=0;D.each(function(F){var E=new Asset.image(F,{onload:function(){C.onProgress.call(this,B,D.indexOf(F));B++;if(B==D.length){C.onComplete();
}}});A.push(E);});return new Elements(A);}});var Sortables=new Class({Implements:[Events,Options],options:{snap:4,opacity:1,clone:false,revert:false,handle:false,constrain:false},initialize:function(A,B){this.setOptions(B);
this.elements=[];this.lists=[];this.idle=true;this.addLists($$($(A)||A));if(!this.options.clone){this.options.revert=false;}if(this.options.revert){this.effect=new Fx.Morph(null,$merge({duration:250,link:"cancel"},this.options.revert));
}},attach:function(){this.addLists(this.lists);return this;},detach:function(){this.lists=this.removeLists(this.lists);return this;},addItems:function(){Array.flatten(arguments).each(function(A){this.elements.push(A);
var B=A.retrieve("sortables:start",this.start.bindWithEvent(this,A));(this.options.handle?A.getElement(this.options.handle)||A:A).addEvent("mousedown",B);
},this);return this;},addLists:function(){Array.flatten(arguments).each(function(A){this.lists.push(A);this.addItems(A.getChildren());},this);return this;
},removeItems:function(){var A=[];Array.flatten(arguments).each(function(B){A.push(B);this.elements.erase(B);var C=B.retrieve("sortables:start");(this.options.handle?B.getElement(this.options.handle)||B:B).removeEvent("mousedown",C);
},this);return $$(A);},removeLists:function(){var A=[];Array.flatten(arguments).each(function(B){A.push(B);this.lists.erase(B);this.removeItems(B.getChildren());
},this);return $$(A);},getClone:function(B,A){if(!this.options.clone){return new Element("div").inject(document.body);}if($type(this.options.clone)=="function"){return this.options.clone.call(this,B,A,this.list);
}return A.clone(true).setStyles({margin:"0px",position:"absolute",visibility:"hidden",width:A.getStyle("width")}).inject(this.list).position(A.getPosition(A.getOffsetParent()));
},getDroppables:function(){var A=this.list.getChildren();if(!this.options.constrain){A=this.lists.concat(A).erase(this.list);}return A.erase(this.clone).erase(this.element);
},insert:function(C,B){var A="inside";if(this.lists.contains(B)){this.list=B;this.drag.droppables=this.getDroppables();}else{A=this.element.getAllPrevious().contains(B)?"before":"after";
}this.element.inject(B,A);this.fireEvent("sort",[this.element,this.clone]);},start:function(B,A){if(!this.idle){return ;}this.idle=false;this.element=A;
this.opacity=A.get("opacity");this.list=A.getParent();this.clone=this.getClone(B,A);this.drag=new Drag.Move(this.clone,{snap:this.options.snap,container:this.options.constrain&&this.element.getParent(),droppables:this.getDroppables(),onSnap:function(){B.stop();
this.clone.setStyle("visibility","visible");this.element.set("opacity",this.options.opacity||0);this.fireEvent("start",[this.element,this.clone]);}.bind(this),onEnter:this.insert.bind(this),onCancel:this.reset.bind(this),onComplete:this.end.bind(this)});
this.clone.inject(this.element,"before");this.drag.start(B);},end:function(){this.drag.detach();this.element.set("opacity",this.opacity);if(this.effect){var A=this.element.getStyles("width","height");
var B=this.clone.computePosition(this.element.getPosition(this.clone.offsetParent));this.effect.element=this.clone;this.effect.start({top:B.top,left:B.left,width:A.width,height:A.height,opacity:0.25}).chain(this.reset.bind(this));
}else{this.reset();}},reset:function(){this.idle=true;this.clone.destroy();this.fireEvent("complete",this.element);},serialize:function(){var C=Array.link(arguments,{modifier:Function.type,index:$defined});
var B=this.lists.map(function(D){return D.getChildren().map(C.modifier||function(E){return E.get("id");},this);},this);var A=C.index;if(this.lists.length==1){A=0;
}return $chk(A)&&A>=0&&A<this.lists.length?B[A]:B;}});var Tips=new Class({Implements:[Events,Options],options:{onShow:function(A){A.setStyle("visibility","visible");
},onHide:function(A){A.setStyle("visibility","hidden");},showDelay:100,hideDelay:100,className:null,offsets:{x:16,y:16},fixed:false},initialize:function(){var C=Array.link(arguments,{options:Object.type,elements:$defined});
this.setOptions(C.options||null);this.tip=new Element("div").inject(document.body);if(this.options.className){this.tip.addClass(this.options.className);
}var B=new Element("div",{"class":"tip-top"}).inject(this.tip);this.container=new Element("div",{"class":"tip"}).inject(this.tip);var A=new Element("div",{"class":"tip-bottom"}).inject(this.tip);
this.tip.setStyles({position:"absolute",top:0,left:0,visibility:"hidden"});if(C.elements){this.attach(C.elements);}},attach:function(A){$$(A).each(function(D){var G=D.retrieve("tip:title",D.get("title"));
var F=D.retrieve("tip:text",D.get("rel")||D.get("href"));var E=D.retrieve("tip:enter",this.elementEnter.bindWithEvent(this,D));var C=D.retrieve("tip:leave",this.elementLeave.bindWithEvent(this,D));
D.addEvents({mouseenter:E,mouseleave:C});if(!this.options.fixed){var B=D.retrieve("tip:move",this.elementMove.bindWithEvent(this,D));D.addEvent("mousemove",B);
}D.store("tip:native",D.get("title"));D.erase("title");},this);return this;},detach:function(A){$$(A).each(function(C){C.removeEvent("mouseenter",C.retrieve("tip:enter")||$empty);
C.removeEvent("mouseleave",C.retrieve("tip:leave")||$empty);C.removeEvent("mousemove",C.retrieve("tip:move")||$empty);C.eliminate("tip:enter").eliminate("tip:leave").eliminate("tip:move");
var B=C.retrieve("tip:native");if(B){C.set("title",B);}});return this;},elementEnter:function(B,A){$A(this.container.childNodes).each(Element.dispose);
var D=A.retrieve("tip:title");if(D){this.titleElement=new Element("div",{"class":"tip-title"}).inject(this.container);this.fill(this.titleElement,D);}var C=A.retrieve("tip:text");
if(C){this.textElement=new Element("div",{"class":"tip-text"}).inject(this.container);this.fill(this.textElement,C);}this.timer=$clear(this.timer);this.timer=this.show.delay(this.options.showDelay,this);
this.position((!this.options.fixed)?B:{page:A.getPosition()});},elementLeave:function(A){$clear(this.timer);this.timer=this.hide.delay(this.options.hideDelay,this);
},elementMove:function(A){this.position(A);},position:function(D){var B=window.getSize(),A=window.getScroll();var E={x:this.tip.offsetWidth,y:this.tip.offsetHeight};
var C={x:"left",y:"top"};for(var F in C){var G=D.page[F]+this.options.offsets[F];if((G+E[F]-A[F])>B[F]){G=D.page[F]-this.options.offsets[F]-E[F];}this.tip.setStyle(C[F],G);
}},fill:function(A,B){(typeof B=="string")?A.set("html",B):A.adopt(B);},show:function(){this.fireEvent("show",this.tip);},hide:function(){this.fireEvent("hide",this.tip);
}});var SmoothScroll=new Class({Extends:Fx.Scroll,initialize:function(B,C){C=C||document;var E=C.getDocument(),D=C.getWindow();this.parent(E,B);this.links=(this.options.links)?$$(this.options.links):$$(E.links);
var A=D.location.href.match(/^[^#]*/)[0]+"#";this.links.each(function(G){if(G.href.indexOf(A)!=0){return ;}var F=G.href.substr(A.length);if(F&&$(F)){this.useLink(G,F);
}},this);if(!Browser.Engine.webkit419){this.addEvent("complete",function(){D.location.hash=this.anchor;},true);}},useLink:function(B,A){B.addEvent("click",function(C){this.anchor=A;
this.toElement(A);C.stop();}.bind(this));}});var Slider=new Class({Implements:[Events,Options],options:{onTick:function(A){if(this.options.snap){A=this.toPosition(this.step);
}this.knob.setStyle(this.property,A);},snap:false,offset:0,range:false,wheel:false,steps:100,mode:"horizontal"},initialize:function(E,A,D){this.setOptions(D);
this.element=$(E);this.knob=$(A);this.previousChange=this.previousEnd=this.step=-1;this.element.addEvent("mousedown",this.clickedElement.bind(this));if(this.options.wheel){this.element.addEvent("mousewheel",this.scrolledElement.bindWithEvent(this));
}var F,B={},C={x:false,y:false};switch(this.options.mode){case"vertical":this.axis="y";this.property="top";F="offsetHeight";break;case"horizontal":this.axis="x";
this.property="left";F="offsetWidth";}this.half=this.knob[F]/2;this.full=this.element[F]-this.knob[F]+(this.options.offset*2);this.min=$chk(this.options.range[0])?this.options.range[0]:0;
this.max=$chk(this.options.range[1])?this.options.range[1]:this.options.steps;this.range=this.max-this.min;this.steps=this.options.steps||this.full;this.stepSize=Math.abs(this.range)/this.steps;
this.stepWidth=this.stepSize*this.full/Math.abs(this.range);this.knob.setStyle("position","relative").setStyle(this.property,-this.options.offset);C[this.axis]=this.property;
B[this.axis]=[-this.options.offset,this.full-this.options.offset];this.drag=new Drag(this.knob,{snap:0,limit:B,modifiers:C,onDrag:this.draggedKnob.bind(this),onStart:this.draggedKnob.bind(this),onComplete:function(){this.draggedKnob();
this.end();}.bind(this)});if(this.options.snap){this.drag.options.grid=Math.ceil(this.stepWidth);this.drag.options.limit[this.axis][1]=this.full;}},set:function(A){if(!((this.range>0)^(A<this.min))){A=this.min;
}if(!((this.range>0)^(A>this.max))){A=this.max;}this.step=Math.round(A);this.checkStep();this.end();this.fireEvent("tick",this.toPosition(this.step));return this;
},clickedElement:function(C){var B=this.range<0?-1:1;var A=C.page[this.axis]-this.element.getPosition()[this.axis]-this.half;A=A.limit(-this.options.offset,this.full-this.options.offset);
this.step=Math.round(this.min+B*this.toStep(A));this.checkStep();this.end();this.fireEvent("tick",A);},scrolledElement:function(A){var B=(this.options.mode=="horizontal")?(A.wheel<0):(A.wheel>0);
this.set(B?this.step-this.stepSize:this.step+this.stepSize);A.stop();},draggedKnob:function(){var B=this.range<0?-1:1;var A=this.drag.value.now[this.axis];
A=A.limit(-this.options.offset,this.full-this.options.offset);this.step=Math.round(this.min+B*this.toStep(A));this.checkStep();},checkStep:function(){if(this.previousChange!=this.step){this.previousChange=this.step;
this.fireEvent("change",this.step);}},end:function(){if(this.previousEnd!==this.step){this.previousEnd=this.step;this.fireEvent("complete",this.step+"");
}},toStep:function(A){var B=(A+this.options.offset)*this.stepSize/this.full*this.steps;return this.options.steps?Math.round(B-=B%this.stepSize):B;},toPosition:function(A){return(this.full*Math.abs(this.min-A))/(this.steps*this.stepSize)-this.options.offset;
}});var Scroller=new Class({Implements:[Events,Options],options:{area:20,velocity:1,onChange:function(A,B){this.element.scrollTo(A,B);}},initialize:function(B,A){this.setOptions(A);
this.element=$(B);this.listener=($type(this.element)!="element")?$(this.element.getDocument().body):this.element;this.timer=null;this.coord=this.getCoords.bind(this);
},start:function(){this.listener.addEvent("mousemove",this.coord);},stop:function(){this.listener.removeEvent("mousemove",this.coord);this.timer=$clear(this.timer);
},getCoords:function(A){this.page=(this.listener.get("tag")=="body")?A.client:A.page;if(!this.timer){this.timer=this.scroll.periodical(50,this);}},scroll:function(){var B=this.element.getSize(),A=this.element.getScroll(),E=this.element.getPosition(),D={x:0,y:0};
for(var C in this.page){if(this.page[C]<(this.options.area+E[C])&&A[C]!=0){D[C]=(this.page[C]-this.options.area-E[C])*this.options.velocity;}else{if(this.page[C]+this.options.area>(B[C]+E[C])&&B[C]+B[C]!=A[C]){D[C]=(this.page[C]-B[C]+this.options.area-E[C])*this.options.velocity;
}}}if(D.y||D.x){this.fireEvent("change",[A.x+D.x,A.y+D.y]);}}});var Accordion=new Class({Extends:Fx.Elements,options:{display:0,show:false,height:true,width:false,opacity:true,fixedHeight:false,fixedWidth:false,wait:false,alwaysHide:false},initialize:function(){var C=Array.link(arguments,{container:Element.type,options:Object.type,togglers:$defined,elements:$defined});
this.parent(C.elements,C.options);this.togglers=$$(C.togglers);this.container=$(C.container);this.previous=-1;if(this.options.alwaysHide){this.options.wait=true;
}if($chk(this.options.show)){this.options.display=false;this.previous=this.options.show;}if(this.options.start){this.options.display=false;this.options.show=false;
}this.effects={};if(this.options.opacity){this.effects.opacity="fullOpacity";}if(this.options.width){this.effects.width=this.options.fixedWidth?"fullWidth":"offsetWidth";
}if(this.options.height){this.effects.height=this.options.fixedHeight?"fullHeight":"scrollHeight";}for(var B=0,A=this.togglers.length;B<A;B++){this.addSection(this.togglers[B],this.elements[B]);
}this.elements.each(function(E,D){if(this.options.show===D){this.fireEvent("active",[this.togglers[D],E]);}else{for(var F in this.effects){E.setStyle(F,0);
}}},this);if($chk(this.options.display)){this.display(this.options.display);}},addSection:function(E,C,G){E=$(E);C=$(C);var F=this.togglers.contains(E);
var B=this.togglers.length;this.togglers.include(E);this.elements.include(C);if(B&&(!F||G)){G=$pick(G,B-1);E.inject(this.togglers[G],"before");C.inject(E,"after");
}else{if(this.container&&!F){E.inject(this.container);C.inject(this.container);}}var A=this.togglers.indexOf(E);E.addEvent("click",this.display.bind(this,A));
if(this.options.height){C.setStyles({"padding-top":0,"border-top":"none","padding-bottom":0,"border-bottom":"none"});}if(this.options.width){C.setStyles({"padding-left":0,"border-left":"none","padding-right":0,"border-right":"none"});
}C.fullOpacity=1;if(this.options.fixedWidth){C.fullWidth=this.options.fixedWidth;}if(this.options.fixedHeight){C.fullHeight=this.options.fixedHeight;}C.setStyle("overflow","hidden");
if(!F){for(var D in this.effects){C.setStyle(D,0);}}return this;},display:function(A){A=($type(A)=="element")?this.elements.indexOf(A):A;if((this.timer&&this.options.wait)||(A===this.previous&&!this.options.alwaysHide)){return this;
}this.previous=A;var B={};this.elements.each(function(E,D){B[D]={};var C=(D!=A)||(this.options.alwaysHide&&(E.offsetHeight>0));this.fireEvent(C?"background":"active",[this.togglers[D],E]);
for(var F in this.effects){B[D][F]=C?0:E[this.effects[F]];}},this);return this.start(B);}});


var Spry; if (!Spry) Spry = {};
if (!Spry.Utils) Spry.Utils = {};

Spry.Utils.submitForm = function(form, callback, opts, async)
{
	
	if (!form)
		return true;
		
	if(!async)
		async = true;

	if ( typeof form == 'string' )
		form = document.getElementById(form) || document.forms[form];
	
	var frmOpts = {};
	frmOpts.method = form.method;
	frmOpts.url = form.action || document.location.href;

	frmOpts.enctype = form.enctype;

	Spry.Utils.setOptions(frmOpts, opts);
	
	var submitData = Spry.Utils.extractParamsFromForm(form, frmOpts.elements);
	
	if (frmOpts.additionalData)
		submitData += "&" + frmOpts.additionalData;

	if (frmOpts.enctype.toLowerCase() != 'multipart/form-data')
	{
		frmOpts.method = (frmOpts.method.toLowerCase() == "post") ? 'POST' : 'GET';
		if (frmOpts.method == "GET")
		{
			if (frmOpts.url.indexOf('?') == -1)
				frmOpts.url += '?';
			else
				frmOpts.url += '&';
			frmOpts.url += submitData;
		}
		else
		{
			if (!frmOpts.headers) frmOpts.headers = {};
			if (!frmOpts.headers['Content-Type'] || frmOpts.headers['Content-Type'].indexOf("application/x-www-form-urlencoded") ==-1 )
				frmOpts.headers['Content-Type'] = 'application/x-www-form-urlencoded';

			// Set the postData
			frmOpts.postData = submitData;
		}

		Spry.Utils.loadURL(frmOpts.method, frmOpts.url, async, callback, frmOpts);

		return false;
	}
	// Native submission when 'multipart/form-data' is used.
	return false;
};

Spry.Utils.extractParamsFromForm = function (form, elements)
{
	if (!form || !form.elements)
		return '';

	if ( typeof form == 'string' )
		form = document.getElementById(form) || document.forms[form];

	var formElements;
	if (elements)
		formElements = ',' + elements.join(',') + ',';

	var compStack = new Array(); // key=value pairs

	var el;
	
	for (var i = 0; i < form.elements.length; i++ )
	{
		el = form.elements[i];
		
		/*if (el.disabled || !el.name)
		{
			// Don't submit disabled elements.
			// Don't submit elements without name.
			continue;
		}*/
		if(el.type && el.type.toUpperCase() == "SUBMIT" && form.hasClass('buyForm') )
		{
			el.style.display = 'none';
			var productId = form.elements["productId"].value;			
			var loadingImage = document.createElement('img');
			loadingImage.src = shop.templatePath + '/images/smallLoading.gif';
			loadingImage.id = 'loadingImage' + productId;
			el.parentNode.appendChild(loadingImage);
		}
		else if(el.type && el.type.toUpperCase() == "SUBMIT" && form.hasClass('checkoutForm') )
		{
			el.style.display = 'none';
			var loadingImage = document.createElement('img');
			loadingImage.src = shop.templatePath + '/images/smallLoading.gif';
			loadingImage.id = 'loadingImage';
			el.parentNode.appendChild(loadingImage);
		}

		if (!el.type)
		{
			// It seems that this element doesn't have a type set,
			// so skip it.
			continue;
		}

		if (formElements && formElements.indexOf(',' + el.name + ',')==-1)
			continue;

		switch(el.type.toLowerCase())
		{
			case 'text':
			case 'password':
			case 'textarea':
			case 'hidden':
			case 'submit':
				compStack.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value));
				break;
			case 'select-one':
				var value = '';
				var opt;
				if (el.selectedIndex >= 0) {
					opt = el.options[el.selectedIndex];
					value = opt.value || opt.text;
				}
				compStack.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(value));
				break;
			case 'select-multiple':
				for (var j = 0; j < el.length; j++)
				{
					if (el.options[j].selected)
					{
						value = el.options[j].value || el.options[j].text;
						compStack.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(value));
					}
				}
				break;
			case 'checkbox':
			case 'radio':
				if (el.checked)
					compStack.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value));
				break;
			default:
			// file, button, reset
			break;
			}
		}
				
	return compStack.join('&');
};

Spry.Utils.msProgIDs = ["MSXML2.XMLHTTP.6.0", "MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];

Spry.Utils.createXMLHttpRequest = function()
{
	var req = null;
	try
	{
		// Try to use the ActiveX version of XMLHttpRequest. This will
		// allow developers to load file URLs in IE7 when running in the
		// local zone.

		if (window.ActiveXObject)
		{
			while (!req && Spry.Utils.msProgIDs.length)
			{
				try { req = new ActiveXObject(Spry.Utils.msProgIDs[0]); } catch (e) { req = null; }
				if (!req)
					Spry.Utils.msProgIDs.splice(0, 1);
			}
		}

		// We're either running in a non-IE browser, or we failed to
		// create the ActiveX version of the XMLHttpRequest object.
		// Try to use the native version of XMLHttpRequest if it exists.

		if (!req && window.XMLHttpRequest)
			req = new XMLHttpRequest();
	}
	catch (e) { req = null;	}

	if (!req)
		Spry.Debug.reportError("Failed to create an XMLHttpRequest object!" );

	return req;
};

Spry.Utils.loadURL = function(method, url, async, callback, opts)
{
	var req = new Spry.Utils.loadURL.Request();
	req.method = method;
	req.url = url;
	req.async = async;
	req.successCallback = callback;
	Spry.Utils.setOptions(req, opts);

	try
	{
		req.xhRequest = Spry.Utils.createXMLHttpRequest();
		if (!req.xhRequest)
			return null;

		if (req.async)
			req.xhRequest.onreadystatechange = function() { Spry.Utils.loadURL.callback(req); };

		req.xhRequest.open(req.method, req.url, req.async, req.username, req.password);

		if (req.headers)
		{
			for (var name in req.headers)
				req.xhRequest.setRequestHeader(name, req.headers[name]);
		}

		req.xhRequest.send(req.postData);

		if (!req.async)
			Spry.Utils.loadURL.callback(req);
	}
	catch(e)
	{
		if (req.errorCallback)
			req.errorCallback(req);
		else
			Spry.Debug.reportError("Exception caught while loading " + url + ": " + e);
		req = null;
	}

	return req;
};

Spry.Utils.loadURL.callback = function(req)
{
	if (!req || req.xhRequest.readyState != 4)
		return;
	if (req.successCallback /*&& (req.xhRequest.status == 200 || req.xhRequest.status == 0)*/){
		req.successCallback(req);
	}
	else if (req.errorCallback)
		req.errorCallback(req);
};

Spry.Utils.loadURL.Request = function()
{
	var props = Spry.Utils.loadURL.Request.props;
	var numProps = props.length;

	for (var i = 0; i < numProps; i++)
		this[props[i]] = null;

	this.method = "GET";
	this.async = true;
	this.headers = {};
};

Spry.Utils.loadURL.Request.props = [ "method", "url", "async", "username", "password", "postData", "successCallback", "errorCallback", "headers", "userData", "xhRequest" ];

Spry.Utils.loadURL.Request.prototype.extractRequestOptions = function(opts, undefineRequestProps)
{
	if (!opts)
		return;

	var props = Spry.Utils.loadURL.Request.props;
	var numProps = props.length;

	for (var i = 0; i < numProps; i++)
	{
		var prop = props[i];
		if (opts[prop] != undefined)
		{
			this[prop] = opts[prop];
			if (undefineRequestProps)
				opts[prop] = undefined;
		}
	}
};

Spry.Utils.loadURL.Request.prototype.clone = function()
{
	var props = Spry.Utils.loadURL.Request.props;
	var numProps = props.length;
	var req = new Spry.Utils.loadURL.Request;
	for (var i = 0; i < numProps; i++)
		req[props[i]] = this[props[i]];
	if (this.headers)
	{
		req.headers = {};
		Spry.Utils.setOptions(req.headers, this.headers);
	}
	return req;
};

Spry.Utils.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
{
	if (!optionsObj)
		return;

	for (var optionName in optionsObj)
	{
		if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
			continue;
		obj[optionName] = optionsObj[optionName];
	}
};

var Spry;
if (!Spry) Spry = {};
if (!Spry.Widget) Spry.Widget = {};

Spry.Widget.ValidationCheckbox = function(element, opts)
{
	this.init(element);
	
	Spry.Widget.Utils.setOptions(this, opts);

	// set validateOn flags
	var validateOn = ['submit'].concat(this.validateOn || []);
	validateOn = validateOn.join(",");
	this.validateOn = 0 | (validateOn.indexOf('submit') != -1 ? Spry.Widget.ValidationCheckbox.ONSUBMIT : 0);
	this.validateOn = this.validateOn | (validateOn.indexOf('blur') != -1 ? Spry.Widget.ValidationCheckbox.ONBLUR : 0);
	this.validateOn = this.validateOn | (validateOn.indexOf('change') != -1 ? Spry.Widget.ValidationCheckbox.ONCHANGE : 0);
	
	// sanity checks
	if (!isNaN(this.minSelections)) {
		this.minSelections = (this.minSelections > 0)? parseInt(this.minSelections, 10): null;
	}
	if (!isNaN(this.maxSelections)) {
		this.maxSelections = (this.maxSelections > 0)? parseInt(this.maxSelections, 10): null;
	}

	if (this.additionalError)
		this.additionalError = this.getElement(this.additionalError);
	// Unfortunately in some browsers like Safari, the Stylesheets our
	// page depends on may not have been loaded at the time we are called.
	// This means we have to defer attaching our behaviors until after the
	// onload event fires, since some of our behaviors rely on dimensions
	// specified in the CSS.

	if (Spry.Widget.ValidationCheckbox.onloadDidFire)
		this.attachBehaviors();
	else 
		Spry.Widget.ValidationCheckbox.loadQueue.push(this);
};

Spry.Widget.ValidationCheckbox.ONCHANGE = 1;
Spry.Widget.ValidationCheckbox.ONBLUR = 2;
Spry.Widget.ValidationCheckbox.ONSUBMIT = 4;

Spry.Widget.ValidationCheckbox.prototype.init = function(element)
{
	this.element = this.getElement(element);
	this.checkboxElements = null;
	this.additionalError = false;
	this.form = null;
	this.event_handlers = [];
	
	 // this.element can be either the container (<span>)
	 // or the <input type="checkbox"> element, when no error messages are used.
	this.hasFocus = false;
	this.requiredClass = "checkboxRequiredState";
	this.minSelectionsClass = "checkboxMinSelectionsState";
	this.maxSelectionsClass = "checkboxMaxSelectionsState";
	this.focusClass = "checkboxFocusState";
	this.validClass = "checkboxValidState";
	
	this.isRequired = true;
	
	this.minSelections = null;
	this.maxSelections = null;
	
	this.validateOn = ["submit"];  // change, submit (blur ?)
};

Spry.Widget.ValidationCheckbox.prototype.destroy = function() {
	for (var i=0; i<this.event_handlers.length; i++) {
		Spry.Widget.Utils.removeEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false);
	}
	try { delete this.element; } catch(err) {}
	for(var i=0; i<this.checkboxElements.length; i++) {
		try { delete this.checkboxElements[i];} catch(err) {}
	}
	try { delete this.checkboxElements; } catch(err) {}

	try { delete this.form; } catch(err) {}
	try { delete this.event_handlers; } catch(err) {}

	var q = Spry.Widget.Form.onSubmitWidgetQueue;
	var qlen = q.length;
	for (var i = 0; i < qlen; i++) {
		if (q[i] == this) {
			q.splice(i, 1);
			break;
		}
	}
};

Spry.Widget.ValidationCheckbox.onloadDidFire = false;
Spry.Widget.ValidationCheckbox.loadQueue = [];

Spry.Widget.ValidationCheckbox.prototype.getElement = function(ele)
{
	if (ele && typeof ele == "string")
		return document.getElementById(ele);
	return ele;
};

Spry.Widget.ValidationCheckbox.processLoadQueue = function(handler)
{
	Spry.Widget.ValidationCheckbox.onloadDidFire = true;
	var q = Spry.Widget.ValidationCheckbox.loadQueue;
	var qlen = q.length;
	for (var i = 0; i < qlen; i++)
		q[i].attachBehaviors();
};

Spry.Widget.ValidationCheckbox.addLoadListener = function(handler)
{
	if (typeof window.addEventListener != 'undefined')
		window.addEventListener('load', handler, false);
	else if (typeof document.addEventListener != 'undefined')
		document.addEventListener('load', handler, false);
	else if (typeof window.attachEvent != 'undefined')
		window.attachEvent('onload', handler);
};

Spry.Widget.ValidationCheckbox.addLoadListener(Spry.Widget.ValidationCheckbox.processLoadQueue);
Spry.Widget.ValidationCheckbox.addLoadListener(function(){
	Spry.Widget.Utils.addEventListener(window, "unload", Spry.Widget.Form.destroyAll, false);
});

Spry.Widget.ValidationCheckbox.prototype.attachBehaviors = function()
{
	// find the INPUT type="checkbox" element(s) inside current container
	if (!this.element)
		return;

	if (this.element.nodeName == "INPUT") {
		this.checkboxElements = [this.element];
	} else {
		this.checkboxElements = this.getCheckboxes();
	}
	if (this.checkboxElements) {
		var self = this;
		this.event_handlers = [];

		var qlen = this.checkboxElements.length;
		for (var i = 0; i < qlen; i++) {
			// focus
			this.event_handlers.push([this.checkboxElements[i], "focus", function(e) { return self.onFocus(e); }]);
			// blur
			this.event_handlers.push([this.checkboxElements[i], "blur", function(e) { return self.onBlur(e); }]);
			// add click instead of onChange
			if (this.validateOn & Spry.Widget.ValidationCheckbox.ONCHANGE) {
				this.event_handlers.push([this.checkboxElements[i], "click", function(e) { return self.onClick(e); }]);
			}
		}

		for (var i=0; i<this.event_handlers.length; i++) {
			Spry.Widget.Utils.addEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false);
		}

		// submit
		this.form = Spry.Widget.Utils.getFirstParentWithNodeName(this.element, "FORM");
		if (this.form) {
			// if no "onSubmit" handler has been attached to the current form, attach one
			if (!this.form.attachedSubmitHandler && !this.form.onsubmit) {
				this.form.onsubmit = function(e) { e = e || event; return Spry.Widget.Form.onSubmit(e, e.srcElement || e.currentTarget) };
				this.form.attachedSubmitHandler = true;                 
			}
			if (!this.form.attachedResetHandler) {
				Spry.Widget.Utils.addEventListener(this.form, "reset", function(e) { e = e || event; return Spry.Widget.Form.onReset(e, e.srcElement || e.currentTarget) }, false);
				this.form.attachedResetHandler = true;                 
			}
			// add the currrent widget to the "onSubmit" check queue;
			Spry.Widget.Form.onSubmitWidgetQueue.push(this);
		}
	}
	
};

Spry.Widget.ValidationCheckbox.prototype.getCheckboxes = function() {
	var arrCheckboxes;
	var elements  = this.element.getElementsByTagName("INPUT");
	if (elements.length) {
		arrCheckboxes = [];
		var qlen = elements.length;
		for (var i = 0; i < qlen; i++) {
			if (elements[i].type == "checkbox" || (elements[i].type == "text" || elements[i].type == "hidden")) {
				arrCheckboxes.push(elements[i]);
			}
		}
		return arrCheckboxes;
	}
	return null;
}

Spry.Widget.ValidationCheckbox.prototype.addClassName = function(ele, className)
{
	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
		return;
	ele.className += (ele.className ? " " : "") + className;
};

Spry.Widget.ValidationCheckbox.prototype.removeClassName = function(ele, className)
{
	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1))
		return;
	ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
};



Spry.Widget.ValidationCheckbox.prototype.onFocus = function(e)
{
	var eventCheckbox = (e.srcElement != null) ? e.srcElement : e.target;
 	if (eventCheckbox.disabled) return;
 	
	this.hasFocus = true;
	this.addClassName(this.element, this.focusClass);
	this.addClassName(this.additionalError, this.focusClass);
};

Spry.Widget.ValidationCheckbox.prototype.onBlur = function(e)
{
	var eventCheckbox = (e.srcElement != null) ? e.srcElement : e.target;
	if (eventCheckbox.disabled) return;
	
	this.hasFocus = false;
	var doValidation = false;
	if (this.validateOn & Spry.Widget.ValidationCheckbox.ONBLUR)
		doValidation = true;
	if (doValidation)
		this.validate();
	this.removeClassName(this.element, this.focusClass);
	this.removeClassName(this.additionalError, this.focusClass);
	
};

Spry.Widget.ValidationCheckbox.prototype.onClick = function(e) {
	var eventCheckbox = (e.srcElement != null) ? e.srcElement : e.target;
	if (eventCheckbox.disabled) return;
	
	this.validate();
};

Spry.Widget.ValidationCheckbox.prototype.reset = function() {
	this.removeClassName(this.element, this.validClass);
	this.removeClassName(this.element, this.requiredClass);
	this.removeClassName(this.element, this.minSelectionsClass);
	this.removeClassName(this.element, this.maxSelectionsClass);
	this.removeClassName(this.additionalError, this.validClass);
	this.removeClassName(this.additionalError, this.requiredClass);
	this.removeClassName(this.additionalError, this.minSelectionsClass);
	this.removeClassName(this.additionalError, this.maxSelectionsClass);
};

Spry.Widget.ValidationCheckbox.prototype.validate = function() {
	this.reset();
	var nochecked = 0;
	if (this.checkboxElements) {
		var qlen = this.checkboxElements.length;
		for (var i = 0; i < qlen; i++) {
			typeElement = this.checkboxElements[i].type;
			if(!this.checkboxElements[i].disabled){
				if(typeElement.toLowerCase() == "checkbox" && this.checkboxElements[i].checked){
					nochecked++;
				}
				else if(typeElement.toLowerCase() == "hidden" || typeElement.toLowerCase() == "text"){
					if(this.checkboxElements[i].value.length > 0){
						nochecked++;
					}
				}
			}
		}
	}
	// check isRequired
	if (this.isRequired) {
		if (nochecked == 0) {
			this.addClassName(this.element, this.requiredClass);
			this.addClassName(this.additionalError, this.requiredClass);
			return false;
		}
	}
	if (this.minSelections) {
		if (this.minSelections > nochecked) {
			this.addClassName(this.element, this.minSelectionsClass);
			this.addClassName(this.additionalError, this.minSelectionsClass);
			return false;
		}
	}
	if (this.maxSelections) {
		if (this.maxSelections < nochecked) {
			this.addClassName(this.element, this.maxSelectionsClass);
			this.addClassName(this.additionalError, this.maxSelectionsClass);
			return false;
		}
	}
	this.addClassName(this.element, this.validClass);
	this.addClassName(this.additionalError, this.validClass);
	return true;
}

Spry.Widget.ValidationCheckbox.prototype.isDisabled = function() {
	var ret = true;
	if (this.checkboxElements) {
		var qlen = this.checkboxElements.length;
		for (var i = 0; i < qlen; i++) {
			if (!this.checkboxElements[i].disabled) {
				ret = false;
				break;
			}
		}
	}
	return ret;
}

if (!Spry.Widget.Form) Spry.Widget.Form = {};
if (!Spry.Widget.Form.onSubmitWidgetQueue) Spry.Widget.Form.onSubmitWidgetQueue = [];

if (!Spry.Widget.Form.validate) {
	Spry.Widget.Form.validate = function(vform) {
		var isValid = true;
		var isElementValid = true;
		var q = Spry.Widget.Form.onSubmitWidgetQueue;
		var qlen = q.length;
		for (var i = 0; i < qlen; i++) {
			if (!q[i].isDisabled() && q[i].form == vform) {
				isElementValid = q[i].validate();
				isValid = isElementValid && isValid;
			}
		}
		return isValid;
	}
};

if (!Spry.Widget.Form.onSubmit) {
	Spry.Widget.Form.onSubmit = function(e, form)
	{
		if (Spry.Widget.Form.validate(form) == false) {
			return false;
		}
		return true;
	};
};

if (!Spry.Widget.Form.onReset) {
	Spry.Widget.Form.onReset = function(e, vform)
	{
		var q = Spry.Widget.Form.onSubmitWidgetQueue;
		var qlen = q.length;
		for (var i = 0; i < qlen; i++) {
			if (!q[i].isDisabled() && q[i].form == vform && typeof(q[i].reset) == 'function') {
				q[i].reset();
			}
		}
		return true;
	};
};

if (!Spry.Widget.Form.destroy) {
	Spry.Widget.Form.destroy = function(form)
	{
		var q = Spry.Widget.Form.onSubmitWidgetQueue;
		for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) {
			if (q[i].form == form && typeof(q[i].destroy) == 'function') {
				q[i].destroy();
				i--;
			}
		}
	}
};

if (!Spry.Widget.Form.destroyAll) {
	Spry.Widget.Form.destroyAll = function()
	{
		var q = Spry.Widget.Form.onSubmitWidgetQueue;
		for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) {
			if (typeof(q[i].destroy) == 'function') {
				q[i].destroy();
				i--;
			}
		}
	}
};

if (!Spry.Widget.Utils)	Spry.Widget.Utils = {};

Spry.Widget.Utils.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
{
	if (!optionsObj)
		return;
	for (var optionName in optionsObj)
	{
		if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
			continue;
		obj[optionName] = optionsObj[optionName];
	}
};


Spry.Widget.Utils.getFirstParentWithNodeName = function(node, nodeName)
{
	while (node.parentNode
			&& node.parentNode.nodeName.toLowerCase() != nodeName.toLowerCase()
			&& node.parentNode.nodeName != 'BODY') {
		node = node.parentNode;
	}

	if (node.parentNode && node.parentNode.nodeName.toLowerCase() == nodeName.toLowerCase()) {
		return node.parentNode;
	} else {
		return null;
	}
};

Spry.Widget.Utils.destroyWidgets = function (container)
{
	if (typeof container == 'string') {
		container = document.getElementById(container);
	}

	var q = Spry.Widget.Form.onSubmitWidgetQueue;
	for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) {
		if (typeof(q[i].destroy) == 'function' && Spry.Widget.Utils.contains(container, q[i].element)) {
			q[i].destroy();
			i--;
		}
	}
};

Spry.Widget.Utils.contains = function (who, what)
{
	if (typeof who.contains == 'object') {
		return what && who && (who == what || who.contains(what));
	} else {
		var el = what;
		while(el) {
			if (el == who) {
				return true;
			}
			el = el.parentNode;
		}
		return false;
	}
};

Spry.Widget.Utils.addEventListener = function(element, eventType, handler, capture)
{
	try
	{
		if (element.addEventListener)
			element.addEventListener(eventType, handler, capture);
		else if (element.attachEvent)
			element.attachEvent("on" + eventType, handler, capture);
	}
	catch (e) {}
};

Spry.Widget.Utils.removeEventListener = function(element, eventType, handler, capture)
{
	try
	{
		if (element.removeEventListener)
			element.removeEventListener(eventType, handler, capture);
		else if (element.detachEvent)
			element.detachEvent("on" + eventType, handler, capture);
	}
	catch (e) {}
};

Spry.Widget.ValidationRadio = function(element, opts)
{
	this.init(element);

	Spry.Widget.Utils.setOptions(this, opts);

	// set validateOn flags
	var validateOn = ['submit'].concat(this.validateOn || []);
	validateOn = validateOn.join(",");
	this.validateOn = 0 | (validateOn.indexOf('submit') != -1 ? Spry.Widget.ValidationRadio.ONSUBMIT : 0);
	this.validateOn = this.validateOn | (validateOn.indexOf('blur') != -1 ? Spry.Widget.ValidationRadio.ONBLUR : 0);
	this.validateOn = this.validateOn | (validateOn.indexOf('change') != -1 ? Spry.Widget.ValidationRadio.ONCHANGE : 0);

	if (this.additionalError)
		this.additionalError = this.getElement(this.additionalError);

	// Unfortunately in some browsers like Safari, the Stylesheets our
	// page depends on may not have been loaded at the time we are called.
	// This means we have to defer attaching our behaviors until after the
	// onload event fires, since some of our behaviors rely on dimensions
	// specified in the CSS.

	if (Spry.Widget.ValidationRadio.onloadDidFire)
		this.attachBehaviors();
	else 
		Spry.Widget.ValidationRadio.loadQueue.push(this);
};

Spry.Widget.ValidationRadio.ONCHANGE = 1;
Spry.Widget.ValidationRadio.ONBLUR = 2;
Spry.Widget.ValidationRadio.ONSUBMIT = 4;

Spry.Widget.ValidationRadio.prototype.init = function(element)
{
	this.element = this.getElement(element);
	this.additionalError = false;
	this.radioElements = null;
	this.form = null;
	this.event_handlers = [];
	
	 // this.element can be either the container (<span>)
	 // or the <input type="radio"> element, when no error messages are used.
	this.requiredClass = "radioRequiredState";
	this.focusClass = "radioFocusState";
	this.invalidClass = "radioInvalidState";
	this.validClass = "radioValidState";

	this.emptyValue = "";
	this.invalidValue = null;
	this.isRequired = true;
	this.validateOn = ["submit"]; // change, submit (blur ?)
};

Spry.Widget.ValidationRadio.onloadDidFire = false;
Spry.Widget.ValidationRadio.loadQueue = [];

Spry.Widget.ValidationRadio.prototype.getElement = function(ele)
{
	if (ele && typeof ele == "string")
		return document.getElementById(ele);
	return ele;
};

Spry.Widget.ValidationRadio.processLoadQueue = function(handler)
{
	Spry.Widget.ValidationRadio.onloadDidFire = true;

	var q = Spry.Widget.ValidationRadio.loadQueue;
	var qlen = q.length;
	for (var i = 0; i < qlen; i++)
		q[i].attachBehaviors();
};

Spry.Widget.ValidationRadio.addLoadListener = function(handler)
{
	if (typeof window.addEventListener != 'undefined')
		window.addEventListener('load', handler, false);
	else if (typeof document.addEventListener != 'undefined')
		document.addEventListener('load', handler, false);
	else if (typeof window.attachEvent != 'undefined')
		window.attachEvent('onload', handler);
};

Spry.Widget.ValidationRadio.addLoadListener(Spry.Widget.ValidationRadio.processLoadQueue);
Spry.Widget.ValidationRadio.addLoadListener(function(){
	Spry.Widget.Utils.addEventListener(window, "unload", Spry.Widget.Form.destroyAll, false);
});

Spry.Widget.ValidationRadio.prototype.attachBehaviors = function()
{
	if (!this.element)
		return;
	// find the INPUT type="Radio" element(s) inside current container
	if (this.element.nodeName == "INPUT") {
		this.radioElements = [this.element];
	} else {
		this.radioElements = this.getRadios();
	}
	if (this.radioElements) {
		var self = this;
		this.event_handlers = [];

		var qlen = this.radioElements.length;
		for (var i = 0; i < qlen; i++) {
			// focus
			this.event_handlers.push([this.radioElements[i], "focus", function(e) { return self.onFocus(e); }]);
			// blur
			this.event_handlers.push([this.radioElements[i], "blur", function(e) { return self.onBlur(e); }]);
			// add click instead of onChange
			if (this.validateOn & Spry.Widget.ValidationRadio.ONCHANGE) {
				this.event_handlers.push([this.radioElements[i], "click", function(e) { return self.onClick(e); }]);
			}
		}

		for (var i=0; i<this.event_handlers.length; i++) {
			Spry.Widget.Utils.addEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false);
		}

		// submit
		this.form = Spry.Widget.Utils.getFirstParentWithNodeName(this.element, "FORM");
		if (this.form) {
			// if no "onSubmit" handler has been attached to the current form, attach one
			if (!this.form.attachedSubmitHandler && !this.form.onsubmit) {
				this.form.onsubmit = function(e) { e = e || event; return Spry.Widget.Form.onSubmit(e, e.srcElement || e.currentTarget) };
				this.form.attachedSubmitHandler = true;
			}
			if (!this.form.attachedResetHandler) {

				Spry.Widget.Utils.addEventListener(this.form, "reset", function(e) { e = e || event; return Spry.Widget.Form.onReset(e, e.srcElement || e.currentTarget) }, false);
				this.form.attachedResetHandler = true;
			}
			// add the currrent widget to the "onSubmit" check queue;
			Spry.Widget.Form.onSubmitWidgetQueue.push(this);
		}
	}
};

Spry.Widget.ValidationRadio.prototype.getRadios = function()
{
	var arrRadios;
	var elements  = this.element.getElementsByTagName("INPUT");
	if (elements.length) {
		arrRadios = [];
		var qlen = elements.length;
		for (var i = 0; i < qlen; i++)
		{
			if (elements[i].getAttribute('type').toLowerCase() == "radio" || elements[i].getAttribute('type').toLowerCase() == "text" || elements[i].getAttribute('type').toLowerCase() == "hidden")
				arrRadios.push(elements[i]);
		}
		return arrRadios;
	}
	return null;
};

Spry.Widget.ValidationRadio.prototype.addClassName = function(ele, className)
{
	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
		return;
	ele.className += (ele.className ? " " : "") + className;
};

Spry.Widget.ValidationRadio.prototype.removeClassName = function(ele, className)
{
	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1))
		return;
	ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
};

Spry.Widget.ValidationRadio.prototype.onFocus = function(e)
{
	var eventRadio = (e.srcElement != null) ? e.srcElement : e.target;
 	if (eventRadio.disabled) return;
 
	this.addClassName(this.element, this.focusClass);
	this.addClassName(this.additionalError, this.focusClass);
};

Spry.Widget.ValidationRadio.prototype.onBlur = function(e)
{
	var eventRadio = (e.srcElement != null) ? e.srcElement : e.target;
	if (eventRadio.disabled) return;

	var doValidation = false;
	if (this.validateOn & Spry.Widget.ValidationRadio.ONBLUR)
		doValidation = true;
	if (doValidation)
		this.validate();
	this.removeClassName(this.element, this.focusClass);
	this.removeClassName(this.additionalError, this.focusClass);
};

Spry.Widget.ValidationRadio.prototype.onClick = function(e) {
	var eventRadio = (e.srcElement != null) ? e.srcElement : e.target;
	if (eventRadio.disabled) return;
	this.validate();
};

Spry.Widget.ValidationRadio.prototype.reset = function()
{
	this.removeClassName(this.element, this.validClass);
	this.removeClassName(this.element, this.requiredClass);
	this.removeClassName(this.element, this.invalidClass);
	this.removeClassName(this.additionalError, this.validClass);
	this.removeClassName(this.additionalError, this.requiredClass);
	this.removeClassName(this.additionalError, this.invalidClass);
};

Spry.Widget.ValidationRadio.prototype.validate = function()
{
	this.reset();
	var nochecked = 0;
	var invalid = 0;
	var required = 0;
	if (this.radioElements)
	{
		var qlen = this.radioElements.length;
		for (var i = 0; i < qlen; i++)
		{
			if (!this.radioElements[i].disabled){

				type = this.radioElements[i].type;
				if((type.toLowerCase() == "radio" && this.radioElements[i].checked) || (type.toLowerCase() == "text" || type.toLowerCase() == "hidden")){
					if (this.radioElements[i].value == this.emptyValue){
						required++;
 					}else if (this.invalidValue && this.radioElements[i].value == this.invalidValue){
						invalid++;
					}else{
						nochecked++;
					}
				}
			}
		}
	}
	
	if (this.invalidValue && invalid != 0)
	{
		this.addClassName(this.element, this.invalidClass);
		this.addClassName(this.additionalError, this.invalidClass);
		return false;
	}

	// check isRequired
	if (this.isRequired && (nochecked == 0 || required != 0))
	{
			this.addClassName(this.element, this.requiredClass);
			this.addClassName(this.additionalError, this.requiredClass);
			return false;
	}
	this.addClassName(this.element, this.validClass);
	this.addClassName(this.additionalError, this.validClass);
	return true;
};

Spry.Widget.ValidationRadio.prototype.isDisabled = function()
{
	var ret = true;
	if (this.radioElements) {
		var qlen = this.radioElements.length;
		for (var i = 0; i < qlen; i++)
		{
			if (!this.radioElements[i].disabled)
			{
				ret = false;
				break;
			}
		}
	}
	return ret;
};

Spry.Widget.ValidationRadio.prototype.destroy = function()
{
	if (this.event_handlers)
		for (var i=0; i<this.event_handlers.length; i++)
		{
			Spry.Widget.Utils.removeEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false);
		}
	try { delete this.element; } catch(err) {}
	if (this.radioElements)
		for(var i=0; i < this.radioElements.length; i++)
		{
			try { delete this.radioElements[i];} catch(err) {}
		}
	try { delete this.radioElements; } catch(err) {}
	try { delete this.form; } catch(err) {}
	try { delete this.event_handlers; } catch(err) {}

	var q = Spry.Widget.Form.onSubmitWidgetQueue;
	var qlen = q.length;
	for (var i = 0; i < qlen; i++) {
		if (q[i] == this) {
			q.splice(i, 1);
			break;
		}
	}
};

Spry.Widget.Utils.addEventListener = function(element, eventType, handler, capture)
{
	try{
		if (element.addEventListener)
			element.addEventListener(eventType, handler, capture);
		else if (element.attachEvent)
			element.attachEvent("on" + eventType, handler, capture);
	}catch (e){}
};
Spry.Widget.Utils.removeEventListener = function(element, eventType, handler, capture)
{
	try{
		if (element.removeEventListener)
			element.removeEventListener(eventType, handler, capture);
		else if (element.detachEvent)
			element.detachEvent("on" + eventType, handler, capture);
	}catch (e) {}
};

Spry.Widget.BrowserSniff = function() {
	var b = navigator.appName.toString();
	var up = navigator.platform.toString();
	var ua = navigator.userAgent.toString();

	this.mozilla = this.ie = this.opera = r = false;
	var re_opera = /Opera.([0-9\.]*)/i;
	var re_msie = /MSIE.([0-9\.]*)/i;
	var re_gecko = /gecko/i;
	var re_safari = /safari\/([\d\.]*)/i;
	
	if (ua.match(re_opera)) {
		r = ua.match(re_opera);
		this.opera = true;
		this.version = parseFloat(r[1]);
	} else if (ua.match(re_msie)) {
		r = ua.match(re_msie);
		this.ie = true;
		this.version = parseFloat(r[1]);
	} else if (ua.match(re_safari)) {
		this.safari = true;
		this.version = 1.4;
	} else if (ua.match(re_gecko)) {
		var re_gecko_version = /rv:\s*([0-9\.]+)/i;
		r = ua.match(re_gecko_version);
		this.mozilla = true;
		this.version = parseFloat(r[1]);
	}
	this.windows = this.mac = this.linux = false;

	this.Platform = ua.match(/windows/i) ? "windows" :
					(ua.match(/linux/i) ? "linux" :
					(ua.match(/mac/i) ? "mac" :
					ua.match(/unix/i)? "unix" : "unknown"));
	this[this.Platform] = true;
	this.v = this.version;

	if (this.safari && this.mac && this.mozilla) {
		this.mozilla = false;
	}
};

Spry.is = new Spry.Widget.BrowserSniff();


Spry.Widget.ValidationTextarea = function(element, options){
	
	options = options || {};
	this.flags = {locked: false};
	this.options = {};
	this.element = element;
	this.init(element);

	if (!this.isBrowserSupported()){
		return;	
	}

	options.useCharacterMasking = Spry.Widget.Utils.firstValid(options.useCharacterMasking, true);
	options.hint = Spry.Widget.Utils.firstValid(options.hint, '');
	options.isRequired = Spry.Widget.Utils.firstValid(options.isRequired, true);
	options.additionalError = Spry.Widget.Utils.firstValid(options.additionalError, false);

	Spry.Widget.Utils.setOptions(this, options);
	Spry.Widget.Utils.setOptions(this.options, options);

	if (options.additionalError)
		this.additionalError = this.getElement(options.additionalError);

	//make sure we validate at least on submit
	var validateOn = ['submit'].concat(Spry.Widget.Utils.firstValid(this.options.validateOn, []));
	validateOn = validateOn.join(",");
	this.validateOn = 0;
	this.validateOn = this.validateOn | (validateOn.indexOf('submit') != -1 ? Spry.Widget.ValidationTextarea.ONSUBMIT : 0);
	this.validateOn = this.validateOn | (validateOn.indexOf('blur') != -1 ? Spry.Widget.ValidationTextarea.ONBLUR : 0);
	this.validateOn = this.validateOn | (validateOn.indexOf('change') != -1 ? Spry.Widget.ValidationTextarea.ONCHANGE : 0);

	if (Spry.Widget.ValidationTextarea.onloadDidFire){
		this.attachBehaviors();
	}else{
		Spry.Widget.ValidationTextarea.loadQueue.push(this);
	}
};

Spry.Widget.ValidationTextarea.ONCHANGE = 1;
Spry.Widget.ValidationTextarea.ONBLUR = 2;
Spry.Widget.ValidationTextarea.ONSUBMIT = 4;

Spry.Widget.ValidationTextarea.INITIAL = 'Initial';
Spry.Widget.ValidationTextarea.REQUIRED = 'Required';
Spry.Widget.ValidationTextarea.INVALID = 'Invalid Format';
Spry.Widget.ValidationTextarea.MINIMUM = 'Minimum Number of Chars Not Met';
Spry.Widget.ValidationTextarea.MAXIMUM = 'Maximum Number of Chars Exceeded';
Spry.Widget.ValidationTextarea.VALID = 'Valid';

Spry.Widget.ValidationTextarea.prototype.init = function(element)
{
	this.element = this.getElement(element);
	this.event_handlers = [];

	this.requiredClass = "textareaRequiredState";
	this.invalidCharsMaxClass = "textareaMaxCharsState";
	this.invalidCharsMinClass = "textareaMinCharsState";
	this.validClass = "textareaValidState";
	this.focusClass = "textareaFocusState";
	this.hintClass = "textareaHintState";
	this.textareaFlashClass = "textareaFlashState";

	this.isMaxInvalid = false;
	this.isMinInvalid = false;
	this.isRequireInvalid = false;
	
	this.safariClicked = false;
	this.state = Spry.Widget.ValidationTextarea.INITIAL;
};

Spry.Widget.ValidationTextarea.prototype.destroy = function() {
	for (var i=0; i<this.event_handlers.length; i++) {
		Spry.Widget.Utils.removeEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false);
	}
	try { delete this.element; } catch(err) {}
	try { delete this.input; } catch(err) {}
	try { delete this.counterEl; } catch(err) {}
	try { delete this.form; } catch(err) {}
	try { delete this.event_handlers; } catch(err) {}
	try { this.cursorPosition.destroy(); } catch(err) {}
	try { delete this.cursorPosition; } catch(err) {}
	try { this.initialCursor.destroy(); } catch(err) {}
	try { delete this.initialCursor; } catch(err) {}

	var q = Spry.Widget.Form.onSubmitWidgetQueue;
	var qlen = q.length;
	for (var i = 0; i < qlen; i++) {
		if (q[i] == this) {
			q.splice(i, 1);
			break;
		}
	}
};

Spry.Widget.ValidationTextarea.prototype.isDisabled = function() {
	return this.input && (this.input.disabled || this.input.readOnly) || !this.input;
};

Spry.Widget.ValidationTextarea.prototype.getElement = function(ele)
{
	if (ele && typeof ele == "string")
		return document.getElementById(ele);
	return ele;
};


Spry.Widget.ValidationTextarea.addLoadListener = function(handler){
	if (typeof window.addEventListener != 'undefined'){
		window.addEventListener('load', handler, false);
	}else if (typeof document.addEventListener != 'undefined'){
		document.addEventListener('load', handler, false);
	}else if (typeof window.attachEvent != 'undefined'){
		window.attachEvent('onload', handler);
	}
};

Spry.Widget.ValidationTextarea.processLoadQueue = function(handler){
	Spry.Widget.ValidationTextarea.onloadDidFire = true;
	var q = Spry.Widget.ValidationTextarea.loadQueue;
	var qlen = q.length;
	for (var i = 0; i < qlen; i++){
		q[i].attachBehaviors();
	}
};

Spry.Widget.ValidationTextarea.onloadDidFire = false;
Spry.Widget.ValidationTextarea.loadQueue = [];
Spry.Widget.ValidationTextarea.addLoadListener(Spry.Widget.ValidationTextarea.processLoadQueue);
Spry.Widget.ValidationTextarea.addLoadListener(function(){
	Spry.Widget.Utils.addEventListener(window, "unload", Spry.Widget.Form.destroyAll, false);
});

Spry.Widget.ValidationTextarea.prototype.isBrowserSupported = function()
{
	return Spry.is.ie && Spry.is.v >= 5 && Spry.is.windows
		||
	Spry.is.mozilla && Spry.is.v >= 1.4
		||
	Spry.is.safari
		||
	Spry.is.opera && Spry.is.v >= 9;
};

Spry.Widget.ValidationTextarea.prototype.attachBehaviors = function()
{
	if (this.element){
		if (this.element.nodeName == "TEXTAREA") {
			this.input = this.element;
		} else {
			this.input = Spry.Widget.Utils.getFirstChildWithNodeNameAtAnyLevel(this.element, "TEXTAREA");
		}
	}
	if (this.options && this.options.counterType && (this.options.counterType == 'chars_count' || this.options.counterType == 'chars_remaining')){
			this.counterEl = document.getElementById(this.options.counterId);
			this.counterChar();
	}

	if (this.input) {
		this.input.setAttribute("AutoComplete", "off");
		this.putHint();
		this.selection = null; /*new Spry.Widget.SelectionDescriptor(this.input); CRASHES WITH NEW FIREFOX*/

		var self = this;
		this.event_handlers = [];

		//attach the pattern related event handlers (to stop invalid keys) 
		if (this.useCharacterMasking) {
			if (Spry.is.ie){
				this.event_handlers.push([this.input, "propertychange", function(e) { return self.onKeyEvent(e || event); }]);
				this.event_handlers.push([this.input, "drop", function(e) { return self.onDrop (e || event); }]);
				this.event_handlers.push([this.input, "keypress", function(e) { return self.onKeyPress(e || event); }]);
			} else{
				this.event_handlers.push([this.input, "keydown", function(e) { return self.onKeyDown(e); }]);
				this.event_handlers.push([this.input, "keypress", function(e) { return self.safariKeyPress(e); }]);
				this.event_handlers.push([this.input, "keyup", function(e) { return self.safariValidate(e); }]);
				if (Spry.is.safari){
					this.event_handlers.push([this.input, "mouseup", function(e) { return self.safariMouseUp(e); }]);
					this.event_handlers.push([this.input, "mousedown", function(e) { return self.safariMouseDown(e); }]);
				} else {
					//Firefox bug: 355219
					//this.event_handlers.push([this.input, "input", function(e) { self.onKeyEvent(e); return true;}]);
					this.event_handlers.push([this.input, "dragdrop", function(e) { return self.onKeyEvent(e); }]);
					this.event_handlers.push([this.input, "dragenter", function(e) { self.removeHint(); return self.onKeyDown(e); }]);
					this.event_handlers.push([this.input, "dragexit", function(e) { return self.putHint(); }]);
				}
			}
			// we need to save an initial state in case of invalid input
			this.event_handlers.push([this.input, "keydown", function(e) {return self.onKeyDown(e || event); }]);
		}

		this.event_handlers.push([this.input, "focus", function(e) { return self.onFocus(e || event); }]);
		this.event_handlers.push([this.input, "mousedown", function(e) { return self.onMouseDown(e || event); }]);
		this.event_handlers.push([this.input, "blur", function(e) { return self.onBlur(e || event); }]);

		if (this.validateOn & Spry.Widget.ValidationTextarea.ONCHANGE){
				if (Spry.is.ie){
						this.event_handlers.push([this.input, "propertychange", function(e) { return self.onChange(e || event); }]);
						this.event_handlers.push([this.input, "drop", function(e) { return self.onChange(e || event); }]);
				} else{
						this.event_handlers.push([this.input, "keydown", function(e) { return self.onKeyDown(e); }]);
						this.event_handlers.push([this.input, "keypress", function(e) { return self.safariChangeKeyPress(e); }]);
						this.event_handlers.push([this.input, "keyup", function(e) { return self.safariChangeValidate(e); }]);
						if (Spry.is.safari){
							this.event_handlers.push([this.input, "mouseup", function(e) { return self.safariChangeMouseUp(e); }]);
							this.event_handlers.push([this.input, "mousedown", function(e) { return self.safariMouseDown(e); }]);
						} else {
							// Firefox bug: 355219
							//this.event_handlers.push([this.input, "input", function(e) { return self.onChange(e); }]);
							this.event_handlers.push([this.input, "dragdrop", function(e) {return self.onChange(e); }]);
							this.event_handlers.push([this.input, "dragenter", function(e) { self.removeHint(); return self.onKeyDown(e); }]);
							this.event_handlers.push([this.input, "dragexit", function(e) { return self.putHint(); }]);
						}
				}
		}
		// The counter should be called directly when no enforcement or change restrictions exists
		if (! (this.validateOn & Spry.Widget.ValidationTextarea.ONCHANGE) && !this.useCharacterMasking){
				if (Spry.is.ie){
						this.event_handlers.push([this.input, "propertychange", function(e) { return self.counterChar(); }]);
						this.event_handlers.push([this.input, "drop", function(e) { return self.counterChar(); }]);
				} else{
						this.event_handlers.push([this.input, "keypress", function(e) { return self.counterChar(); }]);
						this.event_handlers.push([this.input, "keyup", function(e) { return self.counterChar(); }]);
						if (Spry.is.safari){
							this.event_handlers.push([this.input, "mouseup", function(e) { return self.counterChar(); }]);
						} else {
							// Firefox bug: 355219
							//this.event_handlers.push([this.input, "input", function(e) { return self.onChange(e); }]);
							this.event_handlers.push([this.input, "dragdrop", function(e) {return self.counterChar(); }]);
						}
				}
		}

		for (var i=0; i<this.event_handlers.length; i++) {
			Spry.Widget.Utils.addEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false);
		}

		this.form = Spry.Widget.Utils.getFirstParentWithNodeName(this.input, "FORM");
		if (this.form) {
			if (!this.form.attachedSubmitHandler && !this.form.onsubmit) {
				this.form.onsubmit = function(e) { e = e || event; return Spry.Widget.Form.onSubmit(e, e.srcElement || e.currentTarget) };
				this.form.attachedSubmitHandler = true;                 
			}
			if (!this.form.attachedResetHandler) {
				Spry.Widget.Utils.addEventListener(this.form, "reset", function(e) { e = e || event; return Spry.Widget.Form.onReset(e, e.srcElement || e.currentTarget) }, false);
				this.form.attachedResetHandler = true;                 
			}
			// add the currrent widget to the "onSubmit" check queue;
			Spry.Widget.Form.onSubmitWidgetQueue.push(this);
		}
	}
	this.saveState();
};

Spry.Widget.ValidationTextarea.prototype.onTyping = function(e){
	if (this.input.disabled == true || this.input.readOnly == true){
			return;	
	}

	if (!this.initialCursor){
		this.initialCursor = this.cursorPosition;	
	}
	// on IE a stack overflow appears
	if (this.flags.locked){
			return true;
	}

	var val = this.input.value;

	var ret = true;
	
	if (this.flags.hintOn){
		return true;
	}
 	if (e && this.input && this.options && this.options.maxChars > 0 && ret){
		if ( val.length > this.options.maxChars  && 
							((!Spry.Widget.Utils.isSpecialKey(e) && this.cursorPosition.start == this.cursorPosition.end) ||
				 			 (Spry.Widget.Utils.isSpecialKey(e) && val != this.initialValue) ||
				 				this.cursorPosition.start != this.cursorPosition.end)
			 ){
					// cut the extra chars and display error
					this.flags.locked = true;
					var initial = this.initialValue;
					var start = this.initialCursor.start;
					var end = this.initialCursor.end;
					if (initial.length && this.initialCursor.end < initial.length) {
							// we try to behave more like maxlength textfield
							var tmp = end - start + this.options.maxChars - initial.length;
							var newValue = initial.substring(0, start) + val.substring(start, start+tmp) + initial.substring(end, initial.length < this.options.maxChars ? initial.length:this.options.maxChars);
							end = start + tmp;
					}else{
							var newValue = val.substring(0, this.options.maxChars);
							end = start = this.options.maxChars;
					}
					if (Spry.is.ie) {
						this.input.innerText = newValue;
					} else {
						this.input.value = newValue;
					}
					this.redTextFlash();
					this.cursorPosition.moveTo(end, end);
					this.flags.locked = false;
					ret = false;
			} else{
					this.setState(Spry.Widget.ValidationTextarea.VALID);
					this.isMaxInvalid = false;
			}
	}
	this.counterChar();
	return ret;
};

Spry.Widget.ValidationTextarea.prototype.validateMinRequired = function(val){
	var oldInvalid = false;
	if (typeof this.notFireMinYet == 'undefined'){
		this.notFireMinYet = false;
	}else{
		oldInvalid = true;
		this.notFireMinYet = true;
	}
	if (this.onBlurOn){
		this.notFireMinYet = true;
	}else if (!this.onKeyEventOn){
		this.notFireMinYet = true;
	}
	val = val.replace(/^(\s|\&nbsp;)*|(\s|\&nbsp;)*$/g,"");
	if (this.input && this.options && this.options.isRequired){
			if (val.length > 0 && this.isRequireInvalid && (!this.hint || (this.hint && !this.flags.hintOn) || (this.hint && val != this.hint))){
						this.switchClassName(this.validClass);
						this.setState(Spry.Widget.ValidationTextarea.VALID);
						this.isRequireInvalid = false;
			}else if ((val.length == 0 || !(!this.hint || (this.hint && !this.flags.hintOn) || (this.hint && val != this.hint))) && (!this.isRequireInvalid || oldInvalid)){
						if (this.notFireMinYet || Spry.is.ie){
							this.switchClassName(this.requiredClass);
							this.setState(Spry.Widget.ValidationTextarea.REQUIRED);
						}
						this.isRequireInvalid = true;
						this.isMinInvalid = false;
			}
	}
	if (this.input && this.options && this.options.minChars > 0 && !this.isRequireInvalid){
			if (val.length >= this.options.minChars && (!this.hint || (this.hint && !this.flags.hintOn) || (this.hint && val != this.hint)) && this.isMinInvalid){
						this.switchClassName(this.validClass);
						this.setState(Spry.Widget.ValidationTextarea.VALID);
						this.isMinInvalid = false;
			}else if ( (val.length < this.options.minChars || (this.hint && val == this.hint && this.flags.hintOn)) && !this.isMinInvalid){
						this.switchClassName(this.invalidCharsMinClass);
						this.setState(Spry.Widget.ValidationTextarea.MINIMUM);
						this.isMinInvalid = true;
			}
	}
};
Spry.Widget.ValidationTextarea.prototype.counterChar = function(){
	if (!this.counterEl || !this.options || !this.options.counterType || (this.options.counterType != 'chars_remaining' && this.options.counterType != 'chars_count')){
		return;	
	}

	if (this.options.counterType == 'chars_remaining') {
		if (this.options.maxChars > 0){
			if (this.flags.hintOn){
				this.setCounterElementValue(this.options.maxChars);
			} else {
				if (this.options.maxChars > this.input.value.length){
					this.setCounterElementValue(this.options.maxChars - this.input.value.length);
				}else{
					this.setCounterElementValue(0);
				}
			}
		}
	} else {
		if (this.flags.hintOn){
			this.setCounterElementValue(0);
		} else {
			if (this.useCharacterMasking && typeof this.options.maxChars != 'undefined' && this.options.maxChars < this.input.value.length){
				this.setCounterElementValue(this.options.maxChars);
			} else {
				this.setCounterElementValue(this.input.value.length);
			}
		}
	}
};

Spry.Widget.ValidationTextarea.prototype.setCounterElementValue = function(val){
		if ( this.counterEl.nodeName.toLowerCase() != 'input' && 
			this.counterEl.nodeName.toLowerCase() != 'textarea' &&
			this.counterEl.nodeName.toLowerCase() != 'select' &&
			this.counterEl.nodeName.toLowerCase() != 'img'){
			this.counterEl.innerHTML = val;
		}
};
Spry.Widget.ValidationTextarea.prototype.reset = function() {
	this.removeHint();
	this.removeClassName(this.requiredClass);
	this.removeClassName(this.invalidCharsMinClass);
	this.removeClassName(this.invalidCharsMaxClass);
	this.removeClassName(this.validClass);
	this.setState(Spry.Widget.ValidationTextarea.INITIAL);
	var self = this;
	setTimeout(function() {self.putHint();self.counterChar();}, 10);
};

Spry.Widget.ValidationTextarea.prototype.validate = function(){
	if (this.input.disabled == true || this.input.readOnly == true){
			return true;	
	}

	var val = this.input.value;
	this.validateMinRequired(val);

	var ret = !this.isMinInvalid && !this.isRequireInvalid;

	if (ret && this.options.maxChars > 0 && !this.useCharacterMasking){
			if (val.length <= this.options.maxChars || (this.hint && this.hint == val && this.flags.hintOn))	{

					this.switchClassName(this.validClass);
					this.setState(Spry.Widget.ValidationTextarea.VALID);
				  this.isMaxInvalid = false;
			}else{
					this.switchClassName(this.invalidCharsMaxClass);
					this.setState(Spry.Widget.ValidationTextarea.MAXIMUM);
					this.isMaxInvalid = true;	
			}
	}
	ret = ret && !this.isMaxInvalid;
	if (ret) {
		this.switchClassName(this.validClass);
	}
	this.counterChar();	
	return ret;
};

Spry.Widget.ValidationTextarea.prototype.setState = function(newstate){
	this.state = newstate;
};

Spry.Widget.ValidationTextarea.prototype.getState = function(){
	return this.state;
};

Spry.Widget.ValidationTextarea.prototype.removeHint = function()
{
	if (this.flags.hintOn) 
	{
		this.flags.locked = true;
		this.input.value = "";
		this.flags.locked = false;
		this.flags.hintOn = false;
		this.removeClassName(this.hintClass);
	}
};

Spry.Widget.ValidationTextarea.prototype.putHint = function()
{
	if(this.hint && this.input.value == "") {
		this.flags.hintOn = true;
		this.input.value = this.hint;
		this.addClassName(this.hintClass);
	}
};

Spry.Widget.ValidationTextarea.prototype.redTextFlash = function()
{
	var self = this;
	this.addClassName(this.textareaFlashClass);
	setTimeout(function() {
		self.removeClassName(self.textareaFlashClass)
	}, 200);
};


Spry.Widget.ValidationTextarea.prototype.onKeyPress = function(e)
{
	//ENTER has length 2 on IE Windows, so will exceed maxLength on proximity
	if (Spry.is.ie && Spry.is.windows && e.keyCode == 13) {
		if ( (this.initialCursor.length + this.options.maxChars - this.input.value.length) < 2) {
			Spry.Widget.Utils.stopEvent(e);
			return false;
		}
	}
};

Spry.Widget.ValidationTextarea.prototype.onKeyDown = function(e)
{ 
	this.saveState();
	this.keyCode = e.keyCode;
	return true;
};

Spry.Widget.ValidationTextarea.prototype.onKeyEvent = function(e){
	// on IE we look only for this input value changes
	if (e.type == 'propertychange' && e.propertyName != 'value'){
			return true;
	}

	var allow = this.onTyping(e);

	if (!allow){
		Spry.Widget.Utils.stopEvent(e);
	}
	//return allow;
};

Spry.Widget.ValidationTextarea.prototype.onChange = function(e){
	if (Spry.is.ie && e && e.type == 'propertychange' && e.propertyName != 'value') {
		return true;
	}

	if (this.flags.drop) {
		//delay this if it's a drop operation
		var self = this;
		setTimeout(function() {
			self.flags.drop = false;
			self.onChange(null);
		}, 0);
		return true;
	}
	if (this.flags.hintOn) {
		return true;
	}
	this.onKeyEventOn = true;
	var answer = this.validate();
	this.onKeyEventOn = false;
	return answer;
};

Spry.Widget.ValidationTextarea.prototype.onMouseDown = function(e)
{
	if (this.flags.active) {
		//mousedown fires before focus
		//avoid double saveState on first focus by mousedown by checking if the control has focus
		//do nothing if it's not focused because saveState will be called onfocus
		this.saveState();
	}
};

Spry.Widget.ValidationTextarea.prototype.onDrop = function(e)
{
	//mark that a drop operation is in progress to avoid race conditions with event handlers for other events
	//especially onchange and onfocus
	this.flags.drop = true;
	this.removeHint();

	if (Spry.is.ie) {
		var rng = document.body.createTextRange();
		rng.moveToPoint(e.x, e.y);
		rng.select();
	}

	this.saveState();
	this.flags.active = true;
	this.addClassName(this.focusClass);
};

Spry.Widget.ValidationTextarea.prototype.onFocus = function(e)
{
	if (this.flags.drop) {
		return;
	}
	this.removeHint();
	this.saveState();
	this.flags.active = true;
	this.addClassName(this.focusClass);
};

Spry.Widget.ValidationTextarea.prototype.onBlur = function(e){
	this.removeClassName(this.focusClass);

	if (this.validateOn & Spry.Widget.ValidationTextarea.ONBLUR) {
		this.onBlurOn = true;
		this.validate();
		this.onBlurOn = false;
	}

	this.flags.active = false;
	var self = this;
	setTimeout(function() {self.putHint();}, 10);
};

Spry.Widget.ValidationTextarea.prototype.safariMouseDown = function(e){
	this.safariClicked = true;
};
Spry.Widget.ValidationTextarea.prototype.safariChangeMouseUp = function(e){
		if (!this.safariClicked){
			this.onKeyDown(e); 
			return this.safariChangeValidate(e, false);
		}else{
			this.safariClicked = false;
			return true;
		}
};

Spry.Widget.ValidationTextarea.prototype.safariMouseUp = function(e){
		if (!this.safariClicked){
			this.onKeyDown(e);
			return this.safariValidate(e, false);
		}else{
			this.safariClicked = false;
			return true;
		}
};

Spry.Widget.ValidationTextarea.prototype.safariKeyPress = function(e){
	this.safariFlag = new Date();
	return this.safariValidate(e, true);
};

Spry.Widget.ValidationTextarea.prototype.safariValidate = function(e, recall)
{
	if (e.keyCode && Spry.Widget.Utils.isSpecialKey(e) && e.keyCode != 8 && e.keyCode != 46){
		return true;
	}
	var answer = this.onTyping(e);

	// the answer to this is not yet final - we schedule another closing check
	if (new Date() - this.safariFlag < 1000 && recall){
		var self = this;
		setTimeout(function(){self.safariValidate(e, false);}, 1000);
	}
	return answer;
};

Spry.Widget.ValidationTextarea.prototype.safariChangeKeyPress = function(e){
	this.safariChangeFlag = new Date();
	return this.safariChangeValidate(e, true);
};

Spry.Widget.ValidationTextarea.prototype.safariChangeValidate = function(e, recall){
	
	if(e.keyCode && Spry.Widget.Utils.isSpecialKey(e) && e.keyCode != 8 && e.keyCode != 46){
		return true;	
	}
	var answer = this.onChange(e);

	// the answer to this is not yet final - we schedule another closing check
	if (new Date() - this.safariChangeFlag < 1000 && recall){
		var self = this;
		setTimeout(function(){ self.safariChangeValidate(e, false);}, 1000 - new Date() + this.safariChangeFlag);
	}
	return answer;
};

Spry.Widget.ValidationTextarea.prototype.saveState = function(e){
	
	// we don't need this initial value that is already invalid
	if (this.options.maxChars > 0 && this.input.value.length > this.options.maxChars){
		return;
	}
	this.cursorPosition.update();
	if (!this.flags.hintOn){
		this.initialValue = this.input.value;
	}else{
		this.initialValue = '';
	}
	this.initialCursor = this.cursorPosition; 
	return true;
};

Spry.Widget.ValidationTextarea.prototype.checkClassName = function(ele, className){
	if (!ele || !className){
		return false;
	}
	if (typeof ele == 'string' ) {
		ele = document.getElementById(ele);
		if (!ele){
			return false;	
		}
	}
	if (!ele.className){
		ele.className = ' ';
	}
	return ele;
};

Spry.Widget.ValidationTextarea.prototype.switchClassName = function (className){
	var classes = [this.invalidCharsMaxClass, this.validClass, this.requiredClass, this.invalidCharsMinClass];

	for (var k = 0; k < classes.length; k++){
		if (classes[k] != className){
				this.removeClassName(classes[k]);			
		}
	}

	this.addClassName(className);
};

Spry.Widget.ValidationTextarea.prototype.addClassName = function(clssName){
	var ele = this.checkClassName(this.element, clssName);
	var add = this.checkClassName(this.additionalError, clssName);

	if (!ele || ele.className.search(new RegExp("\\b" + clssName + "\\b")) != -1){
	  return;
	}
	this.element.className += ' ' + clssName;
	if (add)
		add.className += ' ' + clssName;
};

Spry.Widget.ValidationTextarea.prototype.removeClassName = function(className){
	var ele = this.checkClassName(this.element, className);
	var add = this.checkClassName(this.additionalError, className);
	if (!ele){
	  return;	
	}
	ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), '');
	if (add){
		add.className = add.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), '');
	}
}; 

Spry.Widget.SelectionDescriptor = function (element)
{
	this.element = element;
	this.update();
};

Spry.Widget.SelectionDescriptor.prototype.update = function()
{
	if (Spry.is.ie && Spry.is.windows) {
		if (this.element.nodeName == "TEXTAREA") {
            var sel = this.element.ownerDocument.selection;
            if (sel.type != 'None') {
		var range = this.element.ownerDocument.selection.createRange();
		if (range.parentElement() == this.element){
			var range_all = this.element.ownerDocument.body.createTextRange();
			range_all.moveToElementText(this.element);
			for (var sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start ++){
			 	range_all.moveStart('character', 1);
			}
			this.start = sel_start;
			// create a selection of the whole this.element
			range_all = this.element.ownerDocument.body.createTextRange();
			range_all.moveToElementText(this.element);
			for (var sel_end = 0; range_all.compareEndPoints('StartToEnd', range) < 0; sel_end++){
				range_all.moveStart('character', 1);
			}
			this.end = sel_end;
			this.length = this.end - this.start;
			// get selected and surrounding text
			this.text = range.text;
		 }
            }        
		} else if (this.element.nodeName == "INPUT"){
            var sel = this.element.ownerDocument.selection;
			this.range = this.element.ownerDocument.selection.createRange();
			this.length = this.range.text.length;
			var clone = this.range.duplicate();
			this.start = -clone.moveStart("character", -10000);
			clone = this.range.duplicate();
			clone.collapse(false);
			this.end = -clone.moveStart("character", -10000);
			this.text = this.range.text;
		}
	} else {
		var tmp = this.element;
		var selectionStart = 0;
		var selectionEnd = 0;

		try { selectionStart = tmp.selectionStart; } catch(err) {}
		try { selectionEnd = tmp.selectionEnd; } catch(err) {}

		if (Spry.is.safari) {
			if (selectionStart == 2147483647) {
				selectionStart = 0;
			}
			if (selectionEnd == 2147483647) {
				selectionEnd = 0;
			}
		}
		this.start = selectionStart;
		this.end = selectionEnd;
		this.length = selectionEnd - selectionStart;
		this.text = this.element.value.substring(selectionStart, selectionEnd);
	}
};

Spry.Widget.SelectionDescriptor.prototype.destroy = function() {
	try { delete this.range} catch(err) {}
	try { delete this.element} catch(err) {}
};

Spry.Widget.SelectionDescriptor.prototype.moveTo = function(start, end)
{
	if (Spry.is.ie && Spry.is.windows) {
		if (this.element.nodeName == "TEXTAREA") {
			var ta_range = this.element.createTextRange();
			this.range = this.element.createTextRange();
			this.range.move("character", start);
			this.range.moveEnd("character", end - start);
			
			var c1 = this.range.compareEndPoints("StartToStart", ta_range);
			if (c1 < 0) {
				this.range.setEndPoint("StartToStart", ta_range);
			}

			var c2 = this.range.compareEndPoints("EndToEnd", ta_range);
			if (c2 > 0) {
				this.range.setEndPoint("EndToEnd", ta_range);
			}
		} else if (this.element.nodeName == "INPUT"){
			this.range = this.element.ownerDocument.selection.createRange();
			this.range.move("character", -10000);
			this.start = this.range.moveStart("character", start);
			this.end = this.start + this.range.moveEnd("character", end - start);
		}
		this.range.select();
	} else {
		this.start = start;
		try { this.element.selectionStart = start; } catch(err) {}
		this.end = end;
		try { this.element.selectionEnd = end; } catch(err) {}
	}
	this.ignore = true;
	this.update();
};

Spry.Widget.Utils.firstValid = function() {
	var ret = null;
	for(var i=0; i<Spry.Widget.Utils.firstValid.arguments.length; i++) {
		if (typeof(Spry.Widget.Utils.firstValid.arguments[i]) != 'undefined') {
			ret = Spry.Widget.Utils.firstValid.arguments[i];
			break;
		}
	}
	return ret;
};

Spry.Widget.Utils.specialSafariNavKeys = ",63232,63233,63234,63235,63272,63273,63275,63276,63277,63289,";

Spry.Widget.Utils.specialCharacters = ",8,9,16,17,18,20,27,33,34,35,36,37,38,39,40,45,46,91,92,93,144,192,63232,";
Spry.Widget.Utils.specialCharacters += Spry.Widget.Utils.specialSafariNavKeys;

Spry.Widget.Utils.isSpecialKey = function (ev) {
	return Spry.Widget.Utils.specialCharacters.indexOf("," + ev.keyCode + ",") != -1;
};

Spry.Widget.Utils.getFirstChildWithNodeNameAtAnyLevel = function(node, nodeName) {
	var elements  = node.getElementsByTagName(nodeName);
	if (elements) {
		return elements[0];
	}
	return null;
};

Spry.Widget.Utils.stopEvent = function(ev)
{
	try
	{
		this.stopPropagation(ev);
		this.preventDefault(ev);
	}
	catch (e) {}
};

Spry.Widget.Utils.stopPropagation = function(ev)
{
	if (ev.stopPropagation)
	{
		ev.stopPropagation();
	}
	else
	{
		ev.cancelBubble = true;
	}
};

Spry.Widget.Utils.preventDefault = function(ev)
{
	if (ev.preventDefault)
	{
		ev.preventDefault();
	}
	else
	{
		ev.returnValue = false;
	}
};

Spry.Widget.ValidationTextField = function(element, type, options)
{
	type = Spry.Widget.Utils.firstValid(type, "none");
	if (typeof type != 'string') {
		return;
	}
	if (typeof Spry.Widget.ValidationTextField.ValidationDescriptors[type] == 'undefined') {
		return;
	}
	options = Spry.Widget.Utils.firstValid(options, {});
	this.type = type;
	if (!this.isBrowserSupported()) {
		//disable character masking and pattern behaviors for low level browsers
		options.useCharacterMasking = false;
	}
	this.init(element, options);

	//make sure we validate at least on submit
	var validateOn = ['submit'].concat(Spry.Widget.Utils.firstValid(this.options.validateOn, []));
	validateOn = validateOn.join(",");

	this.validateOn = 0;
	this.validateOn = this.validateOn | (validateOn.indexOf('submit') != -1 ? Spry.Widget.ValidationTextField.ONSUBMIT : 0);
	this.validateOn = this.validateOn | (validateOn.indexOf('blur') != -1 ? Spry.Widget.ValidationTextField.ONBLUR : 0);
	this.validateOn = this.validateOn | (validateOn.indexOf('change') != -1 ? Spry.Widget.ValidationTextField.ONCHANGE : 0);

	if (Spry.Widget.ValidationTextField.onloadDidFire)
		this.attachBehaviors();
	else
		Spry.Widget.ValidationTextField.loadQueue.push(this);
};

Spry.Widget.ValidationTextField.ONCHANGE = 1;
Spry.Widget.ValidationTextField.ONBLUR = 2;
Spry.Widget.ValidationTextField.ONSUBMIT = 4;

Spry.Widget.ValidationTextField.ERROR_REQUIRED = 1;
Spry.Widget.ValidationTextField.ERROR_FORMAT = 2;
Spry.Widget.ValidationTextField.ERROR_RANGE_MIN = 4;
Spry.Widget.ValidationTextField.ERROR_RANGE_MAX = 8;
Spry.Widget.ValidationTextField.ERROR_CHARS_MIN = 16;
Spry.Widget.ValidationTextField.ERROR_CHARS_MAX = 32;
Spry.Widget.ValidationTextField.ValidationDescriptors = {
	'none': {
	},
	'custom': {
	},
	'integer': {
		characterMasking: /[\-\+\d]/,
		regExpFilter: /^[\-\+]?\d*$/,
		validation: function(value, options) {
			if (value == '' || value == '-' || value == '+') {
				return false;
			}
			var regExp = /^[\-\+]?\d*$/;
			if (!regExp.test(value)) {
				return false;
			}
			options = options || {allowNegative:false};
			var ret = parseInt(value, 10);
			if (!isNaN(ret)) {
				var allowNegative = true;
				if (typeof options.allowNegative != 'undefined' && options.allowNegative == false) {
					allowNegative = false;
				}
				if (!allowNegative && value < 0) {
					ret = false;
				}
			} else {
				ret = false;
			}
			return ret;
		}
	},
	'real': {
		characterMasking: /[\d\.,\-\+e]/i,
		regExpFilter: /^[\-\+]?\d(?:|\.,\d{0,2})|(?:|e{0,1}[\-\+]?\d{0,})$/i,
		validation: function (value, options) {
			var regExp = /^[\+\-]?[0-9]+([\.,][0-9]+)?([eE]{0,1}[\-\+]?[0-9]+)?$/;
			if (!regExp.test(value)) {
				return false;
			}
			var ret = parseFloat(value);
			if (isNaN(ret)) {
				ret = false;
			}
			return ret;
		}
	},
	'currency': {
		formats: {
			'dot_comma': {
				characterMasking: /[\d\.\,\-\+\$]/,
				regExpFilter: /^[\-\+]?(?:[\d\.]*)+(|\,\d{0,2})$/,
				validation: function(value, options) {
					var ret = false;
					//2 or no digits after the comma
					if (/^(\-|\+)?\d{1,3}(?:\.\d{3})*(?:\,\d{2}|)$/.test(value) || /^(\-|\+)?\d+(?:\,\d{2}|)$/.test(value)) {
						value = value.toString().replace(/\./gi, '').replace(/\,/, '.');
						ret = parseFloat(value);
					}
					return ret;
				}
			},
			'comma_dot': {
				characterMasking: /[\d\.\,\-\+\$]/,
				regExpFilter: /^[\-\+]?(?:[\d\,]*)+(|\.\d{0,2})$/,
				validation: function(value, options) {
					var ret = false;
					//2 or no digits after the comma
					if (/^(\-|\+)?\d{1,3}(?:\,\d{3})*(?:\.\d{2}|)$/.test(value) || /^(\-|\+)?\d+(?:\.\d{2}|)$/.test(value)) {
						value = value.toString().replace(/\,/gi, '');
						ret = parseFloat(value);
					}
					return ret;
				}
			}
		}
	},
	'email': {
		characterMasking: /[^\s]/,
		validation: function(value, options) {
			var rx = /^[\w\.-]+@[\w\.-]+\.\w+$/i;
			return rx.test(value);
		}
	},
	'date': {
		validation: function(value, options) {
			var formatRegExp = /^([mdy]+)[\.\-\/\\\s]+([mdy]+)[\.\-\/\\\s]+([mdy]+)$/i;
			var valueRegExp = this.dateValidationPattern;
			var formatGroups = options.format.match(formatRegExp);
			var valueGroups = value.match(valueRegExp);
			if (formatGroups !== null && valueGroups !== null) {
				var dayIndex = -1;
				var monthIndex = -1;
				var yearIndex = -1;
				for (var i=1; i<formatGroups.length; i++) {
					switch (formatGroups[i].toLowerCase()) {
						case "dd":
							dayIndex = i;
							break;
						case "mm":
							monthIndex = i;
							break;
						case "yy":
						case "yyyy":
							yearIndex = i;
							break;
					}
				}
				if (dayIndex != -1 && monthIndex != -1 && yearIndex != -1) {
					var maxDay = -1;
					var theDay = parseInt(valueGroups[dayIndex], 10);
					var theMonth = parseInt(valueGroups[monthIndex], 10);
					var theYear = parseInt(valueGroups[yearIndex], 10);

					// Check month value to be between 1..12
					if (theMonth < 1 || theMonth > 12) {
						return false;
					}
					
					// Calculate the maxDay according to the current month
					switch (theMonth) {
						case 1:	// January
						case 3: // March
						case 5: // May
						case 7: // July
						case 8: // August
						case 10: // October
						case 12: // December
							maxDay = 31;
							break;
						case 4:	// April
						case 6: // Juna
						case 9: // September
						case 11: // November
							maxDay = 30;
							break;
						case 2: // February
							if ((parseInt(theYear/4, 10) * 4 == theYear) && (theYear % 100 != 0 || theYear % 400 == 0)) {
								maxDay = 29;
							} else {
								maxDay = 28;
							}
							break;
					}

					// Check day value to be between 1..maxDay
					if (theDay < 1 || theDay > maxDay) {
						return false;
					}
					
					// If successfull we'll return the date object
					return (new Date(theYear, theMonth, theDay));
				}
			} else {
				return false;
			}
		}
	},
	'time': {
		validation: function(value, options) {
			//	HH:MM:SS T
			var formatRegExp = /([hmst]+)/gi;
			var valueRegExp = /(\d+|AM?|PM?)/gi;
			var formatGroups = options.format.match(formatRegExp);
			var valueGroups = value.match(valueRegExp);
			//mast match and have same length
			if (formatGroups !== null && valueGroups !== null) {
				if (formatGroups.length != valueGroups.length) {
					return false;
				}

				var hourIndex = -1;
				var minuteIndex = -1;
				var secondIndex = -1;
				//T is AM or PM
				var tIndex = -1;
				var theHour = 0, theMinute = 0, theSecond = 0, theT = 'AM';
				for (var i=0; i<formatGroups.length; i++) {
					switch (formatGroups[i].toLowerCase()) {
						case "hh":
							hourIndex = i;
							break;
						case "mm":
							minuteIndex = i;
							break;
						case "ss":
							secondIndex = i;
							break;
						case "t":
						case "tt":
							tIndex = i;
							break;
					}
				}
				if (hourIndex != -1) {
					var theHour = parseInt(valueGroups[hourIndex], 10);
					if (isNaN(theHour) || theHour > (formatGroups[hourIndex] == 'HH' ? 23 : 12 )) {
						return false;
					}
				}
				if (minuteIndex != -1) {
					var theMinute = parseInt(valueGroups[minuteIndex], 10);
					if (isNaN(theMinute) || theMinute > 59) {
						return false;
					}
				}
				if (secondIndex != -1) {
					var theSecond = parseInt(valueGroups[secondIndex], 10);
					if (isNaN(theSecond) || theSecond > 59) {
						return false;
					}
				}
				if (tIndex != -1) {
					var theT = valueGroups[tIndex].toUpperCase();
					if (
						formatGroups[tIndex].toUpperCase() == 'TT' && !/^a|pm$/i.test(theT) || 
						formatGroups[tIndex].toUpperCase() == 'T' && !/^a|p$/i.test(theT)
					) {
						return false;
					}
				}
				var date = new Date(2000, 0, 1, theHour + (theT.charAt(0) == 'P'?12:0), theMinute, theSecond);
				return date;
			} else {
				return false;
			}
		}
	},
	'credit_card': {
		characterMasking: /\d/,
		validation: function(value, options) {
			var regExp = null;
			options.format = options.format || 'ALL';
			switch (options.format.toUpperCase()) {
				case 'ALL': regExp = /^[3-6]{1}[0-9]{12,15}$/; break;
				case 'VISA': regExp = /^4[0-9]{12,15}$/; break;
				case 'MASTERCARD': regExp = /^5[1-5]{1}[0-9]{14}$/; break;
				case 'AMEX': regExp = /^3(4|7){1}[0-9]{13}$/; break;
				case 'DISCOVER': regExp = /^6011[0-9]{12}$/; break;
				case 'DINERSCLUB': regExp = /^3((0[0-5]{1}[0-9]{11})|(6[0-9]{12})|(8[0-9]{12}))$/; break;
			}
			if (!regExp.test(value)) {
				return false;
			}
			var digits = [];
			var j = 1, digit = '';
			for (var i = value.length - 1; i >= 0; i--) {

				if ((j%2) == 0) {
					digit = parseInt(value.charAt(i), 10) * 2;
					digits[digits.length] = digit.toString().charAt(0);
					if (digit.toString().length == 2) {
						digits[digits.length] = digit.toString().charAt(1);
					}
				} else {
					digit = value.charAt(i);
					digits[digits.length] = digit;
				}
				j++;
			}
			var sum = 0;
			for(i=0; i < digits.length; i++ ) {
				sum += parseInt(digits[i], 10);
			}
			if ((sum%10) == 0) {
				return true;
			}
			return false;
		}
	},
	'zip_code': {
		formats: {
			'zip_us9': {
				pattern:'00000-0000'
			},
			'zip_us5': {
				pattern:'00000'
			},
			'zip_uk': {
				characterMasking: /[\dA-Z\s]/,
				validation: function(value, options) {
					//check one of the following masks
					// AN NAA, ANA NAA, ANN NAA, AAN NAA, AANA NAA, AANN NAA
					return /^[A-Z]{1,2}\d[\dA-Z]?\s?\d[A-Z]{2}$/.test(value);
				}
			},
			'zip_canada': {
				characterMasking: /[\dA-Z\s]/,
				pattern: 'A0A 0A0'
			},
			'zip_custom': {}
		}
	},
	'phone_number': {
		formats: {
			//US phone number; 10 digits
			'phone_us': {
				pattern:'(000) 000-0000'
			},
			'phone_custom': {}
		}
	},
	'social_security_number': {
		pattern:'000-00-0000'
	},
	'ip': {
		characterMaskingFormats: {
			'ipv4': /[\d\.]/i,
			'ipv6_ipv4': /[\d\.\:A-F\/]/i,
			'ipv6': /[\d\.\:A-F\/]/i
		},
		validation: function (value, options) {
			return Spry.Widget.ValidationTextField.validateIP(value, options.format);
		}
	},

	'url': {
		characterMasking: /[^\s]/,
		validation: function(value, options) {
			//fix for ?ID=223429 and ?ID=223387
			/* the following regexp matches components of an URI as specified in http://tools.ietf.org/html/rfc3986#page-51 page 51, Appendix B.
				scheme    = $2
				authority = $4
				path      = $5
				query     = $7
				fragment  = $9
			*/
			var URI_spliter = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
			var parts = value.match(URI_spliter);
			if (parts && parts[4]) {
				//encode each component of the domain name using Punycode encoding scheme: http://tools.ietf.org/html/rfc3492
				var host  = parts[4].split(".");
				var punyencoded = '';
				for (var i=0; i<host.length; i++) {
					punyencoded = Spry.Widget.Utils.punycode_encode(host[i], 64);
					if (!punyencoded) {
						return false;
					} else {
						if (punyencoded != (host[i] + "-")) {
							host[i] = 'xn--' + punyencoded;
						}
					}
				}
				host = host .join(".");
				//the encoded domain name is replaced into the original URL to be validated again later as URL
				value = value.replace(URI_spliter, "$1//" + host + "$5$6$8");
			}

			var regExp = /^(?:https?|ftp)\:\/\/(?:(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=:]|%[0-9a-f]{2,2})*\@)?(?:((?:(?:[a-z0-9][a-z0-9\-]*[a-z0-9]|[a-z0-9])\.)*(?:[a-z][a-z0-9\-]*[a-z0-9]|[a-z])|(?:\[[^\]]*\]))(?:\:[0-9]*)?)(?:\/(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=\:\@]|%[0-9a-f]{2,2})*)*(?:\?(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=\:\@\/\?]|%[0-9a-f]{2,2})*)?(?:\#(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=\:\@\/\?]|%[0-9a-f]{2,2})*)?$/i;

			var valid = value.match(regExp);
			if (valid) {
				//extract the  address from URL
				var address = valid[1];

				if (address) {
					if (address == '[]') {
						return false;
					}
					if (address.charAt(0) == '[' ) {
						//IPv6 address or IPv4 enclosed in square brackets
						address = address.replace(/^\[|\]$/gi, '');
						return Spry.Widget.ValidationTextField.validateIP(address, 'ipv6_ipv4');
					} else {
						if (/[^0-9\.]/.test(address)) {
							return true;
						} else {
							//check if hostname is all digits and dots and then check for IPv4
							return Spry.Widget.ValidationTextField.validateIP(address, 'ipv4');
						}
					}
				} else {
					return true;
				}
			} else {
				return false;
			}
		}
	}
};

Spry.Widget.ValidationTextField.validateIP = function (value, format)
{
	var validIPv6Addresses = [
		//preferred
		/^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}(?:\/\d{1,3})?$/i,

		//various compressed
		/^[a-f0-9]{0,4}::(?:\/\d{1,3})?$/i,
		/^:(?::[a-f0-9]{1,4}){1,6}(?:\/\d{1,3})?$/i,
		/^(?:[a-f0-9]{1,4}:){1,6}:(?:\/\d{1,3})?$/i,
		/^(?:[a-f0-9]{1,4}:)(?::[a-f0-9]{1,4}){1,6}(?:\/\d{1,3})?$/i,
		/^(?:[a-f0-9]{1,4}:){2}(?::[a-f0-9]{1,4}){1,5}(?:\/\d{1,3})?$/i,
		/^(?:[a-f0-9]{1,4}:){3}(?::[a-f0-9]{1,4}){1,4}(?:\/\d{1,3})?$/i,
		/^(?:[a-f0-9]{1,4}:){4}(?::[a-f0-9]{1,4}){1,3}(?:\/\d{1,3})?$/i,
		/^(?:[a-f0-9]{1,4}:){5}(?::[a-f0-9]{1,4}){1,2}(?:\/\d{1,3})?$/i,
		/^(?:[a-f0-9]{1,4}:){6}(?::[a-f0-9]{1,4})(?:\/\d{1,3})?$/i,


		//IPv6 mixes with IPv4
		/^(?:[a-f0-9]{1,4}:){6}(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i,
		/^:(?::[a-f0-9]{1,4}){0,4}:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i,
		/^(?:[a-f0-9]{1,4}:){1,5}:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i,
		/^(?:[a-f0-9]{1,4}:)(?::[a-f0-9]{1,4}){1,4}:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i,
		/^(?:[a-f0-9]{1,4}:){2}(?::[a-f0-9]{1,4}){1,3}:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i,	
		/^(?:[a-f0-9]{1,4}:){3}(?::[a-f0-9]{1,4}){1,2}:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i,
		/^(?:[a-f0-9]{1,4}:){4}(?::[a-f0-9]{1,4}):(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i
	];
	var validIPv4Addresses = [
		//IPv4
		/^(\d{1,3}\.){3}\d{1,3}$/i
	];
	var validAddresses = [];
	if (format == 'ipv6' || format == 'ipv6_ipv4') {
		validAddresses = validAddresses.concat(validIPv6Addresses);
	}
	if (format == 'ipv4' || format == 'ipv6_ipv4') {
		validAddresses = validAddresses.concat(validIPv4Addresses);
	}

	var ret = false;
	for (var i=0; i<validAddresses.length; i++) {
		if (validAddresses[i].test(value)) {
			ret = true;
			break;
		}
	}

	if (ret && value.indexOf(".") != -1) {
		//if address contains IPv4 fragment, it must be valid; all 4 groups must be less than 256
		var ipv4 = value.match(/:?(?:\d{1,3}\.){3}\d{1,3}/i);
		if(!ipv4) {
			return false;
		}
		ipv4 = ipv4[0].replace(/^:/, '');
		var pieces = ipv4.split('.');
		if (pieces.length != 4) {
			return false;
		}
		var regExp = /^[\-\+]?\d*$/;
		for (var i=0; i< pieces.length; i++) {
			if (pieces[i] == '') {

				return false;
			}
			var piece = parseInt(pieces[i], 10);
			if (isNaN(piece) || piece > 255 || !regExp.test(pieces[i]) || pieces[i].length>3 || /^0{2,3}$/.test(pieces[i])) {
				return false;
			}
		}
	}
	if (ret && value.indexOf("/") != -1) {
		// if prefix-length is specified must be in [1-128]
		var prefLen = value.match(/\/\d{1,3}$/);
		if (!prefLen) return false;
		var prefLenVal = parseInt(prefLen[0].replace(/^\//,''), 10);
		if (isNaN(prefLenVal) || prefLenVal > 128 || prefLenVal < 1) {
			return false;
		}
	}
	return ret;
};

Spry.Widget.ValidationTextField.onloadDidFire = false;
Spry.Widget.ValidationTextField.loadQueue = [];

Spry.Widget.ValidationTextField.prototype.isBrowserSupported = function()
{
	return Spry.is.ie && Spry.is.v >= 5 && Spry.is.windows
		||
	Spry.is.mozilla && Spry.is.v >= 1.4
		||
	Spry.is.safari
		||
	Spry.is.opera && Spry.is.v >= 9;
};

Spry.Widget.ValidationTextField.prototype.init = function(element, options)
{
	this.element = this.getElement(element);
	this.errors = 0;
	this.flags = {locked: false, restoreSelection: true};
	this.options = {};
	this.event_handlers = [];

	this.validClass = "textfieldValidState";
	this.focusClass = "textfieldFocusState";
	this.requiredClass = "textfieldRequiredState";
	this.hintClass = "textfieldHintState";
	this.invalidFormatClass = "textfieldInvalidFormatState";
	this.invalidRangeMinClass = "textfieldMinValueState";
	this.invalidRangeMaxClass = "textfieldMaxValueState";
	this.invalidCharsMinClass = "textfieldMinCharsState";
	this.invalidCharsMaxClass = "textfieldMaxCharsState";
	this.textfieldFlashTextClass = "textfieldFlashText";
	if (Spry.is.safari) {
		this.flags.lastKeyPressedTimeStamp = 0;
	}

	switch (this.type) {
		case 'phone_number':options.format = Spry.Widget.Utils.firstValid(options.format, 'phone_us');break;
		case 'currency':options.format = Spry.Widget.Utils.firstValid(options.format, 'comma_dot');break;
		case 'zip_code':options.format = Spry.Widget.Utils.firstValid(options.format, 'zip_us5');break;
		case 'date':
			options.format = Spry.Widget.Utils.firstValid(options.format, 'mm/dd/yy');
			break;
		case 'time':
			options.format = Spry.Widget.Utils.firstValid(options.format, 'HH:mm');
			options.pattern = options.format.replace(/[hms]/gi, "0").replace(/TT/gi, 'AM').replace(/T/gi, 'A');
			break;
		case 'ip':
			options.format = Spry.Widget.Utils.firstValid(options.format, 'ipv4');
			options.characterMasking = Spry.Widget.ValidationTextField.ValidationDescriptors[this.type].characterMaskingFormats[options.format]; 
			break;
	}

	//retrieve the validation type descriptor to be used with this instance (base on type and format)
	//widgets may have different validations depending on format (like zip_code with formats)
	var validationDescriptor = {};
	if (options.format && Spry.Widget.ValidationTextField.ValidationDescriptors[this.type].formats) {
		if (Spry.Widget.ValidationTextField.ValidationDescriptors[this.type].formats[options.format]) {
			Spry.Widget.Utils.setOptions(validationDescriptor, Spry.Widget.ValidationTextField.ValidationDescriptors[this.type].formats[options.format]);
		}
	} else {
		Spry.Widget.Utils.setOptions(validationDescriptor, Spry.Widget.ValidationTextField.ValidationDescriptors[this.type]);
	}

	//set default values for some parameters which were not aspecified
	options.useCharacterMasking = Spry.Widget.Utils.firstValid(options.useCharacterMasking, false);
	options.hint = Spry.Widget.Utils.firstValid(options.hint, '');
	options.isRequired = Spry.Widget.Utils.firstValid(options.isRequired, true);
	options.additionalError = Spry.Widget.Utils.firstValid(options.additionalError, false);
	if (options.additionalError)
		options.additionalError = this.getElement(options.additionalError);

	//set widget validation parameters
	//get values from validation type descriptor
	//use the user specified values, if defined
	options.characterMasking = Spry.Widget.Utils.firstValid(options.characterMasking, validationDescriptor.characterMasking);
	options.regExpFilter = Spry.Widget.Utils.firstValid(options.regExpFilter, validationDescriptor.regExpFilter);
	options.pattern = Spry.Widget.Utils.firstValid(options.pattern, validationDescriptor.pattern);
	options.validation = Spry.Widget.Utils.firstValid(options.validation, validationDescriptor.validation);
	if (typeof options.validation == 'string') {
		options.validation = eval(options.validation);
	}

	options.minValue = Spry.Widget.Utils.firstValid(options.minValue, validationDescriptor.minValue);
	options.maxValue = Spry.Widget.Utils.firstValid(options.maxValue, validationDescriptor.maxValue);

	options.minChars = Spry.Widget.Utils.firstValid(options.minChars, validationDescriptor.minChars);
	options.maxChars = Spry.Widget.Utils.firstValid(options.maxChars, validationDescriptor.maxChars);

	Spry.Widget.Utils.setOptions(this, options);
	Spry.Widget.Utils.setOptions(this.options, options);
};

Spry.Widget.ValidationTextField.prototype.destroy = function() {
	for (var i=0; i<this.event_handlers.length; i++) {
		Spry.Widget.Utils.removeEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false);
	}
	try { delete this.element; } catch(err) {}
	try { delete this.input; } catch(err) {}
	try { delete this.form; } catch(err) {}
	try { delete this.event_handlers; } catch(err) {}
	try { this.selection.destroy(); } catch(err) {}
	try { delete this.selection; } catch(err) {}

	var q = Spry.Widget.Form.onSubmitWidgetQueue;
	var qlen = q.length;
	for (var i = 0; i < qlen; i++) {
		if (q[i] == this) {
			q.splice(i, 1);
			break;
		}
	}
};

Spry.Widget.ValidationTextField.prototype.attachBehaviors = function()
{
	if (this.element) {
		if (this.element.nodeName == "INPUT") {
			this.input = this.element;
		} else {
			this.input = Spry.Widget.Utils.getFirstChildWithNodeNameAtAnyLevel(this.element, "INPUT");
		}
	}

	if (this.input) {
		if (this.maxChars) {
			this.input.removeAttribute("maxLength");
		}
		this.putHint();
		this.compilePattern();
		if (this.type == 'date') {
			this.compileDatePattern();
		}
		this.input.setAttribute("AutoComplete", "off");
		this.selection = null; /*new Spry.Widget.SelectionDescriptor(this.input); CRASHES WITH NEW FIREFOX*/
		this.oldValue = this.input.value;

		var self = this;
		this.event_handlers = [];

		this.event_handlers.push([this.input, "keydown", function(e) { if (self.isDisabled()) return true; return self.onKeyDown(e || event); }]);
		this.event_handlers.push([this.input, "keypress", function(e) { if (self.isDisabled()) return true; return self.onKeyPress(e || event); }]);
		if (Spry.is.opera) {
			this.event_handlers.push([this.input, "keyup", function(e) { if (self.isDisabled()) return true; return self.onKeyUp(e || event); }]);
		}

		this.event_handlers.push([this.input, "focus", function(e) { if (self.isDisabled()) return true; return self.onFocus(e || event); }]);
		this.event_handlers.push([this.input, "blur", function(e) { if (self.isDisabled()) return true; return self.onBlur(e || event); }]);

		this.event_handlers.push([this.input, "mousedown", function(e) { if (self.isDisabled()) return true; return self.onMouseDown(e || event); }]);

		var changeEvent = 
			Spry.is.mozilla || Spry.is.opera || Spry.is.safari?"input":
			Spry.is.ie?"propertychange":
			"change";
		this.event_handlers.push([this.input, changeEvent, function(e) { if (self.isDisabled()) return true; return self.onChange(e || event); }]);

		if (Spry.is.mozilla || Spry.is.safari) {
			//oninput event on mozilla does not fire ondragdrop
			this.event_handlers.push([this.input, "dragdrop", function(e) { if (self.isDisabled()) return true; self.removeHint();return self.onChange(e || event); }]);
		} else if (Spry.is.ie){
			//ondrop&onpropertychange crash on IE 
			this.event_handlers.push([this.input, "drop", function(e) { if (self.isDisabled()) return true; return self.onDrop(e || event); }]);
		}

		for (var i=0; i<this.event_handlers.length; i++) {
			Spry.Widget.Utils.addEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false);
		}

		// submit
		this.form = Spry.Widget.Utils.getFirstParentWithNodeName(this.input, "FORM");
		if (this.form) {
			// if no "onSubmit" handler has been attached to the current form, attach one
			if (!this.form.attachedSubmitHandler && !this.form.onsubmit) {
				this.form.onsubmit = function(e) { e = e || event; return Spry.Widget.Form.onSubmit(e, e.srcElement || e.currentTarget) };
				this.form.attachedSubmitHandler = true;                 
			}
			if (!this.form.attachedResetHandler) {
				Spry.Widget.Utils.addEventListener(this.form, "reset", function(e) { e = e || event; return Spry.Widget.Form.onReset(e, e.srcElement || e.currentTarget) }, false);
				this.form.attachedResetHandler = true;                 
			}
			// add the currrent widget to the "onSubmit" check queue;
			Spry.Widget.Form.onSubmitWidgetQueue.push(this);
		}
	}	
};

Spry.Widget.ValidationTextField.prototype.isDisabled = function() {
	return this.input && (this.input.disabled || this.input.readOnly) || !this.input;
};

Spry.Widget.ValidationTextField.prototype.getElement = function(ele)
{
	if (ele && typeof ele == "string")
		return document.getElementById(ele);
	return ele;
};

Spry.Widget.ValidationTextField.addLoadListener = function(handler)
{
	if (typeof window.addEventListener != 'undefined')
		window.addEventListener('load', handler, false);
	else if (typeof document.addEventListener != 'undefined')
		document.addEventListener('load', handler, false);
	else if (typeof window.attachEvent != 'undefined')
		window.attachEvent('onload', handler);
};

Spry.Widget.ValidationTextField.processLoadQueue = function(handler)
{
	Spry.Widget.ValidationTextField.onloadDidFire = true;
	var q = Spry.Widget.ValidationTextField.loadQueue;
	var qlen = q.length;
	for (var i = 0; i < qlen; i++)
		q[i].attachBehaviors();
};

Spry.Widget.ValidationTextField.addLoadListener(Spry.Widget.ValidationTextField.processLoadQueue);
Spry.Widget.ValidationTextField.addLoadListener(function(){
	Spry.Widget.Utils.addEventListener(window, "unload", Spry.Widget.Form.destroyAll, false);
});

Spry.Widget.ValidationTextField.prototype.setValue = function(newValue) {
	this.flags.locked = true;
	this.input.value = newValue;
	this.flags.locked = false;
	this.oldValue = newValue;
	if (!Spry.is.ie) {
		this.onChange();
	}
};

Spry.Widget.ValidationTextField.prototype.saveState = function()
{
	this.oldValue = this.input.value;
	this.selection.update();
};

Spry.Widget.ValidationTextField.prototype.revertState = function(revertValue)
{
	if (revertValue != this.input.value) {
		this.input.readOnly = true;
		this.input.value = revertValue;
		this.input.readOnly = false;
		if (Spry.is.safari && this.flags.active) {
			this.input.focus();
		}
	}
  if (this.flags.restoreSelection) {
	this.selection.moveTo(this.selection.start, this.selection.end);
  }

	this.redTextFlash();
};

Spry.Widget.ValidationTextField.prototype.removeHint = function()
{
	if (this.flags.hintOn) {
		this.input.value = "";
		this.flags.hintOn = false;
		this.removeClassName(this.element, this.hintClass);
		this.removeClassName(this.additionalError, this.hintClass);
	}
};

Spry.Widget.ValidationTextField.prototype.putHint = function()
{
	if(this.hint && this.input && this.input.type == "text" && this.input.value == "") {
		this.flags.hintOn = true;
		this.input.value = this.hint;
		this.addClassName(this.element, this.hintClass);
		this.addClassName(this.additionalError, this.hintClass);
	}
};

Spry.Widget.ValidationTextField.prototype.redTextFlash = function()
{
	var self = this;
	this.addClassName(this.element, this.textfieldFlashTextClass);
	setTimeout(function() {
		self.removeClassName(self.element, self.textfieldFlashTextClass)
	}, 100);
};

Spry.Widget.ValidationTextField.prototype.doValidations = function(testValue, revertValue)
{
	if (this.isDisabled()) return false;

	if (this.flags.locked) {
		return false;
	}

	if (testValue.length == 0 && !this.isRequired) {
		this.errors = 0;
		return false;
	}
	this.flags.locked = true;

	var mustRevert = false;
	var continueValidations = true;
	if (!this.options.isRequired && testValue.length == 0) {
		continueValidations = false;
	}

	var errors = 0;
	var fixedValue = testValue;

	//characterMasking - test if all characters are valid with the characterMasking (keyboard filter)
	if (this.useCharacterMasking && this.characterMasking) {
		for(var i=0; i<testValue.length; i++) {
			if (!this.characterMasking.test(testValue.charAt(i))) {
				errors = errors | Spry.Widget.ValidationTextField.ERROR_FORMAT;
				fixedValue = revertValue;
				mustRevert = true;
				break;
			}
		}
	}

	//regExpFilter - character mask positioning (additional mask to restrict some characters only in some position)
	if (!mustRevert && this.useCharacterMasking && this.regExpFilter) {
		if (!this.regExpFilter.test(fixedValue)) {
			errors = errors | Spry.Widget.ValidationTextField.ERROR_FORMAT;
			mustRevert = true;
		}
	}

	//pattern - testValue matches the pattern so far
	if (!mustRevert && this.pattern) {
		var currentRegExp = this.patternToRegExp(testValue.length);
		if (!currentRegExp.test(testValue)) {
			errors = errors | Spry.Widget.ValidationTextField.ERROR_FORMAT;
			mustRevert = true;
		} else if (this.patternLength != testValue.length) {
			//testValue matches pattern so far, but it's not ok if it does not have the proper length
			//do not revert, but should show the error
			errors = errors | Spry.Widget.ValidationTextField.ERROR_FORMAT;
		}
	}

	if (fixedValue == '') {
		errors = errors | Spry.Widget.ValidationTextField.ERROR_REQUIRED;
	}

	if (!mustRevert && this.pattern && this.useCharacterMasking) {
		var n = this.getAutoComplete(testValue.length);
		if (n) {
			fixedValue += n;
		}
	}

	if(!mustRevert && this.minChars !== null  && continueValidations) {
		if (testValue.length < this.minChars) {
			errors = errors | Spry.Widget.ValidationTextField.ERROR_CHARS_MIN;
			continueValidations = false;
		}
	}

	if(!mustRevert && this.maxChars !== null && continueValidations) {
		if (testValue.length > this.maxChars) {
			errors = errors | Spry.Widget.ValidationTextField.ERROR_CHARS_MAX;
			continueValidations = false;
		}
	}

	//validation - testValue passes widget validation function
	if (!mustRevert && this.validation && continueValidations) {
		var value = this.validation(fixedValue, this.options);
		if (false === value) {
			errors = errors | Spry.Widget.ValidationTextField.ERROR_FORMAT;
			continueValidations = false;
		} else {
			this.typedValue = value;
		}
	}

	if(!mustRevert && this.validation && this.minValue !== null && continueValidations) {
		var minValue = this.validation(this.minValue, this.options);
		if (minValue !== false) {
			if (this.typedValue < minValue) {
				errors = errors | Spry.Widget.ValidationTextField.ERROR_RANGE_MIN;
				continueValidations = false;
			}
		}
	}

	if(!mustRevert && this.validation && this.maxValue !== null && continueValidations) {
		var maxValue = this.validation(this.maxValue, this.options);
		if (maxValue !== false) {
			if( this.typedValue > maxValue) {
				errors = errors | Spry.Widget.ValidationTextField.ERROR_RANGE_MAX;
				continueValidations = false;
			}
		}
	}

	//an invalid value was tested; must make sure it does not get inside the input
	if (this.useCharacterMasking && mustRevert) {
		this.revertState(revertValue);
	}

	this.errors = errors;
	this.fixedValue = fixedValue;

	this.flags.locked = false;

	return mustRevert;
};

Spry.Widget.ValidationTextField.prototype.onChange = function(e)
{
	if (Spry.is.opera && this.flags.operaRevertOnKeyUp) {
		return true;
	}
	if (Spry.is.ie && e && e.propertyName != 'value') {
		return true;
	}

	if (this.flags.drop) {
		//delay this if it's a drop operation
		var self = this;
		setTimeout(function() {
			self.flags.drop = false;
			self.onChange(null);
		}, 0);
		return;
	}

	if (this.flags.hintOn) {
		return true;
	}

	if (this.keyCode == 8 || this.keyCode == 46 ) {
		var mustRevert = this.doValidations(this.input.value, this.input.value);
		this.oldValue = this.input.value;
		if ((mustRevert || this.errors) && this.validateOn & Spry.Widget.ValidationTextField.ONCHANGE) {
			var self = this;
			setTimeout(function() {self.validate();}, 0);
			return true;
		}
	}

	var mustRevert = this.doValidations(this.input.value, this.oldValue);
	if ((!mustRevert || this.errors) && this.validateOn & Spry.Widget.ValidationTextField.ONCHANGE) {
		var self = this;
		setTimeout(function() {self.validate();}, 0);
	}
	return true;
};

Spry.Widget.ValidationTextField.prototype.onKeyUp = function(e) {
	if (this.flags.operaRevertOnKeyUp) {
		this.setValue(this.oldValue);
		Spry.Widget.Utils.stopEvent(e);
		this.selection.moveTo(this.selection.start, this.selection.start);
		this.flags.operaRevertOnKeyUp = false;
		return false;
	}
	if (this.flags.operaPasteOperation) {
		window.clearInterval(this.flags.operaPasteOperation);
		this.flags.operaPasteOperation = null;
	}
};

Spry.Widget.ValidationTextField.prototype.operaPasteMonitor = function() {
	if (this.input.value != this.oldValue) {
		var mustRevert = this.doValidations(this.input.value, this.input.value);
		if (mustRevert) {
			this.setValue(this.oldValue);
			this.selection.moveTo(this.selection.start, this.selection.start);
		} else {
			this.onChange();
		}
	}
};


Spry.Widget.ValidationTextField.prototype.compileDatePattern = function () 
{
	var dateValidationPatternString = "";
	var groupPatterns = [];
	var fullGroupPatterns = [];
	var autocompleteCharacters = [];
	
	
	var formatRegExp = /^([mdy]+)([\.\-\/\\\s]+)([mdy]+)([\.\-\/\\\s]+)([mdy]+)$/i;
	var formatGroups = this.options.format.match(formatRegExp);
	if (formatGroups !== null) {
		for (var i=1; i<formatGroups.length; i++) {
			switch (formatGroups[i].toLowerCase()) {
				case "dd":
					groupPatterns[i-1] = "\\d{1,2}";
					fullGroupPatterns[i-1] = "\\d\\d";
					dateValidationPatternString += "(" + groupPatterns[i-1] + ")";
					autocompleteCharacters[i-1] = null;
					break;
				case "mm":
					groupPatterns[i-1] = "\\d{1,2}";
					fullGroupPatterns[i-1] = "\\d\\d";
					dateValidationPatternString += "(" + groupPatterns[i-1] + ")";
					autocompleteCharacters[i-1] = null;
					break;
				case "yy":
					groupPatterns[i-1] = "\\d{1,2}";
					fullGroupPatterns[i-1] = "\\d\\d";
					dateValidationPatternString += "(\\d\\d)";
					autocompleteCharacters[i-1] = null;
					break;
				case "yyyy":
					groupPatterns[i-1] = "\\d{1,4}";
					fullGroupPatterns[i-1] = "\\d\\d\\d\\d";
					dateValidationPatternString += "(\\d\\d\\d\\d)";
					autocompleteCharacters[i-1] = null;
					break;
				default:
					groupPatterns[i-1] = fullGroupPatterns[i-1] = Spry.Widget.ValidationTextField.regExpFromChars(formatGroups[i]);
					dateValidationPatternString += "["+ groupPatterns[i-1] + "]";
					autocompleteCharacters[i-1] = formatGroups[i];
			}
		}
	}
	this.dateValidationPattern = new RegExp("^" + dateValidationPatternString + "$" , "")
	this.dateAutocompleteCharacters = autocompleteCharacters;
	this.dateGroupPatterns = groupPatterns;
	this.dateFullGroupPatterns = fullGroupPatterns;
	this.lastDateGroup = formatGroups.length-2;
}

Spry.Widget.ValidationTextField.prototype.getRegExpForGroup = function (group) 
{
	var ret = '^';
	for (var j = 0; j <= group; j++) ret += this.dateGroupPatterns[j];
	ret += '$';
	return new RegExp(ret, "");	
}

Spry.Widget.ValidationTextField.prototype.getRegExpForFullGroup = function (group) 
{
	var ret = '^';
	for (var j = 0; j < group; j++) ret += this.dateGroupPatterns[j];
	ret += this.dateFullGroupPatterns[group];
	return new RegExp(ret, "");	
}

Spry.Widget.ValidationTextField.prototype.getDateGroup = function(value, pos) 
{
	if (pos == 0) return 0;
	var test_value = value.substring(0, pos);
	for (var i=0; i <= this.lastDateGroup; i++) 
		if (this.getRegExpForGroup(i).test(test_value)) return i;
	return -1;
};


Spry.Widget.ValidationTextField.prototype.isDateGroupFull = function(value, group) 
{
	return this.getRegExpForFullGroup(group).test(value);
}

Spry.Widget.ValidationTextField.prototype.isValueValid = function(value, pos, group) 
{
	var test_value = value.substring(0, pos);
	return this.getRegExpForGroup(group).test(test_value);
	}


Spry.Widget.ValidationTextField.prototype.isPositionAtEndOfGroup = function (value, pos, group)
{
	var test_value = value.substring(0, pos);
	return this.getRegExpForFullGroup(group).test(test_value);
}

Spry.Widget.ValidationTextField.prototype.nextDateDelimiterExists = function (value, pos, group)
{
	var autocomplete = this.dateAutocompleteCharacters[group+1];
	if (value.length < pos  + autocomplete.length) 
		return false;
	else 
	{
		var test_value = value.substring(pos, pos+autocomplete.length);
		if (test_value == autocomplete) 
			return true;
	}
	return false;
}

Spry.Widget.ValidationTextField.prototype.onKeyPress = function(e)
{
	if (this.flags.skp) {
		this.flags.skp = false;
		Spry.Widget.Utils.stopEvent(e);
		return false;
	}

	if (e.ctrlKey || e.metaKey || !this.useCharacterMasking) {
		return true;
	}
/*
	if (Spry.is.safari) {
		if ( (e.timeStamp - this.flags.lastKeyPressedTimeStamp)<10 ) {
			return true;
		}
		this.flags.lastKeyPressedTimeStamp = e.timeStamp;
	}
*/
	if (Spry.is.opera && this.flags.operaRevertOnKeyUp) {
		Spry.Widget.Utils.stopEvent(e);
		return false;
	}

	if (this.keyCode == 8 || this.keyCode == 46) {
		var mr = this.doValidations(this.input.value, this.input.value);
		if (mr) {
			return true;
		}
	}

	var pressed = Spry.Widget.Utils.getCharacterFromEvent(e);

	if (pressed && this.characterMasking) {
		if (!this.characterMasking.test(pressed)) {
			Spry.Widget.Utils.stopEvent(e);
			this.redTextFlash();
			return false;
		}
	}

	if(pressed && this.pattern) {
		var currentPatternChar = this.patternCharacters[this.selection.start];
		if (/[ax]/i.test(currentPatternChar)) {
			//convert the entered character to the pattern character case
			if (currentPatternChar.toLowerCase() == currentPatternChar) {
				pressed = pressed.toLowerCase();
			} else {
				pressed = pressed.toUpperCase();
			}
		}

		var autocomplete = this.getAutoComplete(this.selection.start);
		if (this.selection.start == this.oldValue.length) {
			if (this.oldValue.length < this.patternLength) {
				if (autocomplete) {
					Spry.Widget.Utils.stopEvent(e);
					var futureValue = this.oldValue.substring(0, this.selection.start) + autocomplete + pressed;
					var mustRevert = this.doValidations(futureValue, this.oldValue);
					if (!mustRevert) {
						this.setValue(this.fixedValue);
						this.selection.moveTo(this.fixedValue.length, this.fixedValue.length);
					} else {
						this.setValue(this.oldValue.substring(0, this.selection.start) + autocomplete);
						this.selection.moveTo(this.selection.start + autocomplete.length, this.selection.start + autocomplete.length);
					}
					return false;
				}
			} else {
				Spry.Widget.Utils.stopEvent(e);
				this.setValue(this.input.value);
				return false;
			}
		} else if (autocomplete) {
			Spry.Widget.Utils.stopEvent(e);
			this.selection.moveTo(this.selection.start + autocomplete.length, this.selection.start + autocomplete.length);
			return false;
		}

		Spry.Widget.Utils.stopEvent(e);

		var futureValue = this.oldValue.substring(0, this.selection.start) + pressed + this.oldValue.substring(this.selection.start + 1);
		var mustRevert = this.doValidations(futureValue, this.oldValue);

		if (!mustRevert) {
			autocomplete = this.getAutoComplete(this.selection.start + 1);
			this.setValue(this.fixedValue);
			this.selection.moveTo(this.selection.start + 1 + autocomplete.length, this.selection.start + 1 + autocomplete.length);
		} else {
			this.selection.moveTo(this.selection.start, this.selection.start);
		}

		return false;
	}
	
	
	if (pressed && this.type == 'date' && this.useCharacterMasking) 
	{
		var group = this.getDateGroup(this.oldValue, this.selection.start);
		if (group != -1) {
			Spry.Widget.Utils.stopEvent(e);
			if ( (group % 2) !=0 ) 
				group ++;
			
			if (this.isDateGroupFull(this.oldValue, group)) 
			{
				if(this.isPositionAtEndOfGroup(this.oldValue, this.selection.start, group))
				{
					if(group == this.lastDateGroup) 
					{
						this.redTextFlash(); return false;
					}
					else 
					{
						// add or jump over autocomplete delimiter
						var autocomplete = this.dateAutocompleteCharacters[group+1];
						
						if (this.nextDateDelimiterExists(this.oldValue, this.selection.start, group))
						{
							var autocomplete = this.dateAutocompleteCharacters[group+1];
							
							this.selection.moveTo(this.selection.start + autocomplete.length, this.selection.start + autocomplete.length);
							if (pressed == autocomplete) 
								return false;
							
							if (this.isDateGroupFull(this.oldValue, group+2)) 
								// need to overwrite first char in the next digit group
								futureValue = this.oldValue.substring(0, this.selection.start) + pressed + this.oldValue.substring(this.selection.start + 1);
							else
								futureValue = this.oldValue.substring(0, this.selection.start) + pressed + this.oldValue.substring(this.selection.start);
								
							if (!this.isValueValid(futureValue, this.selection.start + 1, group +2 )) 
							{
								this.redTextFlash(); return false;						
							}
							else
							{
								this.setValue (futureValue);
								this.selection.moveTo(this.selection.start + 1, this.selection.start + 1);									
							}
							return false;					
						}
						else 
						{
							var autocomplete = this.dateAutocompleteCharacters[group+1];
							
							var insertedValue = autocomplete + pressed;
							futureValue = this.oldValue.substring(0, this.selection.start) + insertedValue + this.oldValue.substring(this.selection.start);
							if (!this.isValueValid(futureValue, this.selection.start + insertedValue.length, group +2 )) 
							{
								// block this type
								insertedValue = autocomplete;
								futureValue = this.oldValue.substring(0, this.selection.start) + insertedValue + this.oldValue.substring(this.selection.start);
								this.setValue (futureValue);
								this.selection.moveTo(this.selection.start + insertedValue.length, this.selection.start + insertedValue.length);									
								this.redTextFlash(); return false;
							}
							else 
							{
								this.setValue (futureValue);
								this.selection.moveTo(this.selection.start + insertedValue.length, this.selection.start + insertedValue.length);									
								return false;
							}
						}
						
					}
				}
				else
				{
					// it's not the end of the full digits group
					
					// overwrite
					var movePosition = 1;
					futureValue = this.oldValue.substring(0, this.selection.start) + pressed + this.oldValue.substring(this.selection.start + 1);
					if (!this.isValueValid(futureValue, this.selection.start + 1, group)) 
					{
						this.redTextFlash(); return false;
					}
					else 
					{
						if(this.isPositionAtEndOfGroup(futureValue, this.selection.start+1, group)) 
						{
							if (group != this.lastDateGroup)
							{
								if (this.nextDateDelimiterExists(futureValue, this.selection.start + 1, group))
								{
									var autocomplete = this.dateAutocompleteCharacters[group+1];
									movePosition = 1 + autocomplete.length;
								}
								else
								{
									var autocomplete = this.dateAutocompleteCharacters[group+1];
									futureValue = this.oldValue.substring(0, this.selection.start) + pressed + autocomplete + this.oldValue.substring(this.selection.start + 1);
									movePosition = 1 + autocomplete.length;
								}
							}
						}
						this.setValue (futureValue);
						this.selection.moveTo(this.selection.start + movePosition, this.selection.start + movePosition);									
						return false;							
					}			
				}
			}
			else
			{
				// date group is not full
				// insert
				futureValue = this.oldValue.substring(0, this.selection.start) + pressed + this.oldValue.substring(this.selection.start);
				var movePosition = 1;
				if (!this.isValueValid(futureValue, this.selection.start + 1, group) && !this.isValueValid(futureValue, this.selection.start + 1, group+1)) 
				{
					this.redTextFlash(); return false;
				}
				else 
				{
					var autocomplete = this.dateAutocompleteCharacters[group+1];
					if (pressed == autocomplete) 
					{
						if (this.nextDateDelimiterExists(this.oldValue, this.selection.start, group))
						{
							futureValue = this.oldValue;
							movePosition = 1;
						}
					}
					else
					{
						if(this.isPositionAtEndOfGroup(futureValue, this.selection.start+1, group)) 
						{
							if (group != this.lastDateGroup)
							{
								if (this.nextDateDelimiterExists(futureValue, this.selection.start + 1, group))
								{
									var autocomplete = this.dateAutocompleteCharacters[group+1];
									movePosition = 1 + autocomplete.length;
								}
								else
								{
									var autocomplete = this.dateAutocompleteCharacters[group+1];
									futureValue = this.oldValue.substring(0, this.selection.start) + pressed + autocomplete + this.oldValue.substring(this.selection.start + 1);
									movePosition = 1 + autocomplete.length;
								}
							}
						}
					}
					this.setValue (futureValue);
					this.selection.moveTo(this.selection.start + movePosition, this.selection.start + movePosition);									
					return false;						
				}	
			}
		}
		return false;
	}
	
};

Spry.Widget.ValidationTextField.prototype.onKeyDown = function(e)
{
	this.saveState();
	this.keyCode = e.keyCode;

	if (Spry.is.opera) {
		if (this.flags.operaPasteOperation) {
			window.clearInterval(this.flags.operaPasteOperation);
			this.flags.operaPasteOperation = null;
		}
		if (e.ctrlKey) {
			var pressed = Spry.Widget.Utils.getCharacterFromEvent(e);
			if (pressed && 'vx'.indexOf(pressed.toLowerCase()) != -1) {
				var self = this;
				this.flags.operaPasteOperation = window.setInterval(function() { self.operaPasteMonitor();}, 1);
				return true;
			}
		}
	}

	if (this.keyCode != 8 && this.keyCode != 46 && Spry.Widget.Utils.isSpecialKey(e)) {
		return true;
	}
	if (this.keyCode == 8 || this.keyCode == 46 ) {
		var mr = this.doValidations(this.input.value, this.input.value);
		if (mr) {
			return true;
		}
	}

	//DELETE
	if (this.useCharacterMasking && this.pattern && this.keyCode == 46) {
		if (e.ctrlKey) {
			//delete from selection until end
			this.setValue(this.input.value.substring(0, this.selection.start));
		} else if (this.selection.end == this.input.value.length || this.selection.start == this.input.value.length-1){
			//allow key if selection is at end (will delete selection)
			return true;
		} else {
			this.flags.operaRevertOnKeyUp = true;
		}
		if (Spry.is.mozilla && Spry.is.mac) {
			this.flags.skp = true;
		}
		Spry.Widget.Utils.stopEvent(e);
		return false;
	}

	//BACKSPACE
	if (this.useCharacterMasking && this.pattern && !e.ctrlKey && this.keyCode == 8) {
		if (this.selection.start == this.input.value.length) {
			//delete with BACKSPACE from the end of the input value only
			var n = this.getAutoComplete(this.selection.start, -1);
			this.setValue(this.input.value.substring(0, this.input.value.length - (Spry.is.opera?0:1) - n.length));
			if (Spry.is.opera) {
				//cant stop the event on Opera, we'll just preserve the selection so delete will act on it
				this.selection.start = this.selection.start - 1 - n.length;
				this.selection.end = this.selection.end - 1 - n.length;
			}
		} else if (this.selection.end == this.input.value.length){
			//allow BACKSPACE if selection is at end (will delete selection)
			return true;
		} else {
			this.flags.operaRevertOnKeyUp = true;
		}
		if (Spry.is.mozilla && Spry.is.mac) {
			this.flags.skp = true;
		} 
		Spry.Widget.Utils.stopEvent(e);
		return false;
	}

	return true;
};

Spry.Widget.ValidationTextField.prototype.onMouseDown = function(e)
{
	if (this.flags.active) {
		//mousedown fires before focus
		//avoid double saveState on first focus by mousedown by checking if the control has focus
		//do nothing if it's not focused because saveState will be called onfocus
		this.saveState();
	}
};

Spry.Widget.ValidationTextField.prototype.onDrop = function(e)
{
	//mark that a drop operation is in progress to avoid race conditions with event handlers for other events
	//especially onchange and onfocus
	this.flags.drop = true;
	this.removeHint();
	this.saveState();
	this.flags.active = true;
	this.addClassName(this.element, this.focusClass);
	this.addClassName(this.additionalError, this.focusClass);
};

Spry.Widget.ValidationTextField.prototype.onFocus = function(e)
{
	if (this.flags.drop) {
		return;
	}
	this.removeHint();

	if (this.pattern && this.useCharacterMasking) {
		var autocomplete = this.getAutoComplete(this.selection.start);
		this.setValue(this.input.value + autocomplete);
		this.selection.moveTo(this.input.value.length, this.input.value.length);
	}
	
	this.saveState();
	this.flags.active = true;
	this.addClassName(this.element, this.focusClass);
	this.addClassName(this.additionalError, this.focusClass);
};
	
Spry.Widget.ValidationTextField.prototype.onBlur = function(e)
{
	this.flags.active = false;
	this.removeClassName(this.element, this.focusClass);
	this.removeClassName(this.additionalError, this.focusClass);
	this.flags.restoreSelection = false;
	var mustRevert = this.doValidations(this.input.value, this.input.value);
	this.flags.restoreSelection = true;

	if (this.validateOn & Spry.Widget.ValidationTextField.ONBLUR) {
		this.validate();
	}
	var self = this;
	setTimeout(function() {self.putHint();}, 10);
	return true;
};

Spry.Widget.ValidationTextField.prototype.compilePattern = function() {
	if (!this.pattern) {
		return;
	}
	var compiled = [];
	var regexps = [];
	var patternCharacters = [];
	var idx = 0;
	var c = '', p = '';
	for (var i=0; i<this.pattern.length; i++) {
		c = this.pattern.charAt(i);
		if (p == '\\') {
			if (/[0ABXY\?]/i.test(c)) {
				regexps[idx - 1] = c;
			} else {
				regexps[idx - 1] = Spry.Widget.ValidationTextField.regExpFromChars(c);
			}
			compiled[idx - 1] = c;
			patternCharacters[idx - 1] = null;
			p = '';
			continue;
		}
		regexps[idx] = Spry.Widget.ValidationTextField.regExpFromChars(c);
		if (/[0ABXY\?]/i.test(c)) {
			compiled[idx] = null;
			patternCharacters[idx] = c;
		} else if (c == '\\') {
			compiled[idx] = c;
			patternCharacters[idx] = '\\';
		} else {
			compiled[idx] = c;
			patternCharacters[idx] = null;
		}
		idx++;
		p = c;
	}

	this.autoCompleteCharacters = compiled;
	this.compiledPattern = regexps;
	this.patternCharacters = patternCharacters;
	this.patternLength = compiled.length;
};

Spry.Widget.ValidationTextField.prototype.getAutoComplete = function(from, direction) {
	if (direction == -1) {
		var n = '', m = '';
		while(from && (n = this.getAutoComplete(--from) )) {
			m = n;
		}
		return m;
	}
	var ret = '', c = '';
	for (var i=from; i<this.autoCompleteCharacters.length; i++) {
		c = this.autoCompleteCharacters[i];
		if (c) {
			ret += c;
		} else {
			break;
		}
	}
	return ret;
};

Spry.Widget.ValidationTextField.regExpFromChars = function (string) {
	//string contains pattern characters
	var ret = '', character = '';
	for (var i = 0; i<string.length; i++) {
		character = string.charAt(i);
		switch (character) {
			case '0': ret += '\\d';break;
			case 'A': ret += '[A-Z]';break;
//			case 'A': ret += '[\u0041-\u005A\u0061-\u007A\u0100-\u017E\u0180-\u0233\u0391-\u03CE\u0410-\u044F\u05D0-\u05EA\u0621-\u063A\u0641-\u064A\u0661-\u06D3\u06F1-\u06FE]';break;
			case 'a': ret += '[a-z]';break;
//			case 'a': ret += '[\u0080-\u00FF]';break;
			case 'B': case 'b': ret += '[a-zA-Z]';break;
			case 'x': ret += '[0-9a-z]';break;
			case 'X': ret += '[0-9A-Z]';break;
			case 'Y': case 'y': ret += '[0-9a-zA-Z]';break;
			case '?': ret += '.';break;
			case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
				ret += character;
				break;
			case 'c': case 'C': case 'e': case 'E': case 'f': case 'F':case 'r':case 'd': case 'D':case 'n':case 's':case 'S':case 'w':case 'W':case 't':case 'v':
				ret += character;
				break;
			default: ret += '\\' + character;
		}
	}
	return ret;
};

Spry.Widget.ValidationTextField.prototype.patternToRegExp = function(len) {
	var ret = '^';
	var end = Math.min(this.compiledPattern.length, len);
	for (var i=0; i < end; i++) {
		ret += this.compiledPattern[i];
	}
	ret += '$';
	ret = new RegExp(ret, "");
	return ret;
};

Spry.Widget.ValidationTextField.prototype.resetClasses = function() {
	var classes = [this.requiredClass, this.invalidFormatClass, this.invalidRangeMinClass, this.invalidRangeMaxClass, this.invalidCharsMinClass, this.invalidCharsMaxClass, this.validClass]
	for (var i=0; i < classes.length; i++)
	{
		this.removeClassName(this.element, classes[i]);
		this.removeClassName(this.additionalError, classes[i]);
	}
};

Spry.Widget.ValidationTextField.prototype.reset = function() {
	this.removeHint();
	this.oldValue = this.input.defaultValue;
	
	this.resetClasses();
	if (Spry.is.ie) {
		//this will fire the onpropertychange event right after the className changed on the container element
		//IE6 will not fire the first onpropertychange on an input type text after a onreset handler if inside that handler the className of one of the elements inside the form has been changed
		//to reproduce: change the className of one of the elements inside the form from within the onreset handler; then the onpropertychange does not fire the first time
		this.input.forceFireFirstOnPropertyChange = true;
		this.input.removeAttribute("forceFireFirstOnPropertyChange");
	}
	var self = this;
	setTimeout(function() {self.putHint();}, 10);
};

Spry.Widget.ValidationTextField.prototype.validate = function() {

	this.resetClasses();
	//possible states: required, format, rangeMin, rangeMax, charsMin, charsMax
	if (this.validateOn & Spry.Widget.ValidationTextField.ONSUBMIT) {

		this.removeHint();
		this.doValidations(this.input.value, this.input.value);/*MARCA!*/

		if(!this.flags.active) {
			var self = this;
			setTimeout(function() {self.putHint();}, 10);
		}
	}

	if (this.isRequired && this.errors & Spry.Widget.ValidationTextField.ERROR_REQUIRED) {
		this.addClassName(this.element, this.requiredClass);
		this.addClassName(this.additionalError, this.requiredClass);
		return false;
	}

	if (this.errors & Spry.Widget.ValidationTextField.ERROR_FORMAT) {
		this.addClassName(this.element, this.invalidFormatClass);
		this.addClassName(this.additionalError, this.invalidFormatClass);
		return false;
	}

	if (this.errors & Spry.Widget.ValidationTextField.ERROR_RANGE_MIN) {
		this.addClassName(this.element, this.invalidRangeMinClass);
		this.addClassName(this.additionalError, this.invalidRangeMinClass);
		return false;
	}

	if (this.errors & Spry.Widget.ValidationTextField.ERROR_RANGE_MAX) {
		this.addClassName(this.element, this.invalidRangeMaxClass);
		this.addClassName(this.additionalError, this.invalidRangeMaxClass);
		return false;
	}

	if (this.errors & Spry.Widget.ValidationTextField.ERROR_CHARS_MIN) {
		this.addClassName(this.element, this.invalidCharsMinClass);
		this.addClassName(this.additionalError, this.invalidCharsMinClass);
		return false;
	}

	if (this.errors & Spry.Widget.ValidationTextField.ERROR_CHARS_MAX) {
		this.addClassName(this.element, this.invalidCharsMaxClass);
		this.addClassName(this.additionalError, this.invalidCharsMaxClass);
		return false;
	}

	this.addClassName(this.element, this.validClass);
	this.addClassName(this.additionalError, this.validClass);
	return true;
}

Spry.Widget.ValidationTextField.prototype.addClassName = function(ele, className)
{
	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
		return;
	ele.className += (ele.className ? " " : "") + className;
};

Spry.Widget.ValidationTextField.prototype.removeClassName = function(ele, className)
{
	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1))
		return;
	ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
};

Spry.Widget.SelectionDescriptor = function (element)
{
	this.element = element;
	this.update();
};

Spry.Widget.SelectionDescriptor.prototype.update = function()
{
	if (Spry.is.ie && Spry.is.windows) {
		if (this.element.nodeName == "TEXTAREA") {
            var sel = this.element.ownerDocument.selection;
            if (sel.type != 'None') {
		var range = this.element.ownerDocument.selection.createRange();
		if (range.parentElement() == this.element){
			var range_all = this.element.ownerDocument.body.createTextRange();
			range_all.moveToElementText(this.element);
			for (var sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start ++){
			 	range_all.moveStart('character', 1);
			}
			this.start = sel_start;
			// create a selection of the whole this.element
			range_all = this.element.ownerDocument.body.createTextRange();
			range_all.moveToElementText(this.element);
			for (var sel_end = 0; range_all.compareEndPoints('StartToEnd', range) < 0; sel_end++){
				range_all.moveStart('character', 1);
			}
			this.end = sel_end;
			this.length = this.end - this.start;
			// get selected and surrounding text
			this.text = range.text;
		 }
            }        
		} else if (this.element.nodeName == "INPUT"){
            var sel = this.element.ownerDocument.selection;
			this.range = this.element.ownerDocument.selection.createRange();
			this.length = this.range.text.length;
			var clone = this.range.duplicate();
			this.start = -clone.moveStart("character", -10000);
			clone = this.range.duplicate();
			clone.collapse(false);
			this.end = -clone.moveStart("character", -10000);
			this.text = this.range.text;
		}
	} else {
		var tmp = this.element;
		var selectionStart = 0;
		var selectionEnd = 0;
        
		try { selectionStart = tmp.selectionStart;} catch(err) {}
		try { selectionEnd = tmp.selectionEnd;} catch(err) {}

		if (Spry.is.safari) {
			if (selectionStart == 2147483647) {
				selectionStart = 0;
			}
			if (selectionEnd == 2147483647) {
				selectionEnd = 0;
			}
		}
		this.start = selectionStart;
		this.end = selectionEnd;
		this.length = selectionEnd - selectionStart;
		this.text = this.element.value.substring(selectionStart, selectionEnd);
	}
};

Spry.Widget.SelectionDescriptor.prototype.destroy = function() {
	try { delete this.range} catch(err) {}
	try { delete this.element} catch(err) {}
};

Spry.Widget.SelectionDescriptor.prototype.move = function(amount)
{
	if (Spry.is.ie && Spry.is.windows) {
		this.range.move("character", amount);
		this.range.select();
	} else {
		try { this.element.selectionStart++;}catch(err) {}
	}
	this.update();
};

Spry.Widget.SelectionDescriptor.prototype.moveTo = function(start, end)
{
	if (Spry.is.ie && Spry.is.windows) {
		if (this.element.nodeName == "TEXTAREA") {
			var ta_range = this.element.createTextRange();
			this.range = this.element.createTextRange();
			this.range.move("character", start);
			this.range.moveEnd("character", end - start);
			
			var c1 = this.range.compareEndPoints("StartToStart", ta_range);
			if (c1 < 0) {
				this.range.setEndPoint("StartToStart", ta_range);
			}

			var c2 = this.range.compareEndPoints("EndToEnd", ta_range);
			if (c2 > 0) {
				this.range.setEndPoint("EndToEnd", ta_range);
			}
		} else if (this.element.nodeName == "INPUT"){
			this.range = this.element.ownerDocument.selection.createRange();
			this.range.move("character", -10000);
			this.start = this.range.moveStart("character", start);
			this.end = this.start + this.range.moveEnd("character", end - start);
		}
		this.range.select();
	} else {
		this.start = start;
		try { this.element.selectionStart = start;} catch(err) {}
		this.end = end;
		try { this.element.selectionEnd = end;} catch(err) {}
	}
	this.ignore = true;
	this.update();
};

Spry.Widget.SelectionDescriptor.prototype.moveEnd = function(amount)
{
	if (Spry.is.ie && Spry.is.windows) {
		this.range.moveEnd("character", amount);
		this.range.select();
	} else {
		try { this.element.selectionEnd++;} catch(err) {}
	}
	this.update();
};

Spry.Widget.SelectionDescriptor.prototype.collapse = function(begin)
{
	if (Spry.is.ie && Spry.is.windows) {
		this.range = this.element.ownerDocument.selection.createRange();
		this.range.collapse(begin);
		this.range.select();
	} else {
		if (begin) {
			try { this.element.selectionEnd = this.element.selectionStart;} catch(err) {}
		} else {
			try { this.element.selectionStart = this.element.selectionEnd;} catch(err) {}
		}
	}

	this.update();
};

if (!Spry.Widget.Form.validate) {
	Spry.Widget.Form.validate = function(vform) {
		
		
		$(vform).getElements('a').each( function(el){el.style.color=''} );
		$(vform).getElements('div').each( function(el){el.style.color=''} );
		
		var isValid = true;
		var isElementValid = true;
		var q = Spry.Widget.Form.onSubmitWidgetQueue;
		var qlen = q.length;
		for (var i = 0; i < qlen; i++) {
			if (!q[i].isDisabled() && q[i].form == vform) {
				isElementValid = q[i].validate();
				//if(!isElementValid) highlightTabs(q[i].element); //WARNING
				isValid = isElementValid && isValid;
			}
		}
		return isValid;
	}
};

if (!Spry.Widget.Form.onSubmit) {
	Spry.Widget.Form.onSubmit = function(e, form)
	{
		/*if (Spry.Widget.Form.validate(form) == false) {
			return false;
		}*/
		return false;/*return true; ajax request*/
	};
};

if (!Spry.Widget.Form.onReset) {
	Spry.Widget.Form.onReset = function(e, vform)
	{
		var q = Spry.Widget.Form.onSubmitWidgetQueue;
		var qlen = q.length;
		for (var i = 0; i < qlen; i++) {
			if (!q[i].isDisabled() && q[i].form == vform && typeof(q[i].reset) == 'function') {
				q[i].reset();
			}
		}
		return true;
	};
};

if (!Spry.Widget.Form.destroy) {
	Spry.Widget.Form.destroy = function(form)
	{
		var q = Spry.Widget.Form.onSubmitWidgetQueue;
		for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) {
			if (q[i].form.id == form.id && typeof(q[i].destroy) == 'function') {
				q[i].destroy();
				i--;
			}
		}
	}
};

if (!Spry.Widget.Form.destroyAll) {
	Spry.Widget.Form.destroyAll = function()
	{
		var q = Spry.Widget.Form.onSubmitWidgetQueue;
		for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) {
			if (typeof(q[i].destroy) == 'function') {
				q[i].destroy();
				i--;
			}
		}
	}
};

Spry.Widget.Utils.punycode_constants = {
	base : 36, tmin : 1, tmax : 26, skew : 38, damp : 700,
  initial_bias : 72, initial_n : 0x80, delimiter : 0x2D,
  maxint : 2<<26-1
};

Spry.Widget.Utils.punycode_encode_digit = function (d) {
  return String.fromCharCode(d + 22 + 75 * (d < 26));
};

Spry.Widget.Utils.punycode_adapt = function (delta, numpoints, firsttime) {
	delta = firsttime ? delta / this.punycode_constants.damp : delta >> 1;
	delta += delta / numpoints;
	
	for (var k = 0; delta > ((this.punycode_constants.base - this.punycode_constants.tmin) * this.punycode_constants.tmax) / 2; k += this.punycode_constants.base) {
		delta /= this.punycode_constants.base - this.punycode_constants.tmin;
	}
	return k + (this.punycode_constants.base - this.punycode_constants.tmin + 1) * delta / (delta + this.punycode_constants.skew);
};

Spry.Widget.Utils.punycode_encode = function (input, max_out) {
	var inputc = input.split("");
	input = [];
	for(var i=0; i<inputc.length; i++) {
		input.push(inputc[i].charCodeAt(0));
	}
	var output = '';

  var h, b, j, m, q, k, t;
	var input_len = input.length;
  var n = this.punycode_constants.initial_n;
  var delta = 0;
  var bias = this.punycode_constants.initial_bias;
  var out = 0;

  for (j = 0; j < input_len; j++) {
		if (input[j] < 128) {
			if (max_out - out < 2) {
				return false;
			}
			output += String.fromCharCode(input[j]);
			out++;
		}
	}

	h = b = out;
	if (b > 0) {
		output += String.fromCharCode(this.punycode_constants.delimiter);
		out++;
	}

  while (h < input_len)	{
		for (m = this.punycode_constants.maxint, j = 0; j < input_len; j++) {
			if (input[j] >= n && input[j] < m) {
				m = input[j];
			}
		}
		if (m - n > (this.punycode_constants.maxint - delta) / (h + 1)) {
			return false;
		}
		
		delta += (m - n) * (h + 1);
		n = m;

		for (j = 0; j < input_len; j++) {
			if (input[j] < n ) {
				if (++delta == 0) {
					return false;
				}
			}

			if (input[j] == n) {
				for (q = delta, k = this.punycode_constants.base;; k += this.punycode_constants.base) {
					if (out >= max_out) {
						return false;
					}

					t = k <= bias ? this.punycode_constants.tmin : k >= bias + this.punycode_constants.tmax ? this.punycode_constants.tmax : k - bias;
					if (q < t) {
						break;
					}

					output += this.punycode_encode_digit(t + (q - t) % (this.punycode_constants.base - t));
					out++;
					q = (q - t) / (this.punycode_constants.base - t);
				}

				output += this.punycode_encode_digit(q);
				out++;
				bias = this.punycode_adapt(delta, h + 1, h == b);
				delta = 0;
				h++;
			}
		}
		delta++, n++;
	}

  return output;
};

Spry.Widget.Utils.firstValid = function() {
	var ret = null;
	for(var i=0; i<Spry.Widget.Utils.firstValid.arguments.length; i++) {
		if (typeof(Spry.Widget.Utils.firstValid.arguments[i]) != 'undefined') {
			ret = Spry.Widget.Utils.firstValid.arguments[i];
			break;
		}
	}
	return ret;
};

Spry.Widget.Utils.specialCharacters = ",8,9,16,17,18,20,27,33,34,35,36,37,38,40,45,144,192,63232,";
Spry.Widget.Utils.specialSafariNavKeys = "63232,63233,63234,63235,63272,63273,63275,63276,63277,63289,";
Spry.Widget.Utils.specialNotSafariCharacters = "39,46,91,92,93,";

Spry.Widget.Utils.specialCharacters += Spry.Widget.Utils.specialSafariNavKeys;

if (!Spry.is.safari) {
	Spry.Widget.Utils.specialCharacters += Spry.Widget.Utils.specialNotSafariCharacters;
}

Spry.Widget.Utils.isSpecialKey = function (ev) {
	return Spry.Widget.Utils.specialCharacters.indexOf("," + ev.keyCode + ",") != -1;
};

Spry.Widget.Utils.getCharacterFromEvent = function(e){
	var keyDown = e.type == "keydown";

	var code = null;
	var character = null;
	if(Spry.is.mozilla && !keyDown){
		if(e.charCode){
			character = String.fromCharCode(e.charCode);
		} else {
			code = e.keyCode;
		}
	} else {
		code = e.keyCode || e.which;
		if (code != 13) {
			character = String.fromCharCode(code);
		}
	}

	if (Spry.is.safari) {
		if (keyDown) {
			code = e.keyCode || e.which;
			character = String.fromCharCode(code);
		} else {
			code = e.keyCode || e.which;
			if (Spry.Widget.Utils.specialCharacters.indexOf("," + code + ",") != -1) {
				character = null;
			} else {
				character = String.fromCharCode(code);
			}
		}
	}

	if(Spry.is.opera) {
		if (Spry.Widget.Utils.specialCharacters.indexOf("," + code + ",") != -1) {
			character = null;
		} else {
			character = String.fromCharCode(code);
		}
	}

	return character;
};

Spry.Widget.Utils.getFirstChildWithNodeNameAtAnyLevel = function(node, nodeName)
{
	var elements  = node.getElementsByTagName(nodeName);
	if (elements) {
		return elements[0];
	}
	return null;
};


if(typeof MooTools == 'undefined'){
    // Note: requires MooTools 1.2 Core
    throw 'Unable to load Shadowbox, MooTools library not found';
}

// create the Shadowbox object first
var Shadowbox = {};

var alphaRe;

Shadowbox.lib = function(){

    alphaRe = /alpha\([^\)]*\)/gi;

		var setOpacity = function(el, opacity){
        var s = el.style;
        if(window.ActiveXObject){ // IE
            s.zoom = 1;
            s.filter = (s.filter || '').replace(alphaRe, '') +
                       (opacity == 1 ? '' : ' alpha(opacity=' + opacity * 100 + ')');
        }else{
            s.opacity = opacity;
        }
    };

    return {

        adapter: 'mootools',

        getStyle: function(el, style){
            return $(el).getStyle(style);
        },

        setStyle: function(el, style, value){
            el = $(el);
            if(typeof style != 'object'){
                var o = {};
                o[style] = value;
                style = o;
            }
            for(var s in style){
                if(s == 'opacity'){
                    setOpacity(el, style[s]);
                }else{
                    el.setStyle(s, style[s]);
                }
            }
        },

        get: function(el){
            return $(el);
        },

        remove: function(el){
            el.parentNode.removeChild(el);
        },

        getTarget: function(e){
            return e.target;
        },

        getPageXY: function(e){
            return [e.page.x, e.page.y];
        },

        preventDefault: function(e){
            e.preventDefault();
        },

        keyCode: function(e){
            return e.code;
        },

        addEvent: function(el, name, handler){
            $(el).addEvent(name, handler);
        },

        removeEvent: function(el, name, handler){
            $(el).removeEvent(name, handler);
        },

        append: function(el, html){
            if(el.insertAdjacentHTML){
                el.insertAdjacentHTML('BeforeEnd', html);
            }else if(el.lastChild){
                var range = el.ownerDocument.createRange();
                range.setStartAfter(el.lastChild);
                var frag = range.createContextualFragment(html);
                el.appendChild(frag);
            }else{
                el.innerHTML = html;
            }
        }

    };

}();

Spry.Widget.ValidationSelect = function(element, opts)
{
	this.init(element);
	Spry.Widget.Utils.setOptions(this, opts);

	var validateOn = ['submit'].concat(this.validateOn || []);
	validateOn = validateOn.join(",");
	this.validateOn = 0 | (validateOn.indexOf('submit') != -1 ? Spry.Widget.ValidationSelect.ONSUBMIT : 0);
	this.validateOn = this.validateOn | (validateOn.indexOf('blur') != -1 ? Spry.Widget.ValidationSelect.ONBLUR : 0);
	this.validateOn = this.validateOn | (validateOn.indexOf('change') != -1 ? Spry.Widget.ValidationSelect.ONCHANGE : 0);

	if (Spry.Widget.ValidationSelect.onloadDidFire)
		this.attachBehaviors();
	else 
		Spry.Widget.ValidationSelect.loadQueue.push(this);
};

Spry.Widget.ValidationSelect.ONCHANGE = 1;
Spry.Widget.ValidationSelect.ONBLUR = 2;
Spry.Widget.ValidationSelect.ONSUBMIT = 4;

Spry.Widget.ValidationSelect.prototype.init = function(element)
{
	this.element = this.getElement(element);
	this.selectElement = null;
	this.form = null;
	this.event_handlers = [];
	
	this.requiredClass = "selectRequiredState";
	this.invalidClass = "selectInvalidState";
	this.focusClass = "selectFocusState";
	this.validClass = "selectValidState";
	
	this.emptyValue = "";
	this.invalidValue = null;
	this.isRequired = true;
	
	this.validateOn = ["submit"];  // change, blur, submit
	this.validatedByOnChangeEvent = false;
};

Spry.Widget.ValidationSelect.prototype.destroy = function() {
	for (var i=0; i<this.event_handlers.length; i++) {
		Spry.Widget.Utils.removeEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false);
	}
	try { delete this.element; } catch(err) {}
	try { delete this.selectElement; } catch(err) {}

	try { delete this.form; } catch(err) {}
	try { delete this.event_handlers; } catch(err) {}

	var q = Spry.Widget.Form.onSubmitWidgetQueue;
	var qlen = q.length;
	for (var i = 0; i < qlen; i++) {
		if (q[i] == this) {
			q.splice(i, 1);
			break;
		}
	}
};

Spry.Widget.ValidationSelect.onloadDidFire = false;
Spry.Widget.ValidationSelect.loadQueue = [];

Spry.Widget.ValidationSelect.prototype.getElement = function(ele)
{
	if (ele && typeof ele == "string")
		return document.getElementById(ele);
	return ele;
};

Spry.Widget.ValidationSelect.processLoadQueue = function(handler)
{
	Spry.Widget.ValidationSelect.onloadDidFire = true;
	var q = Spry.Widget.ValidationSelect.loadQueue;
	var qlen = q.length;
	for (var i = 0; i < qlen; i++)
		q[i].attachBehaviors();
};

Spry.Widget.ValidationSelect.addLoadListener = function(handler)
{
	if (typeof window.addEventListener != 'undefined')
		window.addEventListener('load', handler, false);
	else if (typeof document.addEventListener != 'undefined')
		document.addEventListener('load', handler, false);
	else if (typeof window.attachEvent != 'undefined')
		window.attachEvent('onload', handler);
};

Spry.Widget.ValidationSelect.addLoadListener(Spry.Widget.ValidationSelect.processLoadQueue);
Spry.Widget.ValidationSelect.addLoadListener(function(){
	Spry.Widget.Utils.addEventListener(window, "unload", Spry.Widget.Form.destroyAll, false);
});

Spry.Widget.ValidationSelect.prototype.attachBehaviors = function()
{
	if (this.element.nodeName == "SELECT") {
		this.selectElement = this.element;
	} else {
		this.selectElement = Spry.Widget.Utils.getFirstChildWithNodeNameAtAnyLevel(this.element, "SELECT");
	}

	if (this.selectElement) {
		var self = this;
		this.event_handlers = [];

		var focusEventName = "focus";
		if (navigator.userAgent.toLowerCase().indexOf("msie 7.") != -1) {
			focusEventName = "beforeactivate";
		}
		this.event_handlers.push([this.selectElement, focusEventName, function(e) { if (self.isDisabled()) return true; return self.onFocus(e); }]);
		// blur
		this.event_handlers.push([this.selectElement, "blur", function(e) { if (self.isDisabled()) return true; return self.onBlur(e); }]);
		// change
		if (this.validateOn & Spry.Widget.ValidationSelect.ONCHANGE) {
			this.event_handlers.push([this.selectElement, "change", function(e) { if (self.isDisabled()) return true; return self.onChange(e); }]);
			this.event_handlers.push([this.selectElement, "keypress", function(e) { if (self.isDisabled()) return true; return self.onChange(e); }]);
		}

		for (var i=0; i<this.event_handlers.length; i++) {
			Spry.Widget.Utils.addEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false);
		}

		// submit
		this.form = Spry.Widget.Utils.getFirstParentWithNodeName(this.selectElement, "FORM");
		if (this.form) {
			// if no "onSubmit" handler has been attached to the current form, attach one
			if (!this.form.attachedSubmitHandler && !this.form.onsubmit) {
				this.form.onsubmit = function(e) { e = e || event; return Spry.Widget.Form.onSubmit(e, e.srcElement || e.currentTarget) };
				this.form.attachedSubmitHandler = true;                 
			}
			if (!this.form.attachedResetHandler) {
				Spry.Widget.Utils.addEventListener(this.form, "reset", function(e) { e = e || event; return Spry.Widget.Form.onReset(e, e.srcElement || e.currentTarget) }, false);
				this.form.attachedResetHandler = true;                 
			}
			// add the currrent widget to the "onSubmit" check queue;
			Spry.Widget.Form.onSubmitWidgetQueue.push(this);
		}
	}
};

Spry.Widget.ValidationSelect.prototype.addClassName = function(ele, className)
{
	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
		return;
	ele.className += (ele.className ? " " : "") + className;
};

Spry.Widget.ValidationSelect.prototype.removeClassName = function(ele, className)
{
	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1))
		return;
	ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
};

Spry.Widget.ValidationSelect.prototype.onFocus = function(e)
{
	this.hasFocus = true;
	this.validatedByOnChangeEvent = false;
	this.addClassName(this.element, this.focusClass);
};

Spry.Widget.ValidationSelect.prototype.onBlur = function(e)
{
	this.hasFocus = false;
	var doValidation = false;
	if (this.validateOn & Spry.Widget.ValidationSelect.ONBLUR)
		doValidation = true;
	if (doValidation && !this.validatedByOnChangeEvent)
		this.validate();
	this.removeClassName(this.element, this.focusClass);
};

Spry.Widget.ValidationSelect.prototype.onChange = function(e)
{
	this.hasFocus = false;
	this.validate();
	this.validatedByOnChangeEvent = true;
};

Spry.Widget.ValidationSelect.prototype.reset = function() {
	this.removeClassName(this.element, this.requiredClass);
	this.removeClassName(this.element, this.invalidClass);
	this.removeClassName(this.element, this.validClass);
};

Spry.Widget.ValidationSelect.prototype.validate = function() {
	this.removeClassName(this.element, this.requiredClass);
	this.removeClassName(this.element, this.invalidClass);
	this.removeClassName(this.element, this.validClass);
	// check isRequired
	if (this.isRequired) {
		// there are no options, or no option has been selected
		if (this.selectElement.options.length == 0 || this.selectElement.selectedIndex == -1) {
			this.addClassName(this.element, this.requiredClass);
			return false;
		}

		if (this.selectElement.options[this.selectElement.selectedIndex].getAttribute("value") == null || this.selectElement.options[this.selectElement.selectedIndex].getAttribute("value") == -1) {
			this.addClassName(this.element, this.requiredClass);
			return false;
		}
		// the current selected option has blank string ("") value
		if (this.selectElement.options[this.selectElement.selectedIndex].value == this.emptyValue) {
			this.addClassName(this.element, this.requiredClass);
			return false;
		}
		// the current selected option has "disabled" attribute
		if (this.selectElement.options[this.selectElement.selectedIndex].disabled) {
			this.addClassName(this.element, this.requiredClass);
			return false;
		}
	}
	if (this.invalidValue) {
		if (this.selectElement.options.length > 0 && 
			this.selectElement.selectedIndex != -1 &&
			this.selectElement.options[this.selectElement.selectedIndex].value == this.invalidValue) {
			this.addClassName(this.element, this.invalidClass);
			return false;
		}
	}
	this.addClassName(this.element, this.validClass);
	return true;
}

Spry.Widget.ValidationSelect.prototype.isDisabled = function() {
	return this.selectElement.disabled;	
}

if(typeof MooTools=="undefined"){throw"Unable to load Shadowbox, MooTools library not found"}var Shadowbox={};Shadowbox.lib=function(){var A=function(D,B){var C=D.style;if(window.ActiveXObject){C.zoom=1;C.filter=(C.filter||"").replace(alphaRe,"")+(B==1?"":" alpha(opacity="+B*100+")")}else{C.opacity=B}};return{adapter:"mootools",getStyle:function(C,B){return $(C).getStyle(B)},setStyle:function(D,C,E){D=$(D);if(typeof C!="object"){var F={};F[C]=E;C=F}for(var B in C){if(B=="opacity"){A(D,C[B])}else{D.setStyle(B,C[B])}}},get:function(B){return $(B)},remove:function(B){B.parentNode.removeChild(B)},getTarget:function(B){return B.target},getPageXY:function(B){return[B.page.x,B.page.y]},preventDefault:function(B){B.preventDefault()},keyCode:function(B){return B.code},addEvent:function(D,B,C){$(D).addEvent(B,C)},removeEvent:function(D,B,C){$(D).removeEvent(B,C)},append:function(D,C){if(D.insertAdjacentHTML){D.insertAdjacentHTML("BeforeEnd",C)}else{if(D.lastChild){var B=D.ownerDocument.createRange();B.setStartAfter(D.lastChild);var E=B.createContextualFragment(C);D.appendChild(E)}else{D.innerHTML=C}}}}}();
if(typeof Shadowbox=="undefined"){throw"Unable to load Shadowbox, no base library adapter found"}(function(){var version="2.0";var options={animate:true,animateFade:true,animSequence:"wh",flvPlayer:"flvplayer.swf",modal:false,overlayColor:"#000",overlayOpacity:0.8,flashBgColor:"#000000",autoplayMovies:true,showMovieControls:true,slideshowDelay:0,resizeDuration:0.55,fadeDuration:0.35,displayNav:true,continuous:false,displayCounter:true,counterType:"default",counterLimit:10,viewportPadding:20,handleOversize:"resize",handleException:null,handleUnsupported:"link",initialHeight:160,initialWidth:320,enableKeys:true,onOpen:null,onFinish:null,onChange:null,onClose:null,skipSetup:false,errors:{fla:{name:"Flash",url:"http://www.adobe.com/products/flashplayer/"},qt:{name:"QuickTime",url:"http://www.apple.com/quicktime/download/"},wmp:{name:"Windows Media Player",url:"http://www.microsoft.com/windows/windowsmedia/"},f4m:{name:"Flip4Mac",url:"http://www.flip4mac.com/wmv_download.htm"}},ext:{img:["png","jpg","jpeg","gif","bmp"],swf:["swf"],flv:["flv"],qt:["dv","mov","moov","movie","mp4"],wmp:["asf","wm","wmv"],qtwmp:["avi","mpg","mpeg"],ajax:["asp","aspx","cgi","cfm","htm","html","pl","php","php3","php4","php5","phtml","rb","rhtml","shtml","txt","vbs"]}};var SB=Shadowbox;var SL=SB.lib;var default_options;var RE={domain:/:\/\/(.*?)[:\/]/,inline:/#(.+)$/,rel:/^(light|shadow)box/i,gallery:/^(light|shadow)box\[(.*?)\]/i,unsupported:/^unsupported-(\w+)/,param:/\s*([a-z_]*?)\s*=\s*(.+)\s*/,empty:/^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i};var cache=[];var gallery;var current;var content;var content_id="shadowbox_content";var dims;var initialized=false;var activated=false;var slide_timer;var slide_start;var slide_delay=0;var ua=navigator.userAgent.toLowerCase();var client={isStrict:document.compatMode=="CSS1Compat",isOpera:ua.indexOf("opera")>-1,isIE:ua.indexOf("msie")>-1,isIE7:ua.indexOf("msie 7")>-1,isSafari:/webkit|khtml/.test(ua),isWindows:ua.indexOf("windows")!=-1||ua.indexOf("win32")!=-1,isMac:ua.indexOf("macintosh")!=-1||ua.indexOf("mac os x")!=-1,isLinux:ua.indexOf("linux")!=-1};client.isBorderBox=client.isIE&&!client.isStrict;client.isSafari3=client.isSafari&&!!(document.evaluate);client.isGecko=ua.indexOf("gecko")!=-1&&!client.isSafari;var ltIE7=client.isIE&&!client.isIE7;var plugins;if(navigator.plugins&&navigator.plugins.length){var detectPlugin=function(plugin_name){var detected=false;for(var i=0,len=navigator.plugins.length;i<len;++i){if(navigator.plugins[i].name.indexOf(plugin_name)>-1){detected=true;break}}return detected};var f4m=detectPlugin("Flip4Mac");plugins={fla:detectPlugin("Shockwave Flash"),qt:detectPlugin("QuickTime"),wmp:!f4m&&detectPlugin("Windows Media"),f4m:f4m}}else{var detectPlugin=function(plugin_name){var detected=false;try{var axo=new ActiveXObject(plugin_name);if(axo){detected=true}}catch(e){}return detected};plugins={fla:detectPlugin("ShockwaveFlash.ShockwaveFlash"),qt:detectPlugin("QuickTime.QuickTime"),wmp:detectPlugin("wmplayer.ocx"),f4m:false}}var apply=function(o,e){for(var p in e){o[p]=e[p]}return o};var isLink=function(el){return el&&typeof el.tagName=="string"&&(el.tagName.toUpperCase()=="A"||el.tagName.toUpperCase()=="AREA")};SL.getViewportHeight=function(){var h=window.innerHeight;var mode=document.compatMode;if((mode||client.isIE)&&!client.isOpera){h=client.isStrict?document.documentElement.clientHeight:document.body.clientHeight}return h};SL.getViewportWidth=function(){var w=window.innerWidth;var mode=document.compatMode;if(mode||client.isIE){w=client.isStrict?document.documentElement.clientWidth:document.body.clientWidth}return w};SL.createHTML=function(obj){var html="<"+obj.tag;for(var attr in obj){if(attr=="tag"||attr=="html"||attr=="children"){continue}if(attr=="cls"){html+=' class="'+obj.cls+'"'}else{html+=" "+attr+'="'+obj[attr]+'"'}}if(RE.empty.test(obj.tag)){html+="/>"}else{html+=">";var cn=obj.children;if(cn){for(var i=0,len=cn.length;i<len;++i){html+=this.createHTML(cn[i])}}if(obj.html){html+=obj.html}html+="</"+obj.tag+">"}return html};var ease=function(x){return 1+Math.pow(x-1,3)};var animate=function(el,p,to,d,cb){var from=parseFloat(SL.getStyle(el,p));if(isNaN(from)){from=0}if(from==to){if(typeof cb=="function"){cb()}return }var delta=to-from;var op=p=="opacity";var unit=op?"":"px";var fn=function(ease){SL.setStyle(el,p,from+ease*delta+unit)};if(!options.animate&&!op||op&&!options.animateFade){fn(1);if(typeof cb=="function"){cb()}return }d*=1000;var begin=new Date().getTime();var end=begin+d;var timer=setInterval(function(){var time=new Date().getTime();if(time>=end){clearInterval(timer);fn(1);if(typeof cb=="function"){cb()}}else{fn(ease((time-begin)/d))}},10)};var clearOpacity=function(el){var s=el.style;if(client.isIE){if(typeof s.filter=="string"&&(/alpha/i).test(s.filter)){s.filter=s.filter.replace(/[\w\.]*alpha\(.*?\);?/i,"")}}else{s.opacity="";s["-moz-opacity"]="";s["-khtml-opacity"]=""}};var getComputedHeight=function(el){var h=Math.max(el.offsetHeight,el.clientHeight);if(!h){h=parseInt(SL.getStyle(el,"height"),10)||0;if(!client.isBorderBox){h+=parseInt(SL.getStyle(el,"padding-top"),10)+parseInt(SL.getStyle(el,"padding-bottom"),10)+parseInt(SL.getStyle(el,"border-top-width"),10)+parseInt(SL.getStyle(el,"border-bottom-width"),10)}}return h};var getPlayer=function(url){var m=url.match(RE.domain);var d=m&&document.domain==m[1];if(url.indexOf("#")>-1&&d){return"inline"}var q=url.indexOf("?");if(q>-1){url=url.substring(0,q)}if(RE.img.test(url)){return"img"}if(RE.swf.test(url)){return plugins.fla?"swf":"unsupported-swf"}if(RE.flv.test(url)){return plugins.fla?"flv":"unsupported-flv"}if(RE.qt.test(url)){return plugins.qt?"qt":"unsupported-qt"}if(RE.wmp.test(url)){if(plugins.wmp){return"wmp"}if(plugins.f4m){return"qt"}if(client.isMac){return plugins.qt?"unsupported-f4m":"unsupported-qtf4m"}return"unsupported-wmp"}else{if(RE.qtwmp.test(url)){if(plugins.qt){return"qt"}if(plugins.wmp){return"wmp"}return client.isMac?"unsupported-qt":"unsupported-qtwmp"}else{if(!d||RE.ajax.test(url)){return"ajax"}}}return"unsupported"};var handleClick=function(ev){var link;if(isLink(this)){link=this}else{link=SL.getTarget(ev);while(!isLink(link)&&link.parentNode){link=link.parentNode}}if(link){SB.open(link);if(gallery.length){SL.preventDefault(ev)}}};var toggleNav=function(id,on){var el=SL.get("shadowbox_nav_"+id);if(el){el.style.display=on?"":"none"}};var buildBars=function(cb){var obj=gallery[current];var title_i=SL.get("shadowbox_title_inner");title_i.innerHTML=obj.title||"";var nav=SL.get("shadowbox_nav");if(nav){var c,n,pl,pa,p;if(options.displayNav){c=true;var len=gallery.length;if(len>1){if(options.continuous){n=p=true}else{n=(len-1)>current;p=current>0}}if(options.slideshowDelay>0&&hasNext()){pa=slide_timer!="paused";pl=!pa}}else{c=n=pl=pa=p=false}toggleNav("close",c);toggleNav("next",n);toggleNav("play",pl);toggleNav("pause",pa);toggleNav("previous",p)}var counter=SL.get("shadowbox_counter");if(counter){var co="";if(options.displayCounter&&gallery.length>1){if(options.counterType=="skip"){var i=0,len=gallery.length,end=len;var limit=parseInt(options.counterLimit);if(limit<len){var h=Math.round(limit/2);i=current-h;if(i<0){i+=len}end=current+(limit-h);if(end>len){end-=len}}while(i!=end){if(i==len){i=0}co+='<a onclick="Shadowbox.change('+i+');"';if(i==current){co+=' class="shadowbox_counter_current"'}co+=">"+(++i)+"</a>"}}else{co=(current+1)+" "+SB.LANG.of+" "+len}}counter.innerHTML=co}cb()};var hideBars=function(anim,cb){var obj=gallery[current];var title=SL.get("shadowbox_title");var info=SL.get("shadowbox_info");var title_i=SL.get("shadowbox_title_inner");var info_i=SL.get("shadowbox_info_inner");var fn=function(){buildBars(cb)};var title_h=getComputedHeight(title);var info_h=getComputedHeight(info)*-1;if(anim){animate(title_i,"margin-top",title_h,0.35);animate(info_i,"margin-top",info_h,0.35,fn)}else{SL.setStyle(title_i,"margin-top",title_h+"px");SL.setStyle(info_i,"margin-top",info_h+"px");fn()}};var showBars=function(cb){var title_i=SL.get("shadowbox_title_inner");var info_i=SL.get("shadowbox_info_inner");var t=title_i.innerHTML!="";if(t){animate(title_i,"margin-top",0,0.35)}animate(info_i,"margin-top",0,0.35,cb)};var loadContent=function(){var obj=gallery[current];if(!obj){return }var changing=false;if(content){content.remove();changing=true}var p=obj.player=="inline"?"html":obj.player;if(typeof SB[p]!="function"){SB.raise("Unknown player "+obj.player)}content=new SB[p](content_id,obj);listenKeys(false);toggleLoading(true);hideBars(changing,function(){if(!content){return }if(!changing){SL.get("shadowbox").style.display=""}var fn=function(){resizeContent(function(){if(!content){return }showBars(function(){if(!content){return }SL.get("shadowbox_body_inner").innerHTML=SL.createHTML(content.markup(dims));toggleLoading(false,function(){if(!content){return }if(typeof content.onLoad=="function"){content.onLoad()}if(options.onFinish&&typeof options.onFinish=="function"){options.onFinish(gallery[current])}if(slide_timer!="paused"){SB.play()}listenKeys(true)})})})};if(typeof content.ready!="undefined"){var id=setInterval(function(){if(content){if(content.ready){clearInterval(id);id=null;fn()}}else{clearInterval(id);id=null}},100)}else{fn()}});if(gallery.length>1){var next=gallery[current+1]||gallery[0];if(next.player=="img"){var a=new Image();a.src=next.content}var prev=gallery[current-1]||gallery[gallery.length-1];if(prev.player=="img"){var b=new Image();b.src=prev.content}}};var setDimensions=function(height,width,resizable){resizable=resizable||false;var sb=SL.get("shadowbox_body");var h=height=parseInt(height);var w=width=parseInt(width);var view_h=SL.getViewportHeight();var view_w=SL.getViewportWidth();var border_w=parseInt(SL.getStyle(sb,"border-left-width"),10)+parseInt(SL.getStyle(sb,"border-right-width"),10);var extra_w=border_w+2*options.viewportPadding;if(w+extra_w>=view_w){w=view_w-extra_w}var border_h=parseInt(SL.getStyle(sb,"border-top-width"),10)+parseInt(SL.getStyle(sb,"border-bottom-width"),10);var bar_h=getComputedHeight(SL.get("shadowbox_title"))+getComputedHeight(SL.get("shadowbox_info"));var extra_h=border_h+2*options.viewportPadding+bar_h;if(h+extra_h>=view_h){h=view_h-extra_h}var drag=false;var resize_h=height;var resize_w=width;var handle=options.handleOversize;if(resizable&&(handle=="resize"||handle=="drag")){var change_h=(height-h)/height;var change_w=(width-w)/width;if(handle=="resize"){if(change_h>change_w){w=Math.round((width/height)*h)}else{if(change_w>change_h){h=Math.round((height/width)*w)}}resize_w=w;resize_h=h}else{var link=gallery[current];if(link){drag=link.player=="img"&&(change_h>0||change_w>0)}}}dims={height:h+border_h+bar_h,width:w+border_w,inner_h:h,inner_w:w,top:(view_h-(h+extra_h))/2+options.viewportPadding,resize_h:resize_h,resize_w:resize_w,drag:drag}};var resizeContent=function(cb){if(!content){return }setDimensions(content.height,content.width,content.resizable);if(cb){switch(options.animSequence){case"hw":adjustHeight(dims.inner_h,dims.top,true,function(){adjustWidth(dims.width,true,cb)});break;case"wh":adjustWidth(dims.width,true,function(){adjustHeight(dims.inner_h,dims.top,true,cb)});break;case"sync":default:adjustWidth(dims.width,true);adjustHeight(dims.inner_h,dims.top,true,cb)}}else{adjustWidth(dims.width,false);adjustHeight(dims.inner_h,dims.top,false);var c=SL.get(content_id);if(c){if(content.resizable&&options.handleOversize=="resize"){c.height=dims.resize_h;c.width=dims.resize_w}if(gallery[current].player=="img"&&options.handleOversize=="drag"){var top=parseInt(SL.getStyle(c,"top"));if(top+content.height<dims.inner_h){SL.setStyle(c,"top",dims.inner_h-content.height+"px")}var left=parseInt(SL.getStyle(c,"left"));if(left+content.width<dims.inner_w){SL.setStyle(c,"left",dims.inner_w-content.width+"px")}}}}};var adjustHeight=function(height,top,anim,cb){height=parseInt(height);var sb=SL.get("shadowbox_body");if(anim){animate(sb,"height",height,options.resizeDuration)}else{SL.setStyle(sb,"height",height+"px")}var s=SL.get("shadowbox");if(anim){animate(s,"top",top,options.resizeDuration,cb)}else{SL.setStyle(s,"top",top+"px");if(typeof cb=="function"){cb()}}};var adjustWidth=function(width,anim,cb){width=parseInt(width);var s=SL.get("shadowbox");if(anim){animate(s,"width",width,options.resizeDuration,cb)}else{SL.setStyle(s,"width",width+"px");if(typeof cb=="function"){cb()}}};var listenKeys=function(on){if(!options.enableKeys){return }SL[(on?"add":"remove")+"Event"](document,"keydown",handleKey)};var handleKey=function(e){var code=SL.keyCode(e);SL.preventDefault(e);if(code==81||code==88||code==27){SB.close()}else{if(code==37){SB.previous()}else{if(code==39){SB.next()}else{if(code==32){SB[(typeof slide_timer=="number"?"pause":"play")]()}}}}};var toggleLoading=function(on,cb){var loading=SL.get("shadowbox_loading");if(on){loading.style.display="";if(typeof cb=="function"){cb()}}else{var p=gallery[current].player;var anim=(p=="img"||p=="html");var fn=function(){loading.style.display="none";clearOpacity(loading);if(typeof cb=="function"){cb()}};if(anim){animate(loading,"opacity",0,options.fadeDuration,fn)}else{fn()}}};var fixTop=function(){SL.get("shadowbox_container").style.top=document.documentElement.scrollTop+"px"};var fixHeight=function(){SL.get("shadowbox_overlay").style.height=SL.getViewportHeight()+"px"};var hasNext=function(){return gallery.length>1&&(current!=gallery.length-1||options.continuous)};var toggleVisible=function(cb){var els,v=(cb)?"hidden":"visible";var hide=["select","object","embed"];for(var i=0;i<hide.length;++i){els=document.getElementsByTagName(hide[i]);for(var j=0,len=els.length;j<len;++j){els[j].style.visibility=v}}var so=SL.get("shadowbox_overlay");var sc=SL.get("shadowbox_container");var sb=SL.get("shadowbox");if(cb){SL.setStyle(so,{backgroundColor:options.overlayColor,opacity:0});if(!options.modal){SL.addEvent(so,"click",SB.close)}if(ltIE7){fixTop();fixHeight();SL.addEvent(window,"scroll",fixTop)}sb.style.display="none";sc.style.visibility="visible";animate(so,"opacity",parseFloat(options.overlayOpacity),options.fadeDuration,cb)}else{SL.removeEvent(so,"click",SB.close);if(ltIE7){SL.removeEvent(window,"scroll",fixTop)}sb.style.display="none";animate(so,"opacity",0,options.fadeDuration,function(){sc.style.visibility="hidden";sb.style.display="";clearOpacity(so)})}};Shadowbox.init=function(opts){if(initialized){return }if(typeof SB.LANG=="undefined"){SB.raise("No Shadowbox language loaded");return }if(typeof SB.SKIN=="undefined"){SB.raise("No Shadowbox skin loaded");return }apply(options,opts||{});var markup=SB.SKIN.markup.replace(/\{(\w+)\}/g,function(m,p){return SB.LANG[p]});var bd=document.body||document.documentElement;SL.append(bd,markup);if(ltIE7){SL.setStyle(SL.get("shadowbox_container"),"position","absolute");SL.get("shadowbox_body").style.zoom=1;var png=SB.SKIN.png_fix;if(png&&png.constructor==Array){for(var i=0;i<png.length;++i){var el=SL.get(png[i]);if(el){var match=SL.getStyle(el,"background-image").match(/url\("(.*\.png)"\)/);if(match){SL.setStyle(el,{backgroundImage:"none",filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,src="+match[1]+",sizingMethod=scale);"})}}}}}for(var e in options.ext){RE[e]=new RegExp(".("+options.ext[e].join("|")+")s*$","i")}var id;SL.addEvent(window,"resize",function(){if(id){clearTimeout(id);id=null}id=setTimeout(function(){if(ltIE7){fixHeight()}resizeContent()},50)});if(!options.skipSetup){SB.setup()}initialized=true};Shadowbox.loadSkin=function(skin,dir){if(!(/\/$/.test(dir))){dir+="/"}skin=dir+skin+"/";document.write('<link rel="stylesheet" type="text/css" href="'+skin+'skin.css">');document.write('<script type="text/javascript" src="'+skin+'skin.js"><\/script>')};Shadowbox.loadLanguage=function(lang,dir){if(!(/\/$/.test(dir))){dir+="/"}document.write('<script type="text/javascript" src="'+dir+"shadowbox-"+lang+'.js"><\/script>')};Shadowbox.loadPlayer=function(players,dir){if(typeof players=="string"){players=[players]}if(!(/\/$/.test(dir))){dir+="/"}for(var i=0,len=players.length;i<len;++i){document.write('<script type="text/javascript" src="'+dir+"shadowbox-"+players[i]+'.js"><\/script>')}};Shadowbox.setup=function(links,opts){if(!links){var links=[];var a=document.getElementsByTagName("a"),rel;for(var i=0,len=a.length;i<len;++i){rel=a[i].getAttribute("rel");if(rel&&RE.rel.test(rel)){links[links.length]=a[i]}}}else{if(!links.length){links=[links]}}var link;for(var i=0,len=links.length;i<len;++i){link=links[i];if(typeof link.shadowboxCacheKey=="undefined"){link.shadowboxCacheKey=cache.length;SL.addEvent(link,"click",handleClick)}cache[link.shadowboxCacheKey]=this.buildCacheObj(link,opts)}};Shadowbox.buildCacheObj=function(link,opts){var href=link.href;var o={el:link,title:link.getAttribute("title"),player:getPlayer(href),options:apply({},opts||{}),content:href};var opt,l_opts=["player","title","height","width","gallery"];for(var i=0,len=l_opts.length;i<len;++i){opt=l_opts[i];if(typeof o.options[opt]!="undefined"){o[opt]=o.options[opt];delete o.options[opt]}}var rel=link.getAttribute("rel");if(rel){var match=rel.match(RE.gallery);if(match){o.gallery=escape(match[2])}var params=rel.split(";");for(var i=0,len=params.length;i<len;++i){match=params[i].match(RE.param);if(match){if(match[1]=="options"){eval("apply(o.options, "+match[2]+")")}else{o[match[1]]=match[2]}}}}return o};Shadowbox.applyOptions=function(opts){if(opts){default_options=apply({},options);options=apply(options,opts)}};Shadowbox.revertOptions=function(){if(default_options){options=default_options;default_options=null}};Shadowbox.open=function(obj,opts){this.revertOptions();if(isLink(obj)){if(typeof obj.shadowboxCacheKey=="undefined"||typeof cache[obj.shadowboxCacheKey]=="undefined"){obj=this.buildCacheObj(obj,opts)}else{obj=cache[obj.shadowboxCacheKey]}}if(obj.constructor==Array){gallery=obj;current=0}else{var copy=apply({},obj);if(!obj.gallery){gallery=[copy];current=0}else{current=null;gallery=[];var ci;for(var i=0,len=cache.length;i<len;++i){ci=cache[i];if(ci.gallery){if(ci.content==obj.content&&ci.gallery==obj.gallery&&ci.title==obj.title){current=gallery.length}if(ci.gallery==obj.gallery){gallery.push(apply({},ci))}}}if(current==null){gallery.unshift(copy);current=0}}}obj=gallery[current];if(obj.options||opts){this.applyOptions(apply(apply({},obj.options||{}),opts||{}))}var match,r;for(var i=0,len=gallery.length;i<len;++i){r=false;if(gallery[i].player=="unsupported"){r=true}else{if(match=RE.unsupported.exec(gallery[i].player)){if(options.handleUnsupported=="link"){gallery[i].player="html";var s,a,oe=options.errors;switch(match[1]){case"qtwmp":s="either";a=[oe.qt.url,oe.qt.name,oe.wmp.url,oe.wmp.name];break;case"qtf4m":s="shared";a=[oe.qt.url,oe.qt.name,oe.f4m.url,oe.f4m.name];break;default:s="single";if(match[1]=="swf"||match[1]=="flv"){match[1]="fla"}a=[oe[match[1]].url,oe[match[1]].name]}var msg=SB.LANG.errors[s].replace(/\{(\d+)\}/g,function(m,i){return a[i]});gallery[i].content='<div class="shadowbox_message">'+msg+"</div>"}else{r=true}}else{if(gallery[i].player=="inline"){var match=RE.inline.exec(gallery[i].content);if(match){var el;if(el=SL.get(match[1])){gallery[i].content=el.innerHTML}else{SB.raise("Cannot find element with id "+match[1])}}else{SB.raise("Cannot find element id for inline content")}}}}if(r){gallery.splice(i,1);if(i<current){--current}else{if(i==current){current=i>0?current-1:i}}--i;len=gallery.length}}if(gallery.length){if(options.onOpen&&typeof options.onOpen=="function"){options.onOpen(obj)}if(!activated){setDimensions(options.initialHeight,options.initialWidth);adjustHeight(dims.inner_h,dims.top,false);adjustWidth(dims.width,false);toggleVisible(loadContent)}else{loadContent()}activated=true}};Shadowbox.change=function(num){if(!gallery){return }if(!gallery[num]){if(!options.continuous){return }else{num=num<0?(gallery.length-1):0}}if(typeof slide_timer=="number"){clearTimeout(slide_timer);slide_timer=null;slide_delay=slide_start=0}current=num;if(options.onChange&&typeof options.onChange=="function"){options.onChange(gallery[current])}loadContent()};Shadowbox.next=function(){this.change(current+1)};Shadowbox.previous=function(){this.change(current-1)};Shadowbox.play=function(){if(!hasNext()){return }if(!slide_delay){slide_delay=options.slideshowDelay*1000}if(slide_delay){slide_start=new Date().getTime();slide_timer=setTimeout(function(){slide_delay=slide_start=0;SB.next()},slide_delay);toggleNav("play",false);toggleNav("pause",true)}};Shadowbox.pause=function(){if(typeof slide_timer=="number"){var time=new Date().getTime();slide_delay=Math.max(0,slide_delay-(time-slide_start));if(slide_delay){clearTimeout(slide_timer);slide_timer="paused"}toggleNav("pause",false);toggleNav("play",true)}};Shadowbox.close=function(){if(!activated){return }listenKeys(false);toggleVisible(false);if(content){content.remove();content=null}if(typeof slide_timer=="number"){clearTimeout(slide_timer)}slide_timer=null;slide_delay=0;if(options.onClose&&typeof options.onClose=="function"){options.onClose(gallery[current])}activated=false};Shadowbox.clearCache=function(){for(var i=0,len=cache.length;i<len;++i){if(cache[i].el){SL.removeEvent(cache[i].el,"click",handleClick);delete cache[i].el.shadowboxCacheKey}}cache=[]};Shadowbox.getPlugins=function(){return plugins};Shadowbox.getOptions=function(){return options};Shadowbox.getCurrent=function(){return gallery[current]};Shadowbox.getVersion=function(){return version};Shadowbox.getClient=function(){return client};Shadowbox.getContent=function(){return content};Shadowbox.getDimensions=function(){return dims};Shadowbox.raise=function(e){if(typeof options.handleException=="function"){options.handleException(e)}else{throw e}}})();
if(typeof Shadowbox=="undefined"){throw"Unable to load Shadowbox language file, base library not found."}Shadowbox.LANG={code:"en",of:"of",loading:"loading",cancel:"Cancel",next:"Next",previous:"Previous",play:"Play",pause:"Pause",close:"Close",errors:{single:'You must install the <a href="{0}">{1}</a> browser plugin to view this content.',shared:'You must install both the <a href="{0}">{1}</a> and <a href="{2}">{3}</a> browser plugins to view this content.',either:'You must install either the <a href="{0}">{1}</a> or the <a href="{2}">{3}</a> browser plugin to view this content.'}};
(function(){var F=Shadowbox;var L=F.lib;var A=F.getClient();var I;var M;var J="shadowbox_drag_layer";var K;var D=function(){I={x:0,y:0,start_x:null,start_y:null}};var E=function(N,O,C){if(N){D();var P=["position:absolute","height:"+O+"px","width:"+C+"px","cursor:"+(A.isGecko?"-moz-grab":"move"),"background-color:"+(A.isIE?"#fff;filter:alpha(opacity=0)":"transparent")];L.append(L.get("shadowbox_body_inner"),'<div id="'+J+'" style="'+P.join(";")+'"></div>');L.addEvent(L.get(J),"mousedown",H)}else{var Q=L.get(J);if(Q){L.removeEvent(Q,"mousedown",H);L.remove(Q)}}};var H=function(N){L.preventDefault(N);var C=L.getPageXY(N);I.start_x=C[0];I.start_y=C[1];M=L.get("shadowbox_content");L.addEvent(document,"mousemove",G);L.addEvent(document,"mouseup",B);if(A.isGecko){L.setStyle(L.get(J),"cursor","-moz-grabbing")}};var B=function(){L.removeEvent(document,"mousemove",G);L.removeEvent(document,"mouseup",B);if(A.isGecko){L.setStyle(L.get(J),"cursor","-moz-grab")}};var G=function(Q){var O=F.getContent();var R=F.getDimensions();var P=L.getPageXY(Q);var N=P[0]-I.start_x;I.start_x+=N;I.x=Math.max(Math.min(0,I.x+N),R.inner_w-O.width);L.setStyle(M,"left",I.x+"px");var C=P[1]-I.start_y;I.start_y+=C;I.y=Math.max(Math.min(0,I.y+C),R.inner_h-O.height);L.setStyle(M,"top",I.y+"px")};Shadowbox.img=function(O,N){this.id=O;this.obj=N;this.resizable=true;this.ready=false;var C=this;K=new Image();K.onload=function(){C.height=C.obj.height?parseInt(C.obj.height,10):K.height;C.width=C.obj.width?parseInt(C.obj.width,10):K.width;C.ready=true;K.onload="";K=null};K.src=N.content};Shadowbox.img.prototype={markup:function(C){return{tag:"img",id:this.id,height:C.resize_h,width:C.resize_w,src:this.obj.content,style:"position:absolute"}},onLoad:function(){var C=F.getDimensions();if(C.drag&&F.getOptions().handleOversize=="drag"){E(true,C.resize_h,C.resize_w)}},remove:function(){var C=L.get(this.id);if(C){L.remove(C)}E(false);if(K){K.onload="";K=null}}}})();
(function(){var A=Shadowbox;var B=A.lib;Shadowbox.html=function(D,C){this.id=D;this.obj=C;this.height=this.obj.height?parseInt(this.obj.height,10):300;this.width=this.obj.width?parseInt(this.obj.width,10):500};Shadowbox.html.prototype={markup:function(C){return{tag:"div",id:this.id,cls:"html",html:this.obj.content}},remove:function(){var C=B.get(this.id);if(C){B.remove(C)}}}})();
(function(){var A=Shadowbox;var B=A.lib;var D=A.getClient();Shadowbox.ajax=function(E,C){this.id=E;this.obj=C;this.height=this.obj.height?parseInt(this.obj.height,10):B.getViewportHeight();this.width=this.obj.width?parseInt(this.obj.width,10):B.getViewportWidth()};Shadowbox.ajax.prototype={markup:function(E){var C={tag:"ajax",id:this.id,name:this.id,height:"100%",width:"100%",frameborder:"0",marginwidth:"0",marginheight:"0",scrolling:"auto"};if(D.isIE){C.allowtransparency="true";if(!D.isIE7){C.src='javascript:false;document.write("");'}}return C},onLoad:function(){var C=(D.isIE)?B.get(this.id).contentWindow:window.frames[this.id];C.location=this.obj.content},remove:function(){var C=B.get(this.id);if(C){B.remove(C);if(D.isGecko){delete window.frames[this.id]}}}}})();
(function(){var A=Shadowbox;var B=A.lib;Shadowbox.swf=function(D,C){this.id=D;this.obj=C;this.resizable=true;this.height=this.obj.height?parseInt(this.obj.height,10):300;this.width=this.obj.width?parseInt(this.obj.width,10):300};Shadowbox.swf.prototype={markup:function(D){var C=A.getOptions().flashBgColor;return{tag:"object",id:this.id,name:this.id,type:"application/x-shockwave-flash",data:this.obj.content,children:[{tag:"param",name:"movie",value:this.obj.content},{tag:"param",name:"bgcolor",value:C}],height:D.resize_h,width:D.resize_w}},remove:function(){var C=B.get(this.id);if(C){B.remove(C)}}}})();




/*  Copyright Mihai Bazon, 2002-2005  |  www.bazon.net/mishoo
 * -----------------------------------------------------------
 *
 * The DHTML Calendar, version 1.0 "It is happening again"
 *
 * Details and latest version at:
 * www.dynarch.com/projects/calendar
 *
 * This script is developed by Dynarch.com.  Visit us at www.dynarch.com.
 *
 * This script is distributed under the GNU Lesser General Public License.
 * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
 */

// $Id: calendar.js,v 1.51 2005/03/07 16:44:31 mishoo Exp $

/** The Calendar object constructor. */
Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) {
	// member variables
	this.activeDiv = null;
	this.currentDateEl = null;
	this.getDateStatus = null;
	this.getDateToolTip = null;
	this.getDateText = null;
	this.timeout = null;
	this.onSelected = onSelected || null;
	this.onClose = onClose || null;
	this.dragging = false;
	this.hidden = false;
	this.minYear = 1970;
	this.maxYear = 2050;
	this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"];
	this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"];
	this.isPopup = true;
	this.weekNumbers = true;
	this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc.
	this.showsOtherMonths = false;
	this.dateStr = dateStr;
	this.ar_days = null;
	this.showsTime = false;
	this.time24 = true;
	this.yearStep = 2;
	this.hiliteToday = true;
	this.multiple = null;
	// HTML elements
	this.table = null;
	this.element = null;
	this.tbody = null;
	this.firstdayname = null;
	// Combo boxes
	this.monthsCombo = null;
	this.yearsCombo = null;
	this.hilitedMonth = null;
	this.activeMonth = null;
	this.hilitedYear = null;
	this.activeYear = null;
	// Information
	this.dateClicked = false;

	// one-time initializations
	if (typeof Calendar._SDN == "undefined") {
		// table of short day names
		if (typeof Calendar._SDN_len == "undefined")
			Calendar._SDN_len = 3;
		var ar = new Array();
		for (var i = 8; i > 0;) {
			ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len);
		}
		Calendar._SDN = ar;
		// table of short month names
		if (typeof Calendar._SMN_len == "undefined")
			Calendar._SMN_len = 3;
		ar = new Array();
		for (var i = 12; i > 0;) {
			ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len);
		}
		Calendar._SMN = ar;
	}
};

// ** constants

/// "static", needed for event handlers.
Calendar._C = null;

/// detect a special case of "web browser"
Calendar.is_ie = ( /msie/i.test(navigator.userAgent) &&
		   !/opera/i.test(navigator.userAgent) );

Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) );

/// detect Opera browser
Calendar.is_opera = /opera/i.test(navigator.userAgent);

/// detect KHTML-based browsers
Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);

// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate
//        library, at some point.

Calendar.getAbsolutePos = function(el) {
	var SL = 0, ST = 0;
	var is_div = /^div$/i.test(el.tagName);
	if (is_div && el.scrollLeft)
		SL = el.scrollLeft;
	if (is_div && el.scrollTop)
		ST = el.scrollTop;
	var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
	if (el.offsetParent) {
		var tmp = this.getAbsolutePos(el.offsetParent);
		r.x += tmp.x;
		r.y += tmp.y;
	}
	return r;
};

Calendar.isRelated = function (el, evt) {
	var related = evt.relatedTarget;
	if (!related) {
		var type = evt.type;
		if (type == "mouseover") {
			related = evt.fromElement;
		} else if (type == "mouseout") {
			related = evt.toElement;
		}
	}
	while (related) {
		if (related == el) {
			return true;
		}
		try { related = related.parentNode; }
		catch(e) { related = null }
	}
	return false;
};

Calendar.removeClass = function(el, className) {
	if (!(el && el.className)) {
		return;
	}
	var cls = el.className.split(" ");
	var ar = new Array();
	for (var i = cls.length; i > 0;) {
		if (cls[--i] != className) {
			ar[ar.length] = cls[i];
		}
	}
	el.className = ar.join(" ");
};

Calendar.addClass = function(el, className) {
	Calendar.removeClass(el, className);
	el.className += " " + className;
};

// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately.
Calendar.getElement = function(ev) {
	var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget;
	while (f.nodeType != 1 || /^div$/i.test(f.tagName))
		f = f.parentNode;
	return f;
};

Calendar.getTargetElement = function(ev) {
	var f = Calendar.is_ie ? window.event.srcElement : ev.target;
	while (f.nodeType != 1)
		f = f.parentNode;
	return f;
};

Calendar.stopEvent = function(ev) {
	ev || (ev = window.event);
	if (Calendar.is_ie) {
		ev.cancelBubble = true;
		ev.returnValue = false;
	} else {
		ev.preventDefault();
		ev.stopPropagation();
	}
	return false;
};

Calendar.addEvent = function(el, evname, func) {
	if (el.attachEvent) { // IE
		el.attachEvent("on" + evname, func);
	} else if (el.addEventListener) { // Gecko / W3C
		el.addEventListener(evname, func, true);
	} else {
		el["on" + evname] = func;
	}
};

Calendar.removeEvent = function(el, evname, func) {
	if (el.detachEvent) { // IE
		el.detachEvent("on" + evname, func);
	} else if (el.removeEventListener) { // Gecko / W3C
		el.removeEventListener(evname, func, true);
	} else {
		el["on" + evname] = null;
	}
};

Calendar.createElement = function(type, parent) {
	var el = null;
	if (document.createElementNS) {
		// use the XHTML namespace; IE won't normally get here unless
		// _they_ "fix" the DOM2 implementation.
		el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
	} else {
		el = document.createElement(type);
	}
	if (typeof parent != "undefined") {
		parent.appendChild(el);
	}
	return el;
};

// END: UTILITY FUNCTIONS

// BEGIN: CALENDAR STATIC FUNCTIONS

/** Internal -- adds a set of events to make some element behave like a button. */
Calendar._add_evs = function(el) {
	with (Calendar) {
		addEvent(el, "mouseover", dayMouseOver);
		addEvent(el, "mousedown", dayMouseDown);
		addEvent(el, "mouseout", dayMouseOut);
		if (is_ie) {
			addEvent(el, "dblclick", dayMouseDblClick);
			el.setAttribute("unselectable", true);
		}
	}
};

Calendar.findMonth = function(el) {
	if (typeof el.month != "undefined") {
		return el;
	} else if (typeof el.parentNode.month != "undefined") {
		return el.parentNode;
	}
	return null;
};

Calendar.findYear = function(el) {
	if (typeof el.year != "undefined") {
		return el;
	} else if (typeof el.parentNode.year != "undefined") {
		return el.parentNode;
	}
	return null;
};

Calendar.showMonthsCombo = function () {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	var cal = cal;
	var cd = cal.activeDiv;
	var mc = cal.monthsCombo;
	if (cal.hilitedMonth) {
		Calendar.removeClass(cal.hilitedMonth, "hilite");
	}
	if (cal.activeMonth) {
		Calendar.removeClass(cal.activeMonth, "active");
	}
	var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];
	Calendar.addClass(mon, "active");
	cal.activeMonth = mon;
	var s = mc.style;
	s.display = "block";
	if (cd.navtype < 0)
		s.left = cd.offsetLeft + "px";
	else {
		var mcw = mc.offsetWidth;
		if (typeof mcw == "undefined")
			// Konqueror brain-dead techniques
			mcw = 50;
		s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px";
	}
	s.top = (cd.offsetTop + cd.offsetHeight) + "px";
};

Calendar.showYearsCombo = function (fwd) {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	var cal = cal;
	var cd = cal.activeDiv;
	var yc = cal.yearsCombo;
	if (cal.hilitedYear) {
		Calendar.removeClass(cal.hilitedYear, "hilite");
	}
	if (cal.activeYear) {
		Calendar.removeClass(cal.activeYear, "active");
	}
	cal.activeYear = null;
	var Y = cal.date.getFullYear() + (fwd ? 1 : -1);
	var yr = yc.firstChild;
	var show = false;
	for (var i = 12; i > 0; --i) {
		if (Y >= cal.minYear && Y <= cal.maxYear) {

			yr.innerHTML = Y;
			yr.year = Y;
			yr.style.display = "block";
			show = true;
		} else {
			yr.style.display = "none";
		}
		yr = yr.nextSibling;
		Y += fwd ? cal.yearStep : -cal.yearStep;
	}
	if (show) {
		var s = yc.style;
		s.display = "block";
		if (cd.navtype < 0)
			s.left = cd.offsetLeft + "px";
		else {
			var ycw = yc.offsetWidth;
			if (typeof ycw == "undefined")
				// Konqueror brain-dead techniques
				ycw = 50;
			s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px";
		}
		s.top = (cd.offsetTop + cd.offsetHeight) + "px";
	}
};

// event handlers

Calendar.tableMouseUp = function(ev) {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	if (cal.timeout) {
		clearTimeout(cal.timeout);
	}
	var el = cal.activeDiv;
	if (!el) {
		return false;
	}
	var target = Calendar.getTargetElement(ev);
	ev || (ev = window.event);
	Calendar.removeClass(el, "active");
	if (target == el || target.parentNode == el) {
		Calendar.cellClick(el, ev);
	}
	var mon = Calendar.findMonth(target);
	var date = null;
	if (mon) {
		date = new Date(cal.date);
		if (mon.month != date.getMonth()) {
			date.setMonth(mon.month);
			cal.setDate(date);
			cal.dateClicked = false;
			cal.callHandler();
		}
	} else {
		var year = Calendar.findYear(target);
		if (year) {
			date = new Date(cal.date);
			if (year.year != date.getFullYear()) {
				date.setFullYear(year.year);
				cal.setDate(date);
				cal.dateClicked = false;
				cal.callHandler();
			}
		}
	}
	with (Calendar) {
		removeEvent(document, "mouseup", tableMouseUp);
		removeEvent(document, "mouseover", tableMouseOver);
		removeEvent(document, "mousemove", tableMouseOver);
		cal._hideCombos();
		_C = null;
		return stopEvent(ev);
	}
};

Calendar.tableMouseOver = function (ev) {
	var cal = Calendar._C;
	if (!cal) {
		return;
	}
	var el = cal.activeDiv;
	var target = Calendar.getTargetElement(ev);
	if (target == el || target.parentNode == el) {
		Calendar.addClass(el, "hilite active");
		Calendar.addClass(el.parentNode, "rowhilite");
	} else {
		if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2)))
			Calendar.removeClass(el, "active");
		Calendar.removeClass(el, "hilite");
		Calendar.removeClass(el.parentNode, "rowhilite");
	}
	ev || (ev = window.event);
	if (el.navtype == 50 && target != el) {
		var pos = Calendar.getAbsolutePos(el);
		var w = el.offsetWidth;
		var x = ev.clientX;
		var dx;
		var decrease = true;
		if (x > pos.x + w) {
			dx = x - pos.x - w;
			decrease = false;
		} else
			dx = pos.x - x;

		if (dx < 0) dx = 0;
		var range = el._range;
		var current = el._current;
		var count = Math.floor(dx / 10) % range.length;
		for (var i = range.length; --i >= 0;)
			if (range[i] == current)
				break;
		while (count-- > 0)
			if (decrease) {
				if (--i < 0)
					i = range.length - 1;
			} else if ( ++i >= range.length )
				i = 0;
		var newval = range[i];
		el.innerHTML = newval;

		cal.onUpdateTime();
	}
	var mon = Calendar.findMonth(target);
	if (mon) {
		if (mon.month != cal.date.getMonth()) {
			if (cal.hilitedMonth) {
				Calendar.removeClass(cal.hilitedMonth, "hilite");
			}
			Calendar.addClass(mon, "hilite");
			cal.hilitedMonth = mon;
		} else if (cal.hilitedMonth) {
			Calendar.removeClass(cal.hilitedMonth, "hilite");
		}
	} else {
		if (cal.hilitedMonth) {
			Calendar.removeClass(cal.hilitedMonth, "hilite");
		}
		var year = Calendar.findYear(target);
		if (year) {
			if (year.year != cal.date.getFullYear()) {
				if (cal.hilitedYear) {
					Calendar.removeClass(cal.hilitedYear, "hilite");
				}
				Calendar.addClass(year, "hilite");
				cal.hilitedYear = year;
			} else if (cal.hilitedYear) {
				Calendar.removeClass(cal.hilitedYear, "hilite");
			}
		} else if (cal.hilitedYear) {
			Calendar.removeClass(cal.hilitedYear, "hilite");
		}
	}
	return Calendar.stopEvent(ev);
};

Calendar.tableMouseDown = function (ev) {
	if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) {
		return Calendar.stopEvent(ev);
	}
};

Calendar.calDragIt = function (ev) {
	var cal = Calendar._C;
	if (!(cal && cal.dragging)) {
		return false;
	}
	var posX;
	var posY;
	if (Calendar.is_ie) {
		posY = window.event.clientY + document.body.scrollTop;
		posX = window.event.clientX + document.body.scrollLeft;
	} else {
		posX = ev.pageX;
		posY = ev.pageY;
	}
	cal.hideShowCovered();
	var st = cal.element.style;
	st.left = (posX - cal.xOffs) + "px";
	st.top = (posY - cal.yOffs) + "px";
	return Calendar.stopEvent(ev);
};

Calendar.calDragEnd = function (ev) {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	cal.dragging = false;
	with (Calendar) {
		removeEvent(document, "mousemove", calDragIt);
		removeEvent(document, "mouseup", calDragEnd);
		tableMouseUp(ev);
	}
	cal.hideShowCovered();
};

Calendar.dayMouseDown = function(ev) {
	var el = Calendar.getElement(ev);
	if (el.disabled) {
		return false;
	}
	var cal = el.calendar;
	cal.activeDiv = el;
	Calendar._C = cal;
	if (el.navtype != 300) with (Calendar) {
		if (el.navtype == 50) {
			el._current = el.innerHTML;
			addEvent(document, "mousemove", tableMouseOver);
		} else
			addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver);
		addClass(el, "hilite active");
		addEvent(document, "mouseup", tableMouseUp);
	} else if (cal.isPopup) {
		cal._dragStart(ev);
	}
	if (el.navtype == -1 || el.navtype == 1) {
		if (cal.timeout) clearTimeout(cal.timeout);
		cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250);
	} else if (el.navtype == -2 || el.navtype == 2) {
		if (cal.timeout) clearTimeout(cal.timeout);
		cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250);
	} else {
		cal.timeout = null;
	}
	return Calendar.stopEvent(ev);
};

Calendar.dayMouseDblClick = function(ev) {
	Calendar.cellClick(Calendar.getElement(ev), ev || window.event);
	if (Calendar.is_ie) {
		document.selection.empty();
	}
};

Calendar.dayMouseOver = function(ev) {
	var el = Calendar.getElement(ev);
	if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) {
		return false;
	}
	if (el.ttip) {
		if (el.ttip.substr(0, 1) == "_") {
			el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1);
		}
		el.calendar.tooltips.innerHTML = el.ttip;
	}
	if (el.navtype != 300) {
		Calendar.addClass(el, "hilite");
		if (el.caldate) {
			Calendar.addClass(el.parentNode, "rowhilite");
		}
	}
	return Calendar.stopEvent(ev);
};

Calendar.dayMouseOut = function(ev) {
	with (Calendar) {
		var el = getElement(ev);
		if (isRelated(el, ev) || _C || el.disabled)
			return false;
		removeClass(el, "hilite");
		if (el.caldate)
			removeClass(el.parentNode, "rowhilite");
		if (el.calendar)
			el.calendar.tooltips.innerHTML = _TT["SEL_DATE"];
		return stopEvent(ev);
	}
};

/**
 *  A generic "click" handler :) handles all types of buttons defined in this
 *  calendar.
 */
Calendar.cellClick = function(el, ev) {
	var cal = el.calendar;
	var closing = false;
	var newdate = false;
	var date = null;
	if (typeof el.navtype == "undefined") {
		if (cal.currentDateEl) {
			Calendar.removeClass(cal.currentDateEl, "selected");
			Calendar.addClass(el, "selected");
			closing = (cal.currentDateEl == el);
			if (!closing) {
				cal.currentDateEl = el;
			}
		}
		cal.date.setDateOnly(el.caldate);
		date = cal.date;
		var other_month = !(cal.dateClicked = !el.otherMonth);
		if (!other_month && !cal.currentDateEl)
			cal._toggleMultipleDate(new Date(date));
		else
			newdate = !el.disabled;
		// a date was clicked
		if (other_month)
			cal._init(cal.firstDayOfWeek, date);
	} else {
		if (el.navtype == 200) {
			Calendar.removeClass(el, "hilite");
			cal.callCloseHandler();
			return;
		}
		date = new Date(cal.date);
		if (el.navtype == 0)
			date.setDateOnly(new Date()); // TODAY
		// unless "today" was clicked, we assume no date was clicked so
		// the selected handler will know not to close the calenar when
		// in single-click mode.
		// cal.dateClicked = (el.navtype == 0);
		cal.dateClicked = false;
		var year = date.getFullYear();
		var mon = date.getMonth();
		function setMonth(m) {
			var day = date.getDate();
			var max = date.getMonthDays(m);
			if (day > max) {
				date.setDate(max);
			}
			date.setMonth(m);
		};
		switch (el.navtype) {
		    case 400:
			Calendar.removeClass(el, "hilite");
			var text = Calendar._TT["ABOUT"];
			/*if (typeof text != "undefined") {
				text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : "";
			} else {
				// FIXME: this should be removed as soon as lang files get updated!
				text = "Help and about box text is not translated into this language.\n" +
					"If you know this language and you feel generous please update\n" +
					"the corresponding file in \"lang\" subdir to match calendar-en.js\n" +
					"and send it back to <mihai_bazon@yahoo.com> to get it into the distribution  ;-)\n\n" +
					"Thank you!\n" +
					"http://dynarch.com/mishoo/calendar.epl\n";
			}
			alert(text);*/
			return;
		    case -2:
			if (year > cal.minYear) {
				date.setFullYear(year - 1);
			}
			break;
		    case -1:
			if (mon > 0) {
				setMonth(mon - 1);
			} else if (year-- > cal.minYear) {
				date.setFullYear(year);
				setMonth(11);
			}
			break;
		    case 1:
			if (mon < 11) {
				setMonth(mon + 1);
			} else if (year < cal.maxYear) {
				date.setFullYear(year + 1);
				setMonth(0);
			}
			break;
		    case 2:
			if (year < cal.maxYear) {
				date.setFullYear(year + 1);
			}
			break;
		    case 100:
			cal.setFirstDayOfWeek(el.fdow);
			return;
		    case 50:
			var range = el._range;
			var current = el.innerHTML;
			for (var i = range.length; --i >= 0;)
				if (range[i] == current)
					break;
			if (ev && ev.shiftKey) {
				if (--i < 0)
					i = range.length - 1;
			} else if ( ++i >= range.length )
				i = 0;
			var newval = range[i];
			el.innerHTML = newval;
			cal.onUpdateTime();
			return;
		    case 0:
			// TODAY will bring us here
			if ((typeof cal.getDateStatus == "function") &&
			    cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) {
				return false;
			}
			break;
		}
		if (!date.equalsTo(cal.date)) {
			cal.setDate(date);
			newdate = true;
		} else if (el.navtype == 0)
			newdate = closing = true;
	}
	if (newdate) {
		ev && cal.callHandler();
	}
	if (closing) {
		Calendar.removeClass(el, "hilite");
		ev && cal.callCloseHandler();
	}
};

// END: CALENDAR STATIC FUNCTIONS

// BEGIN: CALENDAR OBJECT FUNCTIONS

/**
 *  This function creates the calendar inside the given parent.  If _par is
 *  null than it creates a popup calendar inside the BODY element.  If _par is
 *  an element, be it BODY, then it creates a non-popup calendar (still
 *  hidden).  Some properties need to be set before calling this function.
 */
Calendar.prototype.create = function (_par) {
	var parent = null;
	if (! _par) {
		// default parent is the document body, in which case we create
		// a popup calendar.
		parent = document.getElementsByTagName("body")[0];
		this.isPopup = true;
	} else {
		parent = _par;
		this.isPopup = false;
	}
	this.date = this.dateStr ? new Date(this.dateStr) : new Date();

	var table = Calendar.createElement("table");
	this.table = table;
	table.cellSpacing = 0;
	table.cellPadding = 0;
	table.calendar = this;
	Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown);

	var div = Calendar.createElement("div");
	this.element = div;
	div.className = "calendar";
	if (this.isPopup) {
		div.style.position = "absolute";
		div.style.display = "none";
	}
	div.appendChild(table);

	var thead = Calendar.createElement("thead", table);
	var cell = null;
	var row = null;

	var cal = this;
	var hh = function (text, cs, navtype) {
		cell = Calendar.createElement("td", row);
		cell.colSpan = cs;
		cell.className = "button";
		if (navtype != 0 && Math.abs(navtype) <= 2)
			cell.className += " nav";
		Calendar._add_evs(cell);
		cell.calendar = cal;
		cell.navtype = navtype;
		cell.innerHTML = "<div unselectable='on'>" + text + "</div>";
		return cell;
	};

	row = Calendar.createElement("tr", thead);
	var title_length = 6;
	(this.isPopup) && --title_length;
	(this.weekNumbers) && ++title_length;

	hh(" ", 1, 400).ttip = Calendar._TT[" "];
	this.title = hh("", title_length, 300);
	this.title.className = "title";
	if (this.isPopup) {
		this.title.ttip = Calendar._TT["DRAG_TO_MOVE"];
		this.title.style.cursor = "move";
		hh("&#x00d7;", 1, 200).ttip = Calendar._TT["CLOSE"];
	}

	row = Calendar.createElement("tr", thead);
	row.className = "headrow";

	this._nav_py = hh("&#x00ab;", 1, -2);
	this._nav_py.ttip = Calendar._TT["PREV_YEAR"];

	this._nav_pm = hh("&#x2039;", 1, -1);
	this._nav_pm.ttip = Calendar._TT["PREV_MONTH"];

	this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0);
	this._nav_now.ttip = Calendar._TT["GO_TODAY"];

	this._nav_nm = hh("&#x203a;", 1, 1);
	this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"];

	this._nav_ny = hh("&#x00bb;", 1, 2);
	this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"];

	// day names
	row = Calendar.createElement("tr", thead);
	row.className = "daynames";
	if (this.weekNumbers) {
		cell = Calendar.createElement("td", row);
		cell.className = "name wn";
		cell.innerHTML = Calendar._TT["WK"];
	}
	for (var i = 7; i > 0; --i) {
		cell = Calendar.createElement("td", row);
		if (!i) {
			cell.navtype = 100;
			cell.calendar = this;
			Calendar._add_evs(cell);
		}
	}
	this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild;
	this._displayWeekdays();

	var tbody = Calendar.createElement("tbody", table);
	this.tbody = tbody;

	for (i = 6; i > 0; --i) {
		row = Calendar.createElement("tr", tbody);
		if (this.weekNumbers) {
			cell = Calendar.createElement("td", row);
		}
		for (var j = 7; j > 0; --j) {
			cell = Calendar.createElement("td", row);
			cell.calendar = this;
			Calendar._add_evs(cell);
		}
	}

	if (this.showsTime) {
		row = Calendar.createElement("tr", tbody);
		row.className = "time";

		cell = Calendar.createElement("td", row);
		cell.className = "time";
		cell.colSpan = 2;
		cell.innerHTML = Calendar._TT["TIME"] || "&nbsp;";

		cell = Calendar.createElement("td", row);
		cell.className = "time";
		cell.colSpan = this.weekNumbers ? 4 : 3;

		(function(){
			function makeTimePart(className, init, range_start, range_end) {
				var part = Calendar.createElement("span", cell);
				part.className = className;
				part.innerHTML = init;
				part.calendar = cal;
				part.ttip = Calendar._TT["TIME_PART"];
				part.navtype = 50;
				part._range = [];
				if (typeof range_start != "number")
					part._range = range_start;
				else {
					for (var i = range_start; i <= range_end; ++i) {
						var txt;
						if (i < 10 && range_end >= 10) txt = '0' + i;
						else txt = '' + i;
						part._range[part._range.length] = txt;
					}
				}
				Calendar._add_evs(part);
				return part;
			};
			var hrs = cal.date.getHours();
			var mins = cal.date.getMinutes();
			var t12 = !cal.time24;
			var pm = (hrs > 12);
			if (t12 && pm) hrs -= 12;
			var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23);
			var span = Calendar.createElement("span", cell);
			span.innerHTML = ":";
			span.className = "colon";
			var M = makeTimePart("minute", mins, 0, 59);
			var AP = null;
			cell = Calendar.createElement("td", row);
			cell.className = "time";
			cell.colSpan = 2;
			if (t12)
				AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]);
			else
				cell.innerHTML = "&nbsp;";

			cal.onSetTime = function() {
				var pm, hrs = this.date.getHours(),
					mins = this.date.getMinutes();
				if (t12) {
					pm = (hrs >= 12);
					if (pm) hrs -= 12;
					if (hrs == 0) hrs = 12;
					AP.innerHTML = pm ? "pm" : "am";
				}
				H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs;
				M.innerHTML = (mins < 10) ? ("0" + mins) : mins;
			};

			cal.onUpdateTime = function() {
				var date = this.date;
				var h = parseInt(H.innerHTML, 10);
				if (t12) {
					if (/pm/i.test(AP.innerHTML) && h < 12)
						h += 12;
					else if (/am/i.test(AP.innerHTML) && h == 12)
						h = 0;
				}
				var d = date.getDate();
				var m = date.getMonth();
				var y = date.getFullYear();
				date.setHours(h);
				date.setMinutes(parseInt(M.innerHTML, 10));
				date.setFullYear(y);
				date.setMonth(m);
				date.setDate(d);
				this.dateClicked = false;
				this.callHandler();
			};
		})();
	} else {
		this.onSetTime = this.onUpdateTime = function() {};
	}

	var tfoot = Calendar.createElement("tfoot", table);

	row = Calendar.createElement("tr", tfoot);
	row.className = "footrow";

	cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300);
	cell.className = "ttip";
	if (this.isPopup) {
		cell.ttip = Calendar._TT["DRAG_TO_MOVE"];
		cell.style.cursor = "move";
	}
	this.tooltips = cell;

	div = Calendar.createElement("div", this.element);
	this.monthsCombo = div;
	div.className = "combo";
	for (i = 0; i < Calendar._MN.length; ++i) {
		var mn = Calendar.createElement("div");
		mn.className = Calendar.is_ie ? "label-IEfix" : "label";
		mn.month = i;
		mn.innerHTML = Calendar._SMN[i];
		div.appendChild(mn);
	}

	div = Calendar.createElement("div", this.element);
	this.yearsCombo = div;
	div.className = "combo";
	for (i = 12; i > 0; --i) {
		var yr = Calendar.createElement("div");
		yr.className = Calendar.is_ie ? "label-IEfix" : "label";
		div.appendChild(yr);
	}

	this._init(this.firstDayOfWeek, this.date);
	parent.appendChild(this.element);
};

/** keyboard navigation, only for popup calendars */
Calendar._keyEvent = function(ev) {
	var cal = window._dynarch_popupCalendar;
	if (!cal || cal.multiple)
		return false;
	(Calendar.is_ie) && (ev = window.event);
	var act = (Calendar.is_ie || ev.type == "keypress"),
		K = ev.keyCode;
	if (ev.ctrlKey) {
		switch (K) {
		    case 37: // KEY left
			act && Calendar.cellClick(cal._nav_pm);
			break;
		    case 38: // KEY up
			act && Calendar.cellClick(cal._nav_py);
			break;
		    case 39: // KEY right
			act && Calendar.cellClick(cal._nav_nm);
			break;
		    case 40: // KEY down
			act && Calendar.cellClick(cal._nav_ny);
			break;
		    default:
			return false;
		}
	} else switch (K) {
	    case 32: // KEY space (now)
		Calendar.cellClick(cal._nav_now);
		break;
	    case 27: // KEY esc
		act && cal.callCloseHandler();
		break;
	    case 37: // KEY left
	    case 38: // KEY up
	    case 39: // KEY right
	    case 40: // KEY down
		if (act) {
			var prev, x, y, ne, el, step;
			prev = K == 37 || K == 38;
			step = (K == 37 || K == 39) ? 1 : 7;
			function setVars() {
				el = cal.currentDateEl;
				var p = el.pos;
				x = p & 15;
				y = p >> 4;
				ne = cal.ar_days[y][x];
			};setVars();
			function prevMonth() {
				var date = new Date(cal.date);
				date.setDate(date.getDate() - step);
				cal.setDate(date);
			};
			function nextMonth() {
				var date = new Date(cal.date);
				date.setDate(date.getDate() + step);
				cal.setDate(date);
			};
			while (1) {
				switch (K) {
				    case 37: // KEY left
					if (--x >= 0)
						ne = cal.ar_days[y][x];
					else {
						x = 6;
						K = 38;
						continue;
					}
					break;
				    case 38: // KEY up
					if (--y >= 0)
						ne = cal.ar_days[y][x];
					else {
						prevMonth();
						setVars();
					}
					break;
				    case 39: // KEY right
					if (++x < 7)
						ne = cal.ar_days[y][x];
					else {
						x = 0;
						K = 40;
						continue;
					}
					break;
				    case 40: // KEY down
					if (++y < cal.ar_days.length)
						ne = cal.ar_days[y][x];
					else {
						nextMonth();
						setVars();
					}
					break;
				}
				break;
			}
			if (ne) {
				if (!ne.disabled)
					Calendar.cellClick(ne);
				else if (prev)
					prevMonth();
				else
					nextMonth();
			}
		}
		break;
	    case 13: // KEY enter
		if (act)
			Calendar.cellClick(cal.currentDateEl, ev);
		break;
	    default:
		return false;
	}
	return Calendar.stopEvent(ev);
};

/**
 *  (RE)Initializes the calendar to the given date and firstDayOfWeek
 */
Calendar.prototype._init = function (firstDayOfWeek, date) {
	var today = new Date(),
		TY = today.getFullYear(),
		TM = today.getMonth(),
		TD = today.getDate();
	this.table.style.visibility = "hidden";
	var year = date.getFullYear();
	if (year < this.minYear) {
		year = this.minYear;
		date.setFullYear(year);
	} else if (year > this.maxYear) {
		year = this.maxYear;
		date.setFullYear(year);
	}
	this.firstDayOfWeek = firstDayOfWeek;
	this.date = new Date(date);
	var month = date.getMonth();
	var mday = date.getDate();
	var no_days = date.getMonthDays();

	// calendar voodoo for computing the first day that would actually be
	// displayed in the calendar, even if it's from the previous month.
	// WARNING: this is magic. ;-)
	date.setDate(1);
	var day1 = (date.getDay() - this.firstDayOfWeek) % 7;
	if (day1 < 0)
		day1 += 7;
	date.setDate(-day1);
	date.setDate(date.getDate() + 1);

	var row = this.tbody.firstChild;
	var MN = Calendar._SMN[month];
	var ar_days = this.ar_days = new Array();
	var weekend = Calendar._TT["WEEKEND"];
	var dates = this.multiple ? (this.datesCells = {}) : null;
	for (var i = 0; i < 6; ++i, row = row.nextSibling) {
		var cell = row.firstChild;
		if (this.weekNumbers) {
			cell.className = "day wn";
			cell.innerHTML = date.getWeekNumber();
			cell = cell.nextSibling;
		}
		row.className = "daysrow";
		var hasdays = false, iday, dpos = ar_days[i] = [];
		for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) {
			iday = date.getDate();
			var wday = date.getDay();
			cell.className = "day";
			cell.pos = i << 4 | j;
			dpos[j] = cell;
			var current_month = (date.getMonth() == month);
			if (!current_month) {
				if (this.showsOtherMonths) {
					cell.className += " othermonth";
					cell.otherMonth = true;
				} else {
					cell.className = "emptycell";
					cell.innerHTML = "&nbsp;";
					cell.disabled = true;
					continue;
				}
			} else {
				cell.otherMonth = false;
				hasdays = true;
			}
			cell.disabled = false;
			cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday;
			if (dates)
				dates[date.print("%Y%m%d")] = cell;
			if (this.getDateStatus) {
				var status = this.getDateStatus(date, year, month, iday);
				if (this.getDateToolTip) {
					var toolTip = this.getDateToolTip(date, year, month, iday);
					if (toolTip)
						cell.title = toolTip;
				}
				if (status === true) {
					cell.className += " disabled";
					cell.disabled = true;
				} else {
					if (/disabled/i.test(status))
						cell.disabled = true;
					cell.className += " " + status;
				}
			}
			if (!cell.disabled) {
				cell.caldate = new Date(date);
				cell.ttip = "_";
				if (!this.multiple && current_month
				    && iday == mday && this.hiliteToday) {
					cell.className += " selected";
					this.currentDateEl = cell;
				}
				if (date.getFullYear() == TY &&
				    date.getMonth() == TM &&
				    iday == TD) {
					cell.className += " today";
					cell.ttip += Calendar._TT["PART_TODAY"];
				}
				if (weekend.indexOf(wday.toString()) != -1)
					cell.className += cell.otherMonth ? " oweekend" : " weekend";
			}
		}
		if (!(hasdays || this.showsOtherMonths))
			row.className = "emptyrow";
	}
	this.title.innerHTML = Calendar._MN[month] + ", " + year;
	this.onSetTime();
	this.table.style.visibility = "visible";
	this._initMultipleDates();
	// PROFILE
	// this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms";
};

Calendar.prototype._initMultipleDates = function() {
	if (this.multiple) {
		for (var i in this.multiple) {
			var cell = this.datesCells[i];
			var d = this.multiple[i];
			if (!d)
				continue;
			if (cell)
				cell.className += " selected";
		}
	}
};

Calendar.prototype._toggleMultipleDate = function(date) {
	if (this.multiple) {
		var ds = date.print("%Y%m%d");
		var cell = this.datesCells[ds];
		if (cell) {
			var d = this.multiple[ds];
			if (!d) {
				Calendar.addClass(cell, "selected");
				this.multiple[ds] = date;
			} else {
				Calendar.removeClass(cell, "selected");
				delete this.multiple[ds];
			}
		}
	}
};

Calendar.prototype.setDateToolTipHandler = function (unaryFunction) {
	this.getDateToolTip = unaryFunction;
};

/**
 *  Calls _init function above for going to a certain date (but only if the
 *  date is different than the currently selected one).
 */
Calendar.prototype.setDate = function (date) {
	if (!date.equalsTo(this.date)) {
		this._init(this.firstDayOfWeek, date);
	}
};

/**
 *  Refreshes the calendar.  Useful if the "disabledHandler" function is
 *  dynamic, meaning that the list of disabled date can change at runtime.
 *  Just * call this function if you think that the list of disabled dates
 *  should * change.
 */
Calendar.prototype.refresh = function () {
	this._init(this.firstDayOfWeek, this.date);
};

/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */
Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) {
	this._init(firstDayOfWeek, this.date);
	this._displayWeekdays();
};

/**
 *  Allows customization of what dates are enabled.  The "unaryFunction"
 *  parameter must be a function object that receives the date (as a JS Date
 *  object) and returns a boolean value.  If the returned value is true then
 *  the passed date will be marked as disabled.
 */
Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) {
	this.getDateStatus = unaryFunction;
};

/** Customization of allowed year range for the calendar. */
Calendar.prototype.setRange = function (a, z) {
	this.minYear = a;
	this.maxYear = z;
};

/** Calls the first user handler (selectedHandler). */
Calendar.prototype.callHandler = function () {
	if (this.onSelected) {
		this.onSelected(this, this.date.print(this.dateFormat));
	}
};

/** Calls the second user handler (closeHandler). */
Calendar.prototype.callCloseHandler = function () {
	if (this.onClose) {
		this.onClose(this);
	}
	this.hideShowCovered();
};

/** Removes the calendar object from the DOM tree and destroys it. */
Calendar.prototype.destroy = function () {
	var el = this.element.parentNode;
	el.removeChild(this.element);
	Calendar._C = null;
	window._dynarch_popupCalendar = null;
};

/**
 *  Moves the calendar element to a different section in the DOM tree (changes
 *  its parent).
 */
Calendar.prototype.reparent = function (new_parent) {
	var el = this.element;
	el.parentNode.removeChild(el);
	new_parent.appendChild(el);
};

// This gets called when the user presses a mouse button anywhere in the
// document, if the calendar is shown.  If the click was outside the open
// calendar this function closes it.
Calendar._checkCalendar = function(ev) {
	var calendar = window._dynarch_popupCalendar;
	if (!calendar) {
		return false;
	}
	var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev);
	for (; el != null && el != calendar.element; el = el.parentNode);
	if (el == null) {
		// calls closeHandler which should hide the calendar.
		window._dynarch_popupCalendar.callCloseHandler();
		return Calendar.stopEvent(ev);
	}
};

/** Shows the calendar. */
Calendar.prototype.show = function () {
	var rows = this.table.getElementsByTagName("tr");
	for (var i = rows.length; i > 0;) {
		var row = rows[--i];
		Calendar.removeClass(row, "rowhilite");
		var cells = row.getElementsByTagName("td");
		for (var j = cells.length; j > 0;) {
			var cell = cells[--j];
			Calendar.removeClass(cell, "hilite");
			Calendar.removeClass(cell, "active");
		}
	}
	this.element.style.display = "block";
	this.hidden = false;
	if (this.isPopup) {
		window._dynarch_popupCalendar = this;
		Calendar.addEvent(document, "keydown", Calendar._keyEvent);
		Calendar.addEvent(document, "keypress", Calendar._keyEvent);
		Calendar.addEvent(document, "mousedown", Calendar._checkCalendar);
	}
	this.hideShowCovered();
};

/**
 *  Hides the calendar.  Also removes any "hilite" from the class of any TD
 *  element.
 */
Calendar.prototype.hide = function () {
	if (this.isPopup) {
		Calendar.removeEvent(document, "keydown", Calendar._keyEvent);
		Calendar.removeEvent(document, "keypress", Calendar._keyEvent);
		Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar);
	}
	this.element.style.display = "none";
	this.hidden = true;
	this.hideShowCovered();
};

/**
 *  Shows the calendar at a given absolute position (beware that, depending on
 *  the calendar element style -- position property -- this might be relative
 *  to the parent's containing rectangle).
 */
Calendar.prototype.showAt = function (x, y) {
	var s = this.element.style;
	s.left = x + "px";
	s.top = y + "px";
	this.show();
};

/** Shows the calendar near a given element. */
Calendar.prototype.showAtElement = function (el, opts) {
	var self = this;
	var p = Calendar.getAbsolutePos(el);
	if (!opts || typeof opts != "string") {
		this.showAt(p.x, p.y + el.offsetHeight);
		return true;
	}
	function fixPosition(box) {
		if (box.x < 0)
			box.x = 0;
		if (box.y < 0)
			box.y = 0;
		var cp = document.createElement("div");
		var s = cp.style;
		s.position = "absolute";
		s.right = s.bottom = s.width = s.height = "0px";
		document.body.appendChild(cp);
		var br = Calendar.getAbsolutePos(cp);
		document.body.removeChild(cp);
		if (Calendar.is_ie) {
			br.y += document.body.scrollTop;
			br.x += document.body.scrollLeft;
		} else {
			br.y += window.scrollY;
			br.x += window.scrollX;
		}
		var tmp = box.x + box.width - br.x;
		if (tmp > 0) box.x -= tmp;
		tmp = box.y + box.height - br.y;
		if (tmp > 0) box.y -= tmp;
	};
	this.element.style.display = "block";
	Calendar.continuation_for_the_fucking_khtml_browser = function() {
		var w = self.element.offsetWidth;
		var h = self.element.offsetHeight;
		self.element.style.display = "none";
		var valign = opts.substr(0, 1);
		var halign = "l";
		if (opts.length > 1) {
			halign = opts.substr(1, 1);
		}
		// vertical alignment
		switch (valign) {
		    case "T": p.y -= h; break;
		    case "B": p.y += el.offsetHeight; break;
		    case "C": p.y += (el.offsetHeight - h) / 2; break;
		    case "t": p.y += el.offsetHeight - h; break;
		    case "b": break; // already there
		}
		// horizontal alignment
		switch (halign) {
		    case "L": p.x -= w; break;
		    case "R": p.x += el.offsetWidth; break;
		    case "C": p.x += (el.offsetWidth - w) / 2; break;
		    case "l": p.x += el.offsetWidth - w; break;
		    case "r": break; // already there
		}
		p.width = w;
		p.height = h + 40;
		self.monthsCombo.style.display = "none";
		fixPosition(p);
		self.showAt(p.x, p.y);
	};
	if (Calendar.is_khtml)
		setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
	else
		Calendar.continuation_for_the_fucking_khtml_browser();
};

/** Customizes the date format. */
Calendar.prototype.setDateFormat = function (str) {
	this.dateFormat = str;
};

/** Customizes the tooltip date format. */
Calendar.prototype.setTtDateFormat = function (str) {
	this.ttDateFormat = str;
};

/**
 *  Tries to identify the date represented in a string.  If successful it also
 *  calls this.setDate which moves the calendar to the given date.
 */
Calendar.prototype.parseDate = function(str, fmt) {
	if (!fmt)
		fmt = this.dateFormat;
	this.setDate(Date.parseDate(str, fmt));
};

Calendar.prototype.hideShowCovered = function () {
	if (!Calendar.is_ie && !Calendar.is_opera)
		return;
	function getVisib(obj){
		var value = obj.style.visibility;
		if (!value) {
			if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
				if (!Calendar.is_khtml)
					value = document.defaultView.
						getComputedStyle(obj, "").getPropertyValue("visibility");
				else
					value = '';
			} else if (obj.currentStyle) { // IE
				value = obj.currentStyle.visibility;
			} else
				value = '';
		}
		return value;
	};

	var tags = new Array("applet", "iframe", "select");
	var el = this.element;

	var p = Calendar.getAbsolutePos(el);
	var EX1 = p.x;
	var EX2 = el.offsetWidth + EX1;
	var EY1 = p.y;
	var EY2 = el.offsetHeight + EY1;

	for (var k = tags.length; k > 0; ) {
		var ar = document.getElementsByTagName(tags[--k]);
		var cc = null;

		for (var i = ar.length; i > 0;) {
			cc = ar[--i];

			p = Calendar.getAbsolutePos(cc);
			var CX1 = p.x;
			var CX2 = cc.offsetWidth + CX1;
			var CY1 = p.y;
			var CY2 = cc.offsetHeight + CY1;

			if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
				if (!cc.__msh_save_visibility) {
					cc.__msh_save_visibility = getVisib(cc);
				}
				cc.style.visibility = cc.__msh_save_visibility;
			} else {
				if (!cc.__msh_save_visibility) {
					cc.__msh_save_visibility = getVisib(cc);
				}
				cc.style.visibility = "hidden";
			}
		}
	}
};

/** Internal function; it displays the bar with the names of the weekday. */
Calendar.prototype._displayWeekdays = function () {
	var fdow = this.firstDayOfWeek;
	var cell = this.firstdayname;
	var weekend = Calendar._TT["WEEKEND"];
	for (var i = 0; i < 7; ++i) {
		cell.className = "day name";
		var realday = (i + fdow) % 7;
		if (i) {
			cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]);
			cell.navtype = 100;
			cell.calendar = this;
			cell.fdow = realday;
			Calendar._add_evs(cell);
		}
		if (weekend.indexOf(realday.toString()) != -1) {
			Calendar.addClass(cell, "weekend");
		}
		cell.innerHTML = Calendar._SDN[(i + fdow) % 7];
		cell = cell.nextSibling;
	}
};

/** Internal function.  Hides all combo boxes that might be displayed. */
Calendar.prototype._hideCombos = function () {
	this.monthsCombo.style.display = "none";
	this.yearsCombo.style.display = "none";
};

/** Internal function.  Starts dragging the element. */
Calendar.prototype._dragStart = function (ev) {
	if (this.dragging) {
		return;
	}
	this.dragging = true;
	var posX;
	var posY;
	if (Calendar.is_ie) {
		posY = window.event.clientY + document.body.scrollTop;
		posX = window.event.clientX + document.body.scrollLeft;
	} else {
		posY = ev.clientY + window.scrollY;
		posX = ev.clientX + window.scrollX;
	}
	var st = this.element.style;
	this.xOffs = posX - parseInt(st.left);
	this.yOffs = posY - parseInt(st.top);
	with (Calendar) {
		addEvent(document, "mousemove", calDragIt);
		addEvent(document, "mouseup", calDragEnd);
	}
};

// BEGIN: DATE OBJECT PATCHES

/** Adds the number of days array to the Date object. */
Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);

/** Constants used for time computations */
Date.SECOND = 1000 /* milliseconds */;
Date.MINUTE = 60 * Date.SECOND;
Date.HOUR   = 60 * Date.MINUTE;
Date.DAY    = 24 * Date.HOUR;
Date.WEEK   =  7 * Date.DAY;

Date.parseDate = function(str, fmt) {
	var today = new Date();
	var y = 0;
	var m = -1;
	var d = 0;
	var a = str.split(/\W+/);
	var b = fmt.match(/%./g);
	var i = 0, j = 0;
	var hr = 0;
	var min = 0;
	for (i = 0; i < a.length; ++i) {
		if (!a[i])
			continue;
		switch (b[i]) {
		    case "%d":
		    case "%e":
			d = parseInt(a[i], 10);
			break;

		    case "%m":
			m = parseInt(a[i], 10) - 1;
			break;

		    case "%Y":
		    case "%y":
			y = parseInt(a[i], 10);
			(y < 100) && (y += (y > 29) ? 1900 : 2000);
			break;

		    case "%b":
		    case "%B":
			for (j = 0; j < 12; ++j) {
				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
			}
			break;

		    case "%H":
		    case "%I":
		    case "%k":
		    case "%l":
			hr = parseInt(a[i], 10);
			break;

		    case "%P":
		    case "%p":
			if (/pm/i.test(a[i]) && hr < 12)
				hr += 12;
			else if (/am/i.test(a[i]) && hr >= 12)
				hr -= 12;
			break;

		    case "%M":
			min = parseInt(a[i], 10);
			break;
		}
	}
	if (isNaN(y)) y = today.getFullYear();
	if (isNaN(m)) m = today.getMonth();
	if (isNaN(d)) d = today.getDate();
	if (isNaN(hr)) hr = today.getHours();
	if (isNaN(min)) min = today.getMinutes();
	if (y != 0 && m != -1 && d != 0)
		return new Date(y, m, d, hr, min, 0);
	y = 0; m = -1; d = 0;
	for (i = 0; i < a.length; ++i) {
		if (a[i].search(/[a-zA-Z]+/) != -1) {
			var t = -1;
			for (j = 0; j < 12; ++j) {
				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
			}
			if (t != -1) {
				if (m != -1) {
					d = m+1;
				}
				m = t;
			}
		} else if (parseInt(a[i], 10) <= 12 && m == -1) {
			m = a[i]-1;
		} else if (parseInt(a[i], 10) > 31 && y == 0) {
			y = parseInt(a[i], 10);
			(y < 100) && (y += (y > 29) ? 1900 : 2000);
		} else if (d == 0) {
			d = a[i];
		}
	}
	if (y == 0)
		y = today.getFullYear();
	if (m != -1 && d != 0)
		return new Date(y, m, d, hr, min, 0);
	return today;
};

/** Returns the number of days in the current month */
Date.prototype.getMonthDays = function(month) {
	var year = this.getFullYear();
	if (typeof month == "undefined") {
		month = this.getMonth();
	}
	if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
		return 29;
	} else {
		return Date._MD[month];
	}
};

/** Returns the number of day in the year. */
Date.prototype.getDayOfYear = function() {
	var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
	var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
	var time = now - then;
	return Math.floor(time / Date.DAY);
};

/** Returns the number of the week in year, as defined in ISO 8601. */
Date.prototype.getWeekNumber = function() {
	var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
	var DoW = d.getDay();
	d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
	var ms = d.valueOf(); // GMT
	d.setMonth(0);
	d.setDate(4); // Thu in Week 1
	return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
};

/** Checks date and time equality */
Date.prototype.equalsTo = function(date) {
	return ((this.getFullYear() == date.getFullYear()) &&
		(this.getMonth() == date.getMonth()) &&
		(this.getDate() == date.getDate()) &&
		(this.getHours() == date.getHours()) &&
		(this.getMinutes() == date.getMinutes()));
};

/** Set only the year, month, date parts (keep existing time) */
Date.prototype.setDateOnly = function(date) {
	var tmp = new Date(date);
	this.setDate(1);
	this.setFullYear(tmp.getFullYear());
	this.setMonth(tmp.getMonth());
	this.setDate(tmp.getDate());
};

/** Prints the date in a string according to the given format. */
Date.prototype.print = function (str) {
	var m = this.getMonth();
	var d = this.getDate();
	var y = this.getFullYear();
	var wn = this.getWeekNumber();
	var w = this.getDay();
	var s = {};
	var hr = this.getHours();
	var pm = (hr >= 12);
	var ir = (pm) ? (hr - 12) : hr;
	var dy = this.getDayOfYear();
	if (ir == 0)
		ir = 12;
	var min = this.getMinutes();
	var sec = this.getSeconds();
	s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N]
	s["%A"] = Calendar._DN[w]; // full weekday name
	s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N]
	s["%B"] = Calendar._MN[m]; // full month name
	// FIXME: %c : preferred date and time representation for the current locale
	s["%C"] = 1 + Math.floor(y / 100); // the century number
	s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
	s["%e"] = d; // the day of the month (range 1 to 31)
	// FIXME: %D : american date style: %m/%d/%y
	// FIXME: %E, %F, %G, %g, %h (man strftime)
	s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
	s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
	s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
	s["%k"] = hr;		// hour, range 0 to 23 (24h format)
	s["%l"] = ir;		// hour, range 1 to 12 (12h format)
	s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
	s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
	s["%n"] = "\n";		// a newline character
	s["%p"] = pm ? "PM" : "AM";
	s["%P"] = pm ? "pm" : "am";
	// FIXME: %r : the time in am/pm notation %I:%M:%S %p
	// FIXME: %R : the time in 24-hour notation %H:%M
	s["%s"] = Math.floor(this.getTime() / 1000);
	s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
	s["%t"] = "\t";		// a tab character
	// FIXME: %T : the time in 24-hour notation (%H:%M:%S)
	s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
	s["%u"] = w + 1;	// the day of the week (range 1 to 7, 1 = MON)
	s["%w"] = w;		// the day of the week (range 0 to 6, 0 = SUN)
	// FIXME: %x : preferred date representation for the current locale without the time
	// FIXME: %X : preferred time representation for the current locale without the date
	s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
	s["%Y"] = y;		// year with the century
	s["%%"] = "%";		// a literal '%' character

	var re = /%./g;
	if (!Calendar.is_ie5 && !Calendar.is_khtml)
		return str.replace(re, function (par) { return s[par] || par; });

	var a = str.match(re);
	for (var i = 0; i < a.length; i++) {
		var tmp = s[a[i]];
		if (tmp) {
			re = new RegExp(a[i], 'g');
			str = str.replace(re, tmp);
		}
	}

	return str;
};

Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear;
Date.prototype.setFullYear = function(y) {
	var d = new Date(this);
	d.__msh_oldSetFullYear(y);
	if (d.getMonth() != this.getMonth())
		this.setDate(28);
	this.__msh_oldSetFullYear(y);
};

// END: DATE OBJECT PATCHES


// global object that remembers the calendar
window._dynarch_popupCalendar = null;

function showMessageClearBasket(){
	shop.cuteQuestion.addMessage('', languageSheet.lblClearBasket, languageSheet.lblContinue, languageSheet.lblCancel, 1, "clear", shop.url + '/ecommerce/basket/updateBasket.cfm', 0,0);
}

function validateGiftCode(giftCodeCheck, giftCodeField)
{
	var url = shop.url+'/ajaxTemplates/common/checkoutActions.cfm?action=giftCode';
	var useGiftCodeCheck = document.getElementById(giftCodeCheck);
	var giftCode = document.getElementById(giftCodeField).value;
	var useGiftCode = 0;
	if(useGiftCodeCheck && useGiftCodeCheck.checked) useGiftCode = 1;
	
	url += '&useGiftCode='+useGiftCode;
	url += '&giftCode='+giftCode;
	
	var responseText = ajaxLoadSync(url);
	
	var objResponse = eval('(' + responseText + ')');
	
	if( objResponse.ERROR )
	{
		switch (objResponse.ERROR)
		{
			case 'TLG1201':
				shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblCodeNotFound,0,0,messageWidth,messageHeight);
				break;
			case 'TLG1202':
				shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblErrorReadingCodes,0,0,messageWidth,messageHeight);
				break;
			case 'TLG1203':
				shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblCodeInUse,0,0,messageWidth,messageHeight);
				break;
			case 'TLG1204':
				shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblCodeInOtherSession,0,0,messageWidth,messageHeight);
				break;
		}
	}
	else
	{
		ajaxLoad(shop.url+'/ajaxTemplates/basket/giftCode.cfm', $('giftCode') );
		//reloadCheckoutBasket();
		
		if(globalStep == 1)	reloadCheckoutBasket();
		else	loadBasketStep(3,1);
	}
}

function selectPaymentMethod(value){
	ajaxLoad(shop.url+'/ajaxTemplates/common/checkoutActions.cfm?action=payment&paymentMethodId='+value, null, 'reloadBasket()');
}

function changeSelectPaymentMethod(obj, nameClass, nameClassSelected){
	$$('.'+nameClassSelected).each(function(el){el.removeClass(nameClassSelected);}); 
	$(obj).className = nameClass + " "+ nameClassSelected;
}

function getCountries(divId, countryId, subCountryId, level)
{
		selectCountryShippingMethod(0);
		if(countryId.length > 0)
		{
			var imageLoading = "<img src='" + shop.templatePath + "/images/smallLoading.gif'>"
			ajaxLoad(shop.url + '/ajaxTemplates/basket/checkoutScreen/subCountriesAjax.cfm?countryId='+countryId+'&subCountryId='+subCountryId+'&level='+(parseInt(level))+'&addToSession=1', $(divId), 'reloadBasket()', imageLoading);
		}
		else{
			selectCountryShippingMethod(0);
			$(divId).innerHTML = "";
			if($('shippingMethodDiv'))$('shippingMethodDiv').innerHTML = "";
		}
}

function getSubCountries(divId, countryId, subCountryId, level)
{
		if(checkSessionCountries() == false){window.location.href = shop.url + '/ecommerce/basket/basket.cfm'; return;}
		if(subCountryId.length > 0)
		{
			var imageLoading = "<img src='" + shop.templatePath + "/images/smallLoading.gif'>"
			var result = checkShippingMethod(countryId, subCountryId);
			if(result == false){ 
				ajaxLoad(shop.url + '/ajaxTemplates/basket/checkoutScreen/subCountriesAjax.cfm?countryId='+countryId+'&subCountryId='+subCountryId+'&level='+level+'&addToSession=1' , $(divId), 'reloadBasket()', imageLoading);
				if($('shippingMethodDiv'))$('shippingMethodDiv').innerHTML = "";
			}
			else{
				ajaxLoad(shop.url + '/ajaxTemplates/basket/checkoutScreen/subCountriesAjax.cfm?countryId='+countryId+'&subCountryId='+subCountryId+'&level='+level+'&addToSession=1' ,  $(divId),  'reloadBasket()', imageLoading);
			}
		}
		else{
			$(divId).innerHTML = "";
			if($('shippingMethodDiv'))$('shippingMethodDiv').innerHTML = "";
			selectCountryShippingMethod(0);
		}
}

function sameHeightBasket(){
	if($('mainCenterContent') && $('mainMiddleContentInfo') && $('tableCategoriesMenu') && $('tableCategoriesMenu') && $('colRightContent')){
		var heightCenter = $('mainCenterContent').offsetHeight + $('mainMiddleContentInfo').offsetHeight;
		if(heightCenter > $('tableCategoriesMenu').offsetHeight){
			$('tableCategoriesMenu').style.height = heightCenter + 'px';
			$('colRightContent').style.height = (heightCenter - $('colRightContent').offsetTop)  + 'px';
		}
	}
}


function reloadCheckoutBasket(){
	ajaxLoad(shop.url+'/ajaxTemplates/basket/basket.cfm?editBasket=0', $('totalBasket'), 'reloadMiniBasket();');
}


function selectCountryShippingMethod(value){
	ajaxLoad(shop.url+'/ajaxTemplates/common/checkoutActions.cfm?action=shipping&shippingMethodId='+value, null, '');
	ajaxLoad(shop.url+'/ajaxTemplates/common/checkoutActions.cfm?action=countryShippingMethod&countryShippingMethodId='+value, null, 'reloadBasket()');
}


function selectShippingMethod(value){
	ajaxLoad(shop.url+'/ajaxTemplates/common/checkoutActions.cfm?action=shipping&shippingMethodId='+value, null, 'reloadBasket()');
}


function checkSessionCountries(){
	var xmlObj = createXMLRequest();
	
	xmlObj.open('GET', shop.url + '/ajaxTemplates/basket/checkoutScreen/checkSessionCountries.cfm?noCache='+getUniqueId(), false);
	xmlObj.send(null);
	if(xmlObj.responseText.indexOf('0') != -1)return false;
	return true;
}

function checkShippingMethod(countryId, subCountryId){
	var xmlObj = createXMLRequest();
	
	xmlObj.open('GET', shop.url + '/ajaxTemplates/basket/checkoutScreen/checkShippingMethod.cfm?countryId='+countryId+'&subCountryId='+subCountryId+'&noCache='+getUniqueId(), false);
	xmlObj.send(null);
	if(xmlObj.responseText.indexOf('0') == 0)return true;
	return false;
}


function changeSelectShippingMethod(obj, nameClass, nameClassSelected){
	$$('.'+nameClassSelected).each(function(el){el.removeClass(nameClassSelected);}); 
	$(obj).className = nameClass + " "+ nameClassSelected;
}

function checkLogin(obj){	
	if(obj){
		if(obj.checked == true)
			setTimeout('requireSignIn(0)', 200);	
		else setTimeout('requireSignIn(1)', 200);
	}
}

function getUniqueId()
{
	var stamp = new Date();
	var id = stamp.getMonth().toString() + stamp.getDay() + stamp.getHours() + stamp.getMinutes() + stamp.getSeconds() + stamp.getMilliseconds() ;
	return id;
}

function ajaxPost(url, container, postParams, encoding)
{
	var xmlObj = createXMLRequest();
	if( url.indexOf('?') == -1 )
	{
		url += '?noCache=' + getUniqueId();
	}
	else
	{
		url += '&noCache=' + getUniqueId();
	}
	xmlObj.open('POST', url, false);
	if(encoding)
		xmlObj.setRequestHeader('Content-Type', encoding);
	else 
		xmlObj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
		
	xmlObj.send(postParams);
}


function ajaxLoad(url, container, callBack, imageLoading)/*THIS FUNCTION LOADS A PAGE INTO A DIV*/
{
	var xmlObj = createXMLRequest();
	
	if( imageLoading && imageLoading.length > 0 && $(container) )
	{
		container.innerHTML = imageLoading;
	}
	
	xmlObj.onreadystatechange=function(){
			loadPage(xmlObj, container, callBack)
	}
	if( url.indexOf('?') == -1 )
	{
		url += '?noCache=' + getUniqueId();
	}
	else
	{
		url += '&noCache=' + getUniqueId();
	}
	xmlObj.open('GET', url, true)
	xmlObj.send(null)
	return xmlObj;
}

function ajaxLoadSync(url, container)/*THIS FUNCTION LOADS A PAGE INTO A DIV*/
{
	
	var xmlObj = createXMLRequest();
	
	if( url.indexOf('?') == -1 )
	{
		url += '?noCache=' + getUniqueId();
	}
	else
	{
		url += '&noCache=' + getUniqueId();
	}
	
	xmlObj.open('GET', url, false);
	xmlObj.send(null);
	
	if(container)container.innerHTML=xmlObj.responseText;
	return xmlObj.responseText;
}

function loadPage(request, container, callBack){
	if(request.readyState == 4)
	{
		if (container){container.innerHTML=request.responseText;}
		if(callBack){eval(callBack);}
	}
}

function ajaxCancel(obj){
	obj.abort();
}

function createXMLRequest(){
var XMLObj;
if(window.XMLHttpRequest) {XMLObj = new XMLHttpRequest()} 
else if(window.ActiveXObject){
	try
	{XMLObj = new ActiveXObject("Msxml2.XMLHTTP")} 
	catch(e){try{XMLObj = new ActiveXObject("Microsoft.XMLHTTP")}catch (e){}}}
else
{
	return false
}
return XMLObj; 
}

function loadAjaxFile(nameFile, nameDiv, callBack, ajaxLoading) {	var div_pointer = $(nameDiv);	ajaxLoad(nameFile,div_pointer,callBack, ajaxLoading);}

var basketTime;var basketDisplay="none";
function initAsyncBasket(mode){	
	if(!mode) mode = 1;
	if(mode == 1 && $('asyncBasketBox')){		
		shop.asyncBasketBox = $('asyncBasketBox');
		shop.asyncBasketBox.transition = new Fx.Tween( shop.asyncBasketBox , 'opacity', {duration:700, transition:new Fx.Transition(Fx.Transitions.linear) } );		
		
	}
	else if(mode == 2 && $('asyncBasketBox')){		
		shop.asyncBasketBox = $('asyncBasketBox');
		shop.asyncBasketBox.slide = new Fx.Slide('asyncBasketBox', {duration:700});
	}
}

function showMiniBasket(){
	hideAsyncBasket();
	if(shop.asyncBasketBox && (shop.asyncBasketBox.style.visibility == "hidden" || shop.asyncBasketBox.style.visibility == "")){
		shop.asyncBasketBox.transition.start('opacity',0,1);
		basketTime = setTimeout("hideAsyncBasketInShow()", 4000);
	}
}

function showMiniBasketSlide(){
	//hideAsyncBasketSlide();
	if(shop.asyncBasketBox && shop.asyncBasketBox.slide && !(shop.asyncBasketBox.slide.open)){
		shop.asyncBasketBox.slide.toggle();
		basketTime = setTimeout("hideAsyncBasketSlide()", 4000);
	}
}

function hideAsyncBasketSlide(){
	if(shop.asyncBasketBox && shop.asyncBasketBox.slide && shop.asyncBasketBox.slide.open){
		clearTimeout(basketTime);
		shop.asyncBasketBox.slide.toggle();
	}
}

function hideAsyncBasketInShow(){	
	if(shop.asyncBasketBox && shop.asyncBasketBox.style.visibility == "visible"){
		clearTimeout(basketTime);
		shop.asyncBasketBox.transition.start('opacity',1,0);
	}
}

function hideAsyncBasket(){
	if(shop.asyncBasketBox && shop.asyncBasketBox.style.visibility == "visible"){
		clearTimeout(basketTime);
		shop.asyncBasketBox.transition.start('opacity',1,0);
	}
}

function hideOrCloseAsyncBasket(obj){
	var elements = obj.getParents();
	var findShadowbox = false;
	for(var i=0;i<elements.length && !findShadowbox;i++){
		var el = elements[i];
			if(el.id.search("shadowbox")){
				findShadowbox = true;
			}
	}
	if(findShadowbox) Shadowbox.close();
	else hideAsyncBasket();
}

var smallLoginTime;var smallLoginDisplay="none";
function initSmallLogin(mode){	
	if(!mode) mode = 1;
	if(mode == 1 && $('smallLoginBox')){		
		shop.smallLoginBox = $('smallLoginBox');
		shop.smallLoginBox.transition = new Fx.Tween( shop.smallLoginBox , 'opacity', {duration:700, transition:new Fx.Transition(Fx.Transitions.linear) } );		
		
	}
	else if(mode == 2 && $('smallLoginBox')){		
		shop.smallLoginBox = $('smallLoginBox');
		shop.smallLoginBox.slide = new Fx.Slide('smallLoginBox', {duration:700});
	}
}


function showSmallLogin(){
	//hideSmallLogin();
	if(shop.smallLoginBox && (shop.smallLoginBox.style.visibility == "hidden" || shop.smallLoginBox.style.visibility == "")){
		shop.smallLoginBox.transition.start('opacity',0,1);
		smallLoginTime = setTimeout("hideSmallLoginInShow()", 4000);
	}
}

function hideSmallLoginInShow(){	
	if(shop.smallLoginBox && shop.smallLoginBox.style.visibility == "visible"){
		clearTimeout(smallLoginTime);
		shop.smallLoginBox.transition.start('opacity',1,0);
	}
}

function hideSmallLogin(){
	if(shop.smallLoginBox && shop.smallLoginBox.style.visibility == "visible"){
		clearTimeout(smallLoginTime);
		shop.smallLoginBox.transition.start('opacity',1,0);
	}
}

function stopHideSmallLogin(){
	clearTimeout(smallLoginTime);
}

function showSmallLoginSlide(){
	//hideAsyncBasketSlide();
	if(shop.smallLoginBox && shop.smallLoginBox.slide && !(shop.smallLoginBox.slide.open)){
		shop.smallLoginBox.slide.toggle();
		smallLoginTime = setTimeout("hideSmallLoginSlide()", 4000);
	}
}

function hideSmallLoginSlide(){
	if(shop.smallLoginBox && shop.smallLoginBox.slide && shop.smallLoginBox.slide.open){
		clearTimeout(smallLoginTime);
		shop.smallLoginBox.slide.toggle();
	}
}




$(window).addEvent('click', function(){ hideAsyncBasket(); hideAsyncBasketSlide();  /*hideSmallLogin(); hideSmallLoginSlide();*/ } );

var interval_IDH = new Array();
var interval_IDV = new Array();
var arrMaxHeight = new Array();
var arrMaxHeightContent = new Array();
var arrMaxWidth = new Array();
var arrMaxWidthContent = new Array();

function loadContent(nameFile, nameDiv, callBack, ajaxLoading) {	
	if(ajaxLoading != "")
		ajaxLoading = "<img src='" + shop.templatePath + "/images/"+ajaxLoading+"'>";	
	if($(nameDiv+'Floater')){
		$(nameDiv+'Floater').style.top = 30+ (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + 'px';	
		callBack = callBack + ';createOverlay()';
	}
	if(displayKeyboard && displayKeyboard == true){callBack = callBack + ';initKeyboard()';}
	
	loadAjaxFile(nameFile, nameDiv, callBack, ajaxLoading);
}

function closeContent(){	
	$('informationBox').innerHTML = '';	$('informationBox').style.visibility = 'hidden';
	deleteOverlay();
}

function submitForm(form, divId, callBack, imageLoading){	
	if(imageLoading)
		document.getElementById(divId).innerHTML = "<img src='" + shop.templatePath + "/images/"+imageLoading+"'>";	
	
	Spry.Utils.submitForm(form, function(req){
																			 document.getElementById(divId).innerHTML = req.xhRequest.responseText; 
																			 eval(callBack);
																			 } );
}
function initScrollH(step, divId){	
	getWidthItem(divId);	
	interval_IDH[divId] = setInterval('startScrollH("'+divId+'",'+step+');',15);
}
function startScrollH(divID, step){	
	var the_style = getStyleObject(divID);
	if (the_style){
		if(the_style.left != "")
			var current_left = parseInt(the_style.left);
		else 
			var current_left = 0; 

		var new_left = current_left + step;
		if(step > 0 && current_left < 0 ){
			if (document.layers) the_style.left = new_left;
			else the_style.left = new_left + "px";
		}
		if(step < 0 && current_left >= (-arrMaxWidth[divID] + (arrMaxWidthContent[divID]))){
			if (document.layers) the_style.left = new_left;
			else the_style.left = new_left + "px";
		}
	}
}

function stopScrollH(divId){
	clearInterval(interval_IDH[divId]);
}


function initScrollV(step, divId){
	getHeightItem(divId);	
	interval_IDV[divId] = setInterval('startScrollV("'+divId+'",'+(step)+');',15);
}

function startScrollV(divID, step){
	var the_style = getStyleObject(divID);
	if (the_style){
		if(the_style.top!= "")
			var current_top = parseInt(the_style.top);
		else var current_top = 0;
		
		var new_top = current_top + step;
		if(step > 0 && current_top < 0 ){
			if (document.layers) the_style.top = new_top;
			else the_style.top = new_top + "px";
		}
		if(step < 0 && current_top >= (-arrMaxHeight[divID] + (arrMaxHeightContent[divID]))){
			if (document.layers) the_style.top = new_top;
			else the_style.top = new_top + "px";
		}
	}
}

function stopScrollV(divId){
	clearInterval(interval_IDV[divId]);
}

function changeClass(obj, nameClass, nameClass2){	
	if(obj.className == nameClass) 
		obj.className = nameClass2;	
	else obj.className = nameClass;
}

function restartShadowbox(){Shadowbox.setup(); }

function getStyleObject(objectId) {  
	if(document.getElementById && document.getElementById(objectId)) {
		return document.getElementById(objectId).style;  
	}
	else if (document.all && document.all(objectId)) {
		return document.all(objectId).style;
	}
	else if (document.layers && document.layers[objectId]){
		return document.layers[objectId];
	} 
	else{return false;}
}

function getWidthItem(id){
	if(id && document.getElementById("menuTabsTableVertical"+id) && document.getElementById("menuTabsVertical"+id)){
		if(document.getElementById("menuTabsTableVertical"+id)){
			arrMaxWidth[id] = document.getElementById("menuTabsTableVertical"+id).offsetWidth;
		}
		if(document.getElementById("menuTabsVertical"+id)){
			arrMaxWidthContent[id] = document.getElementById("menuTabsVertical"+id).style.width;
			arrMaxWidthContent[id] = parseInt(arrMaxWidthContent[id].replace("px", ""));
		}
	}
	else if(id && document.getElementById(id) && document.getElementById(id+"Content")){
		if(document.getElementById(id+"Content")){
			arrMaxWidth[id] = document.getElementById(id+"Content").offsetWidth;
		}
		if(document.getElementById(id)){
			arrMaxWidthContent[id] = document.getElementById(id).offsetWidth;
		}
	}
}

function getHeightItem(id){
	if(id && document.getElementById("menuTabsTableVertical"+id) && document.getElementById("menuTabsVertical"+id)){
		if(document.getElementById("menuTabsTableVertical"+id)){
			arrMaxHeight[id] = document.getElementById("menuTabsTableVertical"+id).offsetHeight;
		}
		if(document.getElementById("menuTabsVertical"+id)){
			arrMaxHeightContent[id] = document.getElementById("menuTabsVertical"+id).style.height;
			arrMaxHeightContent[id] = parseInt(arrMaxHeightContent[id].replace("px", ""));
		}
	}
	else if(id && document.getElementById(id) && document.getElementById(id+"Content")){
		if(document.getElementById(id+"Content")){
			arrMaxHeight[id] = document.getElementById(id+"Content").offsetHeight;
		}
		if(document.getElementById(id)){
			arrMaxHeightContent[id] = document.getElementById(id).offsetHeight;
		}
	}
}


function cuteAlert(){this.timeOut = null;	this.showing = false;	this.messageQueue = new Array();	this.addMessage = function(title, content, image, timeout, width, height){	this.messageQueue.push( {title:title, content:content, image:image, timeout:timeout, width:width, height:height} );	if(!this.showing)this.showMessage();};	this.showMessage = function(){	if(this.messageQueue.length)	{this.showing = true;var message = this.messageQueue.shift();document.getElementById('alertMessage').innerHTML = message.content;if(!message.width) message.width = messageWidth;if(!message.height) message.height = messageHeight;Shadowbox.open({	player:     'html',	content:    $('alertBox').innerHTML,	title: 	message.title,	width:      message.width,	height: message.height},{	animate: false,	onClose: shop.cuteAlert.closeMessage()});if(message.timeout && message.timeout > 0){	var self = this;	this.timeOut = setTimeout(function(){ self.closeMessage()}, message.timeout);}	}	else	{this.showing = false;	}};	this.clear = function(){	this.messageQueue = new Array();	clearTimeout(this.timeOut);};	this.closeMessage = function(){	clearTimeout(this.timeOut);	shop.alertBox.transition.start('opacity',1,0);	var self = this;	setTimeout(function(){self.showMessage();},700);};}

function cuteQuestion(){this.timeOut = null;	this.showing = false;	this.messageQueue = new Array();	this.addMessage = function(title, content, textButtonOK, textButtonKO, positionOK, actionNameOK, actionForm, image, timeout){	this.messageQueue.push( {title:title, content:content, textButtonOK:textButtonOK, textButtonKO:textButtonKO, positionOK:positionOK, actionNameOK:actionNameOK, actionForm:actionForm, image:image, timeout:timeout} );	if(!this.showing)this.showMessage();};	this.showMessage = function(){	if(this.messageQueue.length)	{this.showing = true;var message = this.messageQueue.shift();positionOK = message.positionOK;if(positionOK == 1)positionKO = 2;else positionKO = 1;document.getElementById('questionMessage').innerHTML = message.content;document.getElementById('questionForm'+positionOK).action = message.actionForm;document.getElementById('questionForm'+positionKO).action = "javascript:Shadowbox.close();";document.getElementById('buttonQuestion'+positionOK).value = message.textButtonOK;document.getElementById('buttonQuestion'+positionOK).className = "submitOK";document.getElementById('formActionName'+positionOK).value = message.actionNameOK;document.getElementById('buttonQuestion'+positionKO).value = message.textButtonKO;document.getElementById('buttonQuestion'+positionKO).className = "submitKO";Shadowbox.open({	player:     'html',	content:    $('questionBox').innerHTML,	title: 	message.title,	width:      350,	height: 90},{	animate: false,	onClose: shop.cuteQuestion.closeMessage()});if(message.timeout && message.timeout > 0){	var self = this;	this.timeOut = setTimeout(function(){ self.closeMessage()}, message.timeout);}	}	else	{this.showing = false;	}};	this.clear = function(){	this.messageQueue = new Array();	clearTimeout(this.timeOut);};	this.closeMessage = function(){	clearTimeout(this.timeOut);	shop.questionBox.transition.start('opacity',1,0);	var self = this;	setTimeout(function(){self.showMessage();},700);};}

function initAlert(){shop.alertDiv = $('alertFloater'); if(shop.alertDiv){shop.alertDiv.style.top = '180px';shop.alertBox = $('alertBox');shop.alertBox.transition = new Fx.Tween( shop.alertBox , 'opacity', {duration:700, wait:true , transition:new Fx.Transition(Fx.Transitions.linear) } );shop.cuteAlert = new cuteAlert();}}

function initBuyForms(){
	
	$$('.buyForm').each(function(form){/*getStockByCombination(form);*/showPriceByOption(form);form.addEvent('submit', function(){this.action = shop.url + '/ajaxTemplates/products/addProduct.cfm';if( Spry.Widget.Form.validate(this) ){return Spry.Utils.submitForm(this, validateAddProduct);}});}); }

function getStockByCombination(form){	

	var element;	
	var formParams = new Array();	
	if(form && (form.getAttribute('checkStock') && form.getAttribute('checkStock') == 1) || (form && !form.getAttribute('checkStock'))){
		for (var i = 0; i < form.elements.length; i++ )	{
			element = form.elements[i];
			
			if( element.getAttribute('affectsstock') && element.getAttribute('affectsstock') == 1 ){
				if( element.tagName.toUpperCase() != 'INPUT' || (element.type.toUpperCase() != 'CHECKBOX' && element.checked == true) || (element.type.toUpperCase() == 'HIDDEN' && element.getAttribute('optionType') == 'radioImage') || (element.type.toUpperCase() == 'HIDDEN' && element.getAttribute('optionType') == 'checkImage'))	
				formParams.push(encodeURIComponent(element.name) + '=' + encodeURIComponent(element.value));
			}else if(element.name.toUpperCase() == 'PRODUCTID'){	
				formParams.push(encodeURIComponent(element.name) + '=' + encodeURIComponent(element.value));	
				el = document.getElementById('addProduct'+element.value );	
				el.style.display = 'none';	
				var loadingImage = document.createElement('img');	
				loadingImage.src = shop.templatePath + '/images/smallLoading.gif';	
				loadingImage.id = 'loadingImage' + element.value;	
				el.parentNode.appendChild(loadingImage);
			}	
		}	
		formParams = formParams.join("&");
		var frmOpts = {};	
		frmOpts.method = 'POST';	
		frmOpts.url = shop.url + '/ajaxTemplates/products/checkStockByCombination.cfm';	
		frmOpts.headers = {};	
		frmOpts.headers['Content-Type'] = 'application/x-www-form-urlencoded';	
		frmOpts.postData = formParams;
		Spry.Utils.loadURL('post', frmOpts.url, true, setStockByCombination, frmOpts);	
	}
}
			
function setStockByCombination(response){	
	var objResponse = eval('(' + response.xhRequest.responseText + ')');	
	var productId = parseInt(objResponse.PRODUCTID);	
	var buyButton = document.getElementById('addProduct'+productId );	
	var stock = parseInt(objResponse.STOCK);
	var showValueAtLoad = buyButton.getAttribute('showValueAtLoad');
	
	if(!shop.buyButtonExistentCombination) shop.buyButtonExistentCombination = buyButton.className;
	if( stock == 0 )	{
		if(objResponse.ALLOWRESERVE){	
			buyButton.className = shop.buyButtonExistentCombination;	
			buyButton.value = languageSheet.lblReserve;	
			buyButton.disabled = false;
		}else{	
			buyButton.value = languageSheet.lblInexistentCombination; 
			buyButton.className = shop.buyButtonInexistentCombination;	
			buyButton.disabled = true;
		}
	}	
	else if( stock == -1 )	{
		buyButton.value = languageSheet.lblInexistentCombination;
		buyButton.className = shop.buyButtonInexistentCombination;
		buyButton.disabled = true;	
	}	
	else	{
		buyButton.className = shop.buyButtonExistentCombination;	
		if(showValueAtLoad == 1)buyButton.value = languageSheet.lblBuy;
		buyButton.disabled = false;	
	}
	$('loadingImage' + productId).destroy();	
	buyButton.style.display = ''; 
	reloadStock(stock);
	setProductAvailability(objResponse);
}

function setProductAvailability(objResponse){}


function initFormFields(form){
	if(typeof form == "string")var form = document.getElementById(form);
	Spry.Widget.Form.destroy(form);	
	if(form && form.elements){
		for (var i = 0; i < form.elements.length; i++ )	{	
			element = form.elements[i];
			fieldType = element.getAttribute('fieldType');	
			requiredField = element.getAttribute('requiredField');
			if( element.getAttribute('affectsstock') == 1 )	{
				$(element).addEvent('change', function(){ /*getStockByCombination(form);*/ } );	
			}
			if(fieldType != null)	{
				try{	
					if(requiredField == 1)required = true;	
					else required = false;
				}
				catch(err){ required = false }
				switch(fieldType){	
					case 'natural':element.validate = new Spry.Widget.ValidationTextField(element, "integer", { isRequired:required, validateOn:['blur'], minValue:0 } );break;	
					case 'integer':element.validate = new Spry.Widget.ValidationTextField(element, "integer", { isRequired:required, validateOn:['blur'] } );	break;
					case 'float':element.validate = new Spry.Widget.ValidationTextField(element, "real", { isRequired:required,validateOn:['blur'] } );break;
					case 'email':element.validate = new Spry.Widget.ValidationTextField(element, "email", { isRequired:required,validateOn:["blur"] });break;
					case 'time':element.validate = new Spry.Widget.ValidationTextField(element, "time", { isRequired:required, validateOn:['blur'] , useCharacterMasking:true , format:formats.timeFormat } );break;
					case 'date':element.validate = new Spry.Widget.ValidationTextField(element, "date", { isRequired:required, useCharacterMasking:true, format:formats.dateFormat, hint:formats.dateFormat, validateOn:["blur"]} );Calendar.setup({inputField:element, button:element, formats:formats.dateFormat});break;	
					case 'phone':element.validate = new Spry.Widget.ValidationTextField(element, "integer", { isRequired:required, validateOn:["blur"], allowNegative:false, minValue:10000000 });break;
					case 'zip':element.validate = new Spry.Widget.ValidationTextField(element, "integer", { isRequired:required, validateOn:["blur"], allowNegative:false});break;
					case 'url':element.validate = new Spry.Widget.ValidationTextField(element, "url", { isRequired:required, validateOn:["blur"]});break;
					case 'creditcard':	element.validate = new Spry.Widget.ValidationTextField(element, "zip_code", { isRequired:required, useCharacterMasking:true, pattern:'0000-0000-0000-0000' , validateOn:['blur'] } );break;
					case 'ip':element.validate = new Spry.Widget.ValidationTextField(element, "ip", { isRequired:required, validateOn:['blur'] } );break;	
					case 'shortmemo':element.validate = new Spry.Widget.ValidationTextarea(element, { isRequired:required, validateOn:['blur'] } );break;
					case 'checkbox':var container = element.getAttribute('fieldContainerId');if( container ) container = $(container);else container = $(element);new Spry.Widget.ValidationCheckbox(container,{isRequired:required});break;
					case 'checkbox_group':var container = element.getAttribute('fieldContainerId');var minSelections = element.getAttribute('minSelections');if( container ) container = $(container);else container = $(element);new Spry.Widget.ValidationCheckbox(container,{isRequired:required, minSelections:minSelections,validateOn:["blur", "change"]});break;	
					case 'radio':var container = element.getAttribute('fieldContainerId');if( container ) container = $(container);else container = $(element);new Spry.Widget.ValidationRadio(container,{isRequired:required, validateOn:["blur", "change"]});break;	
					case 'select': 	var noValidValue = element.getAttribute('invalidValue'); var container = element.getAttribute('fieldContainerId'); if( container ) {container = $(container);}	else {container = $(element);} element.validate = new Spry.Widget.ValidationSelect(container,{isRequired:required, validateOn:["blur", "change"], invalidValue:noValidValue});break;
					default:	element.validate = new Spry.Widget.ValidationTextField(element, "none", { isRequired:required, validateOn:['blur'] } );break;	
				}
			}
		}
	}
}

function initQuestion(){shop.questionBox = $('questionBox'); if(shop.questionBox){shop.questionBox.transition = new Fx.Tween( shop.questionBox , 'opacity', {duration:700, wait:true , transition:new Fx.Transition(Fx.Transitions.linear) } );shop.cuteQuestion = new cuteQuestion();}}

function validateAccount(req){
	var objResponse = eval('(' + req.xhRequest.responseText + ')');
	if( parseInt(objResponse.ERROR) ){
		switch (objResponse.ERROR){
			case 'TLG1000':
			case 'TLG1001':shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblUserNotFound,0,0,messageWidth,messageHeight);break;
			case 'TLG1002':shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblDifferentPassword,0,0,messageWidth,messageHeight);break;
			case 'TLG1003':shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblEmailInUse,0,0,messageWidth,messageHeight);break;
			case 'TLG1004':shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblDifferentEmail,0,0,messageWidth,messageHeight);break;
		}
	}else{
		if(objResponse.ACTION == 'customer') {
			if(window.location.href.search('users/user') != -1){ trackPageView('/users/createAccount.cfm'); window.location.href=shop.url+'/ecommerce/users/user.cfm';} //userControlPanel o user.cfm
			else
			{
				loadBasketStep(3, true); reloadSmallLogin(); generateNewCalendar();
				if(objResponse.SIGNIN)
				{
					trackPageView('/checkout/createAccount.cfm');
				}
				else
				{
					trackPageView('/checkout/buyOnly.cfm');
				}
			} //basket.cfm
		}
		if(objResponse.ACTION == 'login')
		{
			if(window.location.href.search('users/user') != -1){window.location.href=shop.url+'/ecommerce/users/user.cfm';} //userControlPanel o user.cfm
			else
			{
				loadBasketStep(2); reloadSmallLogin(); trackPageView('/checkout/loggedIn.cfm');
			} //userInformation.cfm
		}
		
	}
}

function scrollWindowToTop(){
	var myFx = new Fx.Scroll(window);
	
	myFx.toTop();
}

var globalStep = 1;

function loadBasketStep(step, sync){
	
	globalStep = step;
	if(checkBasket() == false){window.location.reload(); return false;}
	
	loadStep = "ajaxLoad('"+shop.url+"/ajaxTemplates/basket/steps.cfm?step="+step+"', $('basketStepsContent'), 'restartShadowbox()'); restartShadowbox();scrollWindowToTop();";
	
	if(displayKeyboard && displayKeyboard == true){loadStep = loadStep + 'initKeyboard();';}
	
	hideAsyncBasket();
	createOverlay();

	if(step == 1){
		newLoadStep = loadStep + "initFormsUser();restartShadowbox();initAsyncBasket();reloadMiniBasket(); deleteOverlay();";
		ajaxLoad(shop.url+'/ajaxTemplates/basket/basket.cfm', $('basketContent'), newLoadStep);
	}
	else if(step == 2){
		callBack = "";
		newLoadStep = loadStep + "initUserInformation();initFormsUser();restartShadowbox();initAsyncBasket();reloadMiniBasket(); deleteOverlay();";
		if(checkSessionInCheckout() == false){
			if(checkUserGroup() == true) {
				if(fileExists(shop.url+'/ajaxTemplates/users/userLogin.cfm?checkout=1')){
					if(checkSession() == false){
						callBack = "ajaxLoad('"+shop.url+"/ajaxTemplates/users/userLogin.cfm?checkout=1', $('basketContent'),\""+newLoadStep+"\");";
					}
					else{
						callBack = "ajaxLoad('"+shop.url+"/ajaxTemplates/users/userRegister.cfm?checkout=1&type="+getUserGroupId()+"', $('basketContent'),\""+newLoadStep+"\");";
					}
				}
				else
					callBack = "ajaxLoad('"+shop.url+"/ajaxTemplates/users/user.cfm?checkout=1', $('basketContent'),\""+newLoadStep+"\");";
			}
			else{window.location.reload();}
			
		}
		else{
			if(checkUserGroup() == true) {
				if(fileExists(shop.url+'/ajaxTemplates/users/userLogin.cfm?checkout=1')){
					if(checkSession() == false){
						callBack = "ajaxLoad('"+shop.url+"/ajaxTemplates/users/userLogin.cfm?checkout=1', $('basketContent'),\""+newLoadStep+"\");";
					}
					else{
						callBack = "ajaxLoad('"+shop.url+"/ajaxTemplates/users/userRegister.cfm?checkout=1&type="+getUserGroupId()+"', $('basketContent'),\""+newLoadStep+"\");";
					}
				}
				else
					callBack = "ajaxLoad('"+shop.url+"/ajaxTemplates/users/user.cfm?checkout=1', $('basketContent'),\""+newLoadStep+"\");";
			}
			else{window.location.reload();}
		}
		if(callBack == ""){callBack = newLoadStep;}
		
		if($('basketForm'))	Spry.Utils.submitForm('basketForm', function(req){eval(callBack)}, {method:'post', url:shop.url+'/ajaxTemplates/basket/updateBasket.cfm'}, false);
		else eval(callBack);
		//if( !checkBasket() ) window.location.reload();

		
		trackPageView('/checkout/userData.cfm');
	}
	else if(step == 3){
		newLoadStep = loadStep + "checkFirstShippingType();checkFirstPaymentSystem();initAsyncBasket();reloadMiniBasket();restartShadowbox(); deleteOverlay();";
		if(!sync) {
		ajaxLoad(shop.url+'/ajaxTemplates/basket/shippingAndPaymentMethod.cfm?editBasket=0', $('basketContent'), newLoadStep);
		} else {
			ajaxLoadSync(shop.url+'/ajaxTemplates/basket/shippingAndPaymentMethod.cfm?editBasket=0', $('basketContent'));			
			eval(newLoadStep);
		}
		
		trackPageView('/checkout/shippingAndPaymentMethod.cfm');
}
	else if(step == 4){
		if(validateOrderComments()){
			newLoadStep = loadStep + "restartShadowbox();initAsyncBasket();reloadMiniBasket(); deleteOverlay();";
			if(shop.numberTotalOfStepsInCheckout == 5){ajaxLoad(shop.url+'/ajaxTemplates/basket/resume.cfm?editBasket=0', $('basketContent'), newLoadStep);}
			else window.location.href = shop.url + '/ecommerce/checkout/checkOrder.cfm';
		}
		else{deleteOverlay();}
	}
	else if(step == 5){
		if(validateOrderComments()){
			window.location.href = shop.url + '/ecommerce/checkout/checkOrder.cfm';
		}
		else{deleteOverlay();}
	}
	
}

function checkUserGroup(){
	if(fileExists(shop.url+'/ajaxTemplates/users/checkUserGroup.cfm') == false) return true;
	else{
		var xmlObj = createXMLRequest();
		xmlObj.open('GET', shop.url + '/ajaxTemplates/users/checkUserGroup.cfm?'+getUniqueId(), false);
		xmlObj.send(null);
		if(xmlObj.responseText.search('OK') != -1){return true;}	
		return false;
	}
}

function getUserGroupId(){
	var url = shop.url + '/ajaxTemplates/users/getUserGroup.cfm?'+getUniqueId();
	var responseText = ajaxLoadSync(url);
	var objResponse = eval('(' + responseText + ')');
	return objResponse.USERGROUPID;
}

function checkFirstShippingType(){
	var url = shop.url + '/ajaxTemplates/basket/getShippingMethod.cfm';
	if(fileExists(url) == true){
		var responseText = ajaxLoadSync(url);
		var objResponse = eval('(' + responseText + ')');
		if(objResponse.SHIPPINGMETHODID != -1){
			if(document.getElementById('shippingMethod')) var objShippingMethod = document.getElementById('shippingMethod');
			else var objShippingMethod = document.getElementById('shippingMethodsItems');
			if(objShippingMethod){
				var objShippingMethodRadios = objShippingMethod.getElementsByTagName('input');
				for(var i=0;i<objShippingMethodRadios.length;i++){
					el = objShippingMethodRadios[i];
					if(el.value == objResponse.SHIPPINGMETHODID){ el.checked = true;}
				}
				updateShippingMethod(objResponse.SHIPPINGMETHODID);
			}
		}
	}
}

function checkFirstPaymentSystem(){
	var url = shop.url + '/ajaxTemplates/basket/getPaymentSystem.cfm';
	if(fileExists(url) == true){
		var responseText = ajaxLoadSync(url);
		var objResponse = eval('(' + responseText + ')');
		if(objResponse.PAYMENTSYSTEMID != -1){
			if(document.getElementById('paymentMethod')) var objPaymentMethod = document.getElementById('paymentMethod');
			else var objPaymentMethod = document.getElementById('paymentSystemsItems');
			if(objPaymentMethod){
				var objPaymentMethodRadios = objPaymentMethod.getElementsByTagName('input');
				for(var i=0;i<objPaymentMethodRadios.length;i++){
					el = objPaymentMethodRadios[i];
					if(el.value == objResponse.PAYMENTSYSTEMID){ el.checked = true;}
				}
				updatePaymentSystem(objResponse.PAYMENTSYSTEMID);
			}
		}
	}
}

function fileExists(strURL){
	var xmlObj = createXMLRequest();
	xmlObj.open("HEAD", strURL, false);
	xmlObj.send(null);
	return (xmlObj.status==404) ? false : true;
}



function validateOrderComments(){
	var element = $('orderCommentsCommentsField');
	if(element){
		var required = element.getAttribute('requiredField');
		if(required ==  1){
		 if(element.value.length == 0) {element.addClass('textareaRequiredState'); return false;}
		 else {element.removeClass('textareaRequiredState');element.addClass('textareaValidState'); return true;}
		}
		else return true;
	}
	else return true;
}
function createOverlay(){
  var overlay = document.createElement('div');
  overlay.id = 'overlay';
  overlay.style.height = document.html.clientHeight + 'px';
	
  document.body.appendChild(overlay);
  $(window).addEvent('scroll', moveOverlay);
  moveOverlay();
}

function moveOverlay(){
	var overlay = document.getElementById('overlay');
	overlay.style.top = document.documentElement.scrollTop+'px'; 
}

function deleteOverlay(){
	var overlay = $('overlay');
	$(window).removeEvent('scroll', moveOverlay);
	overlay.destroy();
}


/*function loadNextCheckoutScreen(step, path, targetDiv, callBack ){ajaxLoad(path, targetDiv, "ajaxLoad('"+shop.url+"/ajaxTemplates/checkout/steps.cfm?step="+step+"', $('stepsCheckout'));"+callBack);}*/

function quantityIncrement(productId, increment){
	document.getElementById('quantity_'+productId).value = parseInt(document.getElementById('quantity_'+productId).value) + increment;
	if(parseInt(document.getElementById('quantity_'+productId).value) < 0) document.getElementById('quantity_'+productId).value = 0;
}

function validateAccountNewUser(req){var objResponse = eval('(' + req.xhRequest.responseText + ')');if( objResponse.ERROR ){switch (objResponse.ERROR){case 'TLG1000':case 'TLG1001':shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblUserNotFound,0,0,messageWidth,messageHeight);break;case 'TLG1002':shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblDifferentPassword,0,0,messageWidth,messageHeight);break;case 'TLG1003':shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblEmailInUse,0,0,messageWidth,messageHeight);break;case 'TLG1004':shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblDifferentEmail,0,0,messageWidth,messageHeight);break;}}else{if(objResponse.ACTION && objResponse.ACTION == 'signIn')window.location = shop.url+'/ecommerce/users/user.cfm?signIn=1';elsewindow.location = shop.url+'/ecommerce/users/user.cfm';}}

function validateAddProductGoToBasket(req){window.location.href = shop.url + '/ecommerce/basket/basket.cfm';}

function validateAddProductShowMessage(req){
	var objResponse = eval('('+req.xhRequest.responseText+')');
	if(objResponse.ADDED){
		$('loadingImage'+ objResponse.PRODUCTID).destroy();
		$('addProduct'+objResponse.PRODUCTID).style.display = '';
		reloadMiniBasket();
		shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblProductAdded, 0, 0, messageWidth,messageHeight);  
	}
	else{
		shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblProductNotAdded, 0, 0, messageWidth,messageHeight);
	}
}

function validateAddProductShowMessageGoToCart(req){
	var objResponse = eval('('+req.xhRequest.responseText+')');
	if(objResponse.ADDED){
		$('loadingImage'+ objResponse.PRODUCTID).destroy();
		$('addProduct'+objResponse.PRODUCTID).style.display = '';
		reloadMiniBasket();
		shop.cuteQuestion.addMessage('', languageSheet.lblProductAdded, languageSheet.lblYes, languageSheet.lblNo, 2, "yes", shop.url + '/ecommerce/basket/basket.cfm', 0,0);
	}
	else{
		shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblProductNotAdded, 0, 0, messageWidth,messageHeight);
	}
}

function validateAddProductShowMiniBasket(req){
	var objResponse = eval('('+req.xhRequest.responseText+')');
	if(objResponse.ADDED){
		$('loadingImage'+ objResponse.PRODUCTID).destroy();
		$('addProduct'+objResponse.PRODUCTID).style.display = '';
		reloadMiniBasket();
	}else{
		shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblProductNotAdded, 0, 0, messageWidth,messageHeight);
	}
}

function validateAddProductShowAsyncBasket(req, width, height){
	var objResponse = eval('('+req.xhRequest.responseText+')');
	if(objResponse.ADDED){
		$('loadingImage'+ objResponse.PRODUCTID).destroy();
		$('addProduct'+objResponse.PRODUCTID).style.display = '';
		reloadMiniBasket();
		setTimeout('openAsyncBasketInShadowbox('+width+','+height+');', 2000);
	}else{
		shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblProductNotAdded, 0, 0, messageWidth,messageHeight);
	}
}

function openAsyncBasketInShadowbox(width, height){
	if(document.getElementById('asyncBasketBox')){
		Shadowbox.open({player:'html',	
										content:document.getElementById('asyncBasketBox').innerHTML,	
										width:  width,	
										height: height});
	}
}

$(window).addEvent('domready', function(){ initFormFields('contact'); } );

function selectOption(optionId, optionValueId){$('optionValue'+optionId).value = optionValueId;}

function ltrim(s) {
	return s.replace(/^\s+/, "");
}

function rtrim(s) {
	return s.replace(/\s+$/, "");
}

function trim(s) {
	return rtrim(ltrim(s));
}

function selectOptionGroup(optionId, optionValueId){
	option = $('optionValue'+optionId);
	values = option.value;
	if(values.search(optionValueId) != -1){
		values = values.replace(optionValueId, "");
	}
	else{
		if(values.length > 0)	values = values + ",";
		values = values + optionValueId;
	}
	
	$('optionValue'+optionId).value = values;
}

function addWishList(productId){	var div = $(shop.productInfoAddToWishlist);var el = $(shop.productInfoAddToWishlist+productId);el.style.display = 'none';var loadingImage = document.createElement('img');loadingImage.src = shop.templatePath + '/images/smallLoading.gif';loadingImage.id = 'loadingImage' + productId;div.parentNode.appendChild(loadingImage);loadContent(shop.url + '/ajaxTemplates/products/addToWishlist.cfm?id='+productId, null, 'addWishListActions('+productId+')', null);}function addWishListActions(productId){$('loadingImage'+productId).destroy();shop.cuteAlert.addMessage(null, languageSheet.lblProductWishlistAdded, 0, 0, messageWidth,messageHeight);}function showMessageMustRegister(){shop.cuteQuestion.addMessage('', languageSheet.lblMustRegister, languageSheet.lblYes, languageSheet.lblNo, 2, "yes", shop.url + '/ecommerce/users/user.cfm', 0,0);}

function getRadioButtonSelectedValue(ctrl) {
	value = "";
	for(i=0;i<ctrl.length;i++){
			if(ctrl[i].checked) value = ctrl[i].value;
	}
	
	return value;
}

function getCheckButtonSelectedValue(ctrl) {
	values = "";
	for(i=0;i<ctrl.length;i++){
		if(ctrl[i].checked){
			if(values.length > 0) values = values + ",";
			values = values + ctrl[i].value;
		}
	}
	return values;
}

 
function showPriceByOptionOnlyValue(form, option){ 
	if(!form.productId)return;
	
	var productId = form.productId.value;
	var listOptions = "";
	var optionsValue = "";
	$$('input.productOptionValue').each(function(el){	
																			if(el.type == 'hidden'){
																				if(optionsValue.length > 0) optionsValue = optionsValue + ","; 
																				optionsValue = optionsValue + el.getAttribute('optionId');
																			}
																			else if(el.checked){
																				if(optionsValue.length > 0) optionsValue = optionsValue + ","; 
																				optionsValue = optionsValue + el.getAttribute('optionId');
																			}
																			}); 
	$$('select.productOptionValue').each(function(el){	
																			if(optionsValue.length > 0) optionsValue = optionsValue + ","; 
																			optionsValue = optionsValue + el.getAttribute('optionId');
																			}); 
 
	if(optionsValue.length > 0){
		arrOptionsValue = optionsValue.split(",");
		for(var i=0; i<arrOptionsValue.length; i++){
			optionId = arrOptionsValue[i];
			objOption = $('optionValue'+optionId);
			optionType = objOption.getAttribute('optiontype');
			if(optionType == 'radio') {
				radioValue = getRadioButtonSelectedValue(document.getElementsByName('optionValue'+optionId));
				if(radioValue.length > 0){
					if(listOptions.length > 0) listOptions = listOptions + ",";
					listOptions = listOptions + radioValue;
				}
			}else if(optionType == 'select') {
				selectValue = objOption[objOption.selectedIndex].value;
				if(selectValue.length > 0){
					if(listOptions.length > 0) listOptions = listOptions + ",";
					listOptions = listOptions + selectValue;
				}
			}else if(optionType == 'check'){
				checkValue = getCheckButtonSelectedValue(document.getElementsByName('optionValue'+optionId));
				if(checkValue.length > 0){
					if(listOptions.length > 0) listOptions = listOptions + ",";
					listOptions = listOptions + checkValue;
				}
			}else if(optionType == 'radioImage' || optionType == 'checkImage'){
				optionValue = objOption.value;
				if(optionValue.length > 0){
					if(listOptions.length > 0) listOptions = listOptions + ",";
					listOptions = listOptions + optionValue;
				}
			}
		}
	}
	arrListOptions = listOptions.split(",");
	listOptions = "";
	for(var i=0; i<arrListOptions.length; i++){
		if(trim(arrListOptions[i]).length > 0){
			if(i > 0) listOptions = listOptions + ",";
			listOptions = listOptions + arrListOptions[i];
		}
	}

	//if(listOptions.length > 0){
		var url = shop.url + '/ajaxTemplates/products/showPriceByOptions.cfm?productId='+productId+'&listOptions='+listOptions;
		var responseText = ajaxLoadSync(url);
		var objResponse = eval('(' + responseText + ')');
		if($(shop.productPriceDiv))$(shop.productPriceDiv).innerHTML = objResponse.BASEPRICE;
		if($(shop.productPriceRetailDiv))$(shop.productPriceRetailDiv).innerHTML = objResponse.RETAILPRICE;
		if( objResponse.SALEDIFFERENCE && $('productInfoSalePercentPrice'))$('productInfoSalePercentPrice').innerHTML = objResponse.SALEDIFFERENCE;
		if( objResponse.SALEPERCENT && $('SalePercentValue'))$('SalePercentValue').innerHTML = objResponse.SALEPERCENT;
	//}
	
	getStockByCombination(form);
}



function showPriceByOptionWithImage(form, option){
	
	showPriceByOptionOnlyValue(form);
	
	if(!option){
		var found = false;
		var els = form.getElementsByTagName('select');
		for(var i=0;i<els.length && found == false;i++){
			var sel = els[i];
			if(sel[sel.selectedIndex].getAttribute('smallImage') && sel[sel.selectedIndex].getAttribute('smallImage').length > 0){ option = sel; found=true;}
		}
	}
	if(option){
		optionValue = 0;
		optionType = option.getAttribute('optiontype');
		if(optionType == 'radio') {
			optionValue = option.value;
		}else if(optionType == 'select') {
			optionValue = option[option.selectedIndex].value;
		}else if(optionType == 'check'){
			optionValue = option.value;
		}else if(optionType == 'radioImage' || optionType == 'checkImage'){
			optionValue = option.getAttribute('value');
		}
			
		var url = shop.url + '/ajaxTemplates/products/showImageByOption.cfm?optionValueId='+optionValue;
		var responseText = ajaxLoadSync(url);
		var objResponse = eval('(' + responseText + ')');
		if(objResponse.SMALL.length > 0){
			if($(shop.productInfoImageImg))$(shop.productInfoImageImg).src = objResponse.SMALL;
			if($(shop.productInfoImageLink))$(shop.productInfoImageLink).href = objResponse.LARGE;
			setTimeout('restartShadowbox();', 10);
		}
	}
}

$(window).addEvent('domready', function(){if($('userControlPanelLoginForm'))initFormFields('userControlPanelLoginForm');initUserControlPanel();});

function initUserControlPanel(){	if($('rememberPassword')) initFormFields('rememberPassword');}

function loadUserContent(nameFile, nameDiv, callBack, ajaxLoading) {	if(checkSession() == false){window.location.href = shop.url + '/ecommerce/users/user.cfm'; return;}	else{		loadContent(nameFile, nameDiv, callBack, ajaxLoading);	}}

function checkSessionInUserOrder(){	if(checkSession() == false){window.location.href = shop.url + '/ecommerce/users/userControlPanel.cfm'; Shadowbox.close(); return false;}	return true;}

function checkSession(){	var xmlObj = createXMLRequest();		xmlObj.open('GET', shop.url + '/ajaxTemplates/users/checkSession.cfm?'+getUniqueId(), false);	xmlObj.send(null);	if(xmlObj.responseText.indexOf('0') != -1)return false;	return true;}

function checkSessionInCheckout(){	var xmlObj = createXMLRequest();		xmlObj.open('GET', shop.url + '/ajaxTemplates/users/checkSessionInCheckout.cfm?'+getUniqueId(), false);	xmlObj.send(null);	if(xmlObj.responseText.indexOf('0') != -1){return false;}	return true;}

function showMessageDeleteAccount(formAction){	if(checkSession() == false){window.location.href = shop.url + '/ecommerce/users/user.cfm'; return false;}	shop.cuteQuestion.addMessage('', languageSheet.lblDeleteAccount, languageSheet.lblYes, languageSheet.lblNo, 1, "yes", formAction, 0,0,messageWidth,messageHeight );}

/*function initWishlistTable(){	if($('listWishlistDetailsId')) $('listWishlistDetailsId').value = "";	if($('listProductsIdToEmail')) $('listProductsIdToEmail').value = "";	if($('listProductsId')) $('listProductsId').value = "";	$$('.checkWishlistDetail').each(function(el){el.checked = false;});	}



function findInArray(array, stringToSearch){	for (var i = 0; i < array.length; i++){		if(array[i] == stringToSearch) return i;	}	return -1;}

function generateListProductsId(productId){	var content = $('listProductsId').value;	if(content.length > 0)var arrContent = content.split(',');	else var arrContent = new Array();		var pos = findInArray(arrContent, productId);	if(pos >= 0)arrContent.splice(pos, 1);	else arrContent.push(productId);		content = arrContent.join(",");	$('listProductsId').value = content;	$('listProductsIdToEmail').value = content;}

function emptyListListProductsId(){	$('listProductsId').value = "";	$('listProductsIdToEmail').value = "";}

function generateListWishlistDetailsId(wishlistDetailId){	var content = $('listWishlistDetailsId').value;	if(content.length > 0)var arrContent = content.split(',');	else var arrContent = new Array();		var pos = findInArray(arrContent, wishlistDetailId);	if(pos >= 0)arrContent.splice(pos, 1);	else arrContent.push(wishlistDetailId);		content = arrContent.join(",");	$('listWishlistDetailsId').value = content;}

function emptyListWishlistDetailsId(){	$('listWishlistDetailsId').value = "";}

function addProducts(form){	$('productList').value = $('listProductsId').value;	return Spry.Utils.submitForm(form, reloadMiniBaskets );}

function deleteWishList(){	if(checkSession() == false){window.location.href = shop.url + '/ecommerce/users/user.cfm'; return;}	var content = $('listWishlistDetailsId').value;		var arrContent = content.split(',');	content = arrContent.join(',');	if(content.length>0){		loadContent(shop.url + '/ajaxTemplates/users/userControlPanel/wishlistDelete.cfm?listWishlistDetailsId='+content, 'wishlistTable', "initWishlistTable()",'');	}	else{		shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblSelectProducts,0,0,messageWidth,messageHeight);	}}

function generateEmail(){	if(checkSession() == false){window.location.href = shop.url + '/ecommerce/users/user.cfm'; return;}	var content = $('listProductsIdToEmail').value;	var arrContent = content.split(',');	content = arrContent.join(',');	if(content.length>0){		loadContent(shop.url + '/ajaxTemplates/users/userControlPanel/wishlistToEmail.cfm?listProductsId='+content, 'informationBox', 'initWishlistToEmail();', '');	}	else{shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblSelectProducts,0,0,messageWidth,messageHeight);	}}

function selectAllProductsWishlist(){	$$('.checkWishlistDetail').each(		function(el){ var arrId = el.id.split("_"); if(el.checked == true){	 	el.checked = false;	 	emptyListWishlistDetailsId();		emptyListListProductsId(); } else{	 generateListWishlistDetailsId(arrId[0]); 	 generateListProductsId(arrId[1]); 	 el.checked = true; } changeClass($('divWishlistDetail'+arrId[0]), 'selectRow', 'selectedRow');		});}$(window).addEvent('domready', function(){if($('userInformationForm'))initFormFields('userInformationForm');});*/


function deleteItemsWishlist(req){
	var length = getWishlistItemsQuantity(req);
	if(length == 0) shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblSelectProducts,0,0,messageWidth,messageHeight);	
	reloadWishlist();
}

function generateEmail(req){
	var length = getWishlistItemsQuantity(req);
	var items = getWishlistItems(req);
	if(length > 0){
		loadContent(shop.url + '/ajaxTemplates/users/wishlistToEmail.cfm?listProductsId='+items, 'informationBox', 'initWishlistToEmail();', '');
	}
	else{
		shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblSelectProducts,0,0,messageWidth,messageHeight);	
	}
}

function getWishlistItemsQuantity(req){
	var content = eval('(' + req.xhRequest.responseText + ')');
	var length = 0;
	var items = content.ITEMS;
	if(typeof items == 'number') length = 1;
	else if(typeof items == 'string' && items.length > 0) length = items.split(",").length;
	return length;
}

function getWishlistItems(req){
	var content = eval('(' + req.xhRequest.responseText + ')');
	return content.ITEMS;
}

function reloadCountries(value){
	if(value == 1){		
		$('userShipping').style.display = '';	
		if($('countryTD')){
			$('subCountries').style.display = 'none';
			$('lblOtherCountry').style.display = 'none';
			$('lblOtherCountryShipTo').style.display = '';
			$('lblCountryShipTo').style.display = 'none';
			$('lblCountry').style.display = '';
			$('countryNoShipTo').style.display = '';		
		}		
		$('lblInvoiceAddressSameShippingAdrressInfo').style.display = 'none';		
		$('lblInvoiceShippingAddressInfo').style.display = '';	
	}	
	else{		
		$('userShipping').style.display = 'none';	
		if($('countryTD')){
			$('subCountries').style.display = '';
			$('lblOtherCountry').style.display = '';
			$('lblOtherCountryShipTo').style.display = 'none';
			$('lblCountryShipTo').style.display = '';
			$('lblCountry').style.display = 'none';
			$('countryNoShipTo').style.display = 'none';		
		}		
		$('lblInvoiceAddressSameShippingAdrressInfo').style.display = '';		
		$('lblInvoiceShippingAddressInfo').style.display = 'none';	
	}	
}


function showPostalCodes(zip, country, shipTo){
	if(!shipTo) shipTo = 0;

	if(zip.length < 2){
		hideZipResult(shipTo);
		return;
	}

	countryId = country[country.selectedIndex].value;
	if(postalCodesCheck(zip,countryId) == true){
		valueZipResult(zip, shipTo);
	}
	else{
		valuesStateAndCity('', '', shipTo);
	}
}

function getPostalCodes(zip, country, eventKey, shipTo){
	ev = new Event(eventKey)
	if(ev.key == 'up' || ev.key == 'down' || ev.key == 'left' || ev.key == 'right'){
	
	}else{
		showPostalCodes(zip, country, shipTo);
	}
}

function assignPostalCodeInSelect(id, zip, subcountryId, shipTo){
	
	if(shipTo == 1) divId = "subCountryIdShipTo";
	else {shipTo = 0; divId = "subCountryId";}

	document.getElementById(divId).value=subcountryId;
	/*document.getElementById('inputPostalCodes').value=zip;*/
	valueZip(zip, shipTo);
	hidePostalCodes(shipTo);
	ajaxLoadSync(shop.url+'/ajaxTemplates/users/updateSubCountryAndPostalCode.cfm?subCountryId='+subcountryId+'&postalCode='+id+'&shipTo='+shipTo);
	responseText = ajaxLoadSync(shop.url+'/ajaxTemplates/users/postalCodeRegions.cfm?postalCodeId='+id);
	var objResponse = eval('(' + responseText + ')');
	valuesStateAndCity(id, objResponse.STATE, objResponse.CITY, shipTo);
	
	if(shipTo == 0)	loadShippingMethod(objResponse.COUNTRYID, objResponse.SUBCOUNTRYID);
}

function hidePostalCodes(shipTo){
		hideZipResult(shipTo);
}

function postalCodesCheck(zip,country){
	var responseText = ajaxLoadSync(shop.url + '/ajaxTemplates/users/postalCodesCheck.cfm?zip='+zip+'&country='+country);
	if(responseText.indexOf('0') != -1)return false;
	return true;
}

function loadShippingMethod(country, subcountry){
	ajaxLoad(shop.url+'/ajaxTemplates/basket/shippingMethod.cfm?countryId='+country+'&subcountryId='+subcountry,$('shippingMethods'),null,'smallLoading.gif');
}

function updateShippingMethod(sectionId){
	if(checkBasket() == false){window.location.reload();}
	ajaxLoadSync(shop.url + '/ajaxTemplates/basket/updateShippingMethod.cfm?sectionId='+sectionId);
	
	reloadCheckoutBasket();
	reloadButtonsCheckoutBasket(3);
}

function updatePaymentSystem(paymentSystemId){
	if(checkBasket() == false){window.location.reload();}
	ajaxLoadSync(shop.url + '/ajaxTemplates/basket/updatePaymentSystem.cfm?paymentSystemId='+paymentSystemId);
	
	reloadCheckoutBasket();
	reloadButtonsCheckoutBasket(3);
}


function reloadButtonsCheckoutBasket(step){
	ajaxLoad(shop.url+'/ajaxTemplates/basket/buttonsBasketStep.cfm?step='+step,$('buttonsBasketStep'));
}

function checkBasket(){
	var responseText = ajaxLoadSync(shop.url + '/ajaxTemplates/basket/checkBasket.cfm');
	if(responseText.indexOf('0') != -1)return false;
	return true;
}

function submitUserInformationForm(nameForm){
	initFormFields(nameForm);
	if(Spry.Widget.Form.validate($(nameForm))){
		Spry.Utils.submitForm(nameForm, validateAccount, null, false);
	}
	else{
		shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblErroneousData, 0, 0, messageWidthExtra,messageHeightExtra);
	}
}

function activeShipTo(obj){
	if(obj.checked){
		requireShipTo(1);
		activeShipToGeo(1);
	}
	else{
		requireShipTo(0);
		activeShipToGeo(0);
	}
}

function activeShipToGeo(value){
	if(document.getElementById('fieldGeoShipping_1')){
		children = document.getElementById('fieldGeoShipping_1').getElementsByTagName('select');
		for(var i=0;i<children.length;i++){
			selectOption = children[i];
			selectOption.setAttribute('requiredField', value);
			selectOptionChildren = document.getElementById('fieldGeoShipping_1').getElementsByTagName('option');
			for(var j=0;j<selectOptionChildren.length;j++){
				selectOptionChildren[j].setAttribute('required', value);
			}
		}
		restartUserFormInformation();
	}
}

function updateBasketComments(obj, eventKey){
	ev = new Event(eventKey)
	if(ev.key == 'up' || ev.key == 'down' || ev.key == 'left' || ev.key == 'right'){}
	else{
		value = obj.value;
		ajaxLoadSync(shop.url+'/ajaxTemplates/basket/updateComments.cfm?comments='+value);
	}
}

function showSubCategoriesInAdvancedSearch(parentId, divId){
	var divElement = $(divId);
	if(divElement.className.search("Close") != -1 || divElement.className.search("Open") == -1){
		divElement.className = divElement.className.replace("Close", "");
		divElement.className = divElement.className+"Open";
		ajaxLoad(shop.url + '/ajaxTemplates/search/subCategoriesAdvancedSearch.cfm?parentId='+parentId, divElement, null, null);
	}
	else{
		divElement.className = divElement.className.replace("Open", "");
		divElement.className = divElement.className+"Close";
		divElement.innerHTML = "";
	}
}

function markChildsCheckBox(obj, divId){
	var divElement = $(divId);
	if(divElement){
		var children = divElement.getElementsByTagName('input');
		for(var i=0;i<children.length;i++){
			el = children[i];
			el.checked = obj.checked;
			markChildsCheckBox(obj,el.id); 
		}
	}
}

var checked = new Array();

function markChildsCheckBoxAll(divId, level){
	if(!checked[divId]) checked[divId] = false;
	if(level == 1){
		if(checked[divId] == false)checked[divId] = true;
		else checked[divId] = false;
	}
	var divElement = $(divId);
	if(divElement){
		var children = divElement.getElementsByTagName('input');
		for(var i=0;i<children.length;i++){
			el = children[i];
			el.checked = checked[divId];
			markChildsCheckBoxAll(el.id, level+1); 
		}
	}
}

function restartMainImage(obj){
	var className = obj.getAttribute('nameClass');
	if(document.getElementById(className+'mainImage')){
		var mainImage = document.getElementById(className+'mainImage');
		mainImage.src = obj.getAttribute('largeSrc');
		setTimeout(function(){restartShadowboxContent('productInfoDetailImagesContentMain')}, 500);
	}
	else{
		var mainImage = document.getElementById('mainImage');
		var mainImageLink = document.getElementById('mainImageLink');
		mainImage.src = obj.getAttribute('largeSrc');
		mainImageLink.href = obj.getAttribute('largeSrc');
	
		restartShadowbox();
	}
	return mainImage.src;
}

function restartShadowboxContent(divId){
	document.getElementById('shadowbox_content').innerHTML = document.getElementById(divId).innerHTML;
}

function initUserInformation(){
	if(document.getElementById('fieldGeo_1')){
		var el = document.getElementById('fieldGeo_1');
		loadGeoCountry(el);
	}
	if(document.getElementById('fieldGeoShipping_1')){
		var el = document.getElementById('fieldGeoShipping_1');
		loadGeoCountry(el);
	}
}

function loadGeoCountry(el){
	var imageLoading = "<img src='" + shop.templatePath + "/images/smallLoading.gif'>";
	
	if(typeof el == 'string')
	{
		el = document.getElementById(el);
		if(!el)
			return null;
		el = el.options[el.options.selectedIndex];
	}
	
	var content = el;
	var index = parseInt(el.getAttribute('position'));
	var value = el.getAttribute('value');
	var countryId = el.getAttribute('countryId');
	var shipTo = el.getAttribute('shipTo');
	var useValueNotShipTo = el.getAttribute('useValueNotShipTo');
	var required = el.getAttribute('required');
	var area = el.getAttribute('area');

	if(!index) index = 1;
	if(!value) value = 0;
	if(!countryId) countryId = 0;
	if(!area) area = 0;
	if(!required) required = -1;
	if(value == countryId) value = 0;
	
	if(area == 1){
		if(shipTo == 1)document.getElementById('zipShipping').value = el.text;
		else document.getElementById('zip').value = el.text;
	}
	if(el.getAttribute('field')){el = document.getElementById(el.getAttribute('field'));}
	if(value == -1){
		el.innerHTML = '';
	}
	else{
		if(shipTo == 1){var name = 'selectGeoShipTo_'+index;}
		else {var name = 'selectGeo_'+index;}
		hideSubmitForm(el.id);
		ajaxLoad(shop.url+'/ajaxTemplates/users/geoCountries.cfm?parentId='+value+'&countryId='+countryId+'&shipTo='+shipTo+'&area='+area+'&index='+index+'&required='+required+'&useValueNotShipTo='+useValueNotShipTo, el, 'displaySubmitForm("'+el.id+'");loadGeoCountry("'+name+'"); restartUserFormInformation();', imageLoading);
	}
}

var objSubmitContent = "";
var objSubmitId = "";
function hideSubmitForm(objId){
	var imageLoading = "<img src='" + shop.templatePath + "/images/smallLoading.gif'>";
	var objForm = $(objId).getParent('form');
	var objSubmits_type1 = objForm.getElements('input[type=submit]');
//	var objSubmits_type2 = $(document.body).getElements('input[onclick=submitUserInformationStepBasket();]');
//	var objSubmits_type2 = document.getElementsByTagName('input');
	//var objSubmits_type2 =  $$('input[onclick^=submitUserInformationStepBasket]');
	var objSubmits_type2 = $$('input[type=button]');
//alert(objSubmits_type2.length);
	for(var i=0; i<objSubmits_type2.length; i++){
		var objSubmit_onClick = objSubmits_type2[i].getAttribute("onClick").toString();
		if(objSubmit_onClick.search("submitUserInformationStepBasket") != -1 && $(objSubmits_type2[i].id)){
			objSubmit = $(objSubmits_type2[i].id).getParent();
		}
	}

//	var objSubmits_type3 = objForm.getElements('input[onclick^=submitUserInformationForm]');
//alert("objSubmits_type3 " + objSubmits_type3.length)
	if(objSubmits_type1.length > 0){
		var objSubmit = objSubmits_type1[0].getParent();
	}
	/*else if(objSubmits_type2.length > 0){
		var objSubmit = objSubmits_type2[0].getParent();
	}*/
/*	else if(objSubmits_type3.length > 0){
		var objSubmit = objSubmits_type3[0].getParent();
	}*/
	if(objSubmit != null){
		objSubmitId = objSubmit.id; 
		objSubmitContent = objSubmit.innerHTML;
		objSubmit.innerHTML = imageLoading;
	}
}

function displaySubmitForm(objId){
//	var objForm = $(objId).getParent('form');
	var objSubmit = document.getElementById(objSubmitId);
	if(objSubmit != null){
		objSubmit.innerHTML = objSubmitContent;
	}
}

function restartMainImageOptionColors(obj){}

$(window).addEvent('domready', function(){initUserInformation();});
//$(window).addEvent('click', function(){hidePostalCodes()});


/************************CHAT***************************/
var globalIntervalChat = null;	

function initChat(){
	
	if(document.getElementById('contentChat')){
		initCookiesChat();
	
		globalIntervalChat = 	setInterval('refreshMessages();',10000);
		scrollDown(document.getElementById('messagesChat'));
	}
}

function refreshMessages(){
	ajaxLoad(shop.url+'/ajaxTemplates/chat/messages.cfm',document.getElementById('divMessagesChat'),'postRefreshMessagesChat();');
}

function postRefreshMessagesChat(){
	scrollDown(document.getElementById('messagesChat'));
	if(document.getElementById('openAutoChat')){
		val = document.getElementById('openAutoChat').value;
		if(val > 0) document.getElementById('contentChat').style.display = '';
		
		 if(document.getElementById('redirect')){
				
				if(document.getElementById('redirect').getAttribute('typeObject') == 1)
				 window.location.href=shop.url+'/ecommerce/products/prodDetail.cfm?id='+document.getElementById('redirect').value; 
				else if(document.getElementById('redirect').getAttribute('typeObject') == 2)
				 window.location.href=shop.url+'/ecommerce/categories/categories.cfm?id='+document.getElementById('redirect').value; 
		 
		 }
	}
}

function sendMessageChat(){
	var message = document.getElementById('new_message').value;
	document.getElementById('new_message').value = '';
	ajaxLoad(shop.url+'/ajaxTemplates/chat/SendMessage.cfm?message='+message,null,'refreshMessages();');
	
}

function keyUpChat(e){
	ev = new Event(e);
	if(ev.key == 'enter')  	sendMessageChat();
}

function scrollDown(element){	
	if(element != null){
		$(element).scrollTop = 9999999;
	}
}

function writeAdminToUserId(bool){
	ajaxLoad(shop.url+'/ajaxTemplates/chat/writeUserIdToAdmin.cfm?writeUserIdToAdmin='+bool,null,'refreshMessages();');
	
}

function initCookiesChat(){
	
		if( readCookie('chatState')){			
	
			if(readCookie('chatState') == 1){ 
				if(document.getElementById('contentChat'))
					document.getElementById('contentChat').style.display = '';			
				}
		}else{			
			createCookie('chatState','0',50);	
		}
}


function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
	
	if(value == 0) document.getElementById('contentChat').style.display = 'none';
	else  document.getElementById('contentChat').style.display = '';
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

function initSessionChat(name){
	ajaxLoad(shop.url + '/ajaxTemplates/chat/chatContent.cfm?name='+name,document.getElementById('contentChat'));
}

/****** Update delivery date on checkout *********/
function updateOrderDeliveryDate(date){
	// date should arrive in this format "20100308" (YYYYMMDD)(newCalendar returns this date format)
	ajaxLoadSync(shop.url+'/ajaxTemplates/basket/updateDeliveryDate.cfm?date='+date);
}

function generateNewCalendar() {

	if(window.newCalendar){
		var tomorrow = new Date();

		responseText = ajaxLoadSync(shop.url+'/ajaxTemplates/basket/getLimitHour.cfm');
		var objResponse = eval('(' + responseText + ')');
		if(objResponse.LIMIT == 0) // if time limit is not exceeded
			tomorrow.setDate(tomorrow.getDate()+1); 
		else // if time limit is exceeded
			tomorrow.setDate(tomorrow.getDate()+2); 

		var LEFT_CAL = newCalendar.setup({
						cont: "checkoutCalendar",
						disabled: function(date) {
											if (date.getDay() == 0) { //disable all Sundays
													return true;
												}else{
													return false;
												}
											},
						weekNumbers: true,
						selectionType: newCalendar.SEL_SINGLE,
						min: newCalendar.dateToInt(tomorrow),
						onSelect: function() {
							var date = this.selection.get();
							date = newCalendar.dateToInt(date);
							updateOrderDeliveryDate(date);							
							}
		})
	}
}

/************** Virtual Keyboard *****************/
function initKeyboard(){
	/*var inputsEl = document.getElementsByTagName('input');
	for(var i=0; i<inputsEl.length;i++){
		var el = inputsEl[i];
		if(el.type == 'TEXT' || el.type == 'PASSWORD'){
		}
	}*/
	VKI_buildKeyboardInputs();
}
/************** End Virtual Keyboard *****************/


function createCookieGeneric(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
	
}

function mouseOverProductPolls(itemId,itemType,pollsQuestionId,iteration,div,img){

	for(var i=1; i<= iteration; i++){
	//	alert(iteration);
	//	alert(document.getElementById(div+'_'+itemId+'_'+itemType+'_'+i).src);
	
		document.getElementById(div+'_'+itemId+'_'+itemType+'_'+pollsQuestionId+'_'+i).src=img;
	}
}

function mouseOutProductPolls(itemId,itemType,pollsQuestionId,iteration,div,img){
	for(var i=1; i<= iteration; i++){
		document.getElementById(div+'_'+itemId+'_'+itemType+'_'+pollsQuestionId+'_'+i).src=img;
	}
} 

function pollsClick(itemId,itemType,pollsQuestionId,value){
	
	
	ajaxLoad(shop.url+'/ajaxTemplates/polls/pollsResults.cfm?itemType='+itemType+'&itemId='+itemId+'&pollsQuestionId='+pollsQuestionId+'&value='+value);
	shop.cuteAlert.addMessage(null, languageSheet.lblPollsThanks, 0, 0,300,100);
	
}


var globalClassNamePolls;

function submitPoll(nameForm,className){
	globalClassNamePolls = className;
	initFormFields(nameForm);
	if(Spry.Widget.Form.validate($(nameForm))){
		
		Spry.Utils.submitForm(nameForm, submitPollResponseDiv, null, false);
		
	}
	else{
		shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblErroneousData, 0, 0, messageWidthExtra,messageHeightExtra);
	}
}

function submitPollResponseDiv(req){
	var objResponse = eval('(' + req.xhRequest.responseText + ')');
	
	var urlParams = "";
	if(objResponse.POLLTYPE == 1){
		urlParams = "pollType="+objResponse.POLLTYPE+"&format="+objResponse.FORMAT+"&categoryId="+objResponse.CATEGORYID+"&productId="+objResponse.ITEMID;
	}else if(objResponse.POLLTYPE == 2){
				urlParams = "pollType="+objResponse.POLLTYPE+"&format="+objResponse.FORMAT+"&categoryId="+objResponse.ITEMID;
	}else{
			
				urlParams = "pollType="+objResponse.POLLTYPE+"&format="+objResponse.FORMAT+"&pollId="+objResponse.POLLID+"&position="+objResponse.POSITION;
	}
	
	var div = document.getElementById(globalClassNamePolls);
	
	var divRes = document.getElementById(globalClassNamePolls+'Results');
	if(divRes) divRes.innerHTML='';
	
	ajaxLoad(shop.url + '/ajaxTemplates/polls/pollResultStadistics.cfm?'+urlParams,div);
}


function submitProductComments(nameForm){
	initFormFields(nameForm);
	if(Spry.Widget.Form.validate($(nameForm))){
		Spry.Utils.submitForm(nameForm, submitProductCommentsResponseDiv, null, false);
	}
	else{
		shop.cuteAlert.addMessage(languageSheet.lblError, languageSheet.lblErroneousData, 0, 0, messageWidthExtra,messageHeightExtra);
	}
}

function submitProductCommentsResponseDiv(req){
	var objResponse = eval('(' + req.xhRequest.responseText + ')');
	var text = objResponse.TEXT;
	var div = document.getElementById('DivproductCommentsForm');
	div.innerHTML = text;
}


function visibleSubQuestions(questionId,position,input){
	
	for(var i=1; true; i++){
		if(document.getElementById('subQuestionsId'+questionId+'_'+i)){
			var type = document.getElementById('subQuestionsId'+questionId+'_'+i).getAttribute('typeInput');
			
			
			switch(type){
				case 'radio':
					if(position == i){
						document.getElementById('subQuestionsId'+questionId+'_'+i).style.display='';
						if(document.getElementById('subQuestionsName'+questionId+'_'+i)){
							document.getElementById('subQuestionsName'+questionId+'_'+i).value=1;
						}
					}else{
						document.getElementById('subQuestionsId'+questionId+'_'+i).style.display='none';
						if(document.getElementById('subQuestionsName'+questionId+'_'+i)){
							document.getElementById('subQuestionsName'+questionId+'_'+i).value=0;
						}
					}
				break;
				
				case 'checkbox':
					if(document.getElementById('answerId'+questionId).checked){
						document.getElementById('subQuestionsId'+questionId+'_'+i).style.display='';
						if(document.getElementById('subQuestionsName'+questionId+'_'+i)){
							document.getElementById('subQuestionsName'+questionId+'_'+i).value=1;
						}
					}else{
						document.getElementById('subQuestionsId'+questionId+'_'+i).style.display='none';
						if(document.getElementById('subQuestionsName'+questionId+'_'+i)){
							document.getElementById('subQuestionsName'+questionId+'_'+i).value=0;
						}
					}
				break;
				
				case 'text':
				
				break;
				
				case 'textarea':
				
				break;
			}
		}else{
			break;
		}
	}
}



/*************** FACT FINDER SEARCH ***********************/
/*
var pLastQuery='';

var timeOutFactFinder;

function handleKeyPress(evt) {
	if(timeOutFactFinder) clearTimeout(timeOutFactFinder);
	timeOutFactFinder = setTimeout(function (){
																	inputSearch = document.getElementById('smallSearchSearchField');
																		pLayer = document.getElementById('smallSearchSuggest');
																		
																		evt = (evt) ? evt : ((event) ? event : null);
																		var keyCode = evt.keyCode;
																		 if (keyCode == 38) {
																			
																			moveSelection('up')
																		} else if (keyCode == 27) {	
																			
																			hideLayer();
																		} else if (keyCode == 40) {
																			
																			moveSelection('down');
																		} else {
																			
																			if (inputSearch.value == '') {
																				hideLayer();
																				if (pLayer != null){ pLayer.innerHTML = ''; }
																				return null;
																			}
																			showLayer();
																			if (pLastQuery != inputSearch.value){ startSuggest(); }
																			pLastQuery = inputSearch.value;
																		}
																					 }
																		,700);
	}
	
function hideLayer(){
	document.getElementById('smallSearchSuggest').style.display='none';
}

function showLayer(){
	document.getElementById('smallSearchSuggest').style.display='';
}

function moveSelection(direction) {
		inputSearch = document.getElementById('smallSearchSearchField');
		var pos = pCurrentSelection;
		if (direction == 'up'){	pos--; }
		else{ 					pos += 1; }
		
		if (pos < 1) {
			unMarkAll();
			inputSearch.focus();
			pCurrentSelection	= -0;
		} else {
			var tblCell = document.getElementById('suggestTr'+pos);
			if (tblCell != null) {
				unMarkAll();
				highlightSuggest(tblCell);
				pCurrentSelection = pos;
			}
		}
		
		var query = inputSearch.value;
		inputSearch.value = '';
		inputSearch.focus();
		inputSearch.value = query; 
	}
	
	var pCurrentSelection = 0;
	var classNameNoSelected = 'classSuggestNoSelected';
	var classNameSelected = 'classSuggestSelected';
	
	function handleMouseOver(pos){
		var tblCell = document.getElementById('suggestTr'+pos);
		unMarkAll();
		if (tblCell != null) {
			highlightSuggest(tblCell);
			pCurrentSelection = pos;
		}
	}
	
	function handleMouseOut(pos) {
		var tblCell = document.getElementById('suggestTr'+pos);
		if (tblCell != null) {
			unMarkSuggest(tblCell);
			pCurrentSelection = -0
		}
	}
	
	function handleClick(){
		if(pCurrentSelection > 0){
				inputSearch = document.getElementById('smallSearchSearchField');
				if(pCurrentSelection > 0){
					var name = document.getElementById('suggestTr'+pCurrentSelection).getAttribute('search');
					inputSearch.value = name;
					
					$('smallSearchFactFinderForm').submit();
					

				}
					

		}
	}
	
	function handleEnter(){
		
		if(pCurrentSelection > 0){
				inputSearch = document.getElementById('smallSearchSearchField');
				if(pCurrentSelection > 0){
					inputSearch.value = document.getElementById('suggestTr'+pCurrentSelection).getAttribute('search');
				}
		}
		return true;
	}
	
	
	
	function unMarkAll(){
		for(var i=1; true; i++){
			if(document.getElementById('suggestTr'+i)){
				unMarkSuggest(document.getElementById('suggestTr'+i));
			}else{
				break;
			}
		}
	}
	
	function unMarkSuggest(tbCell){
		tbCell.className = classNameNoSelected;
	}
	
	function highlightSuggest(tbCell){
		tbCell.className = classNameSelected;
	}
	
	function startSuggest(){
		inputSearch = document.getElementById('smallSearchSearchField');
		
	
		
		ajaxLoad(shop.url + '/ajaxTemplates/search/suggest.cfm?query='+inputSearch.value,document.getElementById('smallSearchSuggest'));		
	}
	
	*/
/*********************************************/

function trackPageView(page)
{
	
	try
	{
		if(!_gat || !shop.tracker || !page || page == '') return;
		
		var pageTracker = _gat._getTracker(shop.tracker);
	
		pageTracker._trackPageview(page);
	}
	catch(err) { return; }
}



/*************** FACT FINDER SEARCH ***********************/

var pLastQuery='';

function handleKeyPress(evt) {
		inputSearch = document.getElementById('smallSearchSearchField');
		pLayer = document.getElementById('smallSearchSuggest');
		
		evt = (evt) ? evt : ((event) ? event : null);
		var keyCode = evt.keyCode;
		 if (keyCode == 38) {
			
			moveSelection('up')
		} else if (keyCode == 27) {	
			
			hideLayer();
		} else if (keyCode == 40) {
			
			moveSelection('down');
		} else {
			
			if (inputSearch.value == '') {
				hideLayer();
				if (pLayer != null){ pLayer.innerHTML = ''; }
				return null;
			}
			showLayer();
			if (pLastQuery != inputSearch.value){ startSuggest(); }
			pLastQuery = inputSearch.value;
		}
	}
	
function hideLayer(){
	document.getElementById('smallSearchSuggest').style.display='none';
}

function showLayer(){
	document.getElementById('smallSearchSuggest').style.display='';
}

function moveSelection(direction) {
		inputSearch = document.getElementById('smallSearchSearchField');
		var pos = pCurrentSelection;
		if (direction == 'up'){	pos--; }
		else{ 					pos += 1; }
		
		if (pos < 1) {
			unMarkAll();
			inputSearch.focus();
			pCurrentSelection	= -0;
		} else {
			var tblCell = document.getElementById('suggestTr'+pos);
			if (tblCell != null) {
				unMarkAll();
				highlightSuggest(tblCell);
				pCurrentSelection = pos;
			}
		}
		
		var query = inputSearch.value;
		inputSearch.value = '';
		inputSearch.focus();
		inputSearch.value = query; 
	}
	
	var pCurrentSelection = 0;
	var classNameNoSelected = 'classSuggestNoSelected';
	var classNameSelected = 'classSuggestSelected';
	
	function handleMouseOver(pos){
		var tblCell = document.getElementById('suggestTr'+pos);
		unMarkAll();
		if (tblCell != null) {
			highlightSuggest(tblCell);
			pCurrentSelection = pos;
		}
	}
	
	function handleMouseOut(pos) {
		var tblCell = document.getElementById('suggestTr'+pos);
		if (tblCell != null) {
			unMarkSuggest(tblCell);
			pCurrentSelection = -0
		}
	}
	
	function handleClick(){
		if(pCurrentSelection > 0){
				inputSearch = document.getElementById('smallSearchSearchField');
				if(pCurrentSelection > 0){
					var name = document.getElementById('suggestTr'+pCurrentSelection).getAttribute('search');
					inputSearch.value = name;
					
					$('smallSearchFactFinderForm').submit();
					

				}
					

		}
	}
	
	function handleEnter(){
		
		if(pCurrentSelection > 0){
				inputSearch = document.getElementById('smallSearchSearchField');
				if(pCurrentSelection > 0){
					inputSearch.value = document.getElementById('suggestTr'+pCurrentSelection).getAttribute('search');
				}
		}
		return true;
	}
	
	
	
	function unMarkAll(){
		for(var i=1; true; i++){
			if(document.getElementById('suggestTr'+i)){
				unMarkSuggest(document.getElementById('suggestTr'+i));
			}else{
				break;
			}
		}
	}
	
	function unMarkSuggest(tbCell){
		tbCell.className = classNameNoSelected;
	}
	
	function highlightSuggest(tbCell){
		tbCell.className = classNameSelected;
	}
	
	function startSuggest(){
		inputSearch = document.getElementById('smallSearchSearchField');
		
		ajaxLoad(shop.url + '/ajaxTemplates/search/suggest.cfm?query='+inputSearch.value,document.getElementById('smallSearchSuggest'));		
	}
/*********************************************/
