// jQuery 1.1.2
if(typeof window.jQuery=="undefined"){window.undefined=window.undefined;var jQuery=function(a,c){if(window==this)return new jQuery(a,c);a=a||document;if(jQuery.isFunction(a))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](a);if(typeof a=="string"){var m=/^[^<]*(<(.|\s)+>)[^>]*$/.exec(a);if(m)a=jQuery.clean([m[1]]);else return new jQuery(c).find(a)}return this.setArray(a.constructor==Array&&a||(a.jquery||a.length&&a!=window&&!a.nodeType&&a[0]!=undefined&&a[0].nodeType)&&jQuery.makeArray(a)||[a])};if(typeof $!="undefined")jQuery._$=$;var $=jQuery;jQuery.fn=jQuery.prototype={jquery:"1.1.2",size:function(){return this.length},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num]},pushStack:function(a){var ret=jQuery(a);ret.prevObject=this;return ret},setArray:function(a){this.length=0;[].push.apply(this,a);return this},each:function(fn,args){return jQuery.each(this,fn,args)},index:function(obj){var pos=-1;this.each(function(i){if(this==obj)pos=i});return pos},attr:function(key,value,type){var obj=key;if(key.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],key)||undefined;else{obj={};obj[key]=value}return this.each(function(index){for(var prop in obj)jQuery.attr(type?this.style:this,prop,jQuery.prop(this,obj[prop],type,index,prop))})},css:function(key,value){return this.attr(key,value,"curCSS")},text:function(e){if(typeof e=="string")return this.empty().append(document.createTextNode(e));var t="";jQuery.each(e||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)t+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this])})});return t},wrap:function(){var a=jQuery.clean(arguments);return this.each(function(){var b=a[0].cloneNode(true);this.parentNode.insertBefore(b,this);while(b.firstChild)b=b.firstChild;b.appendChild(this)})},append:function(){return this.domManip(arguments,true,1,function(a){this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,-1,function(a){this.insertBefore(a,this.firstChild)})},before:function(){return this.domManip(arguments,false,1,function(a){this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,false,-1,function(a){this.parentNode.insertBefore(a,this.nextSibling)})},end:function(){return this.prevObject||jQuery([])},find:function(t){return this.pushStack(jQuery.map(this,function(a){return jQuery.find(t,a)}),t)},clone:function(deep){return this.pushStack(jQuery.map(this,function(a){var a=a.cloneNode(deep!=undefined?deep:true);a.$events=null;return a}))},filter:function(t){return this.pushStack(jQuery.isFunction(t)&&jQuery.grep(this,function(el,index){return t.apply(el,[index])})||jQuery.multiFilter(t,this))},not:function(t){return this.pushStack(t.constructor==String&&jQuery.multiFilter(t,this,true)||jQuery.grep(this,function(a){return(t.constructor==Array||t.jquery)?jQuery.inArray(a,t)<0:a!=t}))},add:function(t){return this.pushStack(jQuery.merge(this.get(),t.constructor==String?jQuery(t).get():t.length!=undefined&&(!t.nodeName||t.nodeName=="FORM")?t:[t]))},is:function(expr){return expr?jQuery.filter(expr,this).r.length>0:false},val:function(val){return val==undefined?(this.length?this[0].value:null):this.attr("value",val)},html:function(val){return val==undefined?(this.length?this[0].innerHTML:null):this.empty().append(val)},domManip:function(args,table,dir,fn){var clone=this.length>1;var a=jQuery.clean(args);if(dir<0)a.reverse();return this.each(function(){var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(a[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(document.createElement("tbody"));jQuery.each(a,function(){fn.apply(obj,[clone?this.cloneNode(true):this])})})}};jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0],a=1;if(arguments.length==1){target=this;a=0}var prop;while(prop=arguments[a++])for(var i in prop)target[i]=prop[i];return target};jQuery.extend({noConflict:function(){if(jQuery._$)$=jQuery._$;return jQuery},isFunction:function(fn){return!!fn&&typeof fn!="string"&&!fn.nodeName&&typeof fn[0]=="undefined"&&/function/i.test(fn+"")},isXMLDoc:function(elem){return elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase()},each:function(obj,fn,args){if(obj.length==undefined)for(var i in obj)fn.apply(obj[i],args||[i,obj[i]]);else for(var i=0,ol=obj.length;i<ol;i++)if(fn.apply(obj[i],args||[i,obj[i]])===false)break;return obj},prop:function(elem,value,type,index,prop){if(jQuery.isFunction(value))value=value.call(elem,[index]);var exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i;return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(prop)?value+"px":value},className:{add:function(elem,c){jQuery.each(c.split(/\s+/),function(i,cur){if(!jQuery.className.has(elem.className,cur))elem.className+=(elem.className?" ":"")+cur})},remove:function(elem,c){elem.className=c?jQuery.grep(elem.className.split(/\s+/),function(cur){return!jQuery.className.has(c,cur)}).join(" "):""},has:function(t,c){t=t.className||t;c=c.replace(/([\.\\\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g,"\\$1");return t&&new RegExp("(^|\\s)"+c+"(\\s|$)").test(t)}},swap:function(e,o,f){for(var i in o){e.style["old"+i]=e.style[i];e.style[i]=o[i]}f.apply(e,[]);for(var i in o)e.style[i]=e.style["old"+i]},css:function(e,p){if(p=="height"||p=="width"){var old={},oHeight,oWidth,d=["Top","Bottom","Right","Left"];jQuery.each(d,function(){old["padding"+this]=0;old["border"+this+"Width"]=0});jQuery.swap(e,old,function(){if(jQuery.css(e,"display")!="none"){oHeight=e.offsetHeight;oWidth=e.offsetWidth}else{e=jQuery(e.cloneNode(true)).find(":radio").removeAttr("checked").end().css({visibility:"hidden",position:"absolute",display:"block",right:"0",left:"0"}).appendTo(e.parentNode)[0];var parPos=jQuery.css(e.parentNode,"position");if(parPos==""||parPos=="static")e.parentNode.style.position="relative";oHeight=e.clientHeight;oWidth=e.clientWidth;if(parPos==""||parPos=="static")e.parentNode.style.position="static";e.parentNode.removeChild(e)}});return p=="height"?oHeight:oWidth}return jQuery.curCSS(e,p)},curCSS:function(elem,prop,force){var ret;if(prop=="opacity"&&jQuery.browser.msie)return jQuery.attr(elem.style,"opacity");if(prop=="float"||prop=="cssFloat")prop=jQuery.browser.msie?"styleFloat":"cssFloat";if(!force&&elem.style[prop])ret=elem.style[prop];else if(document.defaultView&&document.defaultView.getComputedStyle){if(prop=="cssFloat"||prop=="styleFloat")prop="float";prop=prop.replace(/([A-Z])/g,"-$1").toLowerCase();var cur=document.defaultView.getComputedStyle(elem,null);if(cur)ret=cur.getPropertyValue(prop);else if(prop=="display")ret="none";else jQuery.swap(elem,{display:"block"},function(){var c=document.defaultView.getComputedStyle(this,"");ret=c&&c.getPropertyValue(prop)||""})}else if(elem.currentStyle){var newProp=prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase()});ret=elem.currentStyle[prop]||elem.currentStyle[newProp]}return ret},clean:function(a){var r=[];jQuery.each(a,function(i,arg){if(!arg)return;if(arg.constructor==Number)arg=arg.toString();if(typeof arg=="string"){var s=jQuery.trim(arg),div=document.createElement("div"),tb=[];var wrap=!s.indexOf("<opt")&&[1,"<select>","</select>"]||(!s.indexOf("<thead")||!s.indexOf("<tbody")||!s.indexOf("<tfoot"))&&[1,"<table>","</table>"]||!s.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!s.indexOf("<td")||!s.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||[0,"",""];div.innerHTML=wrap[1]+s+wrap[2];while(wrap[0]--)div=div.firstChild;if(jQuery.browser.msie){if(!s.indexOf("<table")&&s.indexOf("<tbody")<0)tb=div.firstChild&&div.firstChild.childNodes;else if(wrap[1]=="<table>"&&s.indexOf("<tbody")<0)tb=div.childNodes;for(var n=tb.length-1;n>=0;--n)if(jQuery.nodeName(tb[n],"tbody")&&!tb[n].childNodes.length)tb[n].parentNode.removeChild(tb[n])}arg=[];for(var i=0,l=div.childNodes.length;i<l;i++)arg.push(div.childNodes[i])}if(arg.length===0&&!jQuery.nodeName(arg,"form"))return;if(arg[0]==undefined||jQuery.nodeName(arg,"form"))r.push(arg);else r=jQuery.merge(r,arg)});return r},attr:function(elem,name,value){var fix=jQuery.isXMLDoc(elem)?{}:{"for":"htmlFor","class":"className","float":jQuery.browser.msie?"styleFloat":"cssFloat",cssFloat:jQuery.browser.msie?"styleFloat":"cssFloat",innerHTML:"innerHTML",className:"className",value:"value",disabled:"disabled",checked:"checked",readonly:"readOnly",selected:"selected"};if(name=="opacity"&&jQuery.browser.msie&&value!=undefined){elem.zoom=1;return elem.filter=elem.filter.replace(/alpha\([^\)]*\)/gi,"")+(value==1?"":"alpha(opacity="+value*100+")")}else if(name=="opacity"&&jQuery.browser.msie)return elem.filter?parseFloat(elem.filter.match(/alpha\(opacity=(.*)\)/)[1])/100:1;if(name=="opacity"&&jQuery.browser.mozilla&&value==1)value=0.9999;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]]}else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined)elem.setAttribute(name,value);if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name)}else{name=name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase()});if(value!=undefined)elem[name]=value;return elem[name]}},trim:function(t){return t.replace(/^\s+|\s+$/g,"")},makeArray:function(a){var r=[];if(a.constructor!=Array)for(var i=0,al=a.length;i<al;i++)r.push(a[i]);else r=a.slice(0);return r},inArray:function(b,a){for(var i=0,al=a.length;i<al;i++)if(a[i]==b)return i;return-1},merge:function(first,second){var r=[].slice.call(first,0);for(var i=0,sl=second.length;i<sl;i++)if(jQuery.inArray(second[i],r)==-1)first.push(second[i]);return first},grep:function(elems,fn,inv){if(typeof fn=="string")fn=new Function("a","i","return "+fn);var result=[];for(var i=0,el=elems.length;i<el;i++)if(!inv&&fn(elems[i],i)||inv&&!fn(elems[i],i))result.push(elems[i]);return result},map:function(elems,fn){if(typeof fn=="string")fn=new Function("a","return "+fn);var result=[],r=[];for(var i=0,el=elems.length;i<el;i++){var val=fn(elems[i],i);if(val!==null&&val!=undefined){if(val.constructor!=Array)val=[val];result=result.concat(val)}}var r=result.length?[result[0]]:[];check:for(var i=1,rl=result.length;i<rl;i++){for(var j=0;j<i;j++)if(result[i]==r[j])continue check;r.push(result[i])}return r}});new function(){var b=navigator.userAgent.toLowerCase();jQuery.browser={safari:/webkit/.test(b),opera:/opera/.test(b),msie:/msie/.test(b)&&!/opera/.test(b),mozilla:/mozilla/.test(b)&&!/(compatible|webkit)/.test(b)};jQuery.boxModel=!jQuery.browser.msie||document.compatMode=="CSS1Compat"};jQuery.each({parent:"a.parentNode",parents:"jQuery.parents(a)",next:"jQuery.nth(a,2,'nextSibling')",prev:"jQuery.nth(a,2,'previousSibling')",siblings:"jQuery.sibling(a.parentNode.firstChild,a)",children:"jQuery.sibling(a.firstChild)"},function(i,n){jQuery.fn[i]=function(a){var ret=jQuery.map(this,n);if(a&&typeof a=="string")ret=jQuery.multiFilter(a,ret);return this.pushStack(ret)}});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after"},function(i,n){jQuery.fn[i]=function(){var a=arguments;return this.each(function(){for(var j=0,al=a.length;j<al;j++)jQuery(a[j])[n](this)})}});jQuery.each({removeAttr:function(key){jQuery.attr(this,key,"");this.removeAttribute(key)},addClass:function(c){jQuery.className.add(this,c)},removeClass:function(c){jQuery.className.remove(this,c)},toggleClass:function(c){jQuery.className[jQuery.className.has(this,c)?"remove":"add"](this,c)},remove:function(a){if(!a||jQuery.filter(a,[this]).r.length)this.parentNode.removeChild(this)},empty:function(){while(this.firstChild)this.removeChild(this.firstChild)}},function(i,n){jQuery.fn[i]=function(){return this.each(n,arguments)}});jQuery.each(["eq","lt","gt","contains"],function(i,n){jQuery.fn[n]=function(num,fn){return this.filter(":"+n+"("+num+")",fn)}});jQuery.each(["height","width"],function(i,n){jQuery.fn[n]=function(h){return h==undefined?(this.length?jQuery.css(this[0],n):null):this.css(n,h.constructor==String?h:h+"px")}});jQuery.extend({expr:{"":"m[2]=='*'||jQuery.nodeName(a,m[2])","#":"a.getAttribute('id')==m[2]",":":{lt:"i<m[3]-0",gt:"i>m[3]-0",nth:"m[3]-0==i",eq:"m[3]-0==i",first:"i==0",last:"i==r.length-1",even:"i%2==0",odd:"i%2","nth-child":"jQuery.nth(a.parentNode.firstChild,m[3],'nextSibling',a)==a","first-child":"jQuery.nth(a.parentNode.firstChild,1,'nextSibling')==a","last-child":"jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a","only-child":"jQuery.sibling(a.parentNode.firstChild).length==1",parent:"a.firstChild",empty:"!a.firstChild",contains:"jQuery.fn.text.apply([a]).indexOf(m[3])>=0",visible:'a.type!="hidden"&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',hidden:'a.type=="hidden"||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',enabled:"!a.disabled",disabled:"a.disabled",checked:"a.checked",selected:"a.selected||jQuery.attr(a,'selected')",text:"a.type=='text'",radio:"a.type=='radio'",checkbox:"a.type=='checkbox'",file:"a.type=='file'",password:"a.type=='password'",submit:"a.type=='submit'",image:"a.type=='image'",reset:"a.type=='reset'",button:'a.type=="button"||jQuery.nodeName(a,"button")',input:"/input|select|textarea|button/i.test(a.nodeName)"},".":"jQuery.className.has(a,m[2])","@":{"=":"z==m[4]","!=":"z!=m[4]","^=":"z&&!z.indexOf(m[4])","$=":"z&&z.substr(z.length - m[4].length,m[4].length)==m[4]","*=":"z&&z.indexOf(m[4])>=0","":"z",_resort:function(m){return["",m[1],m[3],m[2],m[5]]},_prefix:"z=a[m[3]];if(!z||/href|src/.test(m[3]))z=jQuery.attr(a,m[3]);"},"[":"jQuery.find(m[2],a).length"},parse:[/^\[ *(@)([a-z0-9_-]*) *([!*$^=]*) *('?"?)(.*?)\4 *\]/i,/^(\[)\s*(.*?(\[.*?\])?[^[]*?)\s*\]/,/^(:)([a-z0-9_-]*)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/i,/^([:.#]*)([a-z0-9_*-]*)/i],token:[/^(\/?\.\.)/,"a.parentNode",/^(>|\/)/,"jQuery.sibling(a.firstChild)",/^(\+)/,"jQuery.nth(a,2,'nextSibling')",/^(~)/,function(a){var s=jQuery.sibling(a.parentNode.firstChild);return s.slice(jQuery.inArray(a,s)+1)}],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r)}return cur},find:function(t,context){if(typeof t!="string")return[t];if(context&&!context.nodeType)context=null;context=context||document;if(!t.indexOf("//")){context=context.documentElement;t=t.substr(2,t.length)}else if(!t.indexOf("/")){context=context.documentElement;t=t.substr(1,t.length);if(t.indexOf("/")>=1)t=t.substr(t.indexOf("/"),t.length)}var ret=[context],done=[],last=null;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t).replace(/^\/\//i,"");var foundToken=false;var re=/^[\/>]\s*([a-z0-9*-]+)/i;var m=re.exec(t);if(m){jQuery.each(ret,function(){for(var c=this.firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(jQuery.nodeName(c,m[1])||m[1]=="*"))r.push(c)});ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true}else{for(var i=0;i<jQuery.token.length;i+=2){var re=jQuery.token[i];var m=re.exec(t);if(m){r=ret=jQuery.map(ret,jQuery.isFunction(jQuery.token[i+1])?jQuery.token[i+1]:function(a){return eval(jQuery.token[i+1])});t=jQuery.trim(t.replace(re,""));foundToken=true;break}}}if(t&&!foundToken){if(!t.indexOf(",")){if(ret[0]==context)ret.shift();jQuery.merge(done,ret);r=ret=[context];t=" "+t.substr(1,t.length)}else{var re2=/^([a-z0-9_-]+)(#)([a-z0-9\\*_-]*)/i;var m=re2.exec(t);if(m){m=[0,m[2],m[3],m[1]]}else{re2=/^([#.]?)([a-z0-9\\*_-]*)/i;m=re2.exec(t)}if(m[1]=="#"&&ret[ret.length-1].getElementById){var oid=ret[ret.length-1].getElementById(m[2]);if(jQuery.browser.msie&&oid&&oid.id!=m[2])oid=jQuery('[@id="'+m[2]+'"]',ret[ret.length-1])[0];ret=r=oid&&(!m[3]||jQuery.nodeName(oid,m[3]))?[oid]:[]}else{if(m[1]==".")var rec=new RegExp("(^|\\s)"+m[2]+"(\\s|$)");jQuery.each(ret,function(){var tag=m[1]!=""||m[0]==""?"*":m[2];if(jQuery.nodeName(this,"object")&&tag=="*")tag="param";jQuery.merge(r,m[1]!=""&&ret.length!=1?jQuery.getAll(this,[],m[1],m[2],rec):this.getElementsByTagName(tag))});if(m[1]=="."&&ret.length==1)r=jQuery.grep(r,function(e){return rec.test(e.className)});if(m[1]=="#"&&ret.length==1){var tmp=r;r=[];jQuery.each(tmp,function(){if(this.getAttribute("id")==m[2]){r=[this];return false}})}ret=r}t=t.replace(re2,"")}}if(t){var val=jQuery.filter(t,r);ret=r=val.r;t=jQuery.trim(val.t)}}if(ret&&ret[0]==context)ret.shift();jQuery.merge(done,ret);return done},filter:function(t,r,not){while(t&&/^[a-z[({<*:.#]/i.test(t)){var p=jQuery.parse,m;jQuery.each(p,function(i,re){m=re.exec(t);if(m){t=t.substring(m[0].length);if(jQuery.expr[m[1]]._resort)m=jQuery.expr[m[1]]._resort(m);return false}});if(m[1]==":"&&m[2]=="not")r=jQuery.filter(m[3],r,true).r;else if(m[1]=="."){var re=new RegExp("(^|\\s)"+m[2]+"(\\s|$)");r=jQuery.grep(r,function(e){return re.test(e.className||"")},not)}else{var f=jQuery.expr[m[1]];if(typeof f!="string")f=jQuery.expr[m[1]][m[2]];eval("f = function(a,i){"+(jQuery.expr[m[1]]._prefix||"")+"return "+f+"}");r=jQuery.grep(r,f,not)}}return{r:r,t:t}},getAll:function(o,r,token,name,re){for(var s=o.firstChild;s;s=s.nextSibling)if(s.nodeType==1){var add=true;if(token==".")add=s.className&&re.test(s.className);else if(token=="#")add=s.getAttribute("id")==name;if(add)r.push(s);if(token=="#"&&r.length)break;if(s.firstChild)jQuery.getAll(s,r,token,name,re)}return r},parents:function(elem){var matched=[];var cur=elem.parentNode;while(cur&&cur!=document){matched.push(cur);cur=cur.parentNode}return matched},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir]){if(cur.nodeType==1)num++;if(num==result||result=="even"&&num%2==0&&num>1&&cur==elem||result=="odd"&&num%2==1&&cur==elem)return cur}},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&(!elem||n!=elem))r.push(n)}return r}});jQuery.event={add:function(element,type,handler,data){if(jQuery.browser.msie&&element.setInterval!=undefined)element=window;if(data)handler.data=data;if(!handler.guid)handler.guid=this.guid++;if(!element.$events)element.$events={};var handlers=element.$events[type];if(!handlers){handlers=element.$events[type]={};if(element["on"+type])handlers[0]=element["on"+type]}handlers[handler.guid]=handler;element["on"+type]=this.handle;if(!this.global[type])this.global[type]=[];this.global[type].push(element)},guid:1,global:{},remove:function(element,type,handler){if(element.$events){var i,j,k;if(type&&type.type){handler=type.handler;type=type.type}if(type&&element.$events[type])if(handler)delete element.$events[type][handler.guid];else for(i in element.$events[type])delete element.$events[type][i];else for(j in element.$events)this.remove(element,j);for(k in element.$events[type])if(k){k=true;break}if(!k)element["on"+type]=null}},trigger:function(type,data,element){data=jQuery.makeArray(data||[]);if(!element)jQuery.each(this.global[type]||[],function(){jQuery.event.trigger(type,data,this)});else{var handler=element["on"+type],val,fn=jQuery.isFunction(element[type]);if(handler){data.unshift(this.fix({type:type,target:element}));if((val=handler.apply(element,data))!==false)this.triggered=true}if(fn&&val!==false)element[type]();this.triggered=false}},handle:function(event){if(typeof jQuery=="undefined"||jQuery.event.triggered)return;event=jQuery.event.fix(event||window.event||{});var returnValue;var c=this.$events[event.type];var args=[].slice.call(arguments,1);args.unshift(event);for(var j in c){args[0].handler=c[j];args[0].data=c[j].data;if(c[j].apply(this,args)===false){event.preventDefault();event.stopPropagation();returnValue=false}}if(jQuery.browser.msie)event.target=event.preventDefault=event.stopPropagation=event.handler=event.data=null;return returnValue},fix:function(event){if(!event.target&&event.srcElement)event.target=event.srcElement;if(event.pageX==undefined&&event.clientX!=undefined){var e=document.documentElement,b=document.body;event.pageX=event.clientX+(e.scrollLeft||b.scrollLeft);event.pageY=event.clientY+(e.scrollTop||b.scrollTop)}if(jQuery.browser.safari&&event.target.nodeType==3){var originalEvent=event;event=jQuery.extend({},originalEvent);event.target=originalEvent.target.parentNode;event.preventDefault=function(){return originalEvent.preventDefault()};event.stopPropagation=function(){return originalEvent.stopPropagation()}}if(!event.preventDefault)event.preventDefault=function(){this.returnValue=false};if(!event.stopPropagation)event.stopPropagation=function(){this.cancelBubble=true};return event}};jQuery.fn.extend({bind:function(type,data,fn){return this.each(function(){jQuery.event.add(this,type,fn||data,data)})},one:function(type,data,fn){return this.each(function(){jQuery.event.add(this,type,function(event){jQuery(this).unbind(event);return(fn||data).apply(this,arguments)},data)})},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn)})},trigger:function(type,data){return this.each(function(){jQuery.event.trigger(type,data,this)})},toggle:function(){var a=arguments;return this.click(function(e){this.lastToggle=this.lastToggle==0?1:0;e.preventDefault();return a[this.lastToggle].apply(this,[e])||false})},hover:function(f,g){function handleHover(e){var p=(e.type=="mouseover"?e.fromElement:e.toElement)||e.relatedTarget;while(p&&p!=this)try{p=p.parentNode}catch(e){p=this};if(p==this)return false;return(e.type=="mouseover"?f:g).apply(this,[e])}return this.mouseover(handleHover).mouseout(handleHover)},ready:function(f){if(jQuery.isReady)f.apply(document,[jQuery]);else{jQuery.readyList.push(function(){return f.apply(this,[jQuery])})}return this}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.apply(document)});jQuery.readyList=null}if(jQuery.browser.mozilla||jQuery.browser.opera)document.removeEventListener("DOMContentLoaded",jQuery.ready,false)}}});new function(){jQuery.each(("blur,focus,load,resize,scroll,unload,click,dblclick,"+"mousedown,mouseup,mousemove,mouseover,mouseout,change,select,"+"submit,keydown,keypress,keyup,error").split(","),function(i,o){jQuery.fn[o]=function(f){return f?this.bind(o,f):this.trigger(o)}});if(jQuery.browser.mozilla||jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);else if(jQuery.browser.msie){document.write("<scr"+"ipt id=__ie_init defer=true "+"src=//:><\/script>");var script=document.getElementById("__ie_init");if(script)script.onreadystatechange=function(){if(this.readyState!="complete")return;this.parentNode.removeChild(this);jQuery.ready()};script=null}else if(jQuery.browser.safari)jQuery.safariTimer=setInterval(function(){if(document.readyState=="loaded"||document.readyState=="complete"){clearInterval(jQuery.safariTimer);jQuery.safariTimer=null;jQuery.ready()}},10);jQuery.event.add(window,"load",jQuery.ready)};if(jQuery.browser.msie)jQuery(window).one("unload",function(){var global=jQuery.event.global;for(var type in global){var els=global[type],i=els.length;if(i&&type!='unload')do jQuery.event.remove(els[i-1],type);while(--i)}});jQuery.fn.extend({loadIfModified:function(url,params,callback){this.load(url,params,callback,1)},load:function(url,params,callback,ifModified){if(jQuery.isFunction(url))return this.bind("load",url);callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null}else{params=jQuery.param(params);type="POST"}var self=this;jQuery.ajax({url:url,type:type,data:params,ifModified:ifModified,complete:function(res,status){if(status=="success"||!ifModified&&status=="notmodified")self.attr("innerHTML",res.responseText).evalScripts().each(callback,[res.responseText,status,res]);else callback.apply(self,[res.responseText,status,res])}});return this},serialize:function(){return jQuery.param(this)},evalScripts:function(){return this.find("script").each(function(){if(this.src)jQuery.getScript(this.src);else jQuery.globalEval(this.text||this.textContent||this.innerHTML||"")}).end()}});if(!window.XMLHttpRequest)XMLHttpRequest=function(){return new ActiveXObject("Microsoft.XMLHTTP")};jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f)}});jQuery.extend({get:function(url,data,callback,type,ifModified){if(jQuery.isFunction(data)){callback=data;data=null}return jQuery.ajax({url:url,data:data,success:callback,dataType:type,ifModified:ifModified})},getIfModified:function(url,data,callback,type){return jQuery.get(url,data,callback,type,1)},getScript:function(url,callback){return jQuery.get(url,null,callback,"script")},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json")},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={}}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type})},ajaxTimeout:function(timeout){jQuery.ajaxSettings.timeout=timeout},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings)},ajaxSettings:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null},lastModified:{},ajax:function(s){s=jQuery.extend({},jQuery.ajaxSettings,s);if(s.data){if(s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.type.toLowerCase()=="get"){s.url+=((s.url.indexOf("?")>-1)?"&":"?")+s.data;s.data=null}}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var requestDone=false;var xml=new XMLHttpRequest();xml.open(s.type,s.url,s.async);if(s.data)xml.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xml.setRequestHeader("X-Requested-With","XMLHttpRequest");if(xml.overrideMimeType)xml.setRequestHeader("Connection","close");if(s.beforeSend)s.beforeSend(xml);if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);var onreadystatechange=function(isTimeout){if(xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null}var status;try{status=jQuery.httpSuccess(xml)&&isTimeout!="timeout"?s.ifModified&&jQuery.httpNotModified(xml,s.url)?"notmodified":"success":"error";if(status!="error"){var modRes;try{modRes=xml.getResponseHeader("Last-Modified")}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;var data=jQuery.httpData(xml,s.dataType);if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s])}else jQuery.handleError(s,xml,status)}catch(e){status="error";jQuery.handleError(s,xml,status,e)}if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");if(s.complete)s.complete(xml,status);if(s.async)xml=null}};var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout")}},s.timeout);try{xml.send(s.data)}catch(e){jQuery.handleError(s,xml,null,e)}if(!s.async)onreadystatechange();return xml},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e])},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||jQuery.browser.safari&&r.status==undefined}catch(e){}return false},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined}catch(e){}return false},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var data=!type&&ct&&ct.indexOf("xml")>=0;data=type=="xml"||data?r.responseXML:r.responseText;if(type=="script")jQuery.globalEval(data);if(type=="json")eval("data = "+data);if(type=="html")jQuery("<div>").html(data).evalScripts();return data},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value))});else for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this))});else s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&")},globalEval:function(data){if(window.execScript)window.execScript(data);else if(jQuery.browser.safari)window.setTimeout(data,0);else eval.call(window,data)}});jQuery.fn.extend({show:function(speed,callback){var hidden=this.filter(":hidden");speed?hidden.animate({height:"show",width:"show",opacity:"show"},speed,callback):hidden.each(function(){this.style.display=this.oldblock?this.oldblock:"";if(jQuery.css(this,"display")=="none")this.style.display="block"});return this},hide:function(speed,callback){var visible=this.filter(":visible");speed?visible.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):visible.each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");if(this.oldblock=="none")this.oldblock="block";this.style.display="none"});return this},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){var args=arguments;return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"].apply(jQuery(this),args)})},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback)},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback)},slideToggle:function(speed,callback){return this.each(function(){var state=jQuery(this).is(":hidden")?"show":"hide";jQuery(this).animate({height:state},speed,callback)})},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback)},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback)},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback)},animate:function(prop,speed,easing,callback){return this.queue(function(){this.curAnim=jQuery.extend({},prop);var opt=jQuery.speed(speed,easing,callback);for(var p in prop){var e=new jQuery.fx(this,opt,p);if(prop[p].constructor==Number)e.custom(e.cur(),prop[p]);else e[prop[p]](prop)}})},queue:function(type,fn){if(!fn){fn=type;type="fx"}return this.each(function(){if(!this.queue)this.queue={};if(!this.queue[type])this.queue[type]=[];this.queue[type].push(fn);if(this.queue[type].length==1)fn.apply(this)})}});jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){jQuery.dequeue(this,"fx");if(jQuery.isFunction(opt.old))opt.old.apply(this)};return opt},easing:{},queue:{},dequeue:function(elem,type){type=type||"fx";if(elem.queue&&elem.queue[type]){elem.queue[type].shift();var f=elem.queue[type][0];if(f)f.apply(elem)}},fx:function(elem,options,prop){var z=this;var y=elem.style;var oldDisplay=jQuery.css(elem,"display");y.overflow="hidden";z.a=function(){if(options.step)options.step.apply(elem,[z.now]);if(prop=="opacity")jQuery.attr(y,"opacity",z.now);else if(parseInt(z.now))y[prop]=parseInt(z.now)+"px";y.display="block"};z.max=function(){return parseFloat(jQuery.css(elem,prop))};z.cur=function(){var r=parseFloat(jQuery.curCSS(elem,prop));return r&&r>-10000?r:z.max()};z.custom=function(from,to){z.startTime=(new Date()).getTime();z.now=from;z.a();z.timer=setInterval(function(){z.step(from,to)},13)};z.show=function(){if(!elem.orig)elem.orig={};elem.orig[prop]=this.cur();options.show=true;z.custom(0,elem.orig[prop]);if(prop!="opacity")y[prop]="1px"};z.hide=function(){if(!elem.orig)elem.orig={};elem.orig[prop]=this.cur();options.hide=true;z.custom(elem.orig[prop],0)};z.toggle=function(){if(!elem.orig)elem.orig={};elem.orig[prop]=this.cur();if(oldDisplay=="none"){options.show=true;if(prop!="opacity")y[prop]="1px";z.custom(0,elem.orig[prop])}else{options.hide=true;z.custom(elem.orig[prop],0)}};z.step=function(firstNum,lastNum){var t=(new Date()).getTime();if(t>options.duration+z.startTime){clearInterval(z.timer);z.timer=null;z.now=lastNum;z.a();if(elem.curAnim)elem.curAnim[prop]=true;var done=true;for(var i in elem.curAnim)if(elem.curAnim[i]!==true)done=false;if(done){y.overflow="";y.display=oldDisplay;if(jQuery.css(elem,"display")=="none")y.display="block";if(options.hide)y.display="none";if(options.hide||options.show)for(var p in elem.curAnim)if(p=="opacity")jQuery.attr(y,p,elem.orig[p]);else y[p]=""}if(done&&jQuery.isFunction(options.complete))options.complete.apply(elem)}else{var n=t-this.startTime;var p=n/options.duration;z.now=options.easing&&jQuery.easing[options.easing]?jQuery.easing[options.easing](p,n,firstNum,(lastNum-firstNum),options.duration):((-Math.cos(p*Math.PI)/2)+0.5)*(lastNum-firstNum)+firstNum;z.a()}}}})}
// dimensions
jQuery.fn._height=jQuery.fn.height;jQuery.fn._width=jQuery.fn.width;jQuery.fn.height=function(){if(this[0]==window)return self.innerHeight||jQuery.boxModel&&document.documentElement.clientHeight||document.body.clientHeight;if(this[0]==document)return Math.max(document.body.scrollHeight,document.body.offsetHeight);return this._height(arguments[0]);};jQuery.fn.width=function(){if(this[0]==window)return self.innerWidth||jQuery.boxModel&&document.documentElement.clientWidth||document.body.clientWidth;if(this[0]==document)return Math.max(document.body.scrollWidth,document.body.offsetWidth);return this._width(arguments[0]);};jQuery.fn.innerHeight=function(){return this[0]==window||this[0]==document?this.height():this.css('display')!='none'?this[0].offsetHeight-(parseInt(this.css("borderTopWidth"))||0)-(parseInt(this.css("borderBottomWidth"))||0):this.height()+(parseInt(this.css("paddingTop"))||0)+(parseInt(this.css("paddingBottom"))||0);};jQuery.fn.innerWidth=function(){return this[0]==window||this[0]==document?this.width():this.css('display')!='none'?this[0].offsetWidth-(parseInt(this.css("borderLeftWidth"))||0)-(parseInt(this.css("borderRightWidth"))||0):this.height()+(parseInt(this.css("paddingLeft"))||0)+(parseInt(this.css("paddingRight"))||0);};jQuery.fn.outerHeight=function(){return this[0]==window||this[0]==document?this.height():this.css('display')!='none'?this[0].offsetHeight:this.height()+(parseInt(this.css("borderTopWidth"))||0)+(parseInt(this.css("borderBottomWidth"))||0)+(parseInt(this.css("paddingTop"))||0)+(parseInt(this.css("paddingBottom"))||0);};jQuery.fn.outerWidth=function(){return this[0]==window||this[0]==document?this.width():this.css('display')!='none'?this[0].offsetWidth:this.height()+(parseInt(this.css("borderLeftWidth"))||0)+(parseInt(this.css("borderRightWidth"))||0)+(parseInt(this.css("paddingLeft"))||0)+(parseInt(this.css("paddingRight"))||0);};jQuery.fn.scrollLeft=function(){if(this[0]==window||this[0]==document)return self.pageXOffset||jQuery.boxModel&&document.documentElement.scrollLeft||document.body.scrollLeft;return this[0].scrollLeft;};jQuery.fn.scrollTop=function(){if(this[0]==window||this[0]==document)return self.pageYOffset||jQuery.boxModel&&document.documentElement.scrollTop||document.body.scrollTop;return this[0].scrollTop;};jQuery.fn.offset=function(options,returnObject){var x=0,y=0,elem=this[0],parent=this[0],absparent=false,relparent=false,op,sl=0,st=0,options=jQuery.extend({margin:true,border:true,padding:false,scroll:true},options||{});do{x+=parent.offsetLeft||0;y+=parent.offsetTop||0;if(jQuery.browser.mozilla||jQuery.browser.msie){var bt=parseInt(jQuery.css(parent,'borderTopWidth'))||0;var bl=parseInt(jQuery.css(parent,'borderLeftWidth'))||0;x+=bl;y+=bt;if(jQuery.browser.mozilla&&parent!=elem&&jQuery.css(parent,'overflow')!='visible'){x+=bl;y+=bt;}if(jQuery.css(parent,'position')=='absolute')absparent=true;if(jQuery.css(parent,'position')=='relative')relparent=true;}if(options.scroll){op=parent.offsetParent;do{sl+=parent.scrollLeft||0;st+=parent.scrollTop||0;parent=parent.parentNode;if(jQuery.browser.mozilla&&parent!=elem&&parent!=op&&jQuery.css(parent,'overflow')!='visible'){x+=parseInt(jQuery.css(parent,'borderLeftWidth'))||0;y+=parseInt(jQuery.css(parent,'borderTopWidth'))||0;}}while(op&&parent!=op);}else parent=parent.offsetParent;if(parent&&(parent.tagName.toLowerCase()=='body'||parent.tagName.toLowerCase()=='html')){if((jQuery.browser.safari||(jQuery.browser.msie&&jQuery.boxModel))&&jQuery.css(elem,'position')!='absolute'){x+=parseInt(jQuery.css(parent,'marginLeft'))||0;y+=parseInt(jQuery.css(parent,'marginTop'))||0;}if((jQuery.browser.mozilla&&!absparent)||(jQuery.browser.msie&&jQuery.css(elem,'position')=='static'&&(!relparent||!absparent))){x+=parseInt(jQuery.css(parent,'borderLeftWidth'))||0;y+=parseInt(jQuery.css(parent,'borderTopWidth'))||0;}break;}}while(parent);if(!options.margin){x-=parseInt(jQuery.css(elem,'marginLeft'))||0;y-=parseInt(jQuery.css(elem,'marginTop'))||0;}if(options.border&&(jQuery.browser.safari||jQuery.browser.opera)){x+=parseInt(jQuery.css(elem,'borderLeftWidth'))||0;y+=parseInt(jQuery.css(elem,'borderTopWidth'))||0;}else if(!options.border&&!(jQuery.browser.safari||jQuery.browser.opera)){x-=parseInt(jQuery.css(elem,'borderLeftWidth'))||0;y-=parseInt(jQuery.css(elem,'borderTopWidth'))||0;}if(options.padding){x+=parseInt(jQuery.css(elem,'paddingLeft'))||0;y+=parseInt(jQuery.css(elem,'paddingTop'))||0;}if(options.scroll&&jQuery.browser.opera&&jQuery.css(elem,'display')=='inline'){sl-=elem.scrollLeft||0;st-=elem.scrollTop||0;}var returnValue=options.scroll?{top:y-st,left:x-sl,scrollTop:st,scrollLeft:sl}:{top:y,left:x};if(returnObject){jQuery.extend(returnObject,returnValue);return this;}else{return returnValue;}};
// metadata plugin
(function($){$.meta={type:"class",name:"metadata",setType:function(type,name){this.type=type;this.name=name},cre:/({.*})/,single:'metadata'};var setArray=$.fn.setArray;$.fn.setArray=function(arr){return setArray.apply(this,arguments).each(function(){if(this.nodeType==9||$.isXMLDoc(this)||this.metaDone)return;var data="{}";if($.meta.type=="class"){var m=$.meta.cre.exec(this.className);if(m)data=m[1]}else if($.meta.type=="elem"){if(!this.getElementsByTagName)return;var e=this.getElementsByTagName($.meta.name);if(e.length)data=$.trim(e[0].innerHTML)}else if(this.getAttribute!=undefined){var attr=this.getAttribute($.meta.name);if(attr)data=attr}if(!/^{/.test(data))data="{"+data+"}";eval("data = "+data);if($.meta.single)this[$.meta.single]=data;else $.extend(this,data);this.metaDone=true})};$.fn.data=function(){return this[0][$.meta.single]}})(jQuery);
// Validate plugin
/*
 * Form Validation: jQuery form validation plug-in v1.0 beta 3
 *
 * Copyright (c) 2006 Jörn Zaefferer
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

/*
TODOs
- use array with {name, message, element} objects intead of errorList object
- remove any dependencie on ids
  - add a forName attribute to generated error message, and for only if an id is present
  - don't generate ids
- implement successPlacement or something similar (see custom-methods-demo.html)
*/

/**
 * Validates a single form.
 *
 * The normal behaviour is to validate a form when a submit button is clicked or
 * the user presses enter when an input of that form is focused.
 *
 * It is also possible to validate each individual element of that form, eg. on blur or keyup.
 *
 * @example $("#myform").validate();
 * @before <form id="myform">
 *   <input name="firstname" class="{required:true}" />
 * </form>
 * @desc Validates a form on submit. Rules are read from metadata.
 *
 * @example $("input").validate({
 * 		focusInvalid: false,
 * 		event: "blur"
 * });
 * @desc Validates all input elements on blur event (when the element looses focus).
 * Deactivates focus of invalid elements.
 *
 * @example $("#myform").validate({
 *   submitHandler: function(form) {
 *   	$(form).ajaxSubmit();
 *   }
 * });
 * @desc Uses form plugin's ajaxSubmit method to handle the form submit, while preventing
 * the default submit.
 *
 * @example $("#myform").validate({
 *  event: "keyup"
 * 	rules: {
 * 		firstname: { required: true },
 * 		age: {
 *			required: "#firstname:blank",
 * 			number: true,
 * 			minValue: 3
 * 		},
 * 		password: {
 * 			required: function() {
 * 				return $("#age").val() < 18;
 * 			},
 * 			minLength: 5,
 * 			maxLength: 32
 * 		}
 * 	},
 *  messages {
 * 		password: {
 * 			required: "Your password is required because you are not yet 18 years or older."
 * 			minLength: "Please enter a password at least 5 characters long.",
 * 			maxLength: "Please enter a password no longer then 32 characters long."
 * 		},
 *		age: "Please specify your age as a number (at least 3)."
 * 	}
 * });
 * @desc Validate a form on submit and each element on keyup. Rules are specified
 * for three elements, and a message is customized for the "password" and the
 * "age" elements. Inline rules are ignored. The password is only required when the age is lower
 * then 18. The age is only required when the firstname is blank.
 *
 * @example $("#myform").validate({
 *   errorClass: "invalid",
 *   errorLabelContainer: $("#messageBox"),
 *   wrapper: "li"
 * });
 * @before <ul id="messageBox"></ul>
 * <form id="myform" action="/login" method="post">
 *   <label>Firstname</label>
 *   <input name="fname" class="{required:true}" />
 *   <label>Lastname</label>
 *   <input name="lname" title="Your lastname, please!" class="{required:true}" />
 * </form>
 * @result <ul id="messageBox">
 *   <li><label for="fname" class="invalid">Please specify your firstname!</label></li>
 *   <li><label for="lname" class="invalid">Your lastname, please!</label></li>
 * </ul>
 * <form id="myform" action="/login" method="post">
 *   <label>Firstname</label>
 *   <input name="fname" class="{required:true} invalid" />
 *   <label>Lastname</label>
 *   <input name="lname" title="Your lastname, please!" class="{required:true} invalid" />
 * </form>
 * @desc Validates a form on submit. The class used to search, create and display
 * error labels is changed to "invalid". This is also added to invalid elements.
 *
 * All error labels are displayed inside an unordered list with the ID "messageBox", as
 * specified by the jQuery object passed as errorContainer option. All error elements
 * are wrapped inside an li element, to create a list of messages.
 *
 * To ease the setup of the form, debug option is set to true, preventing a submit
 * of the form no matter of being valid or not.
 *
 *
 * @example $("#myform").validate({
 * 	errorPlacement: function(error, element) {
 * 		error.appendTo( element.parent("td").next("td") );
 * 	}
 * });
 * @before <form id="myform" action="/login" method="post">
 * 	<table>
 * 		<tr>
 * 			<td><label>Firstname</label>
 * 			<td><input name="fname" class="{required:true}" /></td>
 * 			<td></td>
 * 		</tr>
 * 		<tr>
 * 			<td><label>Lastname</label></td>
 * 			<td><input name="lname" title="Your lastname, please!" class="{required:true}" /></td>
 * 			<td></td>
 * 		</tr>
 * 	</table>
 * </form>
 * @result <form id="myform" action="/login" method="post">
 * 	<table>
 * 		<tr>
 * 			<td><label>Firstname</label>
 * 			<td><input name="fname" class="{required:true}" /></td>
 * 			<td><label for="fname" class="invalid">Please specify your firstname!</label></td>
 * 		</tr>
 * 		<tr>
 * 			<td><label>Lastname</label></td>
 * 			<td><input name="lname" title="Your lastname, please!" class="{required:true}" /></td>
 * 			<td><label for="lname" class="invalid">Your lastname, please!</label></td>
 * 		</tr>
 * 	</table>
 * </form>
 * @desc Validates a form on submit. Customizes the placement of the generated labels
 * by appending them to the next table cell.
 *
 * @example $("#myform").validate({
 *   errorContainer: $("#messageBox1, #messageBox2"),
 *   errorLabelContainer: $("#messageBox1 ul"),
 *   wrapper: "li",
 * });
 * @before <div id="messageBox1">
 *   <h3>The are errors in your form!</h3>
 *   <ul></ul>
 * </div>
 * <form id="myform" action="/login" method="post">
 *   <label>Firstname</label>
 *   <input name="fname" class="{required:true}" />
 *   <label>Lastname</label>
 *   <input name="lname" title="Your lastname, please!" class="{required:true}" />
 * </form>
 * <div id="messageBox2">
 *   <h3>The are errors in your form, see details above!</h3>
 * </div>
 * @result <ul id="messageBox">
 *   <li><label for="fname" class="error">Please specify your firstname!</label></li>
 *   <li><label for="lname" class="error">Your lastname, please!</label></li>
 * </ul>
 * <form id="myform" action="/login" method="post">
 *   <label>Firstname</label>
 *   <input name="fname" class="{required:true} error" />
 *   <label>Lastname</label>
 *   <input name="lname" title="Your lastname, please!" class="{required:true} error" />
 * </form>
 * @desc Validates a form on submit. Similar to the above example, but with an additional
 * container for error messages. The elements given as the errorContainer are all shown
 * and hidden when errors occur. But the error labels themselve are added to the element(s)
 * given as errorLabelContainer, here an unordered list. Therefore the error labels are
 * also wrapped into li elements (wrapper option).
 *
 * @param Map options Optional settings to configure validation
 * @option String errorClass Use this class to look for existing error labels and add it to
 *		invalid elements. Default: "error"
 * @option String wrapper Wrap error labels with the specified element, eg "li". Default: none
 * @option Boolean debug If true, the form is not submitted and certain errors are display on the console (requires Firebug or Firebug lite). Default: none
 * @option Boolean focusInvalid Focus the last active or first invalid element on submit or via validator.focusInvalid(). Default: true
 * @option Function submitHandler Callback for handling the actual
 *		submit when the form is valid. Gets the form as the only argmument. Default: normal form submit
 * @option Map messages Key/value pairs defining custom messages.
 *		Key is the ID or name (for radio/checkbox inputs) of an element,
 *		value the message to display for that element. Instead of a plain message
 *		another map with specific messages for each rule can be used.
 *		Can be specified for one or more elements. Can be overriden by
 *		specifying the title attribute on the element.
 *      Default: none, the default message for the method is used.
 * @option Map rules Key/value pairs defining custom rules.
 *		Key is the ID or name (for radio/checkbox inputs) of an element,
 *		value is an object consisting of rule/parameter pairs, eg. {required: true, min: 3}.
 *   	Once specified, metadata rules are completely ignored.
 *		Default: none, rules are read from metadata via metadata plugin
 * @option String event The event on which to validate. If anything is specified, like
 *		blur or keyup, each element is validated on that event. Default: none
 * @option Boolean onsubmit Validate the form on submit. Set to false to use only other
 *		events for validation (option event). Default: true
 * @option String meta In case you use metadata for other plugins, too, you
 *		want to wrap your validation rules
 *		into their own object that can be specified via this option. Default: none
 * @option jQuery errorContainer Hide and show this container when validating. Default: none
 * @option jQuery errorLabelContainer Search and append error labels to this container, and show and hide it accordingly. Default: none
 * @option Function showErrors A custom message display handler. Gets the map of errors as the
 *		first argument and a refernce to the validator object as the second.
 * 		You can trigger (in addition to your own messages) the default behaviour by calling
 * 		the defaultShowErrors() method of the validator.
 * 		Default: none, uses built-in message disply.
 * @option Function errorPlacement Used to customize placement of created error labels.
 *		First argument: jQuery object containing the created error label
 *		Second argument: jQuery object containing the invalid element
 *		Default: Places the error label after the invalid element
 * @option String errorElement The element to use for generated error messages. Default: "label".
 *
 * @name validate
 * @type $.validator
 * @cat Plugins/Validate
 */

jQuery.extend(jQuery.fn, {
	validate: function( options ) {
		var validator = new jQuery.validator( options, this[0] );
		
		if ( validator.settings.onsubmit ) {
			// validate the form on submit
			this.submit( function( event ) {
				if ( validator.settings.debug )
					// prevent form submit to be able to see console output
					event.preventDefault();
				// prevent submit for invalid forms or custom submit handlers
				if ( validator.form() ) {
					return validator.settings.submitHandler
						&& validator.settings.submitHandler( validator.currentForm )
						&& false
						|| true
				} else {
					validator.focusInvalid();
					return false;
				}
			});
		}
		
		if ( validator.settings.event ) {
			// validate all elements on some other event like blur or keypress
			validator.elements.bind( validator.settings.event, function() {
				validator.element(this);
			} );
		}
		
		return validator;
	},
	// destructive add
	push: function( t ) {
		return this.setArray( jQuery.merge( this.get(), t ) );
	},
	forId: function( id ) {
		return this.filter( "[@for='" + id + "']" );
	}
});

/**
 * Custom expression to filter for blank fields.
 *
 * @example jQuery("input:blank").length
 * @before <input value="" /><input value="  " /><input value="abc" />
 * @result 2
 *
 * @property
 * @type String
 * @name :blank
 * @cat Plugins/Validate
 */
 
/**
 * Custom expression to filter for filled fields.
 *
 * @example jQuery("input:filled").length
 * @before <input value="" /><input value="  " /><input value="abc" />
 * @result 1
 *
 * @property
 * @type String
 * @name :filled
 * @cat Plugins/Validate
 */
jQuery.extend(jQuery.expr[":"], {
	blank: "!jQuery.trim(a.value)",
	filled: "!!jQuery.trim(a.value)"
});

// constructor for validator
jQuery.validator = function( options, form ) {
	this.settings = jQuery.extend( {}, jQuery.validator.defaults, options );
	
	this.currentForm = form;
	this.labelContainer = this.settings.errorLabelContainer;
	this.errorContext = this.labelContainer.length && this.labelContainer || jQuery(form);
	this.containers = this.settings.errorContainer.add( this.settings.errorLabelContainer );
	
	this.reset();
	this.refresh();
};

jQuery.extend(jQuery.validator, {
	
	defaults: {
		messages: {},
		errorClass: "error",
		errorElement: "label",
		focusInvalid: true,
		errorContainer: jQuery( [] ),
		errorLabelContainer: jQuery( [] ),
		onsubmit: true
	},
	
	/**
	 * Modify default settings for validation.
	 *
	 * @example jQuery.validator.setDefaults({
	 * 	debug: true
	 * );
	 * @desc Sets the debug setting for all validation calls following.
	 *
	 * @param Object<String, Object> settings
	 * @name jQuery.validator.setDefaults
	 * @type undefined
	 * @cat Plugins/Validate
	 */
	setDefaults: function(settings) {
		jQuery.extend( jQuery.validator.defaults, settings );
	},
	
	/**
	 * Default messages for all default methods.
	 *
	 * Use addMethod() to add methods with messages.
	 *
	 * Replace these messages for localization.
	 *
	 * @property
	 * @type String
	 * @name jQuery.validator.messages
	 * @cat Plugins/Validate
	 */
	messages: {
		required: "This field is required.",
		maxLength: "Please enter a value no longer then {0} characters.",
		minLength: "Please enter a value of at least {0} characters.",
		rangeLength: "Please enter a value between {0} and {1} characters long.",
		email: "Please enter a valid email address.",
		url: "Please enter a valid URL.",
		date: "Please enter a valid date.",
		dateISO: "Please enter a valid date (ISO).",
		dateDE: "Bitte geben Sie ein gültiges Datum ein.",
		number: "Please enter a valid number.",
		numberDE: "Bitte geben Sie eine Nummer ein.",
		digits: "Please enter only digits",
		equalTo: "Please enter the same value again.",
		rangeValue: "Please enter a value between {0} and {1}.",
		maxValue: "Please enter a value less than or equal to {0}.",
		minValue: "Please enter a value greater than or equal to {0}.",
		accept: "Please enter a value with a valid extension."
	},
	
	prototype: {
	
		/**
		 * Validate on instant the entire form.
		 *
		 * @example $("#myform").validate().form();
		 * @desc Triggers form validation programmatcitally.
		 *
		 * @name jQuery.validator.protoype.form
		 * @type Boolean True when the form is valid, otherwise false
		 * @cat Plugins/Validate
		 */
		form: function() {
			this.prepareForm();
			for ( var i = 0, element; element = this.elements[i]; i++ ) {
				this.check( element );
			}
			return this.valid();
		},
		
		/**
		 * Validate on instant a single element.
		 *
		 * @example $("#myform").validate().element( "#myselect" );
		 * @desc Triggers validation on a single element programmatically.
		 *
		 * @param String|Element element A selector or an element to validate
		 *
		 * @name jQuery.validator.protoype.element
		 * @type Boolean True when the form is valid, otherwise false
		 * @cat Plugins/Validate
		 */
		element: function( element ) {
			this.prepareElement( element );
			this.check( element );
			this.showErrors();
		},
		
		/**
		 * Show the specified messages.
		 *
		 * @example var validator = $("#myform").validate();
		 * validator.showErrors({"firstname": "I know that your firstname is Pete, Pete!"});
		 * @desc Adds and shows error message programmatically.
		 *
		 * @param Map errors One or more key/value pairs of identifiers (IDs or names) and messages
		 *
		 * @name jQuery.validator.protoype.showErrors
		 * @cat Plugins/Validate
		 */
		showErrors: function(errors) {
			if(errors)
				jQuery.extend(this.errorList, errors);
			this.settings.showErrors
				? this.settings.showErrors( this.errorList, this )
				: this.defaultShowErrors();
		},
		
		/**
		 * Resets the controlled form, including resetting input fields
		 * to their original value (requires form plugin), removing classes
		 * indicating invalid elements and hiding error messages.
		 *
		 * @example var validator = $("#myform").validate();
		 * validator.resetForm();
		 * @desc Reset the form controlled by this validator.
		 *
		 * @name jQuery.validator.protoype.resetForm
		 * @cat Plugins/Validate
		 */
		resetForm: function() {
			if( jQuery.fn.resetForm )
				jQuery( this.currentForm ).resetForm();
			this.prepareForm();
			this.hideErrors();
			this.elements.removeClass( this.settings.errorClass );
		},
		
		focusInvalid: function() {
			if( this.settings.focusInvalid ) {
				// check if the last focused element is invalid
				if( this.lastActive && this.errorList[this.lastActive.id])
					// focus it
					this.lastActive.focus();
				// otherwise, find the first invalid lement
				else {
					for ( elementID in this.errorList ) {
						// IE throws an exception when focusing hidden element
						try {
							// focus the first invalid element
							jQuery("#"+elementID).focus();
						} catch(e) { this.settings.debug && window.console && console.log(e); }
						break;
					}
				}
			}
		},
		
		refresh: function() {
			var validator = this;
			function focusHandler() {
				validator.lastActive = this;
			}
			// select all valid inputs inside the form (no submit or reset buttons)
			// and listen for focus events to save reference to last focused element
			this.elements = jQuery(this.currentForm).find(":input:not(:submit):not(:reset)").focus(focusHandler);
		},
		
		clean: function( selector ) {
			return jQuery( selector )[0];
		},
		
		errors: function() {
			return jQuery( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
		},
		
		reset: function( element ) {
			this.errorList = {};
			this.toShow = $( [] );
			this.toHide = $( [] );
		},
		
		prepareForm: function() {
			this.reset();
			this.toHide = this.errors().push( this.containers );
			this.toShow.push( this.containers );
		},
		
		prepareElement: function( element ) {
			this.reset();
			this.toHide = this.errors().forId( this.findId( this.clean( element ) ) );
		},
	
		check: function( element ) {
			element = this.clean( element );
			jQuery( element ).removeClass( this.settings.errorClass );
			var rules = this.rules( element );
			for( var i = 0, rule; rule = rules[i++]; ) {
				try {
					var result = jQuery.validator.methods[rule.method]( jQuery.trim(element.value), element, rule.parameters );
					if( result === -1 )
						break;
					if( !result ) {
						jQuery(element).addClass( this.settings.errorClass );
						this.formatAndAdd( rule, element);
						break;
					}
				} catch(e) {
					this.settings.debug && window.console && console.error("exception occured when checking element " + element.id
						 + ", check the '" + rule.method + "' method");
					throw e;
				}
			}
		},
		
		message: function( id, rule ) {
			var m = this.settings.messages[id];
			return m && (m.constructor == String
				? m
				: m[rule.method]);
		},
		
		formatAndAdd: function( rule, element) {
			var id = this.findId( element ),
				param = rule.parameters;
			this.errorList[id] = (
					this.message(id, rule)
					|| element.title
					|| jQuery.validator.messages[rule.method]
					|| "<strong>Warning: No message defined for " + id + "</strong>"
				)
				.replace( "{0}", (param.constructor == Array
					? "" + param[0]
					: "" + param) || "" )
				.replace( "{1}", "" + param[1] || "" );
		},
		
		valid: function() {
			if ( this.countErrors() ) {
				this.showErrors();
				return false;
			} else {
				this.hideErrors();
				return true;
			}
		},
		
		countErrors: function() {
			var count = 0;
			jQuery.each( this.errorList, function() {
				count++;
			} );			
			return count;
		},
		
		hideErrors: function() {
			this.toggle( "Hide" );
		},
		
		toggle: function(that) {
			var self = this;
			function which() {
				return self["to" + that];
			}
			if ( this.settings.wrapper ) {
				which().push( which().parents( this.settings.wrapper ) );
			}
			which()[that.toLowerCase()]();
			return this;
		},
		
		defaultShowErrors: function() {
			for ( var elementID in this.errorList ) {
				// display the error label for the first failed method
				this.showError( elementID, this.errorList[elementID] );
			}
			this.toHide = this.toHide.not( this.toShow );
			this.toggle( "Hide" ).toggle( "Show" );
		},
		
		showError: function(id, message) {
			var error = this.errors().forId(id);
			if ( error.length ) {
				// check if we have a generated label, replace the message then
				if( error.attr("generated") ) {
					error.html(message);
				}
			} else {
				// create label
				error = jQuery("<" + this.settings.errorElement + ">").attr({"for": id, generated: true}).addClass(this.settings.errorClass).html(message);
				if ( this.settings.wrapper ) {
					// make sure the element is visible, even in IE
					// actually showing the wrapped element is handled elsewhere
					error = error.hide().show().wrap("<" + this.settings.wrapper + ">").parent();
				}
				if ( !this.labelContainer.append(error).length )
					this.settings.errorPlacement
						? this.settings.errorPlacement(error, jQuery("#" + id) )
						: error.insertAfter("#" + id);
			}
			this.toShow.push(error);
		},
		
		rules: function( element ) {
			if( !this.data( element ) )
				return [];
			var rules = [];
			jQuery.each( this.data(element), function(key, value) {
				rules[rules.length] = {
					method: key,
					parameters: value
				};
			} );
			return rules;
		},
		
		data: function( element ) {
			return this.settings.rules
				? this.settings.rules[this.findId(element)]
				: this.settings.meta
					? jQuery(element).data()[ this.settings.meta ]
					: jQuery(element).data();
		},
		
		findId: function(element) {
			var id = ( /radio|checkbox/i.test(element.type) )
				? element.name
				: element.id;
			// generate id when none is found
			if(!id) {
				var formId = element.form.id,
					idcleanup = /[^a-zA-Z0-9\-_]/g;
				id = element.id = (formId ? formId.replace(idcleanup, "") : "") + element.name.replace(idcleanup, "");
			}
			return id;
		}
		
	},
	
	getLength: function(value, element) {
		switch( element.nodeName.toLowerCase() ) {
		case 'select':
			return jQuery("option:selected", element).length;
		case 'input':
			if( /radio|checkbox/i.test(element.type) )
				return jQuery(element.form || document).find('[@name="' + element.name + '"]:checked').length;
		}
		return value.length;
	},
	
	depend: function(param, element) {
		return this.dependTypes[typeof param]
			? this.dependTypes[typeof param](param, element)
			: true;
	},
	
	dependTypes: {
		"boolean": function(param, element) {
			return param;
		},
		"string": function(param, element) {
			return !!jQuery(param, element.form).length;
		},
		"function": function(param, element) {
			return param(element);
		}
	},
	
	/**
	 * Defines a standard set of useful validation methods.
	 * 
	 * Use jQuery.validator.addMethod() to add your own methods.
	 *
	 * If "all kind of text inputs" is mentioned for any if the methods defined here,
	 * it refers to input elements of type text, password and file and textareas.
	 *
	 * @param String value The trimmed value of the element, eg. the text of a text input (trimmed: whitespace removed at start and end)
	 * @param Element element the input element itself, to check for content of attributes other then value
	 * @param Object paramater Some parameter, like a number for min/max rules
	 *
	 * @property
	 * @name jQuery.validator.methods
	 * @type Object<String, Function(String,Element,Object):Boolean>
	 * @cat Plugins/Validate/Methods
	 */
	methods: {
	
		/**
		 * Return false if the element is empty.
		 *
		 * Works with all kind of text inputs, selects, checkboxes and radio buttons.
		 *
		 * To force a user to select an option from a select box, provide
		 * an empty options like <option value="">Choose...</option>
		 *
		 * @example <input name="firstname" class="{required:true}" />
		 * @desc Declares an input element that is required.
		 *
		 * @example <input id="other" type="radio" />
		 * <input name="details" class="{required:'#other:checked'}" />
		 * @desc Declares an input element required, but only if a radio button with id "other" is checked.
		 * In other words: As long the "#other" isn't checked, the details field is valid.
		 *
		 * @example jQuery("#myform").validate({
		 * 	rules: {
		 * 		details: {
		 * 			required: function(element) {
		 *				return jQuery("#other").is(":checked") && jQuery("#other2").is(":checked");
		 *			}
		 *		}
		 * 	}
		 * });
		 * @before <form id="myform">
		 * 	<input id="other" type="checkbox" />
		 * 	<input id="other2" type="checkbox" />
		 * 	<input name="details" />
		 * </form>
		 * @desc Declares an input element "details", required, but only if two other fields
		 * are checked.
		 *
		 * @example <fieldset>
		 * 	<legend>Family</legend>
		 * 	<label for="family_single">
		 * 		<input  type="radio" id="family_single" value="s" name="family" validate="required:true" />
		 * 		Single
		 * 	</label>
		 * 	<label for="family_married">
		 * 		<input  type="radio" id="family_married" value="m" name="family" />
		 * 		Married
		 * 	</label>
		 * 	<label for="family_divorced">
		 * 		<input  type="radio" id="family_divorced" value="d" name="family" />
		 * 		Divorced
		 * 	</label>
		 * 	<label for="family" class="error">Please select your family status.</label>
		 * </fieldset>
		 * @desc Specifies a group of radio elements. The validation rule is specified only for the first
		 * element of the group.
		 *
		 * @param String value The value of the element to check
		 * @param Element element The element to check
		 * @param Boolean|String|Function param A boolean "true" makes a field always required; An expression (String)
		 * is evaluated in the context of the element's form, making the field required only if the expression returns
		 * more then one element. The function is executed with the element as it's only argument: If it returns true,
		 * the element is required.
		 *
		 * @name jQuery.validator.methods.required
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		required: function(value, element, param) {
			// check if dependency is met
			if ( !jQuery.validator.depend(param, element) )
				return -1;
			switch( element.nodeName.toLowerCase() ) {
			case 'select':
				var options = jQuery("option:selected", element);
				return options.length > 0 && ( element.type == "select-multiple" || (jQuery.browser.msie && !(options[0].attributes['value'].specified) ? options[0].text : options[0].value).length > 0);
			case 'input':
				switch( element.type.toLowerCase() ) {
				case 'checkbox':
				case 'radio':
					return jQuery.validator.getLength(value, element) > 0;
				}
			default:
				return value.length > 0;
			}
		},
	
		/**
		 * Return false, if the element is
		 *
		 * - some kind of text input and its value is too short
		 *
		 * - a set of checkboxes has not enough boxes checked
		 *
		 * - a select and has not enough options selected
		 *
		 * Works with all kind of text inputs, checkboxes and select.
		 *
		 * @example <input name="firstname" class="{minLength:5}" />
		 * @desc Declares an optional input element with at least 5 characters (or none at all).
		 *
		 * @example <input name="firstname" class="{required:true,minLength:5}" />
		 * @desc Declares an input element that must have at least 5 characters.
		 *
		 * @example <fieldset>
		 * 	<legend>Spam</legend>
		 * 	<label for="spam_email">
		 * 		<input type="checkbox" id="spam_email" value="email" name="spam" validate="required:true,minLength:2" />
		 * 		Spam via E-Mail
		 * 	</label>
		 * 	<label for="spam_phone">
		 * 		<input type="checkbox" id="spam_phone" value="phone" name="spam" />
		 * 		Spam via Phone
		 * 	</label>
		 * 	<label for="spam_mail">
		 * 		<input type="checkbox" id="spam_mail" value="mail" name="spam" />
		 * 		Spam via Mail
		 * 	</label>
		 * 	<label for="spam" class="error">Please select at least two types of spam.</label>
		 * </fieldset>
		 * @desc Specifies a group of checkboxes. To validate, at least two checkboxes must be selected.
		 *
		 * @param Number min
		 * @name jQuery.validator.methods.min
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		minLength: function(value, element, param) {
			var length = jQuery.validator.getLength(value, element);
			return !jQuery.validator.methods.required(value, element) || length >= param;
		},
	
		/**
		 * Return false, if the element is
		 *
		 * - some kind of text input and its value is too big
		 *
		 * - a set of checkboxes has too many boxes checked
		 *
		 * - a select and has too many options selected
		 *
		 * Works with all kind of text inputs, checkboxes and selects.
		 *
		 * @example <input name="firstname" class="{maxLength:5}" />
		 * @desc Declares an input element with at most 5 characters.
		 *
		 * @example <input name="firstname" class="{required:true,maxLength:5}" />
		 * @desc Declares an input element that must have at least one and at most 5 characters.
		 *
		 * @param Number max
		 * @name jQuery.validator.methods.max
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		maxLength: function(value, element, param) {
			var length = jQuery.validator.getLength(value, element);
			return !jQuery.validator.methods.required(value, element) || length <= param;
		},
		
		/**
		 * Return false, if the element is
		 *
	     * - some kind of text input and its value is too short or too long
	     *
	     * - a set of checkboxes has not enough or too many boxes checked
	     *
	     * - a select and has not enough or too many options selected
	     *
	     * Works with all kind of text inputs, checkboxes and selects.
	     *
		 * @example <input name="firstname" class="{rangeLength:[3,5]}" />
		 * @desc Declares an optional input element with at least 3 and at most 5 characters (or none at all).
		 *
		 * @example <input name="firstname" class="{required:true,rangeLength:[3,5]}" />
		 * @desc Declares an input element that must have at least 3 and at most 5 characters.
		 *
		 * @example <select id="cars" class="{required:true,rangeLength:[2,3]}" multiple="multiple">
		 * 	<option value="m_sl">Mercedes SL</option>
		 * 	<option value="o_c">Opel Corsa</option>
		 * 	<option value="vw_p">VW Polo</option>
		 * 	<option value="t_s">Titanic Skoda</option>
		 * </select>
		 * @desc Specifies a select that must have at least two but no more then three options selected.
		 *
	     * @param Array<Number> min/max
	     * @name jQuery.validator.methods.rangeLength
	     * @type Boolean
	     * @cat Plugins/Validate/Methods
	     */
		rangeLength: function(value, element, param) {
			var length = jQuery.validator.getLength(value, element);
			return !jQuery.validator.methods.required(value, element) || ( length >= param[0] && length <= param[1] );
		},
	
		/**
		 * Return true, if the value is greater than or equal to the specified minimum.
		 *
		 * Works with all kind of text inputs.
		 *
		 * @example <input name="age" class="{minValue:16}" />
		 * @desc Declares an optional input element whose value must be at least 16 (or none at all).
		 *
		 * @example <input name="age" class="{required:true,minValue:16}" />
		 * @desc Declares an input element whose value must be at least 16.
		 *
		 * @param Number min
		 * @name jQuery.validator.methods.minValue
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		minValue: function( value, element, param ) {
			return !jQuery.validator.methods.required(value, element) || value >= param;
		},
		
		/**
		 * Return true, if the value is less than or equal to the specified maximum.
		 *
		 * Works with all kind of text inputs.
		 *
		 * @example <input name="age" class="{maxValue:16}" />
		 * @desc Declares an optional input element whose value must be at most 16 (or none at all).
		 *
		 * @example <input name="age" class="{required:true,maxValue:16}" />
		 * @desc Declares an input element whose required value must be at most 16.
		 *
		 * @param Number max
		 * @name jQuery.validator.methods.maxValue
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		maxValue: function( value, element, param ) {
			return !jQuery.validator.methods.required(value, element) || value <= param;
		},
		
		/**
		 * Return true, if the value is in the specified range.
		 *
		 * Works with all kind of text inputs.
		 *
		 * @example <input name="age" class="{rangeValue:[4,12]}" />
		 * @desc Declares an optional input element whose value must be at least 4 and at most 12 (or none at all).
		 *
		 * @example <input name="age" class="{required:true,rangeValue:[4,12]}" />
		 * @desc Declares an input element whose required value must be at least 4 and at most 12.
		 *
		 * @param Array<Number> min/max
		 * @name jQuery.validator.methods.rangeValue
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		rangeValue: function( value, element, param ) {
			return !jQuery.validator.methods.required(value, element) || ( value >= param[0] && value <= param[1] );
		},
		
		/**
		 * Return true, if the value is not a valid email address.
		 *
		 * Works with all kind of text inputs.
		 *
		 * @example <input name="email1" class="{email:true}" />
		 * @desc Declares an optional input element whose value must be a valid email address (or none at all).
		 *
		 * @example <input name="email1" class="{required:true,email:true}" />
		 * @desc Declares an input element whose value must be a valid email address.
		 *
		 * @name jQuery.validator.methods.email
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		email: function(value, element) {
			return !jQuery.validator.methods.required(value, element) || /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/i.test(value);
		},
	
		/**
		 * Return true, if the value is a valid url.
		 *
		 * Works with all kind of text inputs.
		 *
		 * See http://www.w3.org/Addressing/rfc1738.txt for URL specification.
		 *
		 * @example <input name="homepage" class="{url:true}" />
		 * @desc Declares an optional input element whose value must be a valid URL (or none at all).
		 *
		 * @example <input name="homepage" class="{required:true,url:true}" />
		 * @desc Declares an input element whose value must be a valid URL.
		 *
		 * @name jQuery.validator.methods.url
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		url: function(value, element) {
			return !jQuery.validator.methods.required(value, element) || /^(https?|ftp):\/\/[A-Z0-9](\.?[A-Z0-9ÄÜÖ][A-Z0-9_\-ÄÜÖ]*)*(\/([A-Z0-9ÄÜÖ][A-Z0-9_\-\.ÄÜÖ]*)?)*(\?([A-Z0-9ÄÜÖ][A-Z0-9_\-\.%\+=&ÄÜÖ]*)?)?$/i.test(value);
		},
        
		/**
		 * Return true, if the value is a valid date. Uses JavaScripts built-in
		 * Date to test if the date is valid, and is therefore very limited.
		 *
		 * Works with all kind of text inputs.
		 *
		 * @example <input name="birthdate" class="{date:true}" />
		 * @desc Declares an optional input element whose value must be a valid date (or none at all).
		 *
		 * @example <input name="birthdate" class="{required:true,date:true}" />
		 * @desc Declares an input element whose value must be a valid date.
		 *
		 * @name jQuery.validator.methods.date
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		date: function(value, element) {
			return !jQuery.validator.methods.required(value, element) || !/Invalid|NaN/.test(new Date(value));
		},
	
		/**
		 * Return true, if the value is a valid date, according to ISO date standard.
		 *
		 * Works with all kind of text inputs.
		 *
		 * @example jQuery.validator.methods.date("1990/01/01")
		 * @result true
		 *
		 * @example jQuery.validator.methods.date("1990-01-01")
		 * @result true
		 *
		 * @example jQuery.validator.methods.date("01.01.1990")
		 * @result false
		 *
		 * @example <input name="birthdate" class="{dateISO:true}" />
		 * @desc Declares an optional input element whose value must be a valid ISO date (or none at all).
		 *
		 * @name jQuery.validator.methods.date
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		dateISO: function(value, element) {
			return !jQuery.validator.methods.required(value, element) || /^\d{4}[/-]\d{1,2}[/-]\d{1,2}$/.test(value);
		},
	
		/**
		 * Return true, if the value is a valid date. Supports german
		 * dates (29.04.1994 or 1.1.2006). Doesn't make any sanity checks.
		 *
		 * Works with all kind of text inputs.
		 *
		 * @example jQuery.validator.methods.date("1990/01/01")
		 * @result false
		 *
		 * @example jQuery.validator.methods.date("01.01.1990")
		 * @result true
		 *
		 * @example jQuery.validator.methods.date("0.1.2345")
		 * @result true
		 *
		 * @example <input name="geburtstag" class="{dateDE:true}" />
		 * @desc Declares an optional input element whose value must be a valid german date (or none at all).
		 *
		 * @name jQuery.validator.methods.dateDE
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		dateDE: function(value, element) {
			return !jQuery.validator.methods.required(value, element) || /^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(value);
		},
	
		/**
		 * Return true, if the value is a valid number. Checks for
		 * international number format, eg. 100,000.59
		 *
		 * Works with all kind of text inputs.
		 *
		 * @example <input name="amount" class="{number:true}" />
		 * @desc Declares an optional input element whose value must be a valid number (or none at all).
		 *
		 * @name jQuery.validator.methods.number
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		number: function(value, element) {
			return !jQuery.validator.methods.required(value, element) || /^-?[,0-9]+(\.\d+)?$/.test(value); 
		},
	
		/**
		 * Return true, if the value is a valid number.
		 *
		 * Works with all kind of text inputs.
		 *
		 * Checks for german numbers (100.000,59)
		 *
		 * @example <input name="menge" class="{numberDE:true}" />
		 * @desc Declares an optional input element whose value must be a valid german number (or none at all).
		 *
		 * @name jQuery.validator.methods.numberDE
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		numberDE: function(value, element) {
			return !jQuery.validator.methods.required(value, element) || /^-?[\.0-9]+(,\d+)?$/.test(value);
		},
	
		/**
		 * Returns true if the value contains only digits.
		 *
		 * Works with all kind of text inputs.
		 *
		 * @example <input name="serialnumber" class="{digits:true}" />
		 * @desc Declares an optional input element whose value must contain only digits (or none at all).
		 *
		 * @name jQuery.validator.methods.digits
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		digits: function(value, element) {
			return !jQuery.validator.methods.required(value, element) || /^\d+$/.test(value);
		},
		
		/**
		 * Returns true if the value ends with one of the specified file extensions.
		 * If nothing is specified, only images are allowed (default-param: "png|jpe?g|gif").
		 *
		 * Works with all kind of text inputs.
		 *
		 * @example <input type="file" name="avatar" class="{accept:true}" />
		 * @desc Declares an optional file input element whose value must ends with '.png', '.jpg', '.jpeg' or '.gif'.
		 *
		 * @example <input type="file" name="avatar" class="{accept:'txt|docx?'}" />
		 * @desc Declares an optional file input element whose value must ends with '.txt' or '.doc' or '.docx'.
		 *
		 * @name jQuery.validator.methods.accept
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		accept: function(value, element, param) {
			param = typeof param == "string" ? param : "png|jpe?g|gif";
			return !jQuery.validator.methods.required(value, element) || value.match(new RegExp(".(" + param + ")$")); 
		},
		
		/**
		 * Returns true if the value has the same value
		 * as the element specified by the first parameter.
		 *
		 * Keep the expression simple to avoid spaces when using metadata.
		 *
		 * Works with all kind of text inputs.
		 *
		 * @example <input name="email" id="email" class="{required:true,email:true'}" />
		 * <input name="emailAgain" class="{equalTo:'#email'}" />
		 * @desc Declares two input elements: The first must contain a valid email address,
		 * the second must contain the same adress, enter once more. The paramter is a
		 * expression used via jQuery to select the element.
		 *
		 * @param String selection A jQuery expression
		 * @name jQuery.validator.methods.digits
		 * @type Boolean
		 * @cat Plugins/Validate/Methods
		 */
		equalTo: function(value, element, param) {
			return value == jQuery(param).val();
		}
	},
	
	/**
	 * Add a new validation method. It must consist of a name (must be a legal
	 * javascript identifier), a function and a default message.
	 *
	 * Please note: While the temptation is great to
	 * add a regex method that checks it's paramter against the value,
	 * it is much cleaner to encapsulate those regular expressions
	 * inside their own method. If you need lots of slightly different
	 * expressions, try to extract a common parameter.
	 *
	 * A library of regular expressions: http://regexlib.com/DisplayPatterns.aspx
	 *
	 * @example jQuery.validator.addMethod("domain", function(value) {
	 *   return /^http://mycorporatedomain.com/.test(value);
	 * }, "Please specify the correct domain for your documents");
	 * @desc Adds a method that checks if the value starts with http://mycorporatedomain.com
	 *
	 * @example jQuery.validator.addMethod("math", function(value, element, params) {
	 *  return value == params[0] + params[1];
	 * }, "Please enter the correct value for this simple question.");
	 *
	 * @see jQuery.validator.methods
	 *
	 * @param String name The name of the method, used to identify and referencing it, must be a valid javascript identifier
	 * @param Function rule The actual method implementation, returning true if an element is valid
	 * @param String message The default message to display for this method
	 *
	 * @name jQuery.validator.addMethod
	 * @type undefined
	 * @cat Plugins/Validate
	 */
	addMethod: function(name, method, message) {
		jQuery.validator.methods[name] = method;
		jQuery.validator.messages[name] = message;
	}
});

// datePicker plugin
Date.dayNames=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];Date.abbrDayNames=['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];Date.monthNames=['January','February','March','April','May','June','July','August','September','October','November','December'];Date.abbrMonthNames=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];Date.firstDayOfWeek=1;Date.format='dd/mm/yyyy';Date.fullYearStart='20';(function(){function add(name,method){if(!Date.prototype[name]){Date.prototype[name]=method;}};add("isLeapYear",function(){var y=this.getFullYear();return(y%4==0&&y%100!=0)||y%400==0;});add("isWeekend",function(){return this.getDay()==0||this.getDay()==6;});add("isWeekDay",function(){return!this.isWeekend();});add("getDaysInMonth",function(){return[31,(this.isLeapYear()?29:28),31,30,31,30,31,31,30,31,30,31][this.getMonth()];});add("getDayName",function(abbreviated){return abbreviated?Date.abbrDayNames[this.getDay()]:Date.dayNames[this.getDay()];});add("getMonthName",function(abbreviated){return abbreviated?Date.abbrMonthNames[this.getMonth()]:Date.monthNames[this.getMonth()];});add("getDayOfYear",function(){var tmpdtm=new Date("1/1/"+this.getFullYear());return Math.floor((this.getTime()-tmpdtm.getTime())/86400000);});add("getWeekOfYear",function(){return Math.ceil(this.getDayOfYear()/7);});add("setDayOfYear",function(day){this.setMonth(0);this.setDate(day);return this;});add("addYears",function(num){this.setFullYear(this.getFullYear()+num);return this;});add("addMonths",function(num){var tmpdtm=this.getDate();this.setMonth(this.getMonth()+num);if(tmpdtm>this.getDate())this.addDays(-this.getDate());return this;});add("addDays",function(num){this.setDate(this.getDate()+num);return this;});add("addHours",function(num){this.setHours(this.getHours()+num);return this;});add("addMinutes",function(num){this.setMinutes(this.getMinutes()+num);return this;});add("addSeconds",function(num){this.setSeconds(this.getSeconds()+num);return this;});add("zeroTime",function(){this.setMilliseconds(0);this.setSeconds(0);this.setMinutes(0);this.setHours(0);return this;});add("asString",function(){var r=Date.format;return r.split('yyyy').join(this.getFullYear()).split('yy').join((this.getFullYear()+'').substring(2)).split('mmm').join(this.getMonthName(true)).split('mm').join(_zeroPad(this.getMonth()+1)).split('dd').join(_zeroPad(this.getDate()));});Date.fromString=function(s){var f=Date.format;var d=new Date('01/01/1977');var iY=f.indexOf('yyyy');if(iY>-1){d.setFullYear(Number(s.substr(iY,4)));}else{d.setFullYear(Number(Date.fullYearStart+s.substr(f.indexOf('yy'),2)));}var iM=f.indexOf('mmm');if(iM>-1){var mStr=s.substr(iM,3);for(var i=0;i<Date.abbrMonthNames.length;i++){if(Date.abbrMonthNames[i]==mStr)break;}d.setMonth(i);}else{d.setMonth(Number(s.substr(f.indexOf('mm'),2))-1);}d.setDate(Number(s.substr(f.indexOf('dd'),2)));if(isNaN(d.getTime())){return false;}return d;};var _zeroPad=function(num){var s='0'+num;return s.substring(s.length-2)};})();
(function($){$.fn.extend({renderCalendar:function(s){var dc=function(a){return document.createElement(a);};s=$.extend({month:null,year:null,renderCallback:null,showHeader:$.dpConst.SHOW_HEADER_SHORT,dpController:null,hoverClass:'dp-hover'},s);if(s.showHeader!=$.dpConst.SHOW_HEADER_NONE){var headRow=$(dc('tr'));for(var i=Date.firstDayOfWeek;i<Date.firstDayOfWeek+7;i++){var weekday=i%7;var day=Date.dayNames[weekday];headRow.append(jQuery(dc('th')).attr({'scope':'col','abbr':day,'title':day,'class':(weekday==0||weekday==6?'weekend':'weekday')}).html(s.showHeader==$.dpConst.SHOW_HEADER_SHORT?day.substr(0,1):day));}};var calendarTable=$(dc('table')).attr({'cellspacing':2,'className':'jCalendar'}).append((s.showHeader!=$.dpConst.SHOW_HEADER_NONE?$(dc('thead')).append(headRow):dc('thead')));var tbody=$(dc('tbody'));var today=(new Date()).zeroTime();var month=s.month==undefined?today.getMonth():s.month;var year=s.year||today.getFullYear();var currentDate=new Date(year,month,1);var firstDayOffset=Date.firstDayOfWeek-currentDate.getDay()+1;if(firstDayOffset>1)firstDayOffset-=7;var weeksToDraw=Math.ceil(((-1*firstDayOffset+1)+currentDate.getDaysInMonth())/7);currentDate.addDays(firstDayOffset-1);var doHover=function(){if(s.hoverClass){$(this).addClass(s.hoverClass);}};var unHover=function(){if(s.hoverClass){$(this).removeClass(s.hoverClass);}};var w=0;while(w++<weeksToDraw){var r=jQuery(dc('tr'));for(var i=0;i<7;i++){var thisMonth=currentDate.getMonth()==month;var d=$(dc('td')).text(currentDate.getDate()+'').attr('className',(thisMonth?'current-month ':'other-month ')+(currentDate.isWeekend()?'weekend ':'weekday ')+(thisMonth&&currentDate.getTime()==today.getTime()?'today ':'')).hover(doHover,unHover);if(s.renderCallback){s.renderCallback(d,currentDate,month,year);}r.append(d);currentDate.addDays(1);}tbody.append(r);}calendarTable.append(tbody);return this.each(function(){$(this).empty().append(calendarTable);});},datePicker:function(s){if(!$.event._dpCache)$.event._dpCache=[];s=$.extend({month:undefined,year:undefined,startDate:undefined,endDate:undefined,inline:false,renderCallback:[],createButton:true,showYearNavigation:true,closeOnSelect:true,displayClose:false,selectMultiple:false,clickInput:false,verticalPosition:$.dpConst.POS_TOP,horizontalPosition:$.dpConst.POS_LEFT,verticalOffset:0,horizontalOffset:0,hoverClass:'dp-hover'},s);return this.each(function(){var $this=$(this);var alreadyExists=true;if(!this._dpId){this._dpId=$.event.guid++;$.event._dpCache[this._dpId]=new DatePicker(this);alreadyExists=false;}if(s.inline){s.createButton=false;s.displayClose=false;s.closeOnSelect=false;$this.empty();}var controller=$.event._dpCache[this._dpId];controller.init(s);if(!alreadyExists&&s.createButton){controller.button=$('<a href="#" class="dp-choose-date" title="'+$.dpText.TEXT_CHOOSE_DATE+'">'+$.dpText.TEXT_CHOOSE_DATE+'</a>').bind('click',function(){$this.dpDisplay(this);this.blur();return false;});$this.after(controller.button);}if(!alreadyExists&&$this.is(':text')){$this.bind('dateSelected',function(e,selectedDate,$td){this.value=selectedDate.asString();}).bind('change',function(){var d=Date.fromString(this.value);if(d){controller.setSelected(d,true,true);}});if(s.clickInput){$this.bind('click',function(){$this.dpDisplay();});}var d=Date.fromString(this.value);if(this.value!=''&&d){controller.setSelected(d,true,true);}}$this.addClass('dp-applied');})},dpSetDisabled:function(s){return _w.call(this,'setDisabled',s);},dpSetStartDate:function(d){return _w.call(this,'setStartDate',d);},dpSetEndDate:function(d){return _w.call(this,'setEndDate',d);},dpGetSelected:function(){var c=_getController(this[0]);if(c){return c.getSelected();}return null;},dpSetSelected:function(d,v,m){if(v==undefined)v=true;if(m==undefined)m=true;return _w.call(this,'setSelected',Date.fromString(d),v,m);},dpSetDisplayedMonth:function(m,y){return _w.call(this,'setDisplayedMonth',Number(m),Number(y));},dpDisplay:function(e){return _w.call(this,'display',e);},dpSetRenderCallback:function(a){return _w.call(this,'setRenderCallback',a);},dpSetPosition:function(v,h){return _w.call(this,'setPosition',v,h);},dpSetOffset:function(v,h){return _w.call(this,'setOffset',v,h);},dpClose:function(){return _w.call(this,'_closeCalendar',false,this[0]);},_dpDestroy:function(){}});var _w=function(f,a1,a2,a3){return this.each(function(){var c=_getController(this);if(c){c[f](a1,a2,a3);}});};function DatePicker(ele){this.ele=ele;this.displayedMonth=null;this.displayedYear=null;this.startDate=null;this.endDate=null;this.showYearNavigation=null;this.closeOnSelect=null;this.displayClose=null;this.selectMultiple=null;this.verticalPosition=null;this.horizontalPosition=null;this.verticalOffset=null;this.horizontalOffset=null;this.button=null;this.renderCallback=[];this.selectedDates={};this.inline=null;this.context='#dp-popup';};$.extend(DatePicker.prototype,{init:function(s){this.setStartDate(s.startDate);this.setEndDate(s.endDate);this.setDisplayedMonth(Number(s.month),Number(s.year));this.setRenderCallback(s.renderCallback);this.showYearNavigation=s.showYearNavigation;this.closeOnSelect=s.closeOnSelect;this.displayClose=s.displayClose;this.selectMultiple=s.selectMultiple;this.verticalPosition=s.verticalPosition;this.horizontalPosition=s.horizontalPosition;this.hoverClass=s.hoverClass;this.setOffset(s.verticalOffset,s.horizontalOffset);this.inline=s.inline;if(this.inline){this.context=this.ele;this.display();}},setStartDate:function(d){if(d){this.startDate=Date.fromString(d);}if(!this.startDate){this.startDate=(new Date()).zeroTime();}this.setDisplayedMonth(this.displayedMonth,this.displayedYear);},setEndDate:function(d){if(d){this.endDate=Date.fromString(d);}if(!this.endDate){this.endDate=(new Date('12/31/2999'));}if(this.endDate.getTime()<this.startDate.getTime()){this.endDate=this.startDate;}this.setDisplayedMonth(this.displayedMonth,this.displayedYear);},setPosition:function(v,h){this.verticalPosition=v;this.horizontalPosition=h;},setOffset:function(v,h){this.verticalOffset=parseInt(v)||0;this.horizontalOffset=parseInt(h)||0;},setDisabled:function(s){$e=$(this.ele);$e[s?'addClass':'removeClass']('dp-disabled');if(this.button){$but=$(this.button);$but[s?'addClass':'removeClass']('dp-disabled');$but.attr('title',s?'':$.dpText.TEXT_CHOOSE_DATE);}if($e.is(':text')){$e.attr('disabled',s?'disabled':'');}},setDisplayedMonth:function(m,y){if(this.startDate==undefined||this.endDate==undefined){return;}var s=new Date(this.startDate.getTime());s.setDate(1);var e=new Date(this.endDate.getTime());e.setDate(1);var t;if((!m&&!y)||(isNaN(m)&&isNaN(y))){t=new Date().zeroTime();t.setDate(1);}else if(isNaN(m)){t=new Date(y,this.displayedMonth,1);}else if(isNaN(y)){t=new Date(this.displayedYear,m,1);}else{t=new Date(y,m,1)}if(t.getTime()<s.getTime()){t=s;}else if(t.getTime()>e.getTime()){t=e;}this.displayedMonth=t.getMonth();this.displayedYear=t.getFullYear();},setSelected:function(d,v,moveToMonth){if(this.selectMultiple==false){this.selectedDates={};$('td.selected',this.context).removeClass('selected');}if(moveToMonth){this.setDisplayedMonth(d.getMonth(),d.getFullYear());}this.selectedDates[d.toString()]=v;},isSelected:function(d){return this.selectedDates[d.toString()];},getSelected:function(){var r=[];for(s in this.selectedDates){if(this.selectedDates[s]==true){r.push(Date.parse(s));}}return r;},display:function(eleAlignTo){if($(this.ele).is('.dp-disabled'))return;eleAlignTo=eleAlignTo||this.ele;var c=this;var $ele=$(eleAlignTo);var eleOffset=$ele.offset();var $createIn;var attrs;var attrsCalendarHolder;var cssRules;if(c.inline){$createIn=$(this.ele);attrs={'id':'calendar-'+this.ele._dpId,'className':'dp-popup dp-popup-inline'};cssRules={};}else{$createIn=$('body');attrs={'id':'dp-popup','className':'dp-popup'};cssRules={'top':eleOffset.top+c.verticalOffset,'left':eleOffset.left+c.horizontalOffset};var _checkMouse=function(e){var el=e.target;var cal=$('#dp-popup')[0];while(true){if(el==cal){return true;}else if(el==document){c._closeCalendar();return false;}else{el=$(el).parent()[0];}}};this._checkMouse=_checkMouse;this._closeCalendar(true);}$createIn.append($('<div></div>').attr(attrs).css(cssRules).append($('<h2></h2>'),$('<div class="dp-nav-prev"></div>').append($('<a class="dp-nav-prev-year" href="#" title="'+$.dpText.TEXT_PREV_YEAR+'">&lt;&lt;</a>').bind('click',function(){return c._displayNewMonth.call(c,this,0,-1);}),$('<a class="dp-nav-prev-month" href="#" title="'+$.dpText.TEXT_PREV_MONTH+'">&lt;</a>').bind('click',function(){return c._displayNewMonth.call(c,this,-1,0);})),$('<div class="dp-nav-next"></div>').append($('<a class="dp-nav-next-year" href="#" title="'+$.dpText.TEXT_NEXT_YEAR+'">&gt;&gt;</a>').bind('click',function(){return c._displayNewMonth.call(c,this,0,1);}),$('<a class="dp-nav-next-month" href="#" title="'+$.dpText.TEXT_NEXT_MONTH+'">&gt;</a>').bind('click',function(){return c._displayNewMonth.call(c,this,1,0);})),$('<div></div>').attr('className','dp-calendar')).bgIframe());var $pop=this.inline?$('.dp-popup',this.context):$('#dp-popup');if(this.showYearNavigation==false){$('.dp-nav-prev-year, .dp-nav-next-year',c.context).css('display','none');}if(this.displayClose){$pop.append($('<a href="#" id="dp-close">'+$.dpText.TEXT_CLOSE+'</a>').bind('click',function(){c._closeCalendar();return false;}));}c._renderCalendar();$(this.ele).trigger('dpDisplayed',$pop);if(!c.inline){if(this.verticalPosition==$.dpConst.POS_BOTTOM){$pop.css('top',eleOffset.top+$ele.height()-$pop.height()+c.verticalOffset);}if(this.horizontalPosition==$.dpConst.POS_RIGHT){$pop.css('left',eleOffset.left+$ele.width()-$pop.width()+c.horizontalOffset);}$(document).bind('mousedown',this._checkMouse);}},setRenderCallback:function(a){if(a&&typeof(a)=='function'){a=[a];}this.renderCallback=this.renderCallback.concat(a);},cellRender:function($td,thisDate,month,year){var c=this.dpController;var d=new Date(thisDate.getTime());$td.bind('click',function(){var $this=$(this);if(!$this.is('.disabled')){c.setSelected(d,!$this.is('.selected')||!c.selectMultiple);var s=c.isSelected(d);$(c.ele).trigger('dateSelected',[d,$td,s]);$(c.ele).trigger('change');if(c.closeOnSelect){c._closeCalendar();}else{$this[s?'addClass':'removeClass']('selected');}}});if(c.isSelected(d)){$td.addClass('selected');}for(var i=0;i<c.renderCallback.length;i++){c.renderCallback[i].apply(this,arguments);}},_displayNewMonth:function(ele,m,y){if(!$(ele).is('.disabled')){this.setDisplayedMonth(this.displayedMonth+m,this.displayedYear+y);this._clearCalendar();this._renderCalendar();$(this.ele).trigger('dpMonthChanged',[this.displayedMonth,this.displayedYear]);}ele.blur();return false;},_renderCalendar:function(){$('h2',this.context).html(Date.monthNames[this.displayedMonth]+' '+this.displayedYear);$('.dp-calendar',this.context).renderCalendar({month:this.displayedMonth,year:this.displayedYear,renderCallback:this.cellRender,dpController:this,hoverClass:this.hoverClass});if(this.displayedYear==this.startDate.getFullYear()&&this.displayedMonth==this.startDate.getMonth()){$('.dp-nav-prev-year',this.context).addClass('disabled');$('.dp-nav-prev-month',this.context).addClass('disabled');$('.dp-calendar td.other-month',this.context).each(function(){var $this=$(this);if(Number($this.text())>20){$this.addClass('disabled');}});var d=this.startDate.getDate();$('.dp-calendar td.current-month',this.context).each(function(){var $this=$(this);if(Number($this.text())<d){$this.addClass('disabled');}});}else{$('.dp-nav-prev-year',this.context).removeClass('disabled');$('.dp-nav-prev-month',this.context).removeClass('disabled');var d=this.startDate.getDate();if(d>20){var sd=new Date(this.startDate.getTime());sd.addMonths(1);if(this.displayedYear==sd.getFullYear()&&this.displayedMonth==sd.getMonth()){$('dp-calendar td.other-month',this.context).each(function(){var $this=$(this);if(Number($this.text())<d){$this.addClass('disabled');}});}}}if(this.displayedYear==this.endDate.getFullYear()&&this.displayedMonth==this.endDate.getMonth()){$('.dp-nav-next-year',this.context).addClass('disabled');$('.dp-nav-next-month',this.context).addClass('disabled');$('.dp-calendar td.other-month',this.context).each(function(){var $this=$(this);if(Number($this.text())<14){$this.addClass('disabled');}});var d=this.endDate.getDate();$('.dp-calendar td.current-month',this.context).each(function(){var $this=$(this);if(Number($this.text())>d){$this.addClass('disabled');}});}else{$('.dp-nav-next-year',this.context).removeClass('disabled');$('.dp-nav-next-month',this.context).removeClass('disabled');var d=this.endDate.getDate();if(d<13){var ed=new Date(this.endDate.getTime());ed.addMonths(-1);if(this.displayedYear==ed.getFullYear()&&this.displayedMonth==ed.getMonth()){$('.dp-calendar td.other-month',this.context).each(function(){var $this=$(this);if(Number($this.text())>d){$this.addClass('disabled');}});}}}},_closeCalendar:function(programatic,ele){if(!ele||ele==this.ele){$(document).unbind('mousedown',this._checkMouse);this._clearCalendar();$('#dp-popup a').unbind();$('#dp-popup').empty().remove();if(!programatic){$(this.ele).trigger('dpClosed',[this.getSelected()]);}}},_clearCalendar:function(){$('.dp-calendar td',this.context).unbind();$('.dp-calendar',this.context).empty();}});$.dpConst={SHOW_HEADER_NONE:0,SHOW_HEADER_SHORT:1,SHOW_HEADER_LONG:2,POS_TOP:0,POS_BOTTOM:1,POS_LEFT:0,POS_RIGHT:1};$.dpText={TEXT_PREV_YEAR:'Previous year',TEXT_PREV_MONTH:'Previous month',TEXT_NEXT_YEAR:'Next year',TEXT_NEXT_MONTH:'Next month',TEXT_CLOSE:'Close',TEXT_CHOOSE_DATE:'Choose date'};$.dpVersion='$Id: jquery.datePicker.js 3739 2007-10-25 13:55:30Z kelvin.luck $';function _getController(ele){if(ele._dpId)return $.event._dpCache[ele._dpId];return false;};if($.fn.bgIframe==undefined){$.fn.bgIframe=function(){return this;};};$(window).bind('unload',function(){var els=$.event._dpCache||[];for(var i in els){$(els[i].ele)._dpDestroy();}});})(jQuery);
// masked input plugin
(function($) {
	//Helper Functions for Caret positioning
	getCaretPosition=function(ctl){
		var res = {begin: 0, end: 0 };
		if (ctl.setSelectionRange){
			res.begin = ctl.selectionStart;
			res.end = ctl.selectionEnd;
		}else if (document.selection && document.selection.createRange){
			var range = document.selection.createRange();
			var rTemp = range.duplicate();
			res.begin = 0 - rTemp.moveStart('character', -100000);
			res.end = res.begin + range.text.length;
		}
		return res;
	}

	setCaretPosition=function(ctl, pos){
		if(ctl.setSelectionRange){
			ctl.focus();
			ctl.setSelectionRange(pos,pos);
		}else if (ctl.createTextRange){
			var range = ctl.createTextRange();
			range.collapse(true);
			range.moveEnd('character', pos);
			range.moveStart('character', pos);
			range.select();
		}
	}
	
	//Main Method
	$.fn.maskedinput = function(mask,placeholder) {		
		if(!placeholder)
			placeholder="_";

		//Helper function for regex building
		function getRegexForPosition(pos){
			switch(mask.charAt(pos)){
				case '9':	return "[0-9]";			
				case'a':	return "[A-Za-z]";
				case '*':	return "[A-Za-z0-9]";
				default:	return null;
			}
		}
			
		//Build Regex for format validation
		//This Regex could be seriously optimized
		var reString="^";	
		for(var i=0;i<mask.length;i++)
			reString+=(getRegexForPosition(i) || ("\\"+mask.charAt(i)));					
		reString+="$";
		var re = new RegExp(reString);


		return this.each(
			function(){		
				var input=$(this);
				var buffer=new Array(mask.length);
				var locked=new Array(mask.length);		

				//Build buffer layour from mask
				for(var i=0;i<mask.length;i++){
					if(mask.charAt(i)!='9' && mask.charAt(i)!='a' && mask.charAt(i)!='*'){
						buffer[i]=mask.charAt(i);
						locked[i]=true;
					}else{
						buffer[i]=placeholder;
						locked[i]=false;
					}					
				}

				input.focus(function(){
					checkVal();
					setCaretPosition(this,0);		
				});

				input.blur(checkVal);
				
				//Paste events for IE and Mozilla thanks to Kristinn Sigmundsson
				if ($.browser.msie) {
					this.onpaste= function(){setTimeout(checkVal,0);};                     
				}else if ($.browser.mozilla)
					this.addEventListener('input',checkVal,false);
				
				var ignore=false;  //Variable for ignoring control keys
				input.keydown(function(e){
					var pos=getCaretPosition(this);					
					if((pos.begin-pos.end)!=0){//delete selection before proceeding
						for(var i=pos.begin;i<=pos.end;i++){
							if(!locked[i])
								buffer[i]=placeholder;
						}						
					}					
					var k = e.keyCode;
					//backspace and delete get special treatment
					if(k==8){//backspace										
						while(pos.begin-->0){
							if(!locked[pos.begin]){
								buffer[pos.begin]=placeholder;
								writeBuffer();
								setCaretPosition(this,pos.begin);
								return false;
							}
						}					
					}else if(k==46){//delete						
						for(var i=pos.begin;i<=pos.end;i++){
							if(!locked[i])
								buffer[i]=placeholder;
						}						
						writeBuffer();
						setCaretPosition(this,pos.begin);
						return false;
					}
			        ignore=(k < 16 || (k > 16 && k < 32) || (k > 32 && k < 41));					
				});

				input.keypress(function(e){					
					if(ignore){
						ignore=false;
						return;
					}
					e=e||window.event;
					var k=e.charCode||e.keyCode||e.which;

					var pos=getCaretPosition(this);					
					var caretPos=pos.begin;	
					
					if(e.ctrlKey || e.altKey){//Ignore
						return true;
					}else if ((k>=41 && k<=122) ||k==32 || k>186){//typeable characters
						while(pos.begin<mask.length){	
							var reString=getRegexForPosition(pos.begin);
							var match;
							if(reString){
								var reChar=new RegExp(reString);
								match=String.fromCharCode(k).match(reChar);
							}else{//we're on a mask char, go forward and try again
								pos.begin+=1;
								pos.end=pos.begin;
								caretPos+=1;
								continue;
							}

							if(match)
								buffer[pos.begin]=String.fromCharCode(k);
							else
								return false;//reject char

							while(++caretPos<mask.length){//seek forward to next typable position
								if(!locked[caretPos]){							
									break;
								}
							}
							break;
						}
					}else 
						return false;					

					writeBuffer();
					setCaretPosition(this,caretPos);
					return false;				
				});

				function writeBuffer(){
					var s="";
					for(var i=0;i<mask.length;i++)
						s+=buffer[i];
					input.val(s);
				}

				function checkVal(){
					if(!input.val().match(re)){
						//try to place charcters where they belong
						var test=input.val();
						var pos=0;
						for(var i=0;i<mask.length;i++){
							if(!locked[i]){
								while(pos++<test.length){
									//Regex Test each char here.
									var reChar=new RegExp(getRegexForPosition(i));
									if(test.charAt(pos-1).match(reChar)){
										buffer[i]=test.charAt(pos-1);
										break;
									}									
								}
							}
						}
						writeBuffer();
						if(!input.val().match(re)){							
							input.val("");									
							for(var i=0;i<mask.length;i++){
								if(!locked[i])
									buffer[i]=placeholder;
							}
						}
					}
				}
			}
		);
	};
})(jQuery);

