/* jQuery JavaScript Library v1.3.2
 * http://jquery.com/
 *
 * Copyright (c) 2009 John Resig
 * Dual licensed under the MIT and GPL licenses.
 * http://docs.jquery.com/License
 *
 * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
 * Revision: 6246
 */
(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});

/*
 * Sizzle CSS Selector Engine - v0.9.3
 *  Copyright 2009, The Dojo Foundation
 *  Released under the MIT, BSD, and GPL Licenses.
 *  More information: http://sizzlejs.com/
 */
(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML='   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();

// lib.object 1.2.3
// requires: nothing
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// helper methods for Object type

var lib = lib || {};
lib.object = lib.object || {};




lib.object.name = "lib.object";
lib.object.defaultDepth = "10";




lib.object.isArray = function (obj) {
	return obj instanceof Array;
};

lib.object.isRegExp = function (obj) {
	// returns true if the object is a regular expression
	// return (obj.constructor && (obj.constructor == RegExp.prototype.constructor));
	return obj instanceof RegExp;
};

lib.object.cloneRegExp = function (reg) {
	// returns a new regExp object identical to reg
	var mods = "";
	if (reg.global)     { mods = "g"; }
	if (reg.ignoreCase) { mods += "i"; }
	var result = new RegExp(reg.source, mods);
	return result;
};

lib.object.isEqual = function (obj1, obj2, exact, depth) {
	// detects if two objects are equal
	// exact = true - checks if all references match exactly objects
	exact = exact || false;
	var prop;
	if (typeof depth != "number") {
		depth = lib.object.defaultDepth;
	}
	var noDiffFound = true;
	
	if ((typeof obj1 != "object") || (typeof obj2 != "object") || (obj1 === null) || (obj2 === null)) {
		// compare simple data types
		if (exact) {
			noDiffFound = (obj1 === obj2);
		} else {
			noDiffFound = (obj1 == obj2);
		}
	} else {
		// compare objects
		compareNumberOfProps:
			for (prop in obj2) {
				if (typeof obj1[prop] == "undefined") {
					// obj1 has different properties than obj2
					noDiffFound = false;
					break compareNumberOfProps;
				}
			}
		// end compareNumberOfProps
		if (noDiffFound) {
			compareObjects:
				for (prop in obj1) {
					if (typeof obj2[prop] == "undefined") {
						// obj2 has different properties
						noDiffFound = false;
						break compareObjects;
					}
					if (exact) {
						// if compare is exact, properties including references have to match exactly
						if (obj1[prop] !== obj2[prop]) {
							noDiffFound = false;
							break compareObjects;
						}
					} else {
						// if compare is not exact, only values have to match
						if ((typeof obj1[prop] != "object") || (depth < 1)) {
							// simple types may be compared directly. If you are too deep, compare even objects directly
							if (obj1[prop] != obj2[prop]) {
								noDiffFound = false;
								break compareObjects;
							}
						} else {
							// object have to be compared by value if it's not too deep
							if (!lib.object.isEqual(obj1[prop], obj2[prop], false, depth - 1)) {
								noDiffFound = false;
								break compareObjects;
							}
						}
					}
				}
			// end compareObjects
		}
	}
	return noDiffFound;
};

lib.object.clone = function (obj, depth) {
	// returns copy of the source object obj. 
	// If deep is set to true (default), all references are cloned, too. 
	// If deep is set to false, references are left intact.
	if (typeof depth != "number") {
		depth = lib.object.defaultDepth; // deep clonning is default
	}
	var result;
	if (typeof obj == "object") {
		result = {};
		for (var prop in obj) {
			if ((typeof obj[prop] != "object") || (depth < 1)) {
				// simple types are copied by assignment as well as too deep references
				result[prop] = obj[prop];
			} else {
				// referenced objects are cloned
				result[prop] = lib.object.clone(obj[prop], depth - 1);
			}
		}
	} else {
		result = obj;
	}
	return result;
};
// lib.array 1.1.11
// requires: nothing
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// Numbered array helper functions
// Don't use for asociative arrays!

var lib = lib || {};
lib.array = lib.array || {};




lib.array.name = "lib.array";
lib.array.errorMsg = {
	arrayCopyException: "Error: lib.array.copy can copy only arrays."
};
lib.array.defaultDepth = 10;




lib.array.contains = function (arr, item, exact) {
	// tests if arr contains item. By default, use == for test, if exact is true use === . Not deep testing.
	// TODO: deep testing
	var isItemFound = false;
	var i, l;
	searchForItem:
		for (i = 0, l = arr.length; i < l; i++) {
			if (exact) {
				if (arr[i] === item) {
					isItemFound = true;
					break searchForItem;
				}
			} else if (arr[i] == item) {
				isItemFound = true;
				break searchForItem;
			}
		}
	return isItemFound;
};

lib.array.isEqual = function (arr1, arr2, exact) {
	// compares two arrays. By default, use == for test, if exact is true use ===
	// not for use with associative arrays - that�s the TODO (expressed in docbook) 
	exact = exact || false;
	var result = false;
	var i, l;
	if (
		(arr1 instanceof Array) &&
		(arr2 instanceof Array) &&
		(arr1.length == arr2.length)
	) {
		result = true;
		for (i = 0, l = arr1.length; i < l; i++) {
			if ( (arr1[i] instanceof Array) && (arr2[i] instanceof Array) ) {
				result = result && lib.array.isEqual(arr1[i], arr2[i], exact);
			} else if (exact) {
				if (arr2[i] !== arr1[i]) {
					result = false;
					break;
				}
			} else {
				if (arr2[i] != arr1[i]) {
					result = false;
					break;
				}
			}
		}
	}
	return result;
};

lib.array.concat = function (arr1, arr2) {
	// joins arrays (two or more)
	var args = arguments;
	var arr = [];
	var i1, i2, l1, l2;
	for (i1 = 0, l1 = args.length; i1 < l1; i1++) {
		for (i2 = 0, l2 = args[i1].length; i2 < l2; i2++) {
			arr[arr.length] = args[i1][i2];
		}
	}
	return arr;
};

lib.array.copy = function (arr, depth) {
	// copy an array by value, if deep copying is not necessary set depth to 0
	if (typeof depth != "number") { depth = lib.array.defaultDepth; } // deep clonning is default
	var result = [];
	var i;
	if (arr instanceof Array) {
		i = arr.length;
		while (i--) {
			if ((depth > 0) && (arr[i] instanceof Array)) {
				result[i] = lib.array.copy(arr[i], depth - 1);
			} else {
				result[i] = arr[i];
			}
		}
	} else {
		throw { name: "arrayCopyException", message: lib.array.errorMsg.arrayCopyException };
	}
	return result;
};

lib.array.convert = function (obj) {
	// converts an object to array 
	var result = [];
	var i, l;
	if (typeof obj.length == "number") {
		for (i = 0, l = obj.length; i < l; i++) {
			result[i] = obj[i];
		}
	}
	return result;
};

lib.array.pop = function (arr) {
	// removes the last element of the array a and returns it
	var result = arr[arr.length-1];
	arr.length--;
	return result;
};

lib.array.push = function (arr, item) {
	// add an element to the end of an array, return the new array length
	var arg = arguments;
	var len = arr.length;
	for (var i = 1, l = arg.length; i < l; i++) {
		arr[len + i - 1] = arg[i];
	}
	return arr.length;
};

lib.array.shift = function (arr) {
	// remove and return the first element of an array
	var result = arr[0];
	for(var i = 0, l = arr.length - 1; i < l; i++ ) {
		arr[i] = arr[i + 1];
	}
	arr.length--;
	return result;
};

lib.array.unshift = function (arr, item) {
	// add an element to the beginning of an array and returns new array length
	arr.reverse();
	var a = arguments;
	for (var i = a.length - 1; i > 0; i--) {
		lib.array.push(arr, a[i]);
	}
	arr.reverse();
	return arr.length;
};

lib.array.condense = function (arr, emptyValue) {
	// takes sparse array (vector) and returns it as dense array, throwing out all items that have value emptyValue.
	// if emptyValue is not specified, removes "null" values by default
	if (typeof emptyValue == "undefined") {
		emptyValue = null;
	}
	var i, l;
	var newLength = 0;
	if (typeof arr.length != "undefined") {
		for (i = 0, l = arr.length; i < l; i++) {
			if ((typeof arr[i] != "undefined") && (arr[i] != emptyValue)) {
				arr[newLength] = arr[i];
				newLength++;
			}
		}
		arr.length = newLength;
	}
	return arr;
};

lib.array.insert = function (arr, newValue, emptyValue) {
	// inserts the newValue to array to first empty place (place that has value emptyValue)
	// if there is no such value, adds newValue to the end of the array --- RETURNS i (1)
	// if emptyValue is not specified, replaces "null" values by default -- RETURNS new arr.length
	if (typeof emptyValue == "undefined") {
		emptyValue = null;
	}
	var i, l;
	searchForHole:
		for (i = 0, l = arr.length; i < l; i++) {
			if (arr[i] == emptyValue) {
				break searchForHole;
			}
		}
	arr[i] = newValue;
	return i;
};

lib.array.sort = function (arr) {
	// fixes an ugly bug in Array.sort
	var sortFn = function (a, b) {
		var result = 0;
		if (a < b) {
			result = -1;
		} else if ( a > b ) {
			result = 1;
		}
		return result;
	};
	return arr.sort(sortFn);
};

lib.array.sortBy = function (arr, indexName) {
	// sorts multidimensional array using index "indexName" as a key for sorting
	// elements that don't have this index are put to the end of the array
	var sortFn = function (a, b) {
		var result = 0;
		if (a && b && a[indexName] && b[indexName]) {
			if (a[indexName] < b[indexName]) {
				result = -1;
			} else if ( a[indexName] > b[indexName] ) {
				result = 1;
			}
		} else if (b && b[indexName]) {
			result = -1;
		} else if ((b === null) && (a !== null)) {
			result = -1;
		}
		return result;
	};
	return arr.sort(sortFn);
};

lib.array.apply = function (arr, fn) {
	// for each array element arr[i] run fn(arr[i]) and return the array of results
	// nested arrays are replaced -> null
	var result = [];
	for (var i = 0, l = arr.length; i < l; i++) {
		result[i] = fn(arr[i]);
	}
	return result;
};


// lib.string 1.1.5
// requires: lib.array
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 

var lib = lib || {};
lib.string = lib.string || {};
lib.string.buffer = lib.string.buffer || {};
lib.string.json = lib.string.json || {};




lib.string.name = "lib.string";
lib.string.nbsp = String.fromCharCode(160); // nonbreaking space
lib.string.lineBreak = "\n\r";




lib.string.getValue = function (str) {
	// evaluates the JSON string str
	var result = null;
	try {
		eval("result = " + str.valueOf()); // this evals JSON data, pay attention to security
	} catch (ex) {
		result = null;
	}
	return result;
};

lib.string.ltrim = function (str) {
	// remove leading whitespace
	return str.replace(/^\s*(.*)/, "$1");
};

lib.string.rtrim = function (str) {
	// remove trailing whitespace
	return str.replace(/\s*$/, "");
};

lib.string.trim = function (str) {
	// remove leading and trailing whitespace
	return lib.string.ltrim(lib.string.rtrim(str));
};

lib.string.isEmpty = function (str) {
	// test if the string is empty or containing only whitespace
	return (str.search(/\S/) < 0) ? true : false;
};

lib.string.isEmptyHtml = function (str) {
	// test if string is empty HTML.
	// String is emptyHTML if it contains only whitespace characters 
	// by fczbkk
	var blankCharacters = [" ", "&nbsp;", "&#032;"];
	for (var i = 0, l = blankCharacters.length; i < l; i++) {
		str = str.replace(eval("/" + blankCharacters[i] + "/gi"), ""); // TODO - this is not secure, fix this
	}
	return (lib.string.isEmpty(str));
};

lib.string.removeHtmlTags = function (str) {
	// removes all HTML tags from string, leaves HTML entities intact
	// by Sam Stephenson, http://prototype.conio.net/
	return str.replace(/<\/?[^>]+>/gi, '');
};

lib.string.escapeHtml = function (str) {
	// escapes all "forbiden" HTML characters (<>&")
	// by Sam Stephenson, http://prototype.conio.net/
	var div = document.createElement('div');
	var text = document.createTextNode(str);
	div.appendChild(text);
	return div.innerHTML.replace(/["]/gi,'&quot;');
};

lib.string.htmlToText = function (str) {
	// removes all HTML tags and entities from string
	// by Sam Stephenson, http://prototype.conio.net/
	var div = document.createElement("div");
	div.innerHTML = lib.string.removeHtmlTags(str); // remove entities this way
	return div.childNodes[0].nodeValue;
};

lib.string.camelize = function (str) {
	// transforms CSS-like identifier ("My-property-id") to the proper javascript identifier ("myPropertyId")
	var result = "";
	var strList = str.split('-');
	for (var i = 0, l = strList.length; i < l; i++) {
		result += strList[i].charAt(0).toUpperCase() + strList[i].substring(1);
	}
	if (str.indexOf('-') === 0) {
		result = result.charAt(0).toUpperCase() + result.substring(1);
	} else {
		result = result.charAt(0).toLowerCase() + result.substring(1);
	}
	return result;
};

lib.string.split2 = function (str, delimiter) {
	// split string into 2 substrings by delimiter
	var result = [];
	var index = str.indexOf(delimiter);
	if (index < 0) {
		result[0] = str;
	} else {
		result[0] = str.substring(0, index);
		result[1] = str.substring(index + 1);
	}
	return result;
};




lib.string.buffer.create = function () {
	// creates and returns a new string buffer
	return [];
};

lib.string.buffer.add = function (buffer, str) {
	// adds a string to the string buffer
	lib.array.push(buffer, str);
	return buffer;
};

lib.string.buffer.get = function (buffer) {
	// retrieves merged string from string buffer
	return buffer.join("");
};




lib.string.json.encode = function (obj) {
	// gets JSON string of given object
	// copyright: (c)2005 JSON.org
	// license: http://www.crockford.com/JSON/license.html
	var arr = [];
	
	function addStr(arr, str) {
		// emit a string
		arr[arr.length] = str;
		return arr;
	}
	function convertVal(obj) {
		// convert a value
		var c, i, l, v, ol;
		
		switch (typeof obj) {
		case 'object':
			if (obj) {
				if (obj instanceof Array) {
					arr = addStr(arr, '[');
					l = arr.length;
					for (i = 0, ol = obj.length; i < ol; i += 1) {
						v = obj[i];
						if (typeof v != 'undefined' &&
								typeof v != 'function') {
							if (l < arr.length) {
								arr = addStr(arr, ',');
							}
							convertVal(v);
						}
					}
					arr = addStr(arr, ']');
					return true;
				} else if (typeof obj.valueOf == 'function') {
					arr = addStr(arr, '{');
					l = arr.length;
					for (i in obj) {
						v = obj[i];
						if (typeof v != 'undefined' &&
								typeof v != 'function' &&
								(!v || typeof v != 'object' ||
									typeof v.valueOf == 'function')) {
							if (l < arr.length) {
								arr =addStr(arr, ',');
							}
							convertVal(i);
							arr = addStr(arr, ':');
							convertVal(v);
						}
					}
					arr = addStr(arr, '}');
					return arr;
				}
			}
			arr = addStr(arr, 'null');
			return true;
		case 'number':
			arr = addStr(arr, isFinite(obj) ? +obj : 'null');
			return true;
		case 'string':
			l = obj.length;
			arr = addStr(arr, '"');
			for (i = 0; i < l; i += 1) {
				c = obj.charAt(i);
				if (c >= ' ') {
					if (c == '\\' || c == '"') {
						arr = addStr(arr, '\\');
					}
					arr = addStr(arr, c);
				} else {
					switch (c) {
					case '\b':
						arr = addStr(arr, '\\b');
						break;
					case '\f':
						arr = addStr(arr, '\\f');
						break;
					case '\n':
						arr = addStr(arr, '\\n');
						break;
					case '\r':
						arr = addStr(arr, '\\r');
						break;
					case '\t':
						arr = addStr(arr, '\\t');
						break;
					default:
						c = c.charCodeAt();
						arr = addStr(arr, '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16));
					}
				}
			}
			arr = addStr(arr, '"');
			return true;
		case 'boolean':
			arr = addStr(arr, String(obj));
			return true;
		default:
			arr = addStr(arr, 'null');
			return true;
		}
	}
	convertVal(obj);
	return arr.join('');
};

lib.string.json.decode = function (str) {
	// deserializes the JSON string
	return lib.string.getValue(str);
};
// lib.browser 1.3.0
// requires: nothing
//
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// browser capabilities detection
// WARNING: init runs imediately after script is loaded (you need not to call it).
// may NOT use any JS library, because it is initialized before page load

if (typeof lib == "undefined") {
	var lib = {};
};

if (typeof lib.browser == "undefined") {
	lib.browser = {};
};

if (typeof lib.browser.data == "undefined") {
	lib.browser.data = {};
};




lib.browser.name = "lib.browser";

lib.browser.gecko =     false;
lib.browser.opera =     false;
lib.browser.ie =        false;
lib.browser.ie5 =       false;
lib.browser.ie55 =      false;
lib.browser.ie6 =       false;
lib.browser.safari =    false;
lib.browser.iCab =      false;
lib.browser.konqueror = false;
lib.browser.netscape =  false;

lib.browser.agent =    "an unknown browser";
lib.browser.version =  "an unknown version";
lib.browser.os =       "an unknown OS";




lib.browser.init = function() {
	var browserData = lib.browser._getBrowserData();
	if (browserData != null) {
		lib.browser._setBrowserInfo(browserData);
	};
	var osData = lib.browser._getOsData();
	if (osData != null) {
		lib.browser._setOsInfo(osData);
	};
	return true;
};

lib.browser._getBrowserData = function () {
	for (var i = 0, l = lib.browser.data.agent.length; i < l; i++) {
		var dataString = lib.browser.data.agent[i].string;
		var dataProp = lib.browser.data.agent[i].prop;
		if (dataString) {
			if (dataString.indexOf(lib.browser.data.agent[i].subString) != -1) {
				return lib.browser.data.agent[i];
			}
		} else if (dataProp) {
			return lib.browser.data.agent[i];
		}
	};
	return null; // not found
};

lib.browser._setBrowserInfo = function (browserData) {
	// detect version
	var versionSearchString = browserData.versionSearch || browserData.identity;
	var dataString = navigator.userAgent;
	var index = dataString.indexOf(versionSearchString);
	if (index < 0) {
		dataString = navigator.appVersion;
		index = dataString.indexOf(versionSearchString);
	};
	if (index > 0) {
		lib.browser.version = parseFloat(dataString.substring(index + versionSearchString.length + 1));
	};
	// detect browser
	lib.browser.agent = browserData.identity;
	switch (browserData.identity) {
		case "Safari": lib.browser.safari = true; break;
		case "Opera": lib.browser.opera = true; break;
		case "Firefox": lib.browser.gecko = true; break;
		case "Netscape":
			if (lib.browser.version >= 6) {
				lib.browser.gecko = true;
			} else {
				lib.browser.netscape = true;
			};
			break;
		case "Explorer":
			lib.browser.ie = true;
			if (lib.browser.version == 5) {
				lib.browser.ie5 = true;
			} else if (lib.browser.version == 5.5) {
				lib.browser.ie55 = true;
			} else if (lib.browser.version == 6) {
				lib.browser.ie6 = true;
			};
	};
	return true;
};

lib.browser._getOsData = function () {
	for (var i = 0, l = lib.browser.data.os.length; i < l; i++) {
		var dataString = lib.browser.data.os[i].string;
		if (dataString) {
			if (dataString.indexOf(lib.browser.data.os[i].subString) != -1) {
				return lib.browser.data.os[i];
			}
		}
	};
	return null; // not found
};

lib.browser._setOsInfo = function (osData) {
	lib.browser.os = osData.identity;
};




// browser and os data

lib.browser.data.agent = [
	{
		string: navigator.vendor,
		subString: "Apple",
		identity: "Safari"
	},
	{
		prop: window.opera,
		identity: "Opera"
	},
	{
		string: navigator.vendor,
		subString: "iCab",
		identity: "iCab"
	},
	{
		string: navigator.vendor,
		subString: "KDE",
		identity: "Konqueror"
	},
	{
		string: navigator.userAgent,
		subString: "Firefox",
		identity: "Firefox"
	},
	{	// for newer Netscapes (6+)
		string: navigator.userAgent,
		subString: "Netscape",
		identity: "Netscape"
	},
	{
		string: navigator.userAgent,
		subString: "MSIE",
		identity: "Explorer",
		versionSearch: "MSIE"
	},
	{
		string: navigator.userAgent,
		subString: "Gecko",
		identity: "Mozilla",
		versionSearch: "rv"
	},
	{ 	// for older Netscapes (4-)
		string: navigator.userAgent,
		subString: "Mozilla",
		identity: "Netscape",
		versionSearch: "Mozilla"
	}
];

lib.browser.data.os = [
	{
		string: navigator.platform,
		subString: "Win",
		identity: "Windows"
	},
	{
		string: navigator.platform,
		subString: "Mac",
		identity: "Mac"
	},
	{
		string: navigator.platform,
		subString: "Linux",
		identity: "Linux"
	}
];



lib.browser.init(); // init immediately
// lib.cls 1.0.0
// requires: nothing
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// element class manipulations
// written by FCZBKK - http://www.fczbkk.com

var lib = lib || {};
lib.cls = lib.cls || {};



lib.cls.name = "lib.cls";




lib.cls.get = function (elm) {
	// Array lib.cls.get(HtmlElement elm)
	// Returns all classes of the element elm as Array of Strings
	var cls = ""; // String
	if (elm && (typeof elm.className != "undefined")) {
		cls = elm.className.replace(/\s+/g, " ");
		if (cls === "") {
			return [];
		}
		return cls.split(" ");
	}
	return null;
};

lib.cls.has = function (elm, cls) {
	// Boolean lib.cls.has(HtmlElement elm, String cls)
	// Returns true if element elm contains the class cls
	
	var actCls, i, l;
	if ((typeof cls == "string") && (actCls = lib.cls.get(elm))) {
		for (i = 0, l = actCls.length; i < l; i++) {
			if (actCls[i] == cls) {
				return true;
			}
		}
	}
	return false;
};

lib.cls.add = function (elm, cls) {
	// Boolean lib.cls.add(HtmlElement elm, String cls)
	// Adds class cls to element elm if it is not present
	var actCls = lib.cls.get(elm);
	if (actCls !== null) {
		if (!lib.cls.has(elm, cls)) {
			elm.className += (actCls.length > 0) ? " " + cls : cls;
		}
	} else {
		elm.className = cls;
	}
	return true;
};

lib.cls.remove = function (elm, cls) {
	// Boolean lib.cls.remove(HtmlElement elm, String cls)
	// Removes class cls from element elm
	var actCls = lib.cls.get(elm); // String
	var tempCls = ""; // String
	var i, l;
	if ((typeof cls == "string") && (actCls !== null)) {
		for (i = 0, l = actCls.length; i < l; i++) {
			if (actCls[i] != cls) {
				if (tempCls !== "") {
					tempCls += " ";
				}
				tempCls += actCls[i];
			}
			elm.className = tempCls;
		}
		return true;
	}
	return false;
};

lib.cls.replace = function (elm, oldCls, newCls) {
	// Boolean lib.cls.replace(HtmlElement elm, String oldCls, String newCls)
	// Replaces class oldCls by class newCls. If there is no oldCls adds newCls.
	var actCls = lib.cls.get(elm); // String
	var tempCls = ""; // String
	var i, l;
	if ((typeof oldCls == "string") && (typeof newCls == "string") && (actCls !== null)) {
		if (lib.cls.has(elm, newCls)) {
			lib.cls.remove(elm, oldCls);
		} else if (lib.cls.has(elm, oldCls)) {
			for (i = 0, l = actCls.length; i < l; i++) {
				if (tempCls !== "") {
					tempCls += " ";
				}
				tempCls += (actCls[i] == oldCls) ? newCls : actCls[i];
			}
			elm.className = tempCls;
		} else {
			lib.cls.add(elm, newCls);
		}
		return true;
	}
	return false;
};
// lib.cookie 1.0.0
// requires: nothing
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// cookie manipulations
// written by FCZBKK - http://www.fczbkk.com

if (typeof lib == "undefined") {
	var lib = {};
};

if (typeof lib.cookie == "undefined") {
	lib.cookie = {};
};




lib.cookie.name = "lib.cookie";




lib.cookie.set = function (name, value, days, domain, path) {
	// sets cookie
	var date; // Date
	var expires; // String
	value = value + "; ";
	if ((typeof days != "undefined") && (days != null)) {
		date = new Date();
		date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
		expires = "expires=" + date.toGMTString() + "; ";
	} else {
		expires = "";
	};
	if ((typeof domain != "undefined") && (domain != null) && (domain.indexOf(".") != -1)) {
		domain = "domain=" + domain + "; ";
	} else {
		domain = "";
	};
	if (typeof path != "undefined") {
		path = "path=" + path;
	} else {
		path = "path=/";
	};
	document.cookie = name + "=" + value + expires + domain + path;
	return true;
};

lib.cookie.get = function (name) {
	// gets cookie value by name
	var i; // Int iterator
	var nameEQ = name + "="; // String
	var c; // String
	var ca = document.cookie.split(";"); // Array of Strings
	for (i = 0, l = ca.length; i < l; i++) {
		c = ca[i];
		while (c.charAt(0) == " ") {
			c = c.substring(1, c.length);
		};
		if (c.indexOf(nameEQ) == 0) {
			return c.substring(nameEQ.length, c.length);
		};
	};
	return null;
};

lib.cookie.remove = function (name) {
	// unsets the cookie
	lib.cookie.set(name, "", -1);
	return true;
};
// lib.data 1.0.4
// requires: lib.array
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// allows to set and retrieve data from DOM elements as well as other object

var lib = lib || {};
lib.data = lib.data || {};




lib.data.name = "lib.data";
lib.data.attribute = "_jsData"; // name of DOM element attribute containing all data from sc framework
lib.data._flushData = []; // this is needed for flushing data on unload (to prevent memory leaks)




lib.data.set = function (elm, fieldName, data, nameSpace) {
	if (typeof nameSpace == "undefined") {
		nameSpace = lib.data.name;
	}
	if (typeof elm[lib.data.attribute] == "undefined") {
		elm[lib.data.attribute] = {};
		lib.array.push(lib.data._flushData, {elm: elm});
	}
	if (typeof elm[lib.data.attribute][nameSpace] == "undefined") {
		elm[lib.data.attribute][nameSpace] = {};
	}
	elm[lib.data.attribute][nameSpace][fieldName] = data;
	return true;
};

lib.data.get = function (elm, fieldName, nameSpace) {
	if (typeof nameSpace == "undefined") {
		nameSpace = lib.data.name;
	}
	var data = null;
	if (
		(typeof elm[lib.data.attribute] != "undefined") &&
		(typeof elm[lib.data.attribute][nameSpace] != "undefined") &&
		(typeof elm[lib.data.attribute][nameSpace][fieldName] != "undefined")
	) {
		data = elm[lib.data.attribute][nameSpace][fieldName];
	}
	return data;
};

lib.data.getFieldNames = function (elm, nameSpace) {
	var result = [];
	var fieldName;
	if (
		(typeof elm[lib.data.attribute] != "undefined") &&
		(typeof elm[lib.data.attribute][nameSpace] != "undefined")
	) {
		for (fieldName in elm[lib.data.attribute][nameSpace]) {
			if (
				(typeof elm[lib.data.attribute][nameSpace].hasOwnProperty != "undefined") &&
				(elm[lib.data.attribute][nameSpace].hasOwnProperty(fieldName) )
			) {
				result[result.length] = fieldName;
			}
		}
	}
	return result;
};

lib.data.flush = function () {
	// this shall be called on unload to prevent memory leaks in MSIE
	// this is called in lib.evt on unload by default
	var i, l;
	for (i = 0, l = lib.data._flushData.length; i < l; i++) {
		if (lib.data._flushData[i].elm) {
			lib.data._flushData[i].elm[lib.data.attribute] = null; // remove the reference
		}
	}
	return true;
};
// lib.elm 1.1.6
// requires: lib.array, lib.string, lib.cls
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// handles DOM elements, encapsulates common DOM operations

var lib = lib || {};
lib.elm = lib.elm || {};



lib.elm.name = "lib.elm";
lib.elm.xHtmlNameSpace = "http://www.w3.org/1999/xhtml";




lib.elm.get = function (obj) {
	// HtmlElement lib.elm.get(HtmlElement|String)
	// Returns HTML element that belongs to object obj.
	var result;
	if (typeof obj == "undefined") {
		result = null;
	} else if (typeof obj == "string") {
		// if obj is String, returns object with id obj
		return document.getElementById(obj);
	}
	return obj; // if obj is HtmlElement, returns it unchanged
};

lib.elm.getByTag = function (tagName, parentElm) {
	// returns array of elements with given tagName
	parentElm = parentElm || null;
	parentElm = (parentElm) ? lib.elm.get(parentElm) : document;
	var result = null;
	if (parentElm.all && (tagName == "*")) { // MSIE hack
		result = parentElm.all;
	}
	if (parentElm.getElementsByTagName) { // standard way
		result = parentElm.getElementsByTagName(tagName);
	}
	return result;
};

lib.elm.getByClass = function (className, parentElm, tagName) {
	// not very effective. If you can, use only when parentElement and tagName is specified
	// thanx http://www.dustindiaz.com/getelementsbyclass for inspiration
	parentElm = parentElm || null;
	parentElm = (parentElm) ? lib.elm.get(parentElm) : document;
	var result = [];
	tagName = (tagName) ? tagName : "*";
	var allElm = lib.elm.getByTag(tagName, parentElm);
	var c = 0;
	for (var i = 0, l = allElm.length; i < l; i++ ) {
		if (lib.cls.has(allElm[i], className)) {
			result[c++] = allElm[i];
		}
	}
	return result;
};

lib.elm.hasAttributes = function (elm, attributes) {
	// tests if the element has all attributes specified by associative array
	// don't use href as search attribute - MSIE changes it
	elm = elm || null;
	elm = lib.elm.get(elm);
	var result = true;
	var elmAttr;
	testAttributes:
		for (var attr in attributes) {
			if (attr == "className") {
				if (!lib.cls.has(elm, attributes[attr])) {
					result = false;
					break testAttributes;
				}
			} else {
				elmAttr = lib.elm.getAttribute(elm, attr);
				if (attr == "tagName") {
					elmAttr = elmAttr.toLowerCase();
				}
				if (elmAttr != attributes[attr]) {
					result = false;
					break testAttributes;
				}
			}
		}
	return result;
};

lib.elm.find = function (attributes, parentElm) {
	// finds all elements with attributes specified by associative array
	// don't use href as search attribute - MSIE changes it
	// beware, this is very slow!
	parentElm = parentElm || null;
	parentElm = (parentElm) ? lib.elm.get(parentElm) : document;
	var result = [];
	var tagName = "*";
	if (typeof attributes.tagName == "string") {
		 tagName = attributes.tagName;
	}
	var allElm = lib.elm.getByTag(tagName, parentElm);
	var i, l;
	if (allElm !== null) {
		findElm:
			for (i = 0, l = allElm.length; i < l; i++) {
				if (lib.elm.hasAttributes(allElm[i], attributes)) {
					lib.array.push(result, allElm[i]);
				}
			}
	}
	return result;
};

lib.elm.findFirst = function (attributes, parentElm) {
	// finds the first element that has all attributes specified by associative array
	parentElm = parentElm || null;
	parentElm = (parentElm) ? lib.elm.get(parentElm) : document;
	var result = null;
	var tagName = "*";
	if (typeof attributes.tagName == "string") {
		 tagName = attributes.tagName;
	}
	var allElm = lib.elm.getByTag(tagName, parentElm);
	var i, l;
	if (allElm !== null) {
		findElm:
			for (i = 0, l = allElm.length; i < l; i++) {
				if (lib.elm.hasAttributes(allElm[i], attributes)) {
					result = allElm[i];
					break findElm; // element found!
				}
			}
	}
	return result;
};

lib.elm.getParent = function (elm) {
	// returns parent element. If there is no parent element it returns null
	elm = elm || null;
	elm = lib.elm.get(elm);
	if (typeof elm.parentNode == "undefined") {
		return null;
	} else {
		return elm.parentNode;
	}
};

lib.elm.getAncestorByTag = function (elm, tagName) {
	// returns ancestor elemenet (by tagName), if nothing has been found, returns null
	elm = elm || null;
	elm = lib.elm.get(elm);
	tagName = tagName.toLowerCase();
	var actualTagName = "";
	do {
		elm = lib.elm.getParent(elm);
		if (elm === null) { return null; } // parent not found
		actualTagName = elm.tagName.toLowerCase();
	} while ((actualTagName != tagName) && (actualTagName != "html"));
	if (actualTagName == tagName) {
		return elm; // element found
	} else {
		return null; // no element found
	}
};

lib.elm.getChildrenByTag = function (tagName, elm) {
	// returns array of children, if nothing has been found, returns null
	elm = elm || null;
	elm = lib.elm.get(elm);
	tagName = tagName.toLowerCase();
	var result = null;
	var actualNode;
	if (elm.firstChild) {
		actualNode = elm.firstChild;
		do {
			if (actualNode.tagName && (actualNode.tagName.toLowerCase() == tagName)) {
				if (result === null) {
					result = [];
				}
				result[result.length] = actualNode;
			}
			actualNode = actualNode.nextSibling;
		} while (actualNode !== null);
	}
	return result;
};

lib.elm.getValue = function (elm) {
	// returns the value of the element
	elm = elm || null;
	elm = lib.elm.get(elm);
	var result = "";
	var radioSet;
	var i, l;
	if (elm.type && (elm.type == "checkbox")) {
		result = elm.checked ? elm.value : "";
	} else if (elm.type && (elm.type == "radio")) {
		// radiobutton is special
		radioSet = elm.form[elm.name]; // if there is no form, throw an exception
		findChecked:
			for (i = 0, l = radioSet.length; i < l; i++) {
				if (radioSet[i].checked) {
					result = radioSet[i].value;
					break findChecked;
				}
			}
	} else if ((typeof elm.value != "undefined") && (typeof elm.value !== null)) {
		result = elm.value;
	} else if (elm.tagName.toLowerCase() == "select") {
		if (typeof (elm.selectedIndex != "undefined") && (typeof elm.options != "undefined")) {
			if (elm.selectedIndex >= 0) {
				result = elm.options[elm.selectedIndex].value; // if select is multiple, returns only first value
			}
		}
	} else { result = null; }
	return result;
};

lib.elm.setValue = function (elm, newValue) {
	// sets the element value.
	elm = elm || null;
	elm = lib.elm.get(elm);
	var i, l;
	if (elm.options && (elm.options.length > 0)) { // element is SELECT
		for (i = 0, l = elm.options.length; i < l; i++) {
			if (elm.options[i].value == newValue) {
				elm.options[i].selected = true;
				elm.options[i].setAttribute("selected", "selected");
				// throws exception in MSIE
				// if (elm.focus) { elm.focus(); } // focus the field if possible
				return true;
			} else {
				elm.options[i].selected = false;
				elm.options[i].setAttribute("selected", "");
			}
		}
		return false;
	} else if (typeof elm.value != "undefined") {
		elm.value = newValue;
		// throws exception in MSIE
		// if (elm.focus) { elm.focus(); } // focus the field if possible
		// if (elm.select) { elm.select(); } // select the content if possible
		return true;
	}
	return false;
};

lib.elm.getAttribute = function (elm, attrName) {
	// gets value of attribute attrName of element elm
	elm = elm || null;
	elm = lib.elm.get(elm);
	var result = elm.getAttribute(attrName);
	if (result === null) {
		if ((attrName == "class") && (typeof elm.getAttribute("class") == "undefined")) {
			result = elm.getAttribute("className");
		} else if ((attrName == "for") && (elm.getAttribute("for") === null)) {
			result = elm.getAttribute("htmlFor");
		} else if (typeof elm[attrName] != "undefined") {
			result = elm[attrName];
		}
	}
	return result;
};

lib.elm.getStyle = function(elm, styleProp) {
	// tries to obtain the CSS property value of element elm
	// TODO: add support for composite attributes like "background" or "padding"
	elm = elm || null;
	elm = lib.elm.get(elm);
	var value = elm.style[lib.string.camelize(styleProp)];
	var css;
	if (!value) {
		if (document.defaultView && document.defaultView.getComputedStyle) {
			css = document.defaultView.getComputedStyle(elm, null);
			value = css ? css.getPropertyValue(styleProp) : null;
		} else if (elm.currentStyle) {
			value = elm.currentStyle[lib.string.camelize(styleProp)];
		}
	}
	if (window.opera) {
		if (lib.array.contains(["left", "top", "right", "bottom"], styleProp)) {
			if (lib.elm.getStyle(elm, "position") == "static") {
				value = "auto";
			}
		}
	}
	return value == "auto" ? null : value;
};

lib.elm.applyStyle = function (elm, styleCfg) {
	// apply the style defined in JSON array on element
	elm = elm || null;
	elm = lib.elm.get(elm);
	for (var i in styleCfg) {
		if (typeof styleCfg[i] == "string") {
			elm.style[i] = styleCfg[i];
		}
	}
	return true;
};

lib.elm.create = function (config, contentNodes) {
	// creates element tree defined by config object.
	contentNodes = contentNodes || [];
	config = config || {};
	var result = null;
	var i1, i2, i3, l2, l3;
	var child = null;
	var newElement = null;
	
	// config = { contentNode: x }
	var childConfig;
	var isChildContentNode;
	var contentNodesItem;
	
	if (typeof config.contentNode == "number") {
		if (contentNodes[config.contentNode]) {
			result = contentNodes[config.contentNode];
		} else {
			result = null;
		}
	} else { // config = { tagName: ... }
		config.innerText   = config.innerText || null;
		config.tagName     = config.tagName || null;
		if (config.innerText) {
			// create text node
			result = document.createTextNode(config.innerText);
		}
		if (config.tagName) {
			// create standard HTML element
			if (document.createElementNS) { // Gecko, standard
				newElement = document.createElementNS(lib.elm.xHtmlNameSpace, config.tagName);
			} else {
				newElement = document.createElement(config.tagName);
			}
			if (result !== null) {
				newElement.appendChild(result);
			}
			for (i1 in config) {
				switch (i1) {
					case "tagName": break; // already used
					case "innerText": break; // already used
					case "contentNode": break; // already used
					case "children": // create childNodes
						for (i2 = 0, l2 = config.children.length; i2 < l2; i2++) {
							childConfig = config.children[i2];
							
							isChildContentNode = (typeof childConfig.contentNode == "number") && (typeof contentNodes[childConfig.contentNode] == "object");
							
							if (isChildContentNode) {
								contentNodesItem = contentNodes[childConfig.contentNode];
								
								if (contentNodesItem instanceof Array) {
									// this means the actual contentNode is not 1 HTML element but an array of them
									for (i3 = 0, l3 = contentNodesItem.length; i3 < l3; i3++) {
										newElement.appendChild(contentNodesItem[i3]);
									}
								} else if (contentNodesItem !== null) {
									// this means the contentNode is single HTML element
									newElement.appendChild(contentNodesItem);
								}
							} else {
								child = lib.elm.create(childConfig, contentNodes); // child == null or array or html element
								if (child !== null) {
									newElement.appendChild(child);
								}
							}
						}
						break;
					case "style": // style definitions
						lib.elm.applyStyle(newElement, config[i1]);
						break;
					case "className":
						newElement.className = config[i1];
						break;
					case "htmlFor":
						newElement.setAttribute("for", config[i1]);
						break;
					default: // add standard attribute
						newElement.setAttribute(i1, config[i1]);
						break;
				}
			}
			if (newElement) {
				result = newElement;
			}
		}
	}
	return result;
};

lib.elm.envelope = function (elm, envelopeConfig) {
	// envelopes element elm by newly created element
	elm = elm || null;
	elm = lib.elm.get(elm);
	var envelope = lib.elm.create(envelopeConfig);
	if (elm.parentNode) {
		elm.parentNode.insertBefore(envelope, elm);
	}
	envelope.appendChild(elm);
	return envelope;
};

lib.elm.envelopeChildren = function (elm, envelopeConfig) {
	// envelopes obj childNodes by newly created element
	elm = elm || null;
	elm = lib.elm.get(elm);
	var envelope = lib.elm.create(envelopeConfig, [ lib.array.convert(elm.childNodes) ] );
	elm.appendChild(envelope);
	return envelope;
};
// lib.evt 1.1.6
// requires: lib.array, lib.data
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// event handling function has three arguments - fn(elm, e, evtId)
// these arguments are filled automatically when the event is handled
// elm - trigger DOM element, e - triggering event, evtId - event handler ID
// 

var lib = lib || {};
lib.evt = lib.evt || {};




lib.evt.name = "lib.evt";
lib.evt.defaultPriority = 100; // when the priority is not set, sets this priority

lib.evt._handlers = []; // array storing all event handling functions. You can find them by evtId.
lib.evt._flushData = []; // this is needed for flushing event handlers on unload (to prevent memory leaks)




lib.evt.add = function (elm, evType, fn, priority, callbackContext) {
	// Attaches event listener to element elm
	// returns event id number
	if ((typeof priority == "undefined") || (priority === null)) {
		priority = lib.evt.defaultPriority;
	}
	if ((typeof callbackContext == "undefined") || (callbackContext === null)) {
		callbackContext = elm;
	}
	
	// create a new queue - f (elm, evType)
	var evQue = lib.data.get(elm, evType, lib.evt.name);
	var evName;
	
	if (evQue === null) {
		evQue = [];
		lib.data.set(elm, evType, evQue, lib.evt.name);
		
		evName = "on" + evType;
		
		// if there is an event handler, preserve it
		if (typeof elm[evName] == "function") {
			lib.data.set(elm, evName, elm[evName], lib.evt.name);
		}
		
		// add a real event handler
		// don't use listeners, or you will be unable to handle custom events
		elm[evName] = lib.evt._handler; // add event handler
		lib.array.push(lib.evt._flushData, {elm: elm, evName: evName});
	}
	// add event data record to the queue 
	var handlerData = {
		elm:        elm,
		evType:     evType,
		priority:   priority,
		context:    callbackContext
	};
	var handlerId = lib.array.insert(lib.evt._handlers, handlerData); // register this handler
	handlerData.id = handlerId;
	handlerData.fn = fn;
	
	lib.array.push(evQue, handlerData);
	lib.array.sortBy(evQue, "priority"); // .reverse();  lowest priority goes first
	
	return handlerData.id;
};

lib.evt.remove = function (evtId) {
	// removes the event specified by id
	var elm = lib.evt._handlers[evtId].elm;
	var evType = lib.evt._handlers[evtId].evType;
	lib.evt._handlers[evtId] = null;
	var evQue = lib.data.get(elm, evType, lib.evt.name);
	search:
		for (var i = 0, l = evQue.length; i < l; i++) {
			if (evQue[i].id == evtId) {
				evQue[i] = null;
				break search;
			}
		}
	lib.array.sortBy(evQue, "priority").reverse();
	return true;
};

lib.evt.getTarget = function (e) {
	// gets event target element
	var result = window;
	if (e.target) {
		result = e.target;
	} else if (e.srcElement) {
		result = e.srcElement;
	}
	if (result.nodeType && (result.nodeType == 3)) { // defeat Safari bug, thanks to PPK
		result = result.parentNode;
	}
	return result;
};

lib.evt.getType = function (e) {
	// returns the type of the event ("click", "submit" etc.)
	return e.type;
};

lib.evt.getPriority = function (evtId) {
	return lib.evt._handlers[evtId].priority;
};

lib.evt.getMousePosition = function (e) {
	// returns object { int x, int y } that contains the position of the mouse cursor on the screen
	// when the event has been triggered.
	if (!e) { e = window.event; }
	var pos = { x:0, y:0 };
	if (e.pageX || e.pageY) {
		// Mozilla etc.
		pos.x = e.pageX;
		pos.y = e.pageY;
	} else if (e.clientX || e.clientY) {
		// MSIE
		pos.x = e.clientX;
		pos.y = e.clientY;
		if ( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
			// DOM compliant
			pos.x += document.body.scrollLeft;
			pos.y += document.body.scrollTop;
		} else if ( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
			//IE6 standards compliant mode
			pos.x += document.documentElement.scrollLeft;
			pos.y += document.documentElement.scrollTop;
		}
	}
	return pos;
};

lib.evt.getKey = function (e) {
	// if the event type is "keyPress", "keyDn" or "keyUp", returns the key code
	if (window.event) {
		return window.event.keyCode;
	} else if (e) {
		return e.which;
	} else {
		return null;
	}
};

lib.evt.getHandlerData = function (evtId) {
	// returns a reference to the data object that contains all object data
	return lib.evt._handlers[evtId];
};

lib.evt.stop = function (e) {
	// stops event propagation
	if (e.stopPropagation) {
		e.stopPropagation();
	}
	if (typeof e.cancelBubble == "boolean") {
		e.cancelBubble = true;
	}
	lib.data.set(e, "stop", true, lib.evt.name);
	return true;
};

lib.evt.cancel = function (e) {
	// stops event propagation
	// and cancels processing of default event handler
	lib.evt.stop(e);
	if (e.preventDefault) {
		e.preventDefault();
	} else {
		e.returnValue = false;
	}
	return true;
};

lib.evt.flush = function () {
	// this shall be called on unload to prevent memory leaks in MSIE
	for (var i = 0, l = lib.evt._flushData.length; i < l; i++) {
		if (lib.evt._flushData[i].elm) {
			lib.evt._flushData[i].elm[lib.evt._flushData[i].evName] = null; // remove the event handler
		}
	}
	return true;
};

lib.evt.create = function (evType, props) {
	// creates and returns a custom event
	var evt = {};
	if (props) {
		evt = props;
	}
	evt.type = evType;
	evt.preventDefault = function () {}; // custom event doesn't bubble
	evt.isCustomEvent = true;
	return evt;
};

lib.evt.addType = function (elm, evType) {
	// makes the element capable to process another event type.
	if ((typeof elm["on" + evType] == "undefined") || (elm["on" + evType] === null)) {
		elm["on" + evType] = function () {}; // default handler (empty)
	}
	return true;
};

lib.evt.run = function (elm, evType) {
	// runs event handlers of evType on element elm
	var evQue = lib.data.get(elm, evType, lib.evt.name);
	var e;
	if ((typeof evQue != "undefined") && (evQue !== null)) {
		e = lib.evt.create(evType);
		return lib.evt._process(elm, e);
	}
	return false;
};

lib.evt._process = function (elm, e) {
	// process the event
	var evType = lib.evt.getType(e);
	var evQue = lib.data.get(elm, evType, lib.evt.name);
	
	// first, process preserved original event handler
	var fn = lib.data.get(elm, "on" + evType, lib.evt.name);
	if (fn !== null) {
		fn.apply(elm, [e]);
	}
	if (evQue) {
		// now process standard event queue
		processEvent:
			for (var i = 0, l = evQue.length; i < l; i++) {
				if (lib.data.get(e, "stop", lib.evt.name)) {
					break processEvent;
				} else if (evQue[i]) {
					evQue[i].fn.apply(evQue[i].context, [evQue[i].elm, e, evQue[i].id]);
				}
			}
	}
	return true;
};

lib.evt._handler = function (e) {
	if (typeof e == "undefined") { e = window.event; }
	var elm = this; // handler is attached directly to the trigger object
	return lib.evt._process(elm, e);
};




// prevent memory leaks
lib.evt.add(window, "unload", lib.data.flush);
lib.evt.add(window, "unload", lib.evt.flush);
// lib.log 1.1.1
// requires: lib.elm, lib.cls
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 

if (typeof lib == "undefined") {
	var lib = {};
};

if (typeof lib.log == "undefined") {
	lib.log = {};
};




lib.log.name = "lib.log";
lib.log.enabled =      true;  // if true, logging is on
lib.log.initialized =  false; // if true, log is prepared to work
lib.log.nodeId =       "messages";
lib.log.node =         null;
lib.log.messagesList = null;




lib.log.init = function () {
	lib.log.node = lib.elm.get(lib.log.nodeId);
	if (lib.log.node == null) {
		lib.log.node = lib.log.create();
	};
	lib.log.messagesList = lib.elm.create({tagName: "ul"});
	lib.log.node.appendChild(lib.log.messagesList);
	lib.log.initialized = true; // init succeded
	return true;
};

lib.log.create = function () {
	// creates a new log and places it at the start of the body.
	var node = lib.elm.create({tagName: "div", id: lib.log.nodeId});
	var body = lib.elm.getByTag("body", document)[0];
	body.insertBefore(node, body.firstChild);
	return node;
};

lib.log.write = function (msgText, msgType) {
	var i;
	if ((typeof msgText == "undefined") || (msgText == null) || (typeof msgText.toString != "function")) {
		msgText = "";
	};
	msgText = msgText.toString();
	if (lib.log.enabled) {
		var li = lib.elm.create({tagName: "li"});
		if ((typeof msgType != "undefined") && (msgType != null) && (msgType != "")) {
			lib.cls.add(li, msgType);
		};
		var msgLines = msgText.split("\n");
		for (var i = 0, l = msgLines.length; i < l; i++) {
			var msg = document.createTextNode(msgLines[i]);
			var br = document.createElement("br")
			li.appendChild(msg);
			li.appendChild(br);
		};
		lib.log.messagesList.insertBefore(li, lib.log.messagesList.firstChild);
	};
	return true;
};

lib.log.clear = function () {
	while (messagesList.firstChild) {
		messagesList.removeChild(messagesList.firstChild);
	};
	return true;
};
// lib.mouse 1.4.2
// requires: lib.evt, lib.cls
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// mouse related actions

if (typeof lib == "undefined") {
	var lib = {};
};

if (typeof lib.mouse == "undefined") {
	lib.mouse = {};
};

if (typeof lib.mouse.hover == "undefined") {
	lib.mouse.hover = {};
};




lib.mouse.name = "lib.mouse";
lib.mouse.x = 0;
lib.mouse.y = 0;




lib.mouse.init = function () {
	// test if function has been called. If it was, exit.
	if (arguments.callee.done) {
		return false;
	} else {
		arguments.callee.done = true;
	};
	// track the mouse position
	lib.evt.add(document, "mousemove", lib.mouse._savePos);
	return true;
};

lib.mouse._savePos = function (doc, e) {
	var pos = lib.evt.getMousePosition(e);
	lib.mouse.x = pos.x;
	lib.mouse.y = pos.y;
	return true;
};

lib.mouse.getPos = function () {
	return [lib.mouse.x, lib.mouse.y];
};




// this adds the missing MSIE ability to generate :hover pseudoclass
lib.mouse.hover.className = "hover";




lib.mouse.hover.add = function (elm) {
	// adds hover functionality to element, returns event handler's id
	lib.evt.add(elm, "mouseover", lib.mouse.hover._set);
	lib.evt.add(elm, "mouseout",  lib.mouse.hover._clear);
	return true;
};

lib.mouse.hover._set = function (elm) {
	return lib.cls.add(elm, lib.mouse.hover.className);
};

lib.mouse.hover._clear = function (elm) {
	return lib.cls.remove(elm, lib.mouse.hover.className);
};




// use this if you need to track mouse movements:
// lib.evt.add(window, "load", lib.mouse.init);
// lib.url 0.3.1
// requires: lib.array
//
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// works with url

lib.url = {
	name: "lib.url",
	
	getParameters: function (url) {
		// returns URL parameters as array of pairs {name, value}
		var result = null;
		var parts = url.split("?");
		if (parts.length == 2) {
			result = new Array();
			var resultStr = parts[1].split("#")[0];
			var resultArray = resultStr.split("&");
			for (var i = 0, l = resultArray.length; i < l; i++) {
				var pair = resultArray[i].split("=");
				if (pair.length == 1) { pair[1] = ""; };
				lib.array.push(result, {name: pair[0], value: pair[1]});
			}
		};
		return result;
	},
	
	getParameter: function (url, paramName) {
		var pairs = lib.url.getParameters(url);
		if (pairs) {
			for (var i = 0, l = pairs.length; i < l; i++) {
				if (pairs[i].name == paramName) {
					return pairs[i].value;
				}
			}
		};
		return null;
	}
};
// lib.vector 1.0.2
// requires: nothing
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 

var lib = lib || {};
lib.vector = lib.vector || {};



lib.vector.name = "lib.vector";




lib.vector.adjustDimension = function () {
	// modifies all vectors (arrays) entered as arguments to have the equal dimension
	var dimension = 0;
	var i, l, vector;
	for (i = 0, l = arguments.length; i < l; i++) {
		if (arguments[i].length > dimension) {
			dimension = arguments[i].length;
		}
	}
	for (i = 0, l = arguments.length; i < l; i++) {
		if (arguments[i].length < dimension) {
			vector = arguments[i];
			for (i = 0, l = dimension; i < l; i++) {
				if ((typeof vector[i] == "undefined") || (typeof vector[i] === null)) {
					vector[i] = 0;
				}
			}
		}
	}
	return true;
};

lib.vector.copy = function (vector) {
	// returns the copy of the vector
	var result = [];
	for (var i = 0, l = vector.length; i < l; i++) {
		result[i] = vector[i];
	}
	return result;
};

lib.vector.equals = function (vectorA, vectorB) {
	// returns true if vectorA equals vectorB
	lib.vector.adjustDimension(vectorA, vectorB);
	for (var i = 0, l = vectorA.length; i < l; i++) {
		if (vectorA[i] != vectorB[i]) {
			return false;
		}
	}
	return true;
};

lib.vector.add = function (vectorA, vectorB) {
	// adds vector A to vector B, returns the final vector
	lib.vector.adjustDimension(vectorA, vectorB);
	var result = [];
	for (var i = 0, l = vectorA.length; i < l; i++) {
		result[i] = vectorA[i] + vectorB[i];
	}
	return result;
};

lib.vector.subtract = function (vectorA, vectorB) {
	// subtracts vector B from vector A, returns the final vector
	lib.vector.adjustDimension(vectorA, vectorB);
	var result = [];
	for (var i = 0, l = vectorA.length; i < l; i++) {
		result[i] = vectorA[i] - vectorB[i];
	}
	return result;
};

lib.vector.getDirection = function (startPoint, endPoint) {
	// returns the direction vector
	return lib.vector.subtract(endPoint, startPoint);
};

lib.vector.norm = function (vector) {
	// returns the size ("norm") of the vector
	var result = 0;
	for (var i = 0, l = vector.length; i < l; i++) {
		result += vector[i] * vector[i];
	}
	result = Math.sqrt(result);
	return result;
};

lib.vector.sgn = function (vector) {
	// returns the signum vector - it tells what quadrant the vector belongs to.
	var result = [];
	for (var i = 0, l = vector.length; i < l; i++) {
		if (vector[i] > 0) {
			result[i] = 1;
		} else if (vector[i] < 0 ) {
			result[i] = -1;
		} else {
			result[i] = 0;
		}
	}
	return result;
};
// lib.timeout 1.4.2
// requires: lib.array, lib.evt
//
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// manages timeouts

var lib = lib || {};
lib.timeout = lib.timeout || {};




lib.timeout.name = "lib.timeout";
lib.timeout._data = [];




lib.timeout.create = function (delay, fn, cfg) {
	// creates timeout and prepares it to work
	if (typeof cfg == "undefined") { cfg = {}; }
	var timerData = {
		fn: fn,
		cfg: cfg,
		delay: delay
	};
	var id = lib.array.insert(lib.timeout._data, timerData);
	timerData.id = id;
	return id;
};

lib.timeout.run = function (id) {
	// starts timeout with given id
	var timeout, result = false;
	if (lib.timeout._data && lib.timeout._data[id]) {
		timeout = lib.timeout._data[id];
		timeout.timeout = setTimeout("lib.timeout._trigger("+timeout.id+")", timeout.delay);
		result = true;
	}
	return result;
};

lib.timeout._trigger = function (id) {
	lib.timeout._data[id].fn(lib.timeout._data[id].cfg);
	lib.timeout._data[id] = null;
	return true;
};

lib.timeout.destroy = function (id) {
	// stops and removes the timeout with given id
	var timerData = lib.timeout._data[id];
	clearTimeout(id);
	timerData = null;
	return true;
};

lib.timeout.flush = function () {
	// destroys all timeouts. Prevents memory leaks
	for (var i = 0, l = lib.timeout._data.length; i < l; i++) {
		lib.timeout.destroy(i);
	}
};




lib.evt.add(window, "unload", lib.timeout.flush);
// lib.interval 1.4.1
// requires: lib.array, lib.evt
//
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// timer manages timeouts and intervals

var lib = lib || {};
lib.interval = lib.interval || {};




lib.interval.name = "lib.interval";
lib.interval._data = [];




lib.interval.create = function (delay, fn, cfg) {
	// creates repeater and prepares it to work
	if (typeof cfg == "undefined") { cfg = {}; }
	var timerData = {
		fn: fn,
		cfg: cfg,
		delay: delay,
		iterations: 0,
		started: false
	};
	var id = lib.array.insert(lib.interval._data, timerData);
	timerData.id = id;
	return id;
};

lib.interval.run = function (id) {
	// starts repeater with given id
	var timerData, result = false;
	if (lib.interval._data && lib.interval._data[id]) {
		timerData = lib.interval._data[id];
		if (!timerData.started) {
			timerData.repeater = setInterval("lib.interval._trigger("+timerData.id+")", timerData.delay);
			timerData.started = true;
			result = true;
		}
	}
	return result;
};

lib.interval._trigger = function (id) {
	var timerData = lib.interval._data[id];
	timerData.fn(timerData.cfg);
	return true;
};

lib.interval.stop = function (id) {
	// stops repeater with given id
	var timerData = lib.interval._data[id];
	if (timerData) {
		if (timerData.repeater) {
			clearInterval(timerData.repeater);
		}
		timerData.started = false;
	}
	return true;
};

lib.interval.destroy = function (id) {
	// stops and removes the repeater with given id
	var timerData = lib.interval._data[id];
	lib.interval.stop(id);
	timerData = null;
	return true;
};

lib.interval.flush = function () {
	// destroys all repeaters. Prevents memory leaks
	for (var i = 0, l = lib.interval._data.length; i < l; i++) {
		lib.interval.destroy(i);
	}
};




lib.evt.add(window, "unload", lib.interval.flush);
// lib.dhtml 1.5.1
// requires: lib.elm, lib.evt, lib.interval, lib.vector
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// dhtml positioning and calculations. Replaces sc.dhtml
//
// WARNING
// in MSIE, all positioned elements MUST have layout 
// (see http://www.satzansatz.de/cssd/onhavinglayout.html)
// or the absolute positioning will fail

var lib = lib || {};
lib.dhtml = lib.dhtml || {};




lib.dhtml.name = "lib.dhtml";
lib.dhtml.interval = 50; // if there is an interval, how often it is run (miliseconds). Lower number causes more busy computer.




lib.dhtml.setAbsolute = function (elm) {
	// changes the positioning of elm to absolute.
	elm.style.margin = "0"; // prevent positioning bugs
	elm.style.position = "absolute";
	return true;
};

lib.dhtml.setStatic = function (elm) {
	elm.style.position = "static";
	return true;
};

lib.dhtml.getPos = function (elm) {
	// from http://www.quirksmode.org/js/findpos.html
	// many thanks to Peter Paul Koch
	// element's position relative to page
	var offsetModifier = lib.dhtml._getOffsetModifier(elm);
	var x = elm.offsetLeft + offsetModifier[0];
	var y = elm.offsetTop + offsetModifier[1];
	return [x, y];
};

lib.dhtml.fixPos = function (elm) {
	// sets the position if not set explicitly
	// use this before setting the position to absolute - element will remain on it's place
	lib.dhtml.setPos(elm, lib.dhtml.getPos(elm));
	return true;
};

lib.dhtml.setPos = function (elm, newPos) {
	// moves obj to specified coordinates
	var offsetModifier = lib.dhtml._getOffsetModifier(elm);
	var pos = lib.vector.subtract(newPos, offsetModifier);
	elm.style.left = pos[0] + "px";
	elm.style.top  = pos[1] + "px";
	return true;
};

lib.dhtml.changePos = function (elm, movementVector) {
	var pos = lib.dhtml.getPos(elm);
	var newPos = lib.vector.add(pos, movementVector);
	lib.dhtml.setPos(elm, newPos);
	return true;
};

lib.dhtml.getMouseEvtPos = function (e) {
	// returns the position of the event generated by mouse in absolute coordinates
	var pos = lib.evt.getMousePosition(e);
	return [pos.x, pos.y];
};

lib.dhtml.getRelPos = function (elm, refElm) {
	// returns position of elm relative to position of refElm
	var pos = lib.dhtml.getPos(elm);
	var refPos = lib.dhtml.getPos(refElm);
	var relPos = lib.vector.getDirection(refPos, pos);
	return relPos;
};

lib.dhtml.getSize = function (elm) {
	// returns the size of the block element
	
	// elements with display:none return incorrect size, this shall help
	var vis = null;
	if (elm.style.display == "none") {
		vis = elm.style.visibility;
		elm.style.visibility = "hidden";
		elm.style.display = "";
	}
	
	var w = elm.offsetWidth;
	var h = elm.offsetHeight;
	
	// return to the original state
	if (vis !== null) {
		elm.style.display = "none";
		elm.style.visibility = vis;
	}
	return [w, h];
};

lib.dhtml.fixSize = function (elm) {
	// sets the size if not set explicitly
	// TODO: what if the element has borders or paddings?
	lib.dhtml.setSize(elm, lib.dhtml.getSize(elm));
	return true;
};

lib.dhtml.setSize = function (elm, newSize) {
	// sets size of the object
	
	// standard resize
	elm.style.width = newSize[0] + "px";
	elm.style.height = newSize[1] + "px";
	
	// when the element has got the borders or paddings, the size may be wrong
	var realSize = lib.dhtml.getSize(elm);
	if ((realSize[0] != newSize[0]) || (realSize[1] != newSize[1])) {
		elm.style.width  = "0px";
		elm.style.height = "0px";
		
		elm.style.width = (2*newSize[0] - realSize[0]) + "px";
		elm.style.height = (2*newSize[1] - realSize[1]) + "px";
	}
	return true;
};

lib.dhtml.changeSize = function (elm, sizeModifier) {
	var size = lib.dhtml.getSize(elm);
	var newSize = lib.vector.add(size, sizeModifier);
	lib.dhtml.setSize(elm, newSize);
	return true;
};

lib.dhtml.isOver = function (elm, point) {
	// returns true if point [x,y] is over the object obj
	var x = point[0];
	var y = point[1];
	var pos = lib.dhtml.getPos(elm);
	var size = lib.dhtml.getSize(elm);
	
	var xMin = pos[0];
	if (x < xMin) { return false; }
	var xMax = xMin + size[0];
	if (x > xMax) { return false; }
	var yMin = pos[1];
	if (y < yMin) { return false; }
	var yMax = yMin + size[1];
	if (y > yMax) { return false; }
	return true;
};

lib.dhtml.defaultFloatMovementFn = function (elm, startPos, endPos) {
	// this function returns new coordinates of obj
	// x, y - absolute coordinates where the movement ends
	
	var translationSmoothness = 5; // how smooth the translation should be
	var minStep = 5; // minimal step in pixels
	var currentPos = lib.dhtml.getPos(elm);
	
	var diffPos = lib.vector.getDirection(currentPos, endPos);
	var sgnPos = lib.vector.sgn(diffPos);
	
	diffPos = [Math.floor( diffPos[0] / translationSmoothness ), Math.floor( diffPos[1] / translationSmoothness )];
	
	if (Math.abs(diffPos[0]) < minStep) {
		diffPos[0] = sgnPos[0] * minStep;
	}
	if (Math.abs(diffPos[1]) < minStep) {
		diffPos[1] = sgnPos[1] * minStep;
	}
	
	var newPos = [currentPos[0] + diffPos[0], currentPos[1] + diffPos[1]];
	
	if (Math.abs(endPos[0] - currentPos[0]) < Math.abs(minStep)) {
		newPos[0] = endPos[0];
	}
	if (Math.abs(endPos[1] - currentPos[1]) < Math.abs(minStep)) {
		newPos[1] = endPos[1];
	}
	return newPos;
};

lib.dhtml.floatTo = function (elm, targetPos, movementFn, onAfterMove) {
	// moves element to absolute coordinates targetPos = [x, y] using trajectory defined by movementFn (elm, startPos, targetPos)
	// if movementFn is not set, it uses default straight trajectory
	// after movement ends, it invokes onAfterMove(elm);
	
	var oldCfg = lib.data.get(elm, "floatToCfg", lib.dhtml.name);
	if ((oldCfg !== null) && (typeof oldCfg.intervalId != "undefined") && (oldCfg.intervalId !== null)) {
		lib.interval.stop(oldCfg.intervalId);
	}
	
	if (typeof movementFn != "function") {
		// the default movement function
		movementFn = lib.dhtml.defaultFloatMovementFn;
	}
	
	var cfg = {
		elm: elm,
		targetPos: targetPos,
		startPos: lib.dhtml.getPos(elm),
		movementFn: movementFn
	};
	
	var setNewPos = function (cfg) {
		var elmCfg = cfg.elm;
		var newPos = cfg.movementFn(elmCfg, cfg.startPos, cfg.targetPos);
		lib.dhtml.setPos(elmCfg, newPos);
		
		var targetPosCfg = cfg.targetPos;
		if ((newPos[0] == targetPosCfg[0]) && (newPos[1] == targetPosCfg[1])) {
			lib.interval.destroy(cfg.intervalId);
		}
		return true;
	};
	
	cfg.intervalId = lib.interval.create(lib.dhtml.interval, setNewPos, cfg);
	lib.data.set(cfg.elm, "floatToCfg", cfg, lib.dhtml.name);
	lib.interval.run(cfg.intervalId);
	
	return true;
};

lib.dhtml.getViewPos = function () {
	// get viewport position
	var x = 0;
	var y = 0;
	if( typeof window.pageXOffset == "number" ) {
	// Netscape compliant
		x = window.pageXOffset;
		y = window.pageYOffset;
	} else if ( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
		//DOM compliant
		x = document.body.scrollLeft;
		y = document.body.scrollTop;
	} else if ( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
		//IE6 standards compliant mode
		x = document.documentElement.scrollLeft;
		y = document.documentElement.scrollTop;
	}
	return [ x, y ];
};

lib.dhtml.getViewSize = function () {
	// returns the size of the viewport
	// by pixy, http://www.pixy.cz/blogg/clanky/js-rozmery-okna.html
	var winW = null;
	var winH = null;
	if (window.innerWidth) { // NN4, Opera, Mozilla
		winW = window.innerWidth;
		winH = window.innerHeight;
	} else if (document.documentElement && document.documentElement.clientWidth) { // MSIE6 std. mode
		winW = document.documentElement.clientWidth;
		winH = document.documentElement.clientHeight;
	} else if (document.body && document.body.clientWidth) { // older MSIE + MSIE6 in quirks mode
		winW = document.body.clientWidth;
		winH = document.body.clientHeight;
	}
	return [winW, winH];
};

lib.dhtml.getPageSize = function () {
	// returns the page size
	// Core code from quirksmode.org
	// edit for Firefox by pHaez
	// taken from Lokesh Dhakar - http://www.huddletogether.com
	
	var pageW = null;
	var pageH = null;
	
	var xScroll, yScroll;
	if (window.innerWidth && window.scrollMaxX) {
		xScroll = window.innerWidth + window.scrollMaxX;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollWidth > document.body.offsetWidth){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var viewSize = lib.dhtml.getViewSize();
	
	if (xScroll < viewSize[0]) { // for small pages with total width less then width of the viewport
		pageW = viewSize[0];
	} else {
		pageW = xScroll;
	}
	
	if (yScroll < viewSize[1]) { // for small pages with total width less then width of the viewport
		pageH = viewSize[1];
	} else {
		pageH = yScroll;
	}
	return [pageW, pageH];
};

lib.dhtml.isBlockOver = function (elmA, elmB) {
	// returns true if elm1 and elm2 overlap each other
	var result = true;
	var lhA = lib.dhtml.getPos(elmA);
	var sizeA = lib.dhtml.getSize(elmA);
	var pdA = [lhA[0] + sizeA[0], lhA[1] + sizeA[1]];
	var lhB = lib.dhtml.getPos(elmB);
	var sizeB = lib.dhtml.getSize(elmB);
	var pdB = [lhB[0] + sizeB[0], lhB[1] + sizeB[1]];
	
	if (((lhA[0]-lhB[0]) < 0) && ((lhA[0]-pdB[0]) < 0) && ((lhA[0]-lhB[0]) < 0) && ((lhA[0]-pdB[0]) < 0)) {
		result = false;
	}
	if (((lhA[0]-lhB[0]) > 0) && ((lhA[0]-pdB[0]) > 0) && ((pdA[0]-lhB[0]) > 0) && ((pdA[0]-pdB[0]) > 0)) {
		result = false;
	}
	if (((lhA[1]-lhB[1]) < 0) && ((lhA[1]-pdB[1]) < 0) && ((pdA[1]-lhB[1]) < 0) && ((pdA[1]-pdB[1]) < 0)) {
		result = false;
	}
	if (((lhA[1]-lhB[1]) > 0) && ((lhA[1]-pdB[1]) > 0) && ((pdA[1]-lhB[1]) > 0) && ((pdA[1]-pdB[1]) > 0)) {
		result = false;
	}
	return result;
};

lib.dhtml.center = function (elm, forceCenter) {
	// centers the block on the screen.
	// if the block is bigger than the page, it is positioned to [0, 0] unless forceCenter is true
	var view =  lib.dhtml.getViewSize();
	var pos  =  lib.dhtml.getViewPos();
	var size =  lib.dhtml.getSize(elm);
	
	var newX = Math.floor((view[0] - size[0]) / 2) + pos[0];
	var newY = Math.floor((view[1] - size[1]) / 2) + pos[1];
	
	if (!forceCenter) {
		if (newX < 0) {
			newX = 0;
		}
		if (newY < 0) {
			newY = 0;
		}
	}
	return lib.dhtml.setPos(elm, [newX, newY]);
};

lib.dhtml._getOffsetModifier = function (elm) {
	var result = [0, 0];
	var currentElm;
	if (elm.offsetParent) {
		currentElm = elm;
		while (currentElm.offsetParent) {
			currentElm = currentElm.offsetParent;
			result[0] += currentElm.offsetLeft;
			result[1] += currentElm.offsetTop;
		}
	} else if (typeof elm.x != "undefined") {
		result[0] = elm.x;
		result[1] = elm.y;
	}
	return result;
};

// lib.drag 1.5.0
// requires: lib.data, lib.dhtml, lib.evt
//
// derived from dom-drag.js, www.youngpup.net

if (typeof lib == "undefined") {
	var lib = {};
};

if (typeof lib.drag == "undefined") {
	lib.drag = {};
};




lib.drag.name =    "lib.drag"; // library name
lib.drag.obj       = null; // object that is being dragged right now
lib.drag.dragEvtId = null; // id of event that takes care of dragging
lib.drag.dropEvtId = null; // id of event that takes care of dropping




lib.drag.add = function (elm, handleElm, movementMappingFn) {
	// adds drag/drop functionality to elm
	// if handle is specified, obj may be only dragged by handle
	if ((typeof handleElm == "undefined") || (handleElm == null)) {
		handleElm = elm;
	};
	if ((typeof movementMappingFn == "undefined") || (movementMappingFn == null)) {
		movementMappingFn = lib.drag.defaultMovementMappingFn;
	};
	lib.data.set(handleElm, "object", elm, lib.drag.name);
	lib.data.set(elm, "object", elm, lib.drag.name);
	lib.data.set(elm, "handle", handleElm, lib.drag.name);
	lib.data.set(elm, "movementMappingFn", movementMappingFn, lib.drag.name);
	
//	var pos = lib.dhtml.getPos(elm);
//	lib.dhtml.setPos(elm, pos);
//	lib.drag.enable(elm);
	var startDragEvtId = lib.evt.add(handleElm, "mousedown", lib.drag.onMouseDown);
	lib.data.set(elm, "startDragEvtId", startDragEvtId, lib.drag.name);
	
	// custom ondrag event handlers - override them if you need them
	lib.evt.addType(elm, "dragstart");
	lib.evt.addType(elm, "dragend");
	lib.evt.addType(elm, "drag");
	return true;
};

lib.drag.remove = function (elm) {
	// removes the drag/drop functionality from the elm
	var handleElm = lib.data.get(elm, "handle", lib.drag.name);
	lib.data.set(handleElm, "object", null, lib.drag.name);
	lib.data.set(elm, "object", null, lib.drag.name);
	lib.data.set(elm, "handle", null, lib.drag.name);
	lib.data.set(elm, "movementMappingFn", null, lib.drag.name);
	
	var startDragEvtId = lib.data.get(elm, "startDragEvtId", lib.drag.name);
	lib.evt.remove(startDragEvtId);
	lib.data.set(elm, "startDragEvtId", null, lib.drag.name);
	
	return true;
};

lib.drag.onMouseDown = function (elm, e, evtId) {
	// find drag/drop object
	lib.drag._preventDragSelect(true);
	var obj = elm;
	while (lib.data.get(obj, "object", lib.drag.name) == null) {
		if (obj.parentNode) {
			obj = obj.parentNode;
		} else {
			return false; // failed searching
		};
	};
	obj = lib.data.get(obj, "object", lib.drag.name);
	lib.drag.obj = obj;
	
	// where the obj was clicked?
	var clickPos = lib.dhtml.getMouseEvtPos(e);
	var objPos = lib.dhtml.getPos(obj);
	
	var dragPos = lib.vector.getDirection(objPos, clickPos);
	lib.data.set(obj, "dragPos", dragPos, lib.drag.name);
	
	// run custom event
	lib.evt.run(obj, "dragstart");
	
	if (lib.drag.dragEvtId == null) {
		lib.drag.dragEvtId = lib.evt.add(document, "mousemove", lib.drag.onMouseMove);
	};
	if (lib.drag.dropEvtId == null) {
		lib.drag.dropEvtId = lib.evt.add(document, "mouseup", lib.drag.onMouseUp);
	};
	lib.evt.cancel(e);
	return true;
};

lib.drag.defaultMovementMappingFn = function(elm, mousePos) {
	// reads mouse coordinates and returns corresponding coordinates of the elm
	return mousePos;
};

lib.drag.onMouseMove = function (doc, e, evtId) {
	
	if (lib.drag.obj) {
		var obj = lib.drag.obj;
		
		// move obj
		lib.drag._drag(obj, e);
		
		// run custom event
		lib.evt.run(obj, "drag");
		
		return true;
	};
	lib.evt.cancel(e);
	return false;
};

lib.drag.onMouseUp = function (doc, e, evtId) {
	lib.drag._preventDragSelect(false);
	if (lib.drag.obj) {
		var obj = lib.drag.obj;
		
		// run custom event
		lib.evt.run(obj, "dragend");
		
		lib.drag._drop(obj, e);
		return true;
	};
	return false;
};

lib.drag._drag = function (elm, e) {
	var ePos = lib.dhtml.getMouseEvtPos(e);
	var clickPos = lib.data.get(elm, "dragPos", lib.drag.name);
	var mapPos = [ ePos[0] - clickPos[0], ePos[1] - clickPos[1] ];
	
	var movementMappingFn = lib.data.get(elm, "movementMappingFn", lib.drag.name);
	var newPos = movementMappingFn(elm, mapPos);
	
	lib.dhtml.setPos(elm, newPos);
	return true;
};

lib.drag._drop = function (obj, e) {
	// remove drag and drop event handlers
	lib.drag.obj = null;
	if (lib.drag.dragEvtId) {
		lib.evt.remove(lib.drag.dragEvtId);
		lib.drag.dragEvtId = null;
	};
	if (lib.drag.dropEvtId) {
		lib.evt.remove(lib.drag.dropEvtId);
		lib.drag.dropEvtId = null;
	};
	return true;
};

lib.drag._preventDragSelect = function (preventContentSelection) {
	// prevent IE text selection while dragging!!!
	// thanks to Todd Ditchendorf
	// http://www.ditchnet.org/wp/2005/06/15/ajax-freakshow-drag-n-drop-events-2/
	if (typeof document.body != "undefined") {
		if (typeof document.body.ondrag != "undefined") {
			document.body.ondrag = function () {return !preventContentSelection;}
		};
		if (typeof document.body.onselectstart != "undefined") {
			document.body.onselectstart = function () {return !preventContentSelection;}
		};
	};
	return true;
};
// lib.showSwitch 0.0.6
// requires: lib.elm, lib.evt, lib.cls, lib.data, lib.field
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// turns on and off specified elements

if (typeof lib == "undefined") {
	var lib = {};
};




lib.showSwitch = {
	className:   "jsShowSwitch",
	onAttr:      "jsShowSwitchOn", // this attribute contains array of attributes that have to be turned on when box is checked
	offAttr:     "jsShowSwitchOff", // this attribute contains array of attributes that have to be turned on when box is unchecked
	states: {
		enabled:  { name: "enabled",  className: "jsShowSwitchEnabled",  disabled: false, oposite: "disabled" },
		disabled: { name: "disabled", className: "jsShowSwitchDisabled", disabled: true,  oposite: "enabled" }
	},
	
	switchControls: [],
	
	initForm: function (formElm) {
		if (typeof formElm.elements != "undefined") {
			var elements = formElm.elements;
			for (var i = 0, l = elements.length; i < l; i++) {
				if (lib.cls.has(elements[i], lib.showSwitch.className)) {
					lib.showSwitch.initControl(elements[i]);
				}
			};
			lib.evt.add(formElm, "reset", lib.showSwitch.run);
			lib.showSwitch.run(formElm);
			return true;
		};
		return false; // formElm not a form
	},
	
	initControl: function (fieldElm) {
		var fieldType = lib.field.identifyType(fieldElm);
		switch (fieldType) {
			case "select":
				lib.showSwitch.addControl(fieldElm);
				lib.evt.add(fieldElm, "change", lib.showSwitch.runSelect);
				lib.evt.add(fieldElm, "click", lib.showSwitch.runSelect);
				lib.evt.add(fieldElm, "keyup", lib.showSwitch.runSelect);
				break;
			case "checkBox":
				lib.showSwitch.addControl(fieldElm);
				lib.evt.add(fieldElm, "click", lib.showSwitch.runChkBox);
				break;
			case "radioButton":
				lib.showSwitch.addControl(fieldElm);
				lib.evt.add(fieldElm, "change", lib.showSwitch.runRadioBtn);
				lib.evt.add(fieldElm, "click", lib.showSwitch.runRadioBtn);
				break;
		};
		return true;
	},
	
	addControl: function (fieldElm) {
		// assign the element as a "showSwitcher"
		lib.cls.add(fieldElm, lib.showSwitch.className);
		lib.array.push(lib.showSwitch.switchControls, fieldElm);
		return true;
	},
	
	set: function (elm, statusName) {
		// enables or disables one block
		var opositeStatusName = lib.showSwitch.states[statusName].oposite;
		lib.cls.remove(elm, lib.showSwitch.states[opositeStatusName].className);
		lib.cls.add(elm, lib.showSwitch.states[statusName].className);
		var tagName = elm.tagName.toLowerCase();
		if ((tagName == "input") || (tagName == "select") || (tagName == "texatrea") || (tagName == "button")) {
			 elm.disabled = lib.showSwitch.states[statusName].disabled;
		} else {
			var inputTypes = ["input", "select", "textarea", "button"];
			for (var i = 0, l = inputTypes.length; i < l; i++) {
				var inputFields = lib.elm.getByTag(inputTypes[i], elm);
				for (var i2 = 0, l2 = inputFields.length; i2 < l2; i2++) {
					inputFields[i2].disabled = lib.showSwitch.states[statusName].disabled;
				}
			}
		};
		return true;
	},
	
	setBlocks: function (blockArray, statusName) {
		// enables or disables a bunch of blocks
		if (blockArray) {
			for (var i = 0, l = blockArray.length; i < l; i++) {
				var blockNode = lib.elm.get(blockArray[i]);
				if (blockNode != null) {
					lib.showSwitch.set(blockNode, statusName);
				}
			};
			return true;
		};
		return false;
	},
	
	runChkBox: function (chkBoxElm) {
		var blockIdArray = null;
		if (chkBoxElm.checked) {
			// turn off blocks from offAttr
			blockIdArray = lib.string.getValue(lib.elm.getAttribute(chkBoxElm, lib.showSwitch.offAttr));
			lib.showSwitch.setBlocks(blockIdArray, "disabled");
			
			// turn on blocks from onAttr
			blockIdArray = lib.string.getValue(lib.elm.getAttribute(chkBoxElm, lib.showSwitch.onAttr));
			lib.showSwitch.setBlocks(blockIdArray, "enabled");
		} else {
			// turn on blocks from offAttr
			blockIdArray = lib.string.getValue(lib.elm.getAttribute(chkBoxElm, lib.showSwitch.offAttr));
			lib.showSwitch.setBlocks(blockIdArray, "enabled");
			
			// turn off blocks from onAttr
			blockIdArray = lib.string.getValue(lib.elm.getAttribute(chkBoxElm, lib.showSwitch.onAttr));
			lib.showSwitch.setBlocks(blockIdArray, "disabled");

		};
		return true;
	},
	
	runSelect: function (selectElm) {
		var blockIdArray = null;
		// process the data from the SELECt tag
		blockIdArray = lib.string.getValue(lib.elm.getAttribute(selectElm, lib.showSwitch.offAttr));
		lib.showSwitch.setBlocks(blockIdArray, "disabled");
		blockIdArray = lib.string.getValue(lib.elm.getAttribute(selectElm, lib.showSwitch.onAttr));
		lib.showSwitch.setBlocks(blockIdArray, "enabled");
		
		// now turn on the selected
		for (var i = 0, l = selectElm.options.length; i < l; i++) {
			if (selectElm.options[i].selected) {
				// turn off blocks from offAttr
				blockIdArray = lib.string.getValue(lib.elm.getAttribute(selectElm.options[i], lib.showSwitch.offAttr));
				lib.showSwitch.setBlocks(blockIdArray, "disabled");
				
				// turn on blocks from onAttr
				blockIdArray = lib.string.getValue(lib.elm.getAttribute(selectElm.options[i], lib.showSwitch.onAttr));
				lib.showSwitch.setBlocks(blockIdArray, "enabled");
			}
		};
		return true;
	},
	
	runRadioBtn: function (radioBtnElm) {
		var blockIdArray = null;
		if (radioBtnElm.checked) {
			blockIdArray = lib.string.getValue(lib.elm.getAttribute(radioBtnElm, lib.showSwitch.offAttr));
			lib.showSwitch.setBlocks(blockIdArray, "disabled");
			blockIdArray = lib.string.getValue(lib.elm.getAttribute(radioBtnElm, lib.showSwitch.onAttr));
			lib.showSwitch.setBlocks(blockIdArray, "enabled");
		};
		return true;
	},
	
	run: function () {
		// switches all chkBoxes, radioButtons and selects in the whole form
		var elements = lib.showSwitch.switchControls;
		for (var i = 0, l = elements.length; i < l; i++) {
			var fieldElm = elements[i];
			if (lib.cls.has(fieldElm, lib.showSwitch.className)) {
				var fieldType = lib.field.identifyType(fieldElm);
				switch (fieldType) {
					case "select":
						lib.showSwitch.runSelect(fieldElm);
						break;
					case "checkBox":
						lib.showSwitch.runChkBox(fieldElm);
						break;
					case "radioButton":
						lib.showSwitch.runRadioBtn(fieldElm);
						break;
				};
			} // end if
		}; // end for
		return true;
	}
};
// lib.swf 1.0
// requires sc, lib.evt, lib.elm
// 
// based on Unobtrusive Flash Objects (ufo) v3.20 <http://www.bobbyvandersluis.com/ufo/>
// Copyright 2005, 2006 Bobby van der Sluis
// This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>


lib.swf = {
	name: "lib.swf",
	
	req: ["movie", "width", "height", "majorversion", "build"],
	opt: ["play", "loop", "menu", "quality", "scale", "salign", "wmode", "bgcolor", "base", "flashvars", "devicefont", "allowscriptaccess", "seamlesstabbing"],
	optAtt: ["id", "name", "align"],
	optExc: ["swliveconnect"],
	ximovie: "ufo.swf",
	xiwidth: "215",
	xiheight: "138",
	ua: navigator.userAgent.toLowerCase(),
	pluginType: "",
	fv: [0,0],
	foList: [],
	
	create: function (cfg, id) {
		// creates the swf movie object
		
		if (window.opera && document.embeds[id]) {
			// correct the Opera bug
			lib.swf._prepareOpera(id);
		} else {
			// default settings
			if (typeof cfg.swliveconnect == "undefined") { cfg.swliveconnect = "true" };
			
			if (!lib.swf._uaHas("w3cdom") || lib.swf._uaHas("ieMac")) {
				return false;
			};
			lib.swf.getFlashVersion();
			lib.swf.foList[id] = lib.swf._updateFO(cfg);
			lib.swf._createCSS("#" + id, "visibility:hidden;");
			lib.swf._domLoad(id);
		};
		return true;
	},
	
	get: function (id) {
		// returns the existing swf movie object
		// id - id of <object> and name of <embed>
		var swfObj = null;
		
		if ((navigator.appName.indexOf("Microsoft Internet") == -1) && document.embeds && document.embeds[id]) {
			swfObj = document.embeds[id];
		} else {
			var envelope = lib.elm.get(id);
			var objects = lib.elm.getByTag("object", envelope);
			if ((objects == null) || (objects.length < 1)) {
				var objects = lib.elm.getByTag("embed", envelope);
			};
			if ((objects == null) || (objects.length < 1)) {
				var objects = lib.elm.getByTag("div", envelope);
			};
			if ((objects != null) && (objects.length >= 1)) {
				swfObj = objects[0];
			};
		};
		return swfObj;
	},
	
	// following 7 methods work only if swliveconnect is enabled
	
	play: function (swfObj) { return swfObj.Play(); },
	
	stop: function (swfObj) { return swfObj.StopPlay(); },
	
	rewind: function (swfObj) { return swfObj.Rewind(); },
	
	getFrame: function (swfObj) { return (parseInt(swfObj.TGetProperty("/", 4)) - 1); },
	
	setFrame: function (swfObj, frameNumber) { return swfObj.GotoFrame(frameNumber); },
	
	setVar: function (swfObj, swfVarName, value) { return swfObj.SetVariable(swfVarName, value); },
	
	getVar: function (swfObj, swfVarName) { return swfObj.GetVariable(swfVarName); },
	
	hasFlashVersion: function (major, release) {
		return (lib.swf.fv[0] > major || (lib.swf.fv[0] == major && lib.swf.fv[1] >= release)) ? true : false;
	},
	
	getFlashVersion: function () {
		if (lib.swf.fv[0] != 0) return;  
		if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") {
			lib.swf.pluginType = "npapi";
			var _d = navigator.plugins["Shockwave Flash"].description;
			if (typeof _d != "undefined") {
				_d = _d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
				var _m = parseInt(_d.replace(/^(.*)\..*$/, "$1"), 10);
				var _r = /r/.test(_d) ? parseInt(_d.replace(/^.*r(.*)$/, "$1"), 10) : 0;
				lib.swf.fv = [_m, _r];
			}
		} else if (window.ActiveXObject) {
			lib.swf.pluginType = "ax";
			try { // avoid fp 6 crashes
				var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
			} catch(e) {
				try { 
					var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
					lib.swf.fv = [6, 0];
					_a.AllowScriptAccess = "always"; // throws if fp < 6.47 
				} catch(e) {
					if (lib.swf.fv[0] == 6) return;
				};
				try {
					var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
				} catch(e) {}
			};
			if (typeof _a == "object") {
				var _d = _a.GetVariable("$version"); // bugs in fp 6.21/6.23
				if (typeof _d != "undefined") {
					_d = _d.replace(/^\S+\s+(.*)$/, "$1").split(",");
					lib.swf.fv = [parseInt(_d[0], 10), parseInt(_d[2], 10)];
				}
			}
		}
	},
	
	expressInstallCallback: function () {
		var _b = document.getElementsByTagName("body")[0];
		var _c = document.getElementById("xi-con");
		_b.removeChild(_c);
		lib.swf._createCSS("body", "height:auto; overflow:auto;");
		lib.swf._createCSS("html", "height:auto; overflow:auto;");
	},
	
	_updateFO: function (cfg) {
		if (typeof cfg.xi != "undefined" && cfg.xi == "true") {
			if (typeof cfg.ximovie == "undefined") {
				cfg.ximovie = lib.swf.ximovie;
			};
			if (typeof cfg.xiwidth == "undefined") {
				cfg.xiwidth = lib.swf.xiwidth;
			};
			if (typeof cfg.xiheight == "undefined") {
				cfg.xiheight = lib.swf.xiheight;
			}
		};
		cfg.mainCalled = false;
		return cfg;
	},

	_domLoad: function (id) {
		var _t = setInterval(function () {
			if ((document.getElementsByTagName("body")[0] != null || document.body != null) && document.getElementById(id) != null) {
				lib.swf._main(id);
				clearInterval(_t);
			}
		}, 250);
		if (typeof document.addEventListener != "undefined") {
			document.addEventListener("DOMContentLoaded", function () { lib.swf._main(id); clearInterval(_t); } , null); // Gecko, Opera 9+
		}
	},

	_main: function (id) {
		var _fo = lib.swf.foList[id];
		if (_fo.mainCalled) return;
		lib.swf.foList[id].mainCalled = true;
		document.getElementById(id).style.visibility = "hidden";
		if (lib.swf._hasRequiredParams(id)) {
			if (lib.swf.hasFlashVersion(parseInt(_fo.majorversion, 10), parseInt(_fo.build, 10))) {
				if (typeof _fo.setcontainercss != "undefined" && _fo.setcontainercss == "true") {
					lib.swf._setContainerCSS(id);
				};
				lib.swf._writeSWF(id);
			} else if (_fo.xi == "true" && lib.swf.hasFlashVersion(6, 65)) {
				lib.swf._createDialog(id);
			}
		}
		document.getElementById(id).style.visibility = "visible";
	},
	
	_createCSS: function (selector, declaration) {
		var _h = document.getElementsByTagName("head")[0]; 
		var _s = lib.swf._createElement("style");
		if (!lib.swf._uaHas("ieWin")) _s.appendChild(document.createTextNode(selector + " {" + declaration + "}")); // bugs in IE/Win
		_s.setAttribute("type", "text/css");
		_s.setAttribute("media", "screen"); 
		_h.appendChild(_s);
		if (lib.swf._uaHas("ieWin") && document.styleSheets && document.styleSheets.length > 0) {
			var _ls = document.styleSheets[document.styleSheets.length - 1];
			if (typeof _ls.addRule == "object") _ls.addRule(selector, declaration);
		}
	},
	
	_setContainerCSS: function (id) {
		var _fo = lib.swf.foList[id];
		var _w = /%/.test(_fo.width) ? "" : "px";
		var _h = /%/.test(_fo.height) ? "" : "px";
		lib.swf._createCSS("#" + id, "width:" + _fo.width + _w +"; height:" + _fo.height + _h +";");
		if (_fo.width == "100%") {
			lib.swf._createCSS("body", "margin-left:0; margin-right:0; padding-left:0; padding-right:0;");
		}
		if (_fo.height == "100%") {
			lib.swf._createCSS("html", "height:100%; overflow:hidden;");
			lib.swf._createCSS("body", "margin-top:0; margin-bottom:0; padding-top:0; padding-bottom:0; height:100%;");
		}
	},
	
	_createElement: function (el) {
		return (lib.swf._uaHas("xml") && typeof document.createElementNS != "undefined") ?  document.createElementNS("http://www.w3.org/1999/xhtml", el) : document.createElement(el);
	},
	
	_createObjParam: function (el, aName, aValue) {
		var _p = lib.swf._createElement("param");
		_p.setAttribute("name", aName);	
		_p.setAttribute("value", aValue);
		el.appendChild(_p);
	},
	
	_uaHas: function (ft) {
		var _u = lib.swf.ua;
		switch(ft) {
			case "w3cdom":
				return (typeof document.getElementById != "undefined" && typeof document.getElementsByTagName != "undefined" && (typeof document.createElement != "undefined" || typeof document.createElementNS != "undefined"));
			case "xml":
				var _m = document.getElementsByTagName("meta");
				var _l = _m.length;
				for (var i = 0; i < _l; i++) {
					if (/content-type/i.test(_m[i].getAttribute("http-equiv")) && /xml/i.test(_m[i].getAttribute("content"))) return true;
				}
				return false;
			case "ieMac":
				return /msie/.test(_u) && !/opera/.test(_u) && /mac/.test(_u);
			case "ieWin":
				return /msie/.test(_u) && !/opera/.test(_u) && /win/.test(_u);
			case "gecko":
				return /gecko/.test(_u) && !/applewebkit/.test(_u);
			case "opera":
				return /opera/.test(_u);
			case "safari":
				return /applewebkit/.test(_u);
			default:
				return false;
		}
	},
	
	_hasRequiredParams: function (id) {
		var _l = lib.swf.req.length;
		for (var i = 0; i < _l; i++) {
			if (typeof lib.swf.foList[id][lib.swf.req[i]] == "undefined") return false;
		}
		return true;
	},
	
	_writeSWF: function (id) {
		var _fo = lib.swf.foList[id];
		var _e = document.getElementById(id);
		if (lib.swf.pluginType == "npapi") {
			if (lib.swf._uaHas("gecko") || lib.swf._uaHas("xml")) {
				while(_e.hasChildNodes()) {
					_e.removeChild(_e.firstChild);
				};
				var _obj = lib.swf._createElement("object");
				_obj.setAttribute("type", "application/x-shockwave-flash");
				_obj.setAttribute("data", _fo.movie);
				_obj.setAttribute("width", _fo.width);
				_obj.setAttribute("height", _fo.height);
				var _l = lib.swf.optAtt.length;
				for (var i = 0; i < _l; i++) {
					if (typeof _fo[lib.swf.optAtt[i]] != "undefined") {
						_obj.setAttribute(lib.swf.optAtt[i], _fo[lib.swf.optAtt[i]]);
					}
				};
				var _o = lib.swf.opt.concat(lib.swf.optExc);
				var _l = _o.length;
				for (var i = 0; i < _l; i++) {
					if (typeof _fo[_o[i]] != "undefined") lib.swf._createObjParam(_obj, _o[i], _fo[_o[i]]);
				};
				_e.appendChild(_obj);
			}
			else {
				var _emb = "";
				var _o = lib.swf.opt.concat(lib.swf.optAtt).concat(lib.swf.optExc);
				var _l = _o.length;
				for (var i = 0; i < _l; i++) {
					if (typeof _fo[_o[i]] != "undefined") _emb += ' ' + _o[i] + '="' + _fo[_o[i]] + '"';
				}
				_e.innerHTML = '<embed name="'+ id +'" type="application/x-shockwave-flash" src="' + _fo.movie + '" width="' + _fo.width + '" height="' + _fo.height + '" pluginspage="http://www.macromedia.com/go/getflashplayer"' + _emb + '></embed>';
			}
		} else if (lib.swf.pluginType == "ax") {
			var _objAtt = "";
			var _l = lib.swf.optAtt.length;
			for (var i = 0; i < _l; i++) {
				if (typeof _fo[lib.swf.optAtt[i]] != "undefined") {
					_objAtt += ' ' + lib.swf.optAtt[i] + '="' + _fo[lib.swf.optAtt[i]] + '"';
				}
			};
			var _objPar = "";
			var _o = lib.swf.opt.concat(lib.swf.optExc);
			var _l = _o.length;
			for (var i = 0; i < _l; i++) {
				if (typeof _fo[_o[i]] != "undefined") {
					_objPar += '<param name="' + _o[i] + '" value="' + _fo[_o[i]] + '" />';
				}
			};
			var _p = window.location.protocol == "https:" ? "https:" : "http:";
			_e.innerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + _objAtt + ' width="' + _fo.width + '" height="' + _fo.height + '" codebase="' + _p + '//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=' + _fo.majorversion + ',0,' + _fo.build + ',0"><param name="movie" value="' + _fo.movie + '" />' + _objPar + '</object>';
		}
	},
		
	_createDialog: function (id) {
		var _fo = lib.swf.foList[id];
		lib.swf._createCSS("html", "height:100%; overflow:hidden;");
		lib.swf._createCSS("body", "height:100%; overflow:hidden;");
		lib.swf._createCSS("#xi-con", "position:absolute; left:0; top:0; z-index:1000; width:100%; height:100%; background-color:#fff; filter:alpha(opacity:75); opacity:0.75;");
		lib.swf._createCSS("#xi-dia", "position:absolute; left:50%; top:50%; margin-left: -" + Math.round(parseInt(_fo.xiwidth, 10) / 2) + "px; margin-top: -" + Math.round(parseInt(_fo.xiheight, 10) / 2) + "px; width:" + _fo.xiwidth + "px; height:" + _fo.xiheight + "px;");
		var _b = document.getElementsByTagName("body")[0];
		var _c = lib.swf._createElement("div");
		_c.setAttribute("id", "xi-con");
		var _d = lib.swf._createElement("div");
		_d.setAttribute("id", "xi-dia");
		_c.appendChild(_d);
		_b.appendChild(_c);
		var _mmu = window.location;
		if (lib.swf._uaHas("xml") && lib.swf._uaHas("safari")) {
			var _mmd = document.getElementsByTagName("title")[0].firstChild.nodeValue = document.getElementsByTagName("title")[0].firstChild.nodeValue.slice(0, 47) + " - Flash Player Installation";
		}
		else {
			var _mmd = document.title = document.title.slice(0, 47) + " - Flash Player Installation";
		}
		var _mmp = lib.swf.pluginType == "ax" ? "ActiveX" : "PlugIn";
		var _uc = typeof _fo.xiurlcancel != "undefined" ? "&xiUrlCancel=" + _fo.xiurlcancel : "";
		var _uf = typeof _fo.xiurlfailed != "undefined" ? "&xiUrlFailed=" + _fo.xiurlfailed : "";
		lib.swf.foList["xi-dia"] = { movie:_fo.ximovie, width:_fo.xiwidth, height:_fo.xiheight, majorversion:"6", build:"65", flashvars:"MMredirectURL=" + _mmu + "&MMplayerType=" + _mmp + "&MMdoctitle=" + _mmd + _uc + _uf };
		lib.swf._writeSWF("xi-dia");
	},
	
	_prepareOpera: function (id) {
		// when using swliveconnect in Opera, it is necessary to put <embed> tag right
		// into the block where Flash movie should be.
		// this removes the alternative content
		var elm = lib.elm.get(id);
		for (var i = elm.childNodes.length - 1; i >=0; i--) {
			var actualNode = elm.childNodes[i];
			var deleteNode = true;
			if (actualNode.getAttribute) {
				if (actualNode.getAttribute("name") == id) {
					deleteNode = false;
				}
			};
			if (deleteNode) {
				elm.removeChild(actualNode);
			}
		};
		return true;
	},
	
	_cleanupIELeaks: function () {
		var _o = document.getElementsByTagName("object");
		var _l = _o.length
		for (var i = 0; i < _l; i++) {
			_o[i].style.display = "none";
			for (var x in _o[i]) {
				if (typeof _o[i][x] == "function") {
					_o[i][x] = null;
				}
			}
		}
	}

};

if (lib.swf._uaHas("ieWin")) {
	lib.evt.add(window, "unload", lib.swf._cleanupIELeaks);
};
// lib.field 1.4.0
// requires: lib.data, lib.object, lib.string, lib.elm, lib.evt, lib.cls
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 

if (typeof lib == "undefined") {
	var lib = {};
};

if (typeof lib.field == "undefined") {
	lib.field = {};
};




lib.field.name               = "lib.field";
lib.field.invalidClass       = "invalid";
lib.field.configAttribute    = "libFieldCfg";
lib.field.checkEventPriority = 10;




lib.field.init = function (fieldElm) {
	// run this after the input field is created
	lib.data.set(fieldElm, "loadValue", lib.elm.getValue(fieldElm), lib.field.name);
	var type = lib.field.identifyType(fieldElm);
	// special init for radiobuttons
	if (type == "radioButton") {
		lib.field.acquireRadioSet(fieldElm);
	};
	lib.evt.add(fieldElm, "focus", lib.field.onFocus);
	// add check events
	var priority = lib.field.checkEventPriority;
	switch (type) {
		case "checkBox":
			lib.evt.add(fieldElm, "click", lib.field.onChange, priority);
			break;
		case "radioButton":
			var radioSet = lib.field.getRadioSet(fieldElm); // radioSet has been acquired at addRuleSet method
			for (var i = 0, l = radioSet.length; i < l; i++) {
				lib.evt.add(radioSet[i], "click", lib.field.onChange, priority);
			};
			break;
		case "select":
			lib.evt.add(fieldElm, "change", lib.field.onChange, priority);
			break;
		case "textField":
			lib.evt.add(fieldElm, "focus", lib.field.onChange, priority);
			lib.evt.add(fieldElm, "blur", lib.field.onChange, priority);
			lib.evt.add(fieldElm, "keyup", lib.field.onChange, priority);
			break;
	};
	return true;
};

lib.field.identifyType = function (fieldElm) {
	var tagName = lib.elm.getAttribute(fieldElm, "tagName").toLowerCase();
	var result = null;
	if (tagName == "select") {
		result = "select";
	} else if (tagName == "textarea") {
		result = "textField";
	} else {
		var type = lib.elm.getAttribute(fieldElm, "type").toLowerCase();
		if ((type == "text") || (type == "password")) {
			result = "textField";
		} else if (type == "checkbox") {
			result = "checkBox";
		} else if (type == "radio") {
			result = "radioButton";
		} else if (type == "hidden") {
			result = "hidden";
		};
	};
	if (result != null) {
		lib.data.set(fieldElm, "type", result, lib.field.name);
	};
	return result;
};

lib.field.getType = function (fieldElm, refreshCache) {
	if (typeof refreshCache == "undefined") { refreshCache = false; };
	var result = lib.data.get(fieldElm, "type", lib.field.name); // quick identify
	if ((result == null) || refreshCache) {
		result = lib.field.identifyType(fieldElm);
	};
	return result;
};

lib.field.isModified = function (fieldElm) {
	// was fieldElm changed since initialization?
	var loadValue = lib.data.get(fieldElm, "loadValue", lib.field.name);
	return (lib.elm.getValue(fieldElm) == loadValue);
};

lib.field.isEnabled = function (fieldElm) {
	var result = true;
	if (fieldElm.disabled) {
		result = false;
	};
	return result;
};

lib.field.acquireRadioSet = function (radioBtnElm) {
	// for radiobutton, returns whole set of radiobuttons with the same name
	var radioSet = [radioBtnElm]; // this is for case there is no form
	var name = lib.elm.getAttribute(radioBtnElm, "name");
	var type = lib.elm.getAttribute(radioBtnElm, "type").toLowerCase();
	if (name && (type == "radio") && radioBtnElm.form) {
		radioSet = radioBtnElm.form[name];
	};
	lib.data.set(radioBtnElm, "radioSet", radioSet, lib.field.name);
	return radioSet;
};

lib.field.getRadioSet = function (radioBtnElm, refreshCache) {
	// for radiobutton, returns whole set of radiobuttons with the same name 
	// use only if you are sure you have called acquireRadioSet before
	if (typeof refreshCache == "undefined") { refreshCache = false; };
	var result = lib.data.get(radioBtnElm, "radioSet", lib.field.name); // quick identify
	if ((result == null) || refreshCache) {
		result = lib.field.acquireRadioSet(radioBtnElm);
	};
	return result;
};

lib.field.readConfig = function (fieldElm) {
	// reads config from custom attribute and classNames
	var cfg = {};
	var fieldType = lib.field.getType(fieldElm);
	if (fieldType == "radioButton") {
		cfg = lib.field._readRadioSetConfig(fieldElm);
	} else {
		// get config from custom attribute
		var cfgString = lib.elm.getAttribute(fieldElm, lib.field.configAttribute);
		if (cfgString != null) {
			cfg = lib.string.getValue(cfgString);
		};
		// get config from classNames
		var classNames = lib.cls.get(fieldElm);
		for (var i = 0, l = classNames.length; i < l; i++) {
			if (typeof cfg[classNames[i]] == "undefined") {
				cfg[classNames[i]] = true;
			}
		};
		lib.data.set(fieldElm, "cfg", cfg, lib.field.name);
	};
	return cfg;
};

lib.field._readRadioSetConfig = function (fieldElm) {
	// read configuration from radiobutton set
	var cfg = {};
	var fields = lib.field.getRadioSet(fieldElm);
	// collect configuration data from all radiobuttons
	for (var i = 0, l = fields.length; i < l; i++) {
		var elm = fields[i];
		// get config from custom attribute
		var cfgString = lib.elm.getAttribute(elm, lib.field.configAttribute);
		if (cfgString != null) {
			var cfgObj = lib.string.getValue(cfgString);
			for (cfgName in cfgObj) {
				cfg[cfgName] = cfgObj[cfgName];
			}
		};
		// get config from classNames
		var classNames = lib.cls.get(elm);
		for (var i1 = 0, l1 = classNames.length; i1 < l1; i1++) {
			if (typeof cfg[classNames[i1]] == "undefined") {
				cfg[classNames[i1]] = true;
			}
		}
	};
	// bind configuration to all radiobuttons
	for (var i = 0, l = fields.length; i < l; i++) {
		lib.data.set(fields[i], "cfg", cfg, lib.field.name);
	};
	return cfg;
};

lib.field.getConfig = function (fieldElm) {
	// returns the element configuration read by last readCfg operation
	var result = lib.data.get(fieldElm, "cfg", lib.field.name);
	return result;
};

lib.field.getConfigRule = function (fieldElm, ruleName) {
	// returns a rule specified by ruleName
	var cfg = lib.field.getConfig(fieldElm);
	var result = null;
	if ( (typeof cfg[ruleName] != "undefined") && (cfg[ruleName] != null) ) {
		result = cfg[ruleName];
	};
	return result;
};

lib.field.setRule = function (fieldElm, ruleName, ruleObj) {
	// adds rule to the element
	var rules = lib.data.get(fieldElm, "rules", lib.field.name);
	if (rules == null) { rules = {}; };
	rules[ruleName] = lib.object.clone(ruleObj);
	var fieldType = lib.field.getType(fieldElm);
	if (fieldType == "radioButton") {
		// set rule to a set of radiobuttons
		var radioSet = lib.field.getRadioSet(fieldElm);
		for (var i = 0, l = radioSet.length; i < l; i++) {
			// all radiobuttons have common rules (no clonning needed)
			lib.data.set(radioSet[i], "rules", rules, lib.field.name);
		}
	} else {
		// set rule to normal input field
		lib.data.set(fieldElm, "rules", rules, lib.field.name);
	};
	return true;
};

lib.field.removeRule = function (fieldElm, ruleName) {
	// removes rule (identified by ruleName) from the element
	var rules = lib.data.get(fieldElm, "rules", lib.field.name);
	if ((rules != null) && (typeof rules[ruleName] != "undefined") && (rules[ruleName] != null)) {
		rules[ruleName] = null;
		return true; // rule has been removed
	};
	return false; // rule was not found
};

lib.field.getRules = function (fieldElm) {
	return lib.data.get(fieldElm, "rules", lib.field.name);
};

lib.field.addRuleSet = function (fieldElm, ruleSet, cloneRules) {
	// applies ruleSet to elm. Adds only validation rules that have some config rule
	if ((typeof cloneRules == "undefined") || (cloneRules == null)) {
		cloneRules = false;
	};
	var rules = lib.field.getRules(fieldElm);
	if (rules == null) { rules = {}; };
	var cfg = lib.field.readConfig(fieldElm);
	if (cfg) {
		for (ruleName in cfg) {
			if ((typeof ruleSet[ruleName] != "undefined") && (ruleSet[ruleName] != null)) {
				if (!cloneRules) {
					// add rules as reference links
					rules[ruleName] = ruleSet[ruleName];
				} else {
					// add rules as standalone objects
					rules[ruleName] = lib.object.clone(ruleSet[ruleName]);
				};
				// default value
				if (typeof rules[ruleName].def != "undefined") {
					lib.data.set(fieldElm, "defaultValue", rules[ruleName].def, lib.field.name);
				}
			}
		}
	};
	
	var fieldType = lib.field.getType(fieldElm);
	if (fieldType == "radioButton") {
		// set rules to a set of radiobuttons
		var radioSet = lib.field.getRadioSet(fieldElm);
		for (var i = 0, l = radioSet.length; i < l; i++) { 
			lib.data.set(radioSet[i], "rules", rules, lib.field.name);
		}
	} else {
		// set rules to normal input
		lib.data.set(fieldElm, "rules", rules, lib.field.name);
	};
	lib.field.check(fieldElm);
	return true;
};

lib.field.removeRules = function (fieldElm) {
	// removes all validation rules from the element elm
	lib.data.set(fieldElm, "rules", null, lib.field.name);
	return true;
};

lib.field.check = function (fieldElm, e, evId) {
	// checks field validity
	if (lib.field.isEnabled(fieldElm)) {
		var rules = lib.data.get(fieldElm, "rules", lib.field.name);
		if (rules != null) {
			var cfg = lib.field.getConfig(fieldElm);
			var result = true;
			for (ruleName in rules) {
				if ( (typeof rules[ruleName] != "undefined") && (rules[ruleName] != null) ) {
					// prepare check parameters
					var value = lib.elm.getValue(fieldElm);
					var cfgRule = null;
					if (typeof cfg[ruleName] != "undefined") {
						cfgRule = cfg[ruleName];
					};
					var checkFn = true, checkReg = true;
					// check by function
					if (rules[ruleName].fn) {
						checkFn = rules[ruleName].fn(value, fieldElm, cfgRule);
					};
					// check by regExp
					if (rules[ruleName].reg) {
						checkReg = (rules[ruleName].reg.test(value));
						// checkReg = (value.toString().search(rules[ruleName].reg) >= 0);
					};
					if (!checkFn || !checkReg) {
						lib.field.setInvalid(fieldElm, ruleName);
						return false;
					}
				}
			}
		}
	};
	lib.field.setValid(fieldElm);
	return true;
};

lib.field.setValid = function (fieldElm) {
	if (lib.field.getType(fieldElm) == "radioButton") {
		var radioSet = lib.field.getRadioSet(fieldElm);
		for (var i = 0, l = radioSet.length; i < l; i++) {
			lib.cls.remove(radioSet[i], lib.field.invalidClass);
			lib.data.set(radioSet[i], "invalidRuleName", null, lib.field.name);
		}
	} else {
		lib.cls.remove(fieldElm, lib.field.invalidClass);
		lib.data.set(fieldElm, "invalidRuleName", null, lib.field.name);
	};
	return true;
};

lib.field.setInvalid = function(fieldElm, invalidRuleName) {
	
	// disabled fields should not be set as invalid
	var isDisabled = (lib.elm.getAttribute(fieldElm, "disabled") == "disabled");
	if (!isDisabled) {
		if (lib.field.getType(fieldElm) == "radioButton") {
			var radioSet = lib.field.getRadioSet(fieldElm);
			for (var i = 0, l = radioSet.length; i < l; i++) {
				lib.cls.add(radioSet[i], lib.field.invalidClass);
				lib.data.set(radioSet[i], "invalidRuleName", invalidRuleName, lib.field.name);
			}
		} else {
			lib.cls.add(fieldElm, lib.field.invalidClass);
			lib.data.set(fieldElm, "invalidRuleName", invalidRuleName, lib.field.name);
		}
	};
	return true;
};

lib.field.isValid = function (fieldElm) {
	return !lib.cls.has(fieldElm, lib.field.invalidClass);
};

lib.field.getInvalidRuleName = function (fieldElm) {
	return lib.data.get(fieldElm, "invalidRuleName", lib.field.name);
};

lib.field.setDefaultValue = function (fieldElm) {
	var defaultValue = lib.data.get(fieldElm, "defaultValue", lib.field.name);
	if (defaultValue != null) {
		lib.elm.setValue(fieldElm, defaultValue);
	};
	return true;
};

lib.field.onFocus = function (fieldElm) {
	if (lib.string.trim(lib.elm.getValue(fieldElm)) == "") {
		// the field is empty
		lib.field.setDefaultValue(fieldElm);
		if (fieldElm.select) {
			fieldElm.select();
		};
		lib.field.check(fieldElm);
	};
	return true;
};

lib.field.onChange = function (fieldElm) {
	lib.field.check(fieldElm);
	return true;
};




// helper definitions
lib.field._df                    = {};
lib.field._df.specChars          = " \!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~\xA1-\xBF\xD7\xF7";
lib.field._df.alphaLowercase     = "a-z";
lib.field._df.alphaUppercase     = "A-Z";
lib.field._df.alpha              = lib.field._df.alphaLowercase + lib.field._df.alphaUppercase;
lib.field._df.numeric            = "0-9";
lib.field._df.alphaNum           = lib.field._df.numeric + lib.field._df.alpha;
lib.field._df.alphaLowercaseISO  = lib.field._df.alphaLowercase + lib.field._df.alphaUppercase + "\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
lib.field._df.alphaUppercaseISO  = "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDE";
lib.field._df.alphaISO           = lib.field._df.alphaLowercaseISO + lib.field._df.alphaUppercaseISO;
lib.field._df.alphaNumISO        = lib.field._df.numeric + lib.field._df.alphaISO;
lib.field._df.alphaLowercaseUTF  = "\u00E1\u00E9\u0115\u00ED\u00F3\u00FA\u016F\u00FD\u017E\u0161\u010D\u0159\u010F\u0165\u0148" + lib.field._df.alphaLowercase;
lib.field._df.alphaUppercaseUTF  = "\u00C1\u00C9\u0114\u00CD\u00D3\u00DA\u016E\u00DD\u0160\u017D\u010c\u0158\u010E\u0164\u0147" + lib.field._df.alphaUppercase;
lib.field._df.alphaUTF           = lib.field._df.alphaLowercaseUTF + lib.field._df.alphaUppercaseUTF;
lib.field._df.alphaNumUTF        = lib.field._df.numeric + lib.field._df.alphaUTF;

// should accept IDN domain names
lib.field._df.urlDomain          = "([^"+lib.field._df.specChars+"]+([-_.]?[^"+lib.field._df.specChars+"]){1,}[.]([a-zA-Z]){2,4})";
lib.field._df.urlIp              = "((([0-9]){1,3}\.){3}([0-9]){1,3})";
lib.field._df.urlPath            = "(/([^ \t\n\r\f/])*)*";
lib.field._df.urlGet             = "([\?]{1}[^ \t\n\r\f]*)?";
lib.field._df.urlFragment        = "([\#]{1}([;/?:@&=+$,\-_.!~*'()a-zA-Z0-9]|(%[0-9a-fA-F]{2}))*)?";



/*
// default rules (examples)
if (typeof lib.field.defaultRules == "undefined") {
	lib.field.defaultRules = {};
};

lib.field.defaultRules.url = {
	reg: new RegExp("^((http(s)?://(("+lib.field._df.urlDomain+")|("+lib.field._df.urlIp+"))){1}(:[0-9]{2,5})?("+lib.field._df.urlPath+")("+lib.field._df.urlGet+")("+lib.field._df.urlFragment+"))?$"),
	def: "http://",
	err: "Field {label} must contain valid URL (for example \"http://www.google.com\")."
};

lib.field.defaultRules.domainUrl = {
	reg: new RegExp("^(http(s)?://"+lib.field._df.urlDomain+")?$"),
	def: "http://",
	err: "Field {label} must contain valid domain name."
};

lib.field.defaultRules.phone = {
	reg: new RegExp("^[0-9()+-/ ]{0,16}$"),
	err: "Field {label} must contain a valid phone number."
};

lib.field.defaultRules.required = {
	fn:
		function (str) {
			// return (str.search(/\S/) < 0) ? false : true;
			return true; // EPR-98
		},
	err: "Field {label} must not be empty."
};

lib.field.defaultRules.notNegative = {
	fn: function (num) {
			return (num >= 0);
		},
	err: "Field {label} must contain positive numeric value or 0."
};

lib.field.defaultRules.positive = {
	fn: function (num) {
			return (num > 0);
		},
	err: "Field {label} must contain positive numeric value."
};
*/
// lib.form 1.2.1 DMK modification
// requires: lib.data, lib.string, lib.array, lib.elm, lib.evt, lib.field
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 

if (typeof lib == "undefined") {
	var lib = {};
};

if (typeof lib.form == "undefined") {
	lib.form = {};
};




lib.form.name                           = "lib.form";
lib.form.submitButtonClickEventPriority = 10;
lib.form.groupAttribute                 = "formGroups";
lib.form.invalidMsg                     = "Error: some form fields are not filled correctly"; // localize this




lib.form.init = function (validationRules) {
	
	if (typeof validationRules == "undefined") {
		validationRules = null;
	};
	lib.form.initInputs(validationRules);
	return true;
};

lib.form.initInputs = function (validationRules) {
	if (typeof validationRules == "undefined") {
		validationRules = null;
	};
	var inputFields = lib.elm.getByTag("input");
	if (inputFields) {
		for (var i = 0, l = inputFields.length; i < l; i++) {
			var fieldType = lib.field.getType(inputFields[i]);
			if (fieldType) {
				if (fieldType != "hidden") {
					lib.field.init(inputFields[i]);
					lib.form.addField(inputFields[i], validationRules);
				}
			} else {
				lib.form.addButton(inputFields[i]);
			}
		}
	};
	var buttons = lib.elm.getByTag("button");
	if (buttons) {
		for (var i = 0, l = buttons.length; i < l; i++) {
			lib.form.addButton(buttons[i]);
		}
	};
	var textAreas = lib.elm.getByTag("textarea");
	if (textAreas) {
		for (var i = 0, l = textAreas.length; i < l; i++) {
			lib.field.init(textAreas[i]);
			lib.form.addField(textAreas[i], validationRules);
		}
	};
	var selects = lib.elm.get("select");
	if (selects) {
		for (var i = 0, l = selects.length; i < l; i++) {
			lib.field.init(selects[i]);
			lib.form.addField(selects[i], validationRules);
		}
	};
	return true;
};

lib.form.addButton = function (buttonElm) {
	// update the list of buttons
	if (buttonElm.form) {
		// register the button into the form
		var formElm = buttonElm.form;
		var buttons = lib.data.get(formElm, "buttons", lib.form.name);
		if (buttons == null) {
			buttons = [];
		};
		lib.array.push(buttons, buttonElm);
		lib.data.set(formElm, "buttons", buttons, lib.form.name);
	};
	// identify type and add events
	var buttonType = lib.elm.getAttribute(buttonElm, "type");
	if (buttonType) {
		if ((buttonType == "submit") || (buttonType == "image")) {
			var evId = lib.evt.add(buttonElm, "click", lib.form.submitOnClick, lib.form.submitButtonClickEventPriority);
			lib.data.set(buttonElm, "submitClickEvId", evId, lib.form.name);
		}
	};
	return true;
};

lib.form.removeButton = function (buttonElm) {
	// removes the lib.form functionality from the button
	if (buttonElm.form) {
		var formElm = buttonElm.form;
		var buttons = lib.data.get(formElm, "buttons", lib.form.name);
		if (buttons != null) {
			lib.array.condense(buttons, buttonElm);
		};
		lib.data.set(formElm, "buttons", buttons, lib.form.name);
	};
	var evId = lib.data.get(buttonElm, "submitClickEvId", lib.form.name);
	if (evId != null) {
		lib.evt.remove(evId);
	};
	return true;
};

lib.form.addField = function (fieldElm, validationRules) {
	if (typeof validationRules == "undefined") {
		validationRules = null;
	};
	if (lib.field) {
		lib.field.addRuleSet(fieldElm, validationRules);
	};
	// add the field to the list
	if (fieldElm.form) {
// TODO - what about uncached variant ?
		var fields = lib.data.get(fieldElm.form, "fields", lib.form.name);
		if (fields == null) {
			fields = [];
		};
		lib.array.push(fields, fieldElm);
		lib.data.set(fieldElm.form, "fields", fields, lib.form.name);
		// add the field to the fieldgroup
		var formGroupNames = lib.form.getFormGroupNames(fieldElm);
		if (formGroupNames) {
			var formGroups = lib.data.get(fieldElm.form, "formGroups", lib.form.name);
			if (formGroups == null) {
				formGroups = {};
			}
			for (var i = 0, l = formGroupNames.length; i < l; i++) {
				if ( (typeof formGroups[formGroupNames[i]] == "undefined") || (formGroups[formGroupNames[i]] == null) ) {
					formGroups[formGroupNames[i]] = [];
				};
				lib.array.push(formGroups[formGroupNames[i]], fieldElm);
			};
			lib.data.set(fieldElm.form, "formGroups", formGroups, lib.form.name);
		}
	};
	return true;
};

lib.form.removeField = function (fieldElm) {
	// remove validation rules
	lib.field.removeRules(fieldElm);
	if (fieldElm.form) {
		// remove the field from the list
		var fields = lib.data.get(fieldElm.form, "fields", lib.form.name);
		if (fields == null) {
			fields = [];
		};
		fields = lib.array.condense(fields, fieldElm); // this removes the fieldElm and makes the field dense
		lib.data.set(fieldElm.form, "fields", fields, lib.form.name);
		// remove the field from the fieldgroup
		var formGroupNames = lib.form.getFormGroupNames(fieldElm);
		if (formGroupNames) {
			var formGroups = lib.data.get(fieldElm.form, "formGroups", lib.form.name);
			if (formGroups =! null) {
				for (var i = 0, l = formGroupNames.length; i < l; i++) {
					lib.array.condense(formGroups[formGroupNames[i]], fieldElm);
				};
				lib.data.set(fieldElm.form, "formGroups", formGroups, lib.form.name);
			}
		}
	};
	return true;
};

lib.form.getFormGroupNames = function (inputElm) {
	var groups = null;
	var groupsStr = lib.elm.getAttribute(inputElm, lib.form.groupAttribute);
	if (groupsStr != null) {
		groups = lib.string.getValue(groupsStr);
	};
	return groups;
};

lib.form.getFieldsByFormGroup = function (formElm, formGroupName, refreshCache) {
	if (typeof refreshCache == "undefined") { refreshCache = false; };
/* TODO - what if we have to refresh cache?
	var fieldGroups = lib.data.get(fieldElm, lib.field.name, "fieldGroups", lib.field.name); // quick identify
	if ((result == null) || refreshCache) {
	
	};
*/
	var formGroups = lib.data.get(formElm, "formGroups", lib.form.name);
	var fields = formGroups[formGroupName];
	return fields;
};

lib.form.check = function (formElm) {
	// check all form fields
	var fields = lib.data.get(formElm, "fields", lib.form.name);
	var result = true;
	if (fields != null) {
		for (var i = 0, l = fields.length; i < l; i++) {
			var field = fields[i];
			result = lib.field.check(field) && result;
		}
	};
	return result;
};

lib.form.getInvalidFields = function (formElm, formGroupNames) {
	// returns all invalid fields from selected groups. If no groups are selected, checks all fields
	if (typeof formGroupNames == "undefined") { formGroupNames = null; };
	var invalidFields = [];
	if (formGroupNames) {
		for (var i1 = 0, l1 = formGroupNames.length; i1 < l1; i1++) {
			var formGroupFields = lib.form.getFieldsByFormGroup(formElm, formGroupNames[i1]);
			for (var i2 = 0, l2 = formGroupFields.length; i2 < l2; i2++) {
				var field = formGroupFields[i2];
				if (!lib.field.check(field)) {
					lib.array.push(invalidFields, field);
				}
			}
		}
	} else { // no group names set, validate whole form
		var fields = lib.data.get(formElm, "fields", lib.form.name);
		if (fields != null) {
			for (var i = 0, l = fields.length; i < l; i++) {
				var field = fields[i];
				if (!lib.field.check(field)) {
					lib.array.push(invalidFields, field);
				}
			}
		}
	};
	return invalidFields;
};

lib.form.submitOnClick = function (buttonElm, e, evId) {
	// validates the form when the user hits "submit" button
	var isValid = true;
	
	if (lib.field) {
		var formGroupNames = lib.form.getFormGroupNames(buttonElm);
		var invalidFields = lib.form.getInvalidFields(buttonElm.form, formGroupNames);
		if (invalidFields.length > 0) {
			isValid = false;
		};
		if (!isValid) {
//			lib.form.outputInvalidFieldsReport(invalidFields);
//			lib.evt.cancel(e);
		}
	};
	return isValid;
};

lib.form.submit = function (formElm, formGroupNames) {
	// submits the form. If there are no formGroups specified, it validates all fields
	if (typeof formGroupNames == "undefined") { formGroupNames = null; };
	var isValid = true;
	if (lib.field) {
		var invalidFields = lib.form.getInvalidFields(formElm, formGroupNames);
		if (invalidFields.length > 0) { isValid = false; };
		if (!isValid) {
//			lib.form.outputInvalidFieldsReport(invalidFields);
			formElm.submit();
		}
	};
	if (isValid) {
		formElm.submit();
	};
	return isValid;
};

lib.form.outputInvalidFieldsReport = function () {
	alert(lib.form.invalidMsg);
	return true;
};
// lib.Class 1.4.0
// requires: lib.object
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// Inheritance support
// 
// reserved properties:
//     _parent - reference to parent class. May not be used in Class definition.
// 
// reserved methods:
//     extend - is used to extend the class. May not be used in Class definition.
//     newInstance - is used to create object instance. May not be used in Class definition.
//     init - constructor. Is used automatically when creating the instance

var lib = lib || {};
lib.Class = lib.Class || {};




lib.Class.extend = function (newFeatures) {
	// create a new class (the child)
	var newClassObj = lib.object.clone(this);
	// insert own properties and methods, overriding inherited ones
	for (var prop in newFeatures) {
		newClassObj[prop] = newFeatures[prop];
	}
	return newClassObj;
};

lib.Class.newInstance = function () {
	var newInstanceObj = {};
	// insert inherited properties and methods
	for (var prop in this) {
		if ((prop != "extend") && (prop != "newInstance")) {
			if (typeof this[prop] == "function") {
				// add method
				newInstanceObj[prop] = this[prop];
			} else {
				// add property
				newInstanceObj[prop] = null;
				// the value of the instance property is not copied - it must be set in the constructor
				// if you need the static properties, you have to acces them Class.prop = ...
			}
		}
	}
	if (typeof newInstanceObj.init == "function") {
		newInstanceObj.init.apply(newInstanceObj, arguments);
	}
	return newInstanceObj;
};

lib.Class.init = function () {
	// default constructor
	return true;
};
// Box 0.0.2
// requires: lib.Class, lib.elm, lib.evt, lib.dhtml, 
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// provides the popup window

var lib = lib || {};
lib.Box = lib.Box || {};




lib.Box = lib.Class.extend({
	
	name: "lib.Box",
	
	// public properties
	content:  null,
	envelope: null,
	
	// class properties, don't use in instances
	boxNodes: [],
	envelopeTemplate: {
		tagName: "div",
		className: "jsLibBox",
		children: [ {contentNode:0} ]
	},
	defaultContentTemplate: {
		tagName: "div",
		className: "jsLibBoxContent"
	},
	
	// constructor
	init: function (contentElm, parentElm, envelopeTemplate, contentTemplate) {
		parentElm = parentElm || document.body;
		envelopeTemplate = envelopeTemplate || lib.Box.envelopeTemplate;
		contentTemplate = contentTemplate || lib.Box.defaultContentTemplate;
		
		lib.Class.init.apply(this, arguments);
		
		this.content = contentElm || lib.elm.create(contentTemplate);
		this.envelope = lib.elm.create(envelopeTemplate, [this.content]);
		parentElm.appendChild(this.envelope);
		
		// register the instance
		lib.array.insert(lib.Box.boxNodes, this);
		
		return true;
	},
	
	_addAction: function (elm, action, actionHandler, onActionFn) {
		// this helps to add some box actions to external elements
		// onActionFn receives following parameters:
		// - elm (the element that caused the event),
		// - e (the event itself),
		// - evId (event id),
		// - PopBox (this object)
		action = action || "click";
		actionHandler = actionHandler || function () {};
		onActionFn = onActionFn || function () {};
		var actionClosure = function (actionHandler, onActionFn, contextObj) {
			var actionFn = function (elm, e, evId) {
				actionHandler.apply(contextObj, [elm, e, evId]);
				onActionFn.apply(contextObj, [elm, e, evId, contextObj]);
				if (e) {
					lib.evt.cancel(e);
				}
				return true;
			};
			return actionFn;
		};
		return lib.evt.add(elm, action, actionClosure(actionHandler, onActionFn, this), null, this);
	},
	
	show: function () {
		this.envelope.style.display = "";
		return true;
	},
	
	hide: function () {
		this.envelope.style.display = "none";
		return true;
	}
});
// popBox 0.0.7
// requires: lib.elm, lib.evt, lib.dhtml, lib.Class, lib.Box
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 
// provides the popup window

var lib = lib || {};
lib.PopBox = lib.PopBox || {};




lib.PopBox = lib.Box.extend({
	
	name: "lib.popBox",
	
	// public properties
	isOpen:   null,
	envelopeTemplate: {
		tagName:   "div",
		className: "jsLibPopBox",
		style: {
			zIndex: "1300"
		},
		children: [ {contentNode:0} ]
	},
	
	init: function (contentElm, parentElm, envelopeTemplate, contentTemplate) {
		parentElm = parentElm || document.body;
		envelopeTemplate = envelopeTemplate || lib.PopBox.envelopeTemplate;
		contentTemplate = contentTemplate || null;
		
		lib.Box.init.apply(this, [contentElm, parentElm, envelopeTemplate, contentTemplate]);
		
		// the box starts closed
		this.close(); // set the box closed
		
		// set custom event handlers
		lib.evt.addType(this, "boxopen");
		lib.evt.addType(this, "boxclose");
		
		// register the instance
		lib.array.insert(lib.PopBox.boxNodes, this);
		return true;
	},
	
	open: function (openingElm, e, evId) {
		e = e || null;
		this.envelope.style.display = "";
		if (e) {
			var pos = lib.evt.getMousePosition(e);
			if (pos) {
				lib.dhtml.setAbsolute(this.envelope);
				lib.dhtml.setPos(this.envelope, [pos.x, pos.y]);
			}
		};
		lib.evt.run(this, "boxopen");
		this.isOpen = true;
		if (e) {
			lib.evt.cancel(e);
		};
		return true;
	},
	
	close: function (closingElm, e, evId) {
		e = e || null;
		this.envelope.style.display = "none";
		lib.evt.run(this, "boxclose");
		this.isOpen = false;
		if (e) {
			lib.evt.cancel(e);
		};
		return true;
	},
	
	toggle: function (togglingElm, e, evId) {
		if (this.isOpen) {
			this.close(togglingElm, e, evId);
		} else {
			this.open(togglingElm, e, evId);
		};
		return true;
	},
	
	addOpenAction: function (openerElm, action, onOpenFn) {
		onOpenFn = onOpenFn || null;
		return this._addAction(openerElm, action, this.open, onOpenFn);
	},
	
	addCloseAction: function (closerElm, action, onCloseFn) {
		onCloseFn = onCloseFn || null;
		return this._addAction(closerElm, action, this.close, onCloseFn);
	},
	
	addToggleAction: function (togglerElm, action, onToggleFn) {
		onToggleFn = onToggleFn || null;
		return this._addAction(togglerElm, action, this.toggle, onToggleFn);
	}
});
// modalBox 0.1.0
// requires: lib.elm, lib.evt, lib.dhtml
// 
//	by Lokesh Dhakar - http://www.huddletogether.com
//	more info: http://huddletogether.com/projects/lightbox/
//
//	Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
//	(basically, do anything you want, just leave my name and link)
// 
// provides the modal window

if (typeof lib == "undefined") {
	var lib = {};
};

if (typeof lib.modalBox == "undefined") {
	lib.modalBox = {};
};




lib.modalBox.name = "lib.modalBox";
lib.modalBox.initEventPriority = 10;
lib.modalBox.openEventPriority = 10;
lib.modalBox.closeEventPriority = 10;

lib.modalBox.box       = {}; // the modal window
lib.modalBox.overlay   = {}; // semi-transparent overlay layer
lib.modalBox.hourglass = {}; // "wait" animation
lib.modalBox.closeElm  = {}; // closing object (usually a button)




lib.modalBox.box = {
	node: null,
	
	template: {
		id:           "jsModalBox",
		tagName:      "div",
		style: {
			position: "absolute",
			zIndex:   "100",
			display:  "none"
		}
	},
	
	visible: false,
	
	onClickEvtId: null
};


lib.modalBox.box.create = function () {
	// create the box
	// overlay must be created to perform this operation
	
	lib.modalBox.box.node = lib.elm.get(lib.modalBox.box.template.id);
	if (lib.modalBox.box.node == null) {
		// create the box
		lib.modalBox.box.node = lib.elm.create(lib.modalBox.box.template);
		lib.modalBox.overlay.node.appendChild(lib.modalBox.box.node);
	};
	return lib.modalBox.box.node; // the overlay has been created
};

lib.modalBox.box.center = function () {
	return lib.dhtml.center(lib.modalBox.box.node, false);
};

lib.modalBox.box.flush = function () {
	// removes the box content
	lib.modalBox.box.node.innerHTML = "";
	return true;
};

lib.modalBox.box.show = function () {
	lib.modalBox.box.center();
	lib.modalBox.box.visible = true;
	lib.modalBox.box.node.style.display = "";
	if (lib.modalBox.box.onClickEvtId == null) {
		lib.modalBox.box.onClickEvtId = lib.evt.add(lib.modalBox.box.node, "click", lib.modalBox.close);
	};
	return true;
};

lib.modalBox.box.hide = function () {
	lib.modalBox.box.visible = false;
	lib.modalBox.box.node.style.display = "none";
	if (lib.modalBox.box.onClickEvtId) {
		lib.evt.remove(lib.modalBox.box.onClickEvtId);
		lib.modalBox.box.onClickEvtId = null;
	};
	return true;
};





lib.modalBox.overlay = {
	node: null,
	
	template: {
		id:           "jsModalBoxOverlay",
		tagName:      "div",
		style: {
			position: "absolute",
			top:      "0",
			left:     "0",
			width:    "0", // this will be set later
			height:   "0", // this will be set later
			zIndex:   "90",
			display:  "none"
		}
	},
	
	visible: false,
	
	onResizeEvtId: null
};

lib.modalBox.overlay.create = function () {
	// create the overlay
	var objBody = lib.elm.findFirst({tagName: "body"});
	
	lib.modalBox.overlay.node = lib.elm.get(lib.modalBox.overlay.template.id);
	if (lib.modalBox.overlay.node == null) {
		// create overlay
		lib.modalBox.overlay.node = lib.elm.create(lib.modalBox.overlay.template);
		objBody.insertBefore(lib.modalBox.overlay.node, objBody.firstChild);
	};
	return lib.modalBox.overlay.node; // the overlay has been created
};

lib.modalBox.overlay.resize = function () {
	// resize to overlay the viewport
	var viewSize = lib.dhtml.getPageSize();
	lib.dhtml.setSize(lib.modalBox.overlay.node, viewSize);
	lib.dhtml.setPos(lib.modalBox.overlay.node, [0, 0]);
	// lib.modalBox.overlay.center();
	return true;
};

/*
lib.modalBox.overlay.center = function () {
	return lib.dhtml.center(lib.modalBox.overlay.node, true);
};
*/

lib.modalBox.overlay.show = function () {
	// show the overlay
	// TODO: resize the overlay to fit the viewport
	lib.modalBox.overlay.resize();
	lib.modalBox.overlay.visible = true;
	lib.modalBox.overlay.node.style.display = "";
	if (lib.modalBox.overlay.onResizeEvtId == null) {
		lib.modalBox.overlay.onResizeEvtId = lib.evt.add(window, "resize", lib.modalBox.overlay.resize);
	};
	return true;
};

lib.modalBox.overlay.hide = function () {
	// hide the overlay
	lib.modalBox.overlay.visible = false;
	lib.modalBox.overlay.node.style.display = "none";
	if (lib.modalBox.overlay.onResizeEvtId) {
		lib.evt.remove(lib.modalBox.overlay.onResizeEvtId);
		lib.modalBox.overlay.onResizeEvtId = null;
	};
	return true;
};




lib.modalBox.hourglass = {
	node: null,
	
	template: {
		id:           "jsModalBoxHourglass",
		tagName:       "div",
		innerText: "loading...", // !!! i18n - localize this
		style: {
			position:  "absolute", // position is absolute to lib.modalBox.box (!)
			top:       "0",
			left:      "0",
			width:     "auto",
			height:    "1.5em",
			zIndex:    "90",
			display:   "block"
		}
	},
	
	visible: false,
	
	onResizeEvtId: null,
	onClickEvtId: null
};

lib.modalBox.hourglass.create = function () {
	// create the hourglass element
	// overlay must be created to perform this operation
	
	lib.modalBox.hourglass.node = lib.elm.get(lib.modalBox.hourglass.template.id);
	if (lib.modalBox.hourglass.node == null) {
		// create the hourglass element
		lib.modalBox.hourglass.node = lib.elm.create(lib.modalBox.hourglass.template);
		lib.modalBox.overlay.node.appendChild(lib.modalBox.hourglass.node);
	};
	
	return lib.modalBox.hourglass.node; // the hourglass has been created
};

lib.modalBox.hourglass.center = function () {
	return lib.dhtml.center(lib.modalBox.hourglass.node, true);
};

lib.modalBox.hourglass.show = function () {
	// displays the hourglass
	lib.modalBox.hourglass.center();
	lib.modalBox.hourglass.visible = true;
	lib.modalBox.hourglass.node.style.display = "";
	if (lib.modalBox.hourglass.onResizeEvtId == null) {
		lib.modalBox.hourglass.onResizeEvtId = lib.evt.add(window, "resize", lib.modalBox.hourglass.center);
	};
	if (lib.modalBox.hourglass.onClickEvtId == null) {
		lib.modalBox.hourglass.onClickEvtId = lib.evt.add(lib.modalBox.hourglass.node, "click", lib.modalBox.close);
	};
	return true;
};
	
lib.modalBox.hourglass.hide = function () {
	// hides the hourglass
	lib.modalBox.hourglass.visible = false;
	lib.modalBox.hourglass.node.style.display = "none";
	if (lib.modalBox.hourglass.onResizeEvtId) {
		lib.evt.remove(lib.modalBox.hourglass.onResizeEvtId);
		lib.modalBox.hourglass.onResizeEvtId = null;
	};
	if (lib.modalBox.hourglass.onClickEvtId) {
		lib.evt.remove(lib.modalBox.hourglass.onClickEvtId);
		lib.modalBox.hourglass.onClickEvtId = null;
	};
	return true;
};




lib.modalBox.init = function () {
	lib.modalBox.overlay.create();
	lib.modalBox.hourglass.create();
	lib.modalBox.box.create();
	return true;
};

lib.modalBox.add = function (elm, evType, loadBoxContentFn) {
	// adds the modalBox functionality to specified element's event evType
	lib.data.set(elm, "loadBoxContentFn", loadBoxContentFn, lib.modalBox.name);
	var evId = lib.evt.add(elm, evType, lib.modalBox.open);
	return evId;
};

lib.modalBox.open = function (elm, e, evId) {
	lib.modalBox.overlay.show();
	lib.modalBox.hourglass.show();
	lib.evt.add(elm, "modalBoxOpen", lib.modalBox.onBoxOpen);
	
	var loadBoxContentFn = lib.data.get(elm, "loadBoxContentFn", lib.modalBox.name);
	return loadBoxContentFn(elm, e, evId); // this function shall load the box content and then run the lib.modalBox.onBoxOpened method
};

lib.modalBox.loadBoxContentImage = function (elm, e, evId) {
	// this is the sample function that loads the image
	var newImage = new Image;
	lib.modalBox.box.flush();
	lib.evt.add(newImage, "load", lib.modalBox.onBoxOpen);
	lib.modalBox.box.node.appendChild(newImage);
	newImage.src = elm.href;
	return true;
};

lib.modalBox.onBoxOpen = function (elm, e, evId) {
	lib.modalBox.hourglass.hide();
	lib.modalBox.box.show();
	lib.modalBox.overlay.resize();
	return true;
};

lib.modalBox.close = function () {
	lib.modalBox.box.hide();
	lib.modalBox.overlay.hide();
	return true;
};


// lib.overlay 0.0.1
// requires: lib.elm, lib.evt, lib.dhtml
// 
//	by Lokesh Dhakar - http://www.huddletogether.com
//	more info: http://huddletogether.com/projects/lightbox/
//
//	Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
//	(basically, do anything you want, just leave my name and link)
// 
// provides the overlay layer

var lib = lib || {};
lib.overlay = lib.overlay || {};




lib.overlay.name = "lib.overlay";
lib.overlay.node = null;
lib.overlay.template = {
	id:           "jsOverlay",
	tagName:      "div",
	style: {
		position: "absolute",
		top:      "0",
		left:     "0",
		width:    "0", // this will be set later
		height:   "0", // this will be set later
		zIndex:   "999",
		backgroundColor: "#000",
		filter:   "alpha(opacity=30)",
		opacity:  "0.30",
		display:  "none"
	}
};
lib.overlay.visible = false;
lib.overlay._onResizeEvtId = null;




lib.overlay.create = function () {
	// create the overlay
	var objBody = lib.elm.findFirst({tagName: "body"});
	lib.overlay.node = lib.elm.get(lib.overlay.template.id);
	if (lib.overlay.node === null) {
		// create overlay
		lib.overlay.node = lib.elm.create(lib.overlay.template);
		objBody.insertBefore(lib.overlay.node, objBody.firstChild);
	}
	return lib.overlay.node; // the overlay has been created
};

lib.overlay.resize = function () {
	// resize to overlay the viewport
	var viewSize = lib.dhtml.getPageSize();
	lib.dhtml.setPos(lib.overlay.node, [-20, -20]); // prevent scrollbar
	lib.dhtml.setSize(lib.overlay.node, viewSize);
	lib.dhtml.setPos(lib.overlay.node, [0, 0]);
	return true;
};

lib.overlay.show = function () {
	// show the overlay
	// TODO: resize the overlay to fit the viewport
	lib.overlay.resize();
	lib.overlay.visible = true;
	lib.overlay.node.style.display = "";
	if (lib.overlay.onResizeEvtId === null) {
		lib.overlay.onResizeEvtId = lib.evt.add(window, "resize", lib.overlay.resize);
	}
	return true;
};

lib.overlay.hide = function () {
	// hide the overlay
	lib.overlay.visible = false;
	lib.overlay.node.style.display = "none";
	if (lib.overlay.onResizeEvtId) {
		lib.evt.remove(lib.overlay.onResizeEvtId);
		lib.overlay.onResizeEvtId = null;
	}
	return true;
};
// pulldn replaced by jQuery functionality 
// lib.tooltip 0.0.4
// requires: lib.evt, lib.Box, lib.dhtml
// 
// protected by creative commons deed
// under the following conditions: Attribution, Share Alike
// http://creativecommons.org/licenses/by-sa/2.5/
// 

var lib = lib || {};
lib.tooltip = lib.tooltip || {};




lib.tooltip.name = "lib.tooltip";
lib.tooltip.tooltipImgAttribute = "tooltipImg";
lib.tooltip.box = null;
lib.tooltip.boxContentElm = null;
lib.tooltip.envelopeTemplate = {
	tagName:   "div",
	className: "jsLibTooltip",
	style: {
		zIndex: "2000"
	},
	children: [ {contentNode:0} ]
};
lib.tooltip.boxContentTemplate = {
	tagName: "div",
	style: {
		color: "#333",
		border:"1px solid silver",
		backgroundColor: "snow",
//		filter:"alpha(opacity=50)",
//		opacity:"0.85",
		padding: "3px"
	},
	children: [
		{ contentNode: 1 },
		{ tagName: "div", children: [ { contentNode: 0 } ] }
	]
};
lib.tooltip.mouseMoveEvId = null;
lib.tooltip.tooltipText = null;
lib.tooltip.translationVector = [10, 10];




lib.tooltip.init = function () {

	return true;
};

lib.tooltip.add = function (elm) {
	// do this as first
	lib.evt.add(elm, "mouseover", lib.tooltip._open);
	lib.evt.add(elm, "mouseout", lib.tooltip._close);
	
	if (!lib.tooltip.box) {
		lib.tooltip.box = lib.tooltip._createBox();
	}
	
	return true;
};

lib.tooltip._createBox = function (envelopeTemplate) {
	// run onload !
	envelopeTemplate = envelopeTemplate || lib.tooltip.envelopeTemplate;
	lib.tooltip.boxContentElm = lib.elm.create(lib.tooltip.boxContentTemplate);
	lib.tooltip.box = lib.Box.newInstance(lib.tooltip.boxContentElm, null, envelopeTemplate);
	lib.tooltip.box.hide();
	lib.dhtml.setAbsolute(lib.tooltip.box.envelope);
	
	return lib.tooltip.box;
};

lib.tooltip._updateBox = function (title, tooltipImgSrc) {
	var titleNode = null;
	var imageNode = null;
	if (title) {
		titleNode = lib.elm.create( {innerText: title } );
	}
	if (tooltipImgSrc) {
		imageNode = lib.elm.create( {tagName:"img", src: tooltipImgSrc, alt: "image " + tooltipImgSrc});
	}
	var newBoxContentElm = lib.elm.create(lib.tooltip.boxContentTemplate, [titleNode, imageNode]);
	lib.tooltip.box.content.parentNode.replaceChild(newBoxContentElm, lib.tooltip.box.content);
	lib.tooltip.box.content = newBoxContentElm;
	return true;
};

lib.tooltip.remove = function (elm) {
	// TODO
	return true;
};


lib.tooltip._setBoxPosition = function (elm, e) {
	// set box position
	var mousePosition = lib.dhtml.getMouseEvtPos(e);
	mousePosition = lib.vector.add(mousePosition, lib.tooltip.translationVector);
	lib.dhtml.setPos( lib.tooltip.box.envelope, mousePosition );
	return mousePosition;
};

lib.tooltip._open = function (elm, e, evId) {
	var title, tooltipImgSrc;
	
	title = lib.elm.getAttribute(elm, "title");
	tooltipImgSrc = lib.elm.getAttribute(elm, lib.tooltip.tooltipImgAttribute);
	
	if (title || tooltipImgSrc) {
		lib.tooltip._updateBox(title, tooltipImgSrc);
		
		lib.tooltip.tooltipText = elm.title;
		elm.title = "";
		
		lib.tooltip._setBoxPosition(null, e);
		
		// move box when mouse moves
		lib.tooltip.mouseMoveEvId = lib.evt.add(elm, "mousemove", lib.tooltip._setBoxPosition); 
		
		// show the box
		lib.tooltip.box.show();
	}
	return true;
};

lib.tooltip._close = function (elm) {
	lib.tooltip.box.hide();
	try {
		lib.evt.remove(lib.tooltip.mouseMoveEvId);
	} catch (ex) {}
	
	if (lib.tooltip.tooltipText) {
		elm.title = lib.tooltip.tooltipText || "";
		lib.tooltip.tooltipText = null;
	}
	return true;
};
