/*
 * 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")}})})();
/*
 * jQuery UI 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI
 */
;jQuery.ui || (function($) {

var _remove = $.fn.remove,
	isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);

//Helper functions and ui object
$.ui = {
	version: "1.7.2",

	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
	plugin: {
		add: function(module, option, set) {
			var proto = $.ui[module].prototype;
			for(var i in set) {
				proto.plugins[i] = proto.plugins[i] || [];
				proto.plugins[i].push([option, set[i]]);
			}
		},
		call: function(instance, name, args) {
			var set = instance.plugins[name];
			if(!set || !instance.element[0].parentNode) { return; }

			for (var i = 0; i < set.length; i++) {
				if (instance.options[set[i][0]]) {
					set[i][1].apply(instance.element, args);
				}
			}
		}
	},

	contains: function(a, b) {
		return document.compareDocumentPosition
			? a.compareDocumentPosition(b) & 16
			: a !== b && a.contains(b);
	},

	hasScroll: function(el, a) {

		//If overflow is hidden, the element might have extra content, but the user wants to hide it
		if ($(el).css('overflow') == 'hidden') { return false; }

		var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
			has = false;

		if (el[scroll] > 0) { return true; }

		// TODO: determine which cases actually cause this to happen
		// if the element doesn't have the scroll set, see if it's possible to
		// set the scroll
		el[scroll] = 1;
		has = (el[scroll] > 0);
		el[scroll] = 0;
		return has;
	},

	isOverAxis: function(x, reference, size) {
		//Determines when x coordinate is over "b" element axis
		return (x > reference) && (x < (reference + size));
	},

	isOver: function(y, x, top, left, height, width) {
		//Determines when x, y coordinates is over "b" element
		return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
	},

	keyCode: {
		BACKSPACE: 8,
		CAPS_LOCK: 20,
		COMMA: 188,
		CONTROL: 17,
		DELETE: 46,
		DOWN: 40,
		END: 35,
		ENTER: 13,
		ESCAPE: 27,
		HOME: 36,
		INSERT: 45,
		LEFT: 37,
		NUMPAD_ADD: 107,
		NUMPAD_DECIMAL: 110,
		NUMPAD_DIVIDE: 111,
		NUMPAD_ENTER: 108,
		NUMPAD_MULTIPLY: 106,
		NUMPAD_SUBTRACT: 109,
		PAGE_DOWN: 34,
		PAGE_UP: 33,
		PERIOD: 190,
		RIGHT: 39,
		SHIFT: 16,
		SPACE: 32,
		TAB: 9,
		UP: 38
	}
};

// WAI-ARIA normalization
if (isFF2) {
	var attr = $.attr,
		removeAttr = $.fn.removeAttr,
		ariaNS = "http://www.w3.org/2005/07/aaa",
		ariaState = /^aria-/,
		ariaRole = /^wairole:/;

	$.attr = function(elem, name, value) {
		var set = value !== undefined;

		return (name == 'role'
			? (set
				? attr.call(this, elem, name, "wairole:" + value)
				: (attr.apply(this, arguments) || "").replace(ariaRole, ""))
			: (ariaState.test(name)
				? (set
					? elem.setAttributeNS(ariaNS,
						name.replace(ariaState, "aaa:"), value)
					: attr.call(this, elem, name.replace(ariaState, "aaa:")))
				: attr.apply(this, arguments)));
	};

	$.fn.removeAttr = function(name) {
		return (ariaState.test(name)
			? this.each(function() {
				this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
			}) : removeAttr.call(this, name));
	};
}

//jQuery plugins
$.fn.extend({
	remove: function() {
		// Safari has a native remove event which actually removes DOM elements,
		// so we have to use triggerHandler instead of trigger (#3037).
		$("*", this).add(this).each(function() {
			$(this).triggerHandler("remove");
		});
		return _remove.apply(this, arguments );
	},

	enableSelection: function() {
		return this
			.attr('unselectable', 'off')
			.css('MozUserSelect', '')
			.unbind('selectstart.ui');
	},

	disableSelection: function() {
		return this
			.attr('unselectable', 'on')
			.css('MozUserSelect', 'none')
			.bind('selectstart.ui', function() { return false; });
	},

	scrollParent: function() {
		var scrollParent;
		if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
			scrollParent = this.parents().filter(function() {
				return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
			}).eq(0);
		} else {
			scrollParent = this.parents().filter(function() {
				return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
			}).eq(0);
		}

		return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
	}
});


//Additional selectors
$.extend($.expr[':'], {
	data: function(elem, i, match) {
		return !!$.data(elem, match[3]);
	},

	focusable: function(element) {
		var nodeName = element.nodeName.toLowerCase(),
			tabIndex = $.attr(element, 'tabindex');
		return (/input|select|textarea|button|object/.test(nodeName)
			? !element.disabled
			: 'a' == nodeName || 'area' == nodeName
				? element.href || !isNaN(tabIndex)
				: !isNaN(tabIndex))
			// the element and all of its ancestors must be visible
			// the browser may report that the area is hidden
			&& !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
	},

	tabbable: function(element) {
		var tabIndex = $.attr(element, 'tabindex');
		return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
	}
});


// $.widget is a factory to create jQuery plugins
// taking some boilerplate code out of the plugin code
function getter(namespace, plugin, method, args) {
	function getMethods(type) {
		var methods = $[namespace][plugin][type] || [];
		return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
	}

	var methods = getMethods('getter');
	if (args.length == 1 && typeof args[0] == 'string') {
		methods = methods.concat(getMethods('getterSetter'));
	}
	return ($.inArray(method, methods) != -1);
}

$.widget = function(name, prototype) {
	var namespace = name.split(".")[0];
	name = name.split(".")[1];

	// create plugin method
	$.fn[name] = function(options) {
		var isMethodCall = (typeof options == 'string'),
			args = Array.prototype.slice.call(arguments, 1);

		// prevent calls to internal methods
		if (isMethodCall && options.substring(0, 1) == '_') {
			return this;
		}

		// handle getter methods
		if (isMethodCall && getter(namespace, name, options, args)) {
			var instance = $.data(this[0], name);
			return (instance ? instance[options].apply(instance, args)
				: undefined);
		}

		// handle initialization and non-getter methods
		return this.each(function() {
			var instance = $.data(this, name);

			// constructor
			(!instance && !isMethodCall &&
				$.data(this, name, new $[namespace][name](this, options))._init());

			// method call
			(instance && isMethodCall && $.isFunction(instance[options]) &&
				instance[options].apply(instance, args));
		});
	};

	// create widget constructor
	$[namespace] = $[namespace] || {};
	$[namespace][name] = function(element, options) {
		var self = this;

		this.namespace = namespace;
		this.widgetName = name;
		this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
		this.widgetBaseClass = namespace + '-' + name;

		this.options = $.extend({},
			$.widget.defaults,
			$[namespace][name].defaults,
			$.metadata && $.metadata.get(element)[name],
			options);

		this.element = $(element)
			.bind('setData.' + name, function(event, key, value) {
				if (event.target == element) {
					return self._setData(key, value);
				}
			})
			.bind('getData.' + name, function(event, key) {
				if (event.target == element) {
					return self._getData(key);
				}
			})
			.bind('remove', function() {
				return self.destroy();
			});
	};

	// add widget prototype
	$[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);

	// TODO: merge getter and getterSetter properties from widget prototype
	// and plugin prototype
	$[namespace][name].getterSetter = 'option';
};

$.widget.prototype = {
	_init: function() {},
	destroy: function() {
		this.element.removeData(this.widgetName)
			.removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
			.removeAttr('aria-disabled');
	},

	option: function(key, value) {
		var options = key,
			self = this;

		if (typeof key == "string") {
			if (value === undefined) {
				return this._getData(key);
			}
			options = {};
			options[key] = value;
		}

		$.each(options, function(key, value) {
			self._setData(key, value);
		});
	},
	_getData: function(key) {
		return this.options[key];
	},
	_setData: function(key, value) {
		this.options[key] = value;

		if (key == 'disabled') {
			this.element
				[value ? 'addClass' : 'removeClass'](
					this.widgetBaseClass + '-disabled' + ' ' +
					this.namespace + '-state-disabled')
				.attr("aria-disabled", value);
		}
	},

	enable: function() {
		this._setData('disabled', false);
	},
	disable: function() {
		this._setData('disabled', true);
	},

	_trigger: function(type, event, data) {
		var callback = this.options[type],
			eventName = (type == this.widgetEventPrefix
				? type : this.widgetEventPrefix + type);

		event = $.Event(event);
		event.type = eventName;

		// copy original event properties over to the new event
		// this would happen if we could call $.event.fix instead of $.Event
		// but we don't have a way to force an event to be fixed multiple times
		if (event.originalEvent) {
			for (var i = $.event.props.length, prop; i;) {
				prop = $.event.props[--i];
				event[prop] = event.originalEvent[prop];
			}
		}

		this.element.trigger(event, data);

		return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
			|| event.isDefaultPrevented());
	}
};

$.widget.defaults = {
	disabled: false
};


/** Mouse Interaction Plugin **/

$.ui.mouse = {
	_mouseInit: function() {
		var self = this;

		this.element
			.bind('mousedown.'+this.widgetName, function(event) {
				return self._mouseDown(event);
			})
			.bind('click.'+this.widgetName, function(event) {
				if(self._preventClickEvent) {
					self._preventClickEvent = false;
					event.stopImmediatePropagation();
					return false;
				}
			});

		// Prevent text selection in IE
		if ($.browser.msie) {
			this._mouseUnselectable = this.element.attr('unselectable');
			this.element.attr('unselectable', 'on');
		}

		this.started = false;
	},

	// TODO: make sure destroying one instance of mouse doesn't mess with
	// other instances of mouse
	_mouseDestroy: function() {
		this.element.unbind('.'+this.widgetName);

		// Restore text selection in IE
		($.browser.msie
			&& this.element.attr('unselectable', this._mouseUnselectable));
	},

	_mouseDown: function(event) {
		// don't let more than one widget handle mouseStart
		// TODO: figure out why we have to use originalEvent
		event.originalEvent = event.originalEvent || {};
		if (event.originalEvent.mouseHandled) { return; }

		// we may have missed mouseup (out of window)
		(this._mouseStarted && this._mouseUp(event));

		this._mouseDownEvent = event;

		var self = this,
			btnIsLeft = (event.which == 1),
			elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
			return true;
		}

		this.mouseDelayMet = !this.options.delay;
		if (!this.mouseDelayMet) {
			this._mouseDelayTimer = setTimeout(function() {
				self.mouseDelayMet = true;
			}, this.options.delay);
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted = (this._mouseStart(event) !== false);
			if (!this._mouseStarted) {
				event.preventDefault();
				return true;
			}
		}

		// these delegates are required to keep context
		this._mouseMoveDelegate = function(event) {
			return self._mouseMove(event);
		};
		this._mouseUpDelegate = function(event) {
			return self._mouseUp(event);
		};
		$(document)
			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);

		// preventDefault() is used to prevent the selection of text here -
		// however, in Safari, this causes select boxes not to be selectable
		// anymore, so this fix is needed
		($.browser.safari || event.preventDefault());

		event.originalEvent.mouseHandled = true;
		return true;
	},

	_mouseMove: function(event) {
		// IE mouseup check - mouseup happened when mouse was out of window
		if ($.browser.msie && !event.button) {
			return this._mouseUp(event);
		}

		if (this._mouseStarted) {
			this._mouseDrag(event);
			return event.preventDefault();
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {

			this._mouseStarted =
				(this._mouseStart(this._mouseDownEvent, event) !== false);
			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
		}

		return !this._mouseStarted;
	},

	_mouseUp: function(event) {
		$(document)
			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);

		if (this._mouseStarted) {
			this._mouseStarted = false;
			this._preventClickEvent = (event.target == this._mouseDownEvent.target);
			this._mouseStop(event);
		}

		return false;
	},

	_mouseDistanceMet: function(event) {
		return (Math.max(
				Math.abs(this._mouseDownEvent.pageX - event.pageX),
				Math.abs(this._mouseDownEvent.pageY - event.pageY)
			) >= this.options.distance
		);
	},

	_mouseDelayMet: function(event) {
		return this.mouseDelayMet;
	},

	// These are placeholder methods, to be overriden by extending plugin
	_mouseStart: function(event) {},
	_mouseDrag: function(event) {},
	_mouseStop: function(event) {},
	_mouseCapture: function(event) { return true; }
};

$.ui.mouse.defaults = {
	cancel: null,
	distance: 1,
	delay: 0
};

})(jQuery);

/*
 * jQuery UI Tabs 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Tabs
 *
 * Depends:
 *	ui.core.js
 */
(function($) {

$.widget("ui.tabs", {

	_init: function() {
		if (this.options.deselectable !== undefined) {
			this.options.collapsible = this.options.deselectable;
		}
		this._tabify(true);
	},

	_setData: function(key, value) {
		if (key == 'selected') {
			if (this.options.collapsible && value == this.options.selected) {
				return;
			}
			this.select(value);
		}
		else {
			this.options[key] = value;
			if (key == 'deselectable') {
				this.options.collapsible = value;
			}
			this._tabify();
		}
	},

	_tabId: function(a) {
		return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '') ||
			this.options.idPrefix + $.data(a);
	},

	_sanitizeSelector: function(hash) {
		return hash.replace(/:/g, '\\:'); // we need this because an id may contain a ":"
	},

	_cookie: function() {
		var cookie = this.cookie || (this.cookie = this.options.cookie.name || 'ui-tabs-' + $.data(this.list[0]));
		return $.cookie.apply(null, [cookie].concat($.makeArray(arguments)));
	},

	_ui: function(tab, panel) {
		return {
			tab: tab,
			panel: panel,
			index: this.anchors.index(tab)
		};
	},

	_cleanup: function() {
		// restore all former loading tabs labels
		this.lis.filter('.ui-state-processing').removeClass('ui-state-processing')
				.find('span:data(label.tabs)')
				.each(function() {
					var el = $(this);
					el.html(el.data('label.tabs')).removeData('label.tabs');
				});
	},

	_tabify: function(init) {

		this.list = this.element.children('ul:first');
		this.lis = $('li:has(a[href])', this.list);
		this.anchors = this.lis.map(function() { return $('a', this)[0]; });
		this.panels = $([]);

		var self = this, o = this.options;

		var fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
		this.anchors.each(function(i, a) {
			var href = $(a).attr('href');

			// For dynamically created HTML that contains a hash as href IE < 8 expands
			// such href to the full page url with hash and then misinterprets tab as ajax.
			// Same consideration applies for an added tab with a fragment identifier
			// since a[href=#fragment-identifier] does unexpectedly not match.
			// Thus normalize href attribute...
			var hrefBase = href.split('#')[0], baseEl;
			if (hrefBase && (hrefBase === location.toString().split('#')[0] ||
					(baseEl = $('base')[0]) && hrefBase === baseEl.href)) {
				href = a.hash;
				a.href = href;
			}

			// inline tab
			if (fragmentId.test(href)) {
				self.panels = self.panels.add(self._sanitizeSelector(href));
			}

			// remote tab
			else if (href != '#') { // prevent loading the page itself if href is just "#"
				$.data(a, 'href.tabs', href); // required for restore on destroy

				// TODO until #3808 is fixed strip fragment identifier from url
				// (IE fails to load from such url)
				$.data(a, 'load.tabs', href.replace(/#.*$/, '')); // mutable data

				var id = self._tabId(a);
				a.href = '#' + id;
				var $panel = $('#' + id);
				if (!$panel.length) {
					$panel = $(o.panelTemplate).attr('id', id).addClass('ui-tabs-panel ui-widget-content ui-corner-bottom')
						.insertAfter(self.panels[i - 1] || self.list);
					$panel.data('destroy.tabs', true);
				}
				self.panels = self.panels.add($panel);
			}

			// invalid tab href
			else {
				o.disabled.push(i);
			}
		});

		// initialization from scratch
		if (init) {

			// attach necessary classes for styling
			this.element.addClass('ui-tabs ui-widget ui-widget-content ui-corner-all');
			this.list.addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all');
			this.lis.addClass('ui-state-default ui-corner-top');
			this.panels.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom');

			// Selected tab
			// use "selected" option or try to retrieve:
			// 1. from fragment identifier in url
			// 2. from cookie
			// 3. from selected class attribute on <li>
			if (o.selected === undefined) {
				if (location.hash) {
					this.anchors.each(function(i, a) {
						if (a.hash == location.hash) {
							o.selected = i;
							return false; // break
						}
					});
				}
				if (typeof o.selected != 'number' && o.cookie) {
					o.selected = parseInt(self._cookie(), 10);
				}
				if (typeof o.selected != 'number' && this.lis.filter('.ui-tabs-selected').length) {
					o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected'));
				}
				o.selected = o.selected || 0;
			}
			else if (o.selected === null) { // usage of null is deprecated, TODO remove in next release
				o.selected = -1;
			}

			// sanity check - default to first tab...
			o.selected = ((o.selected >= 0 && this.anchors[o.selected]) || o.selected < 0) ? o.selected : 0;

			// Take disabling tabs via class attribute from HTML
			// into account and update option properly.
			// A selected tab cannot become disabled.
			o.disabled = $.unique(o.disabled.concat(
				$.map(this.lis.filter('.ui-state-disabled'),
					function(n, i) { return self.lis.index(n); } )
			)).sort();

			if ($.inArray(o.selected, o.disabled) != -1) {
				o.disabled.splice($.inArray(o.selected, o.disabled), 1);
			}

			// highlight selected tab
			this.panels.addClass('ui-tabs-hide');
			this.lis.removeClass('ui-tabs-selected ui-state-active');
			if (o.selected >= 0 && this.anchors.length) { // check for length avoids error when initializing empty list
				this.panels.eq(o.selected).removeClass('ui-tabs-hide');
				this.lis.eq(o.selected).addClass('ui-tabs-selected ui-state-active');

				// seems to be expected behavior that the show callback is fired
				self.element.queue("tabs", function() {
					self._trigger('show', null, self._ui(self.anchors[o.selected], self.panels[o.selected]));
				});

				this.load(o.selected);
			}

			// clean up to avoid memory leaks in certain versions of IE 6
			$(window).bind('unload', function() {
				self.lis.add(self.anchors).unbind('.tabs');
				self.lis = self.anchors = self.panels = null;
			});

		}
		// update selected after add/remove
		else {
			o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected'));
		}

		// update collapsible
		this.element[o.collapsible ? 'addClass' : 'removeClass']('ui-tabs-collapsible');

		// set or update cookie after init and add/remove respectively
		if (o.cookie) {
			this._cookie(o.selected, o.cookie);
		}

		// disable tabs
		for (var i = 0, li; (li = this.lis[i]); i++) {
			$(li)[$.inArray(i, o.disabled) != -1 &&
				!$(li).hasClass('ui-tabs-selected') ? 'addClass' : 'removeClass']('ui-state-disabled');
		}

		// reset cache if switching from cached to not cached
		if (o.cache === false) {
			this.anchors.removeData('cache.tabs');
		}

		// remove all handlers before, tabify may run on existing tabs after add or option change
		this.lis.add(this.anchors).unbind('.tabs');

		if (o.event != 'mouseover') {
			var addState = function(state, el) {
				if (el.is(':not(.ui-state-disabled)')) {
					el.addClass('ui-state-' + state);
				}
			};
			var removeState = function(state, el) {
				el.removeClass('ui-state-' + state);
			};
			this.lis.bind('mouseover.tabs', function() {
				addState('hover', $(this));
			});
			this.lis.bind('mouseout.tabs', function() {
				removeState('hover', $(this));
			});
			this.anchors.bind('focus.tabs', function() {
				addState('focus', $(this).closest('li'));
			});
			this.anchors.bind('blur.tabs', function() {
				removeState('focus', $(this).closest('li'));
			});
		}

		// set up animations
		var hideFx, showFx;
		if (o.fx) {
			if ($.isArray(o.fx)) {
				hideFx = o.fx[0];
				showFx = o.fx[1];
			}
			else {
				hideFx = showFx = o.fx;
			}
		}

		// Reset certain styles left over from animation
		// and prevent IE's ClearType bug...
		function resetStyle($el, fx) {
			$el.css({ display: '' });
			if ($.browser.msie && fx.opacity) {
				$el[0].style.removeAttribute('filter');
			}
		}

		// Show a tab...
		var showTab = showFx ?
			function(clicked, $show) {
				$(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active');
				$show.hide().removeClass('ui-tabs-hide') // avoid flicker that way
					.animate(showFx, showFx.duration || 'normal', function() {
						resetStyle($show, showFx);
						self._trigger('show', null, self._ui(clicked, $show[0]));
					});
			} :
			function(clicked, $show) {
				$(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active');
				$show.removeClass('ui-tabs-hide');
				self._trigger('show', null, self._ui(clicked, $show[0]));
			};

		// Hide a tab, $show is optional...
		var hideTab = hideFx ?
			function(clicked, $hide) {
				$hide.animate(hideFx, hideFx.duration || 'normal', function() {
					self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default');
					$hide.addClass('ui-tabs-hide');
					resetStyle($hide, hideFx);
					self.element.dequeue("tabs");
				});
			} :
			function(clicked, $hide, $show) {
				self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default');
				$hide.addClass('ui-tabs-hide');
				self.element.dequeue("tabs");
			};

		// attach tab event handler, unbind to avoid duplicates from former tabifying...
		this.anchors.bind(o.event + '.tabs', function() {
			var el = this, $li = $(this).closest('li'), $hide = self.panels.filter(':not(.ui-tabs-hide)'),
					$show = $(self._sanitizeSelector(this.hash));

			// If tab is already selected and not collapsible or tab disabled or
			// or is already loading or click callback returns false stop here.
			// Check if click handler returns false last so that it is not executed
			// for a disabled or loading tab!
			if (($li.hasClass('ui-tabs-selected') && !o.collapsible) ||
				$li.hasClass('ui-state-disabled') ||
				$li.hasClass('ui-state-processing') ||
				self._trigger('select', null, self._ui(this, $show[0])) === false) {
				this.blur();
				return false;
			}

			o.selected = self.anchors.index(this);

			self.abort();

			// if tab may be closed
			if (o.collapsible) {
				if ($li.hasClass('ui-tabs-selected')) {
					o.selected = -1;

					if (o.cookie) {
						self._cookie(o.selected, o.cookie);
					}

					self.element.queue("tabs", function() {
						hideTab(el, $hide);
					}).dequeue("tabs");

					this.blur();
					return false;
				}
				else if (!$hide.length) {
					if (o.cookie) {
						self._cookie(o.selected, o.cookie);
					}

					self.element.queue("tabs", function() {
						showTab(el, $show);
					});

					self.load(self.anchors.index(this)); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171

					this.blur();
					return false;
				}
			}

			if (o.cookie) {
				self._cookie(o.selected, o.cookie);
			}

			// show new tab
			if ($show.length) {
				if ($hide.length) {
					self.element.queue("tabs", function() {
						hideTab(el, $hide);
					});
				}
				self.element.queue("tabs", function() {
					showTab(el, $show);
				});

				self.load(self.anchors.index(this));
			}
			else {
				throw 'jQuery UI Tabs: Mismatching fragment identifier.';
			}

			// Prevent IE from keeping other link focussed when using the back button
			// and remove dotted border from clicked link. This is controlled via CSS
			// in modern browsers; blur() removes focus from address bar in Firefox
			// which can become a usability and annoying problem with tabs('rotate').
			if ($.browser.msie) {
				this.blur();
			}

		});

		// disable click in any case
		this.anchors.bind('click.tabs', function(){return false;});

	},

	destroy: function() {
		var o = this.options;

		this.abort();

		this.element.unbind('.tabs')
			.removeClass('ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible')
			.removeData('tabs');

		this.list.removeClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all');

		this.anchors.each(function() {
			var href = $.data(this, 'href.tabs');
			if (href) {
				this.href = href;
			}
			var $this = $(this).unbind('.tabs');
			$.each(['href', 'load', 'cache'], function(i, prefix) {
				$this.removeData(prefix + '.tabs');
			});
		});

		this.lis.unbind('.tabs').add(this.panels).each(function() {
			if ($.data(this, 'destroy.tabs')) {
				$(this).remove();
			}
			else {
				$(this).removeClass([
					'ui-state-default',
					'ui-corner-top',
					'ui-tabs-selected',
					'ui-state-active',
					'ui-state-hover',
					'ui-state-focus',
					'ui-state-disabled',
					'ui-tabs-panel',
					'ui-widget-content',
					'ui-corner-bottom',
					'ui-tabs-hide'
				].join(' '));
			}
		});

		if (o.cookie) {
			this._cookie(null, o.cookie);
		}
	},

	add: function(url, label, index) {
		if (index === undefined) {
			index = this.anchors.length; // append by default
		}

		var self = this, o = this.options,
			$li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label)),
			id = !url.indexOf('#') ? url.replace('#', '') : this._tabId($('a', $li)[0]);

		$li.addClass('ui-state-default ui-corner-top').data('destroy.tabs', true);

		// try to find an existing element before creating a new one
		var $panel = $('#' + id);
		if (!$panel.length) {
			$panel = $(o.panelTemplate).attr('id', id).data('destroy.tabs', true);
		}
		$panel.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide');

		if (index >= this.lis.length) {
			$li.appendTo(this.list);
			$panel.appendTo(this.list[0].parentNode);
		}
		else {
			$li.insertBefore(this.lis[index]);
			$panel.insertBefore(this.panels[index]);
		}

		o.disabled = $.map(o.disabled,
			function(n, i) { return n >= index ? ++n : n; });

		this._tabify();

		if (this.anchors.length == 1) { // after tabify
			$li.addClass('ui-tabs-selected ui-state-active');
			$panel.removeClass('ui-tabs-hide');
			this.element.queue("tabs", function() {
				self._trigger('show', null, self._ui(self.anchors[0], self.panels[0]));
			});

			this.load(0);
		}

		// callback
		this._trigger('add', null, this._ui(this.anchors[index], this.panels[index]));
	},

	remove: function(index) {
		var o = this.options, $li = this.lis.eq(index).remove(),
			$panel = this.panels.eq(index).remove();

		// If selected tab was removed focus tab to the right or
		// in case the last tab was removed the tab to the left.
		if ($li.hasClass('ui-tabs-selected') && this.anchors.length > 1) {
			this.select(index + (index + 1 < this.anchors.length ? 1 : -1));
		}

		o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }),
			function(n, i) { return n >= index ? --n : n; });

		this._tabify();

		// callback
		this._trigger('remove', null, this._ui($li.find('a')[0], $panel[0]));
	},

	enable: function(index) {
		var o = this.options;
		if ($.inArray(index, o.disabled) == -1) {
			return;
		}

		this.lis.eq(index).removeClass('ui-state-disabled');
		o.disabled = $.grep(o.disabled, function(n, i) { return n != index; });

		// callback
		this._trigger('enable', null, this._ui(this.anchors[index], this.panels[index]));
	},

	disable: function(index) {
		var self = this, o = this.options;
		if (index != o.selected) { // cannot disable already selected tab
			this.lis.eq(index).addClass('ui-state-disabled');

			o.disabled.push(index);
			o.disabled.sort();

			// callback
			this._trigger('disable', null, this._ui(this.anchors[index], this.panels[index]));
		}
	},

	select: function(index) {
		if (typeof index == 'string') {
			index = this.anchors.index(this.anchors.filter('[href$=' + index + ']'));
		}
		else if (index === null) { // usage of null is deprecated, TODO remove in next release
			index = -1;
		}
		if (index == -1 && this.options.collapsible) {
			index = this.options.selected;
		}

		this.anchors.eq(index).trigger(this.options.event + '.tabs');
	},

	load: function(index) {
		var self = this, o = this.options, a = this.anchors.eq(index)[0], url = $.data(a, 'load.tabs');

		this.abort();

		// not remote or from cache
		if (!url || this.element.queue("tabs").length !== 0 && $.data(a, 'cache.tabs')) {
			this.element.dequeue("tabs");
			return;
		}

		// load remote from here on
		this.lis.eq(index).addClass('ui-state-processing');

		if (o.spinner) {
			var span = $('span', a);
			span.data('label.tabs', span.html()).html(o.spinner);
		}

		this.xhr = $.ajax($.extend({}, o.ajaxOptions, {
			url: url,
			success: function(r, s) {
				$(self._sanitizeSelector(a.hash)).html(r);

				// take care of tab labels
				self._cleanup();

				if (o.cache) {
					$.data(a, 'cache.tabs', true); // if loaded once do not load them again
				}

				// callbacks
				self._trigger('load', null, self._ui(self.anchors[index], self.panels[index]));
				try {
					o.ajaxOptions.success(r, s);
				}
				catch (e) {}

				// last, so that load event is fired before show...
				self.element.dequeue("tabs");
			}
		}));
	},

	abort: function() {
		// stop possibly running animations
		this.element.queue([]);
		this.panels.stop(false, true);

		// terminate pending requests from other tabs
		if (this.xhr) {
			this.xhr.abort();
			delete this.xhr;
		}

		// take care of tab labels
		this._cleanup();

	},

	url: function(index, url) {
		this.anchors.eq(index).removeData('cache.tabs').data('load.tabs', url);
	},

	length: function() {
		return this.anchors.length;
	}

});

$.extend($.ui.tabs, {
	version: '1.7.2',
	getter: 'length',
	defaults: {
		ajaxOptions: null,
		cache: false,
		cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
		collapsible: false,
		disabled: [],
		event: 'click',
		fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
		idPrefix: 'ui-tabs-',
		panelTemplate: '<div></div>',
		spinner: '<em>Loading&#8230;</em>',
		tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>'
	}
});

/*
 * Tabs Extensions
 */

/*
 * Rotate
 */
$.extend($.ui.tabs.prototype, {
	rotation: null,
	rotate: function(ms, continuing) {

		var self = this, o = this.options;

		var rotate = self._rotate || (self._rotate = function(e) {
			clearTimeout(self.rotation);
			self.rotation = setTimeout(function() {
				var t = o.selected;
				self.select( ++t < self.anchors.length ? t : 0 );
			}, ms);

			if (e) {
				e.stopPropagation();
			}
		});

		var stop = self._unrotate || (self._unrotate = !continuing ?
			function(e) {
				if (e.clientX) { // in case of a true click
					self.rotate(null);
				}
			} :
			function(e) {
				t = o.selected;
				rotate();
			});

		// start rotation
		if (ms) {
			this.element.bind('tabsshow', rotate);
			this.anchors.bind(o.event + '.tabs', stop);
			rotate();
		}
		// stop rotation
		else {
			clearTimeout(self.rotation);
			this.element.unbind('tabsshow', rotate);
			this.anchors.unbind(o.event + '.tabs', stop);
			delete this._rotate;
			delete this._unrotate;
		}
	}
});

})(jQuery);


/*
 * jQuery UI Sortable 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Sortables
 *
 * Depends:
 *	ui.core.js
 */
(function($) {

$.widget("ui.sortable", $.extend({}, $.ui.mouse, {
	_init: function() {

		var o = this.options;
		this.containerCache = {};
		this.element.addClass("ui-sortable");

		//Get the items
		this.refresh();

		//Let's determine if the items are floating
		this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) : false;

		//Let's determine the parent's offset
		this.offset = this.element.offset();

		//Initialize mouse events for interaction
		this._mouseInit();

	},

	destroy: function() {
		this.element
			.removeClass("ui-sortable ui-sortable-disabled")
			.removeData("sortable")
			.unbind(".sortable");
		this._mouseDestroy();

		for ( var i = this.items.length - 1; i >= 0; i-- )
			this.items[i].item.removeData("sortable-item");
	},

	_mouseCapture: function(event, overrideHandle) {

		if (this.reverting) {
			return false;
		}

		if(this.options.disabled || this.options.type == 'static') return false;

		//We have to refresh the items data once first
		this._refreshItems(event);

		//Find out if the clicked node (or one of its parents) is a actual item in this.items
		var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
			if($.data(this, 'sortable-item') == self) {
				currentItem = $(this);
				return false;
			}
		});
		if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);

		if(!currentItem) return false;
		if(this.options.handle && !overrideHandle) {
			var validHandle = false;

			$(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
			if(!validHandle) return false;
		}

		this.currentItem = currentItem;
		this._removeCurrentsFromItems();
		return true;

	},

	_mouseStart: function(event, overrideHandle, noActivation) {

		var o = this.options, self = this;
		this.currentContainer = this;

		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
		this.refreshPositions();

		//Create and append the visible helper
		this.helper = this._createHelper(event);

		//Cache the helper size
		this._cacheHelperProportions();

		/*
		 * - Position generation -
		 * This block generates everything position related - it's the core of draggables.
		 */

		//Cache the margins of the original element
		this._cacheMargins();

		//Get the next scrolling parent
		this.scrollParent = this.helper.scrollParent();

		//The element's absolute position on the page minus margins
		this.offset = this.currentItem.offset();
		this.offset = {
			top: this.offset.top - this.margins.top,
			left: this.offset.left - this.margins.left
		};

		// Only after we got the offset, we can change the helper's position to absolute
		// TODO: Still need to figure out a way to make relative sorting possible
		this.helper.css("position", "absolute");
		this.cssPosition = this.helper.css("position");

		$.extend(this.offset, {
			click: { //Where the click happened, relative to the element
				left: event.pageX - this.offset.left,
				top: event.pageY - this.offset.top
			},
			parent: this._getParentOffset(),
			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
		});

		//Generate the original position
		this.originalPosition = this._generatePosition(event);
		this.originalPageX = event.pageX;
		this.originalPageY = event.pageY;

		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
		if(o.cursorAt)
			this._adjustOffsetFromHelper(o.cursorAt);

		//Cache the former DOM position
		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };

		//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
		if(this.helper[0] != this.currentItem[0]) {
			this.currentItem.hide();
		}

		//Create the placeholder
		this._createPlaceholder();

		//Set a containment if given in the options
		if(o.containment)
			this._setContainment();

		if(o.cursor) { // cursor option
			if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
			$('body').css("cursor", o.cursor);
		}

		if(o.opacity) { // opacity option
			if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
			this.helper.css("opacity", o.opacity);
		}

		if(o.zIndex) { // zIndex option
			if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
			this.helper.css("zIndex", o.zIndex);
		}

		//Prepare scrolling
		if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
			this.overflowOffset = this.scrollParent.offset();

		//Call callbacks
		this._trigger("start", event, this._uiHash());

		//Recache the helper size
		if(!this._preserveHelperProportions)
			this._cacheHelperProportions();


		//Post 'activate' events to possible containers
		if(!noActivation) {
			 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
		}

		//Prepare possible droppables
		if($.ui.ddmanager)
			$.ui.ddmanager.current = this;

		if ($.ui.ddmanager && !o.dropBehaviour)
			$.ui.ddmanager.prepareOffsets(this, event);

		this.dragging = true;

		this.helper.addClass("ui-sortable-helper");
		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
		return true;

	},

	_mouseDrag: function(event) {

		//Compute the helpers position
		this.position = this._generatePosition(event);
		this.positionAbs = this._convertPositionTo("absolute");

		if (!this.lastPositionAbs) {
			this.lastPositionAbs = this.positionAbs;
		}

		//Do scrolling
		if(this.options.scroll) {
			var o = this.options, scrolled = false;
			if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {

				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
				else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;

				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
				else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;

			} else {

				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);

				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);

			}

			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
				$.ui.ddmanager.prepareOffsets(this, event);
		}

		//Regenerate the absolute position used for position checks
		this.positionAbs = this._convertPositionTo("absolute");

		//Set the helper position
		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';

		//Rearrange
		for (var i = this.items.length - 1; i >= 0; i--) {

			//Cache variables and intersection, continue if no intersection
			var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
			if (!intersection) continue;

			if(itemElement != this.currentItem[0] //cannot intersect with itself
				&&	this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
				&&	!$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
				&& (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
			) {

				this.direction = intersection == 1 ? "down" : "up";

				if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
					this._rearrange(event, item);
				} else {
					break;
				}

				this._trigger("change", event, this._uiHash());
				break;
			}
		}

		//Post events to containers
		this._contactContainers(event);

		//Interconnect with droppables
		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);

		//Call callbacks
		this._trigger('sort', event, this._uiHash());

		this.lastPositionAbs = this.positionAbs;
		return false;

	},

	_mouseStop: function(event, noPropagation) {

		if(!event) return;

		//If we are using droppables, inform the manager about the drop
		if ($.ui.ddmanager && !this.options.dropBehaviour)
			$.ui.ddmanager.drop(this, event);

		if(this.options.revert) {
			var self = this;
			var cur = self.placeholder.offset();

			self.reverting = true;

			$(this.helper).animate({
				left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
				top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
			}, parseInt(this.options.revert, 10) || 500, function() {
				self._clear(event);
			});
		} else {
			this._clear(event, noPropagation);
		}

		return false;

	},

	cancel: function() {

		var self = this;

		if(this.dragging) {

			this._mouseUp();

			if(this.options.helper == "original")
				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
			else
				this.currentItem.show();

			//Post deactivating events to containers
			for (var i = this.containers.length - 1; i >= 0; i--){
				this.containers[i]._trigger("deactivate", null, self._uiHash(this));
				if(this.containers[i].containerCache.over) {
					this.containers[i]._trigger("out", null, self._uiHash(this));
					this.containers[i].containerCache.over = 0;
				}
			}

		}

		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
		if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
		if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();

		$.extend(this, {
			helper: null,
			dragging: false,
			reverting: false,
			_noFinalSort: null
		});

		if(this.domPosition.prev) {
			$(this.domPosition.prev).after(this.currentItem);
		} else {
			$(this.domPosition.parent).prepend(this.currentItem);
		}

		return true;

	},

	serialize: function(o) {

		var items = this._getItemsAsjQuery(o && o.connected);
		var str = []; o = o || {};

		$(items).each(function() {
			var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
			if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
		});

		return str.join('&');

	},

	toArray: function(o) {

		var items = this._getItemsAsjQuery(o && o.connected);
		var ret = []; o = o || {};

		items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
		return ret;

	},

	/* Be careful with the following core functions */
	_intersectsWith: function(item) {

		var x1 = this.positionAbs.left,
			x2 = x1 + this.helperProportions.width,
			y1 = this.positionAbs.top,
			y2 = y1 + this.helperProportions.height;

		var l = item.left,
			r = l + item.width,
			t = item.top,
			b = t + item.height;

		var dyClick = this.offset.click.top,
			dxClick = this.offset.click.left;

		var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;

		if(	   this.options.tolerance == "pointer"
			|| this.options.forcePointerForContainers
			|| (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
		) {
			return isOverElement;
		} else {

			return (l < x1 + (this.helperProportions.width / 2) // Right Half
				&& x2 - (this.helperProportions.width / 2) < r // Left Half
				&& t < y1 + (this.helperProportions.height / 2) // Bottom Half
				&& y2 - (this.helperProportions.height / 2) < b ); // Top Half

		}
	},

	_intersectsWithPointer: function(item) {

		var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
			isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
			isOverElement = isOverElementHeight && isOverElementWidth,
			verticalDirection = this._getDragVerticalDirection(),
			horizontalDirection = this._getDragHorizontalDirection();

		if (!isOverElement)
			return false;

		return this.floating ?
			( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
			: ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );

	},

	_intersectsWithSides: function(item) {

		var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
			isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
			verticalDirection = this._getDragVerticalDirection(),
			horizontalDirection = this._getDragHorizontalDirection();

		if (this.floating && horizontalDirection) {
			return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
		} else {
			return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
		}

	},

	_getDragVerticalDirection: function() {
		var delta = this.positionAbs.top - this.lastPositionAbs.top;
		return delta != 0 && (delta > 0 ? "down" : "up");
	},

	_getDragHorizontalDirection: function() {
		var delta = this.positionAbs.left - this.lastPositionAbs.left;
		return delta != 0 && (delta > 0 ? "right" : "left");
	},

	refresh: function(event) {
		this._refreshItems(event);
		this.refreshPositions();
	},

	_connectWith: function() {
		var options = this.options;
		return options.connectWith.constructor == String
			? [options.connectWith]
			: options.connectWith;
	},
	
	_getItemsAsjQuery: function(connected) {

		var self = this;
		var items = [];
		var queries = [];
		var connectWith = this._connectWith();

		if(connectWith && connected) {
			for (var i = connectWith.length - 1; i >= 0; i--){
				var cur = $(connectWith[i]);
				for (var j = cur.length - 1; j >= 0; j--){
					var inst = $.data(cur[j], 'sortable');
					if(inst && inst != this && !inst.options.disabled) {
						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper"), inst]);
					}
				};
			};
		}

		queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper"), this]);

		for (var i = queries.length - 1; i >= 0; i--){
			queries[i][0].each(function() {
				items.push(this);
			});
		};

		return $(items);

	},

	_removeCurrentsFromItems: function() {

		var list = this.currentItem.find(":data(sortable-item)");

		for (var i=0; i < this.items.length; i++) {

			for (var j=0; j < list.length; j++) {
				if(list[j] == this.items[i].item[0])
					this.items.splice(i,1);
			};

		};

	},

	_refreshItems: function(event) {

		this.items = [];
		this.containers = [this];
		var items = this.items;
		var self = this;
		var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
		var connectWith = this._connectWith();

		if(connectWith) {
			for (var i = connectWith.length - 1; i >= 0; i--){
				var cur = $(connectWith[i]);
				for (var j = cur.length - 1; j >= 0; j--){
					var inst = $.data(cur[j], 'sortable');
					if(inst && inst != this && !inst.options.disabled) {
						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
						this.containers.push(inst);
					}
				};
			};
		}

		for (var i = queries.length - 1; i >= 0; i--) {
			var targetData = queries[i][1];
			var _queries = queries[i][0];

			for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
				var item = $(_queries[j]);

				item.data('sortable-item', targetData); // Data for target checking (mouse manager)

				items.push({
					item: item,
					instance: targetData,
					width: 0, height: 0,
					left: 0, top: 0
				});
			};
		};

	},

	refreshPositions: function(fast) {

		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
		if(this.offsetParent && this.helper) {
			this.offset.parent = this._getParentOffset();
		}

		for (var i = this.items.length - 1; i >= 0; i--){
			var item = this.items[i];

			//We ignore calculating positions of all connected containers when we're not over them
			if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
				continue;

			var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;

			if (!fast) {
				item.width = t.outerWidth();
				item.height = t.outerHeight();
			}

			var p = t.offset();
			item.left = p.left;
			item.top = p.top;
		};

		if(this.options.custom && this.options.custom.refreshContainers) {
			this.options.custom.refreshContainers.call(this);
		} else {
			for (var i = this.containers.length - 1; i >= 0; i--){
				var p = this.containers[i].element.offset();
				this.containers[i].containerCache.left = p.left;
				this.containers[i].containerCache.top = p.top;
				this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
			};
		}

	},

	_createPlaceholder: function(that) {

		var self = that || this, o = self.options;

		if(!o.placeholder || o.placeholder.constructor == String) {
			var className = o.placeholder;
			o.placeholder = {
				element: function() {

					var el = $(document.createElement(self.currentItem[0].nodeName))
						.addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
						.removeClass("ui-sortable-helper")[0];

					if(!className)
						el.style.visibility = "hidden";

					return el;
				},
				update: function(container, p) {

					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
					if(className && !o.forcePlaceholderSize) return;

					//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
					if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
					if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
				}
			};
		}

		//Create the placeholder
		self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));

		//Append it after the actual current item
		self.currentItem.after(self.placeholder);

		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
		o.placeholder.update(self, self.placeholder);

	},

	_contactContainers: function(event) {
		for (var i = this.containers.length - 1; i >= 0; i--){

			if(this._intersectsWith(this.containers[i].containerCache)) {
				if(!this.containers[i].containerCache.over) {

					if(this.currentContainer != this.containers[i]) {

						//When entering a new container, we will find the item with the least distance and append our item near it
						var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[i].floating ? 'left' : 'top'];
						for (var j = this.items.length - 1; j >= 0; j--) {
							if(!$.ui.contains(this.containers[i].element[0], this.items[j].item[0])) continue;
							var cur = this.items[j][this.containers[i].floating ? 'left' : 'top'];
							if(Math.abs(cur - base) < dist) {
								dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
							}
						}

						if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
							continue;

						this.currentContainer = this.containers[i];
						itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[i].element, true);
						this._trigger("change", event, this._uiHash());
						this.containers[i]._trigger("change", event, this._uiHash(this));

						//Update the placeholder
						this.options.placeholder.update(this.currentContainer, this.placeholder);

					}

					this.containers[i]._trigger("over", event, this._uiHash(this));
					this.containers[i].containerCache.over = 1;
				}
			} else {
				if(this.containers[i].containerCache.over) {
					this.containers[i]._trigger("out", event, this._uiHash(this));
					this.containers[i].containerCache.over = 0;
				}
			}

		};
	},

	_createHelper: function(event) {

		var o = this.options;
		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);

		if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
			$(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);

		if(helper[0] == this.currentItem[0])
			this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };

		if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
		if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());

		return helper;

	},

	_adjustOffsetFromHelper: function(obj) {
		if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;
		if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
		if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;
		if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
	},

	_getParentOffset: function() {


		//Get the offsetParent and cache its position
		this.offsetParent = this.helper.offsetParent();
		var po = this.offsetParent.offset();

		// This is a special case where we need to modify a offset calculated on start, since the following happened:
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
			po.left += this.scrollParent.scrollLeft();
			po.top += this.scrollParent.scrollTop();
		}

		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
			po = { top: 0, left: 0 };

		return {
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
		};

	},

	_getRelativeOffset: function() {

		if(this.cssPosition == "relative") {
			var p = this.currentItem.position();
			return {
				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
			};
		} else {
			return { top: 0, left: 0 };
		}

	},

	_cacheMargins: function() {
		this.margins = {
			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
		};
	},

	_cacheHelperProportions: function() {
		this.helperProportions = {
			width: this.helper.outerWidth(),
			height: this.helper.outerHeight()
		};
	},

	_setContainment: function() {

		var o = this.options;
		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
		if(o.containment == 'document' || o.containment == 'window') this.containment = [
			0 - this.offset.relative.left - this.offset.parent.left,
			0 - this.offset.relative.top - this.offset.parent.top,
			$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
		];

		if(!(/^(document|window|parent)$/).test(o.containment)) {
			var ce = $(o.containment)[0];
			var co = $(o.containment).offset();
			var over = ($(ce).css("overflow") != 'hidden');

			this.containment = [
				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
			];
		}

	},

	_convertPositionTo: function(d, pos) {

		if(!pos) pos = this.position;
		var mod = d == "absolute" ? 1 : -1;
		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);

		return {
			top: (
				pos.top																	// The absolute mouse position
				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
				- ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
			),
			left: (
				pos.left																// The absolute mouse position
				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
				- ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
			)
		};

	},

	_generatePosition: function(event) {

		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);

		// This is another very weird special case that only happens for relative elements:
		// 1. If the css position is relative
		// 2. and the scroll parent is the document or similar to the offset parent
		// we have to refresh the relative offset during the scroll so there are no jumps
		if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
			this.offset.relative = this._getRelativeOffset();
		}

		var pageX = event.pageX;
		var pageY = event.pageY;

		/*
		 * - Position constraining -
		 * Constrain the position to a mix of grid, containment.
		 */

		if(this.originalPosition) { //If we are not dragging yet, we won't check for options

			if(this.containment) {
				if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
				if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
				if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
				if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
			}

			if(o.grid) {
				var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
				pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;

				var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
				pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
			}

		}

		return {
			top: (
				pageY																// The absolute mouse position
				- this.offset.click.top													// Click offset (relative to the element)
				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
				+ ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
			),
			left: (
				pageX																// The absolute mouse position
				- this.offset.click.left												// Click offset (relative to the element)
				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
				+ ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
			)
		};

	},

	_rearrange: function(event, i, a, hardRefresh) {

		a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));

		//Various things done here to improve the performance:
		// 1. we create a setTimeout, that calls refreshPositions
		// 2. on the instance, we have a counter variable, that get's higher after every append
		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
		// 4. this lets only the last addition to the timeout stack through
		this.counter = this.counter ? ++this.counter : 1;
		var self = this, counter = this.counter;

		window.setTimeout(function() {
			if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
		},0);

	},

	_clear: function(event, noPropagation) {

		this.reverting = false;
		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
		// everything else normalized again
		var delayedTriggers = [], self = this;

		// We first have to update the dom position of the actual currentItem
		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
		if(!this._noFinalSort && this.currentItem[0].parentNode) this.placeholder.before(this.currentItem);
		this._noFinalSort = null;

		if(this.helper[0] == this.currentItem[0]) {
			for(var i in this._storedCSS) {
				if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
			}
			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
		} else {
			this.currentItem.show();
		}

		if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
		if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
		if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
			if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
			for (var i = this.containers.length - 1; i >= 0; i--){
				if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
					delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
					delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.containers[i]));
				}
			};
		};

		//Post events to containers
		for (var i = this.containers.length - 1; i >= 0; i--){
			if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
			if(this.containers[i].containerCache.over) {
				delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
				this.containers[i].containerCache.over = 0;
			}
		}

		//Do what was originally in plugins
		if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
		if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset cursor
		if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index

		this.dragging = false;
		if(this.cancelHelperRemoval) {
			if(!noPropagation) {
				this._trigger("beforeStop", event, this._uiHash());
				for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
				this._trigger("stop", event, this._uiHash());
			}
			return false;
		}

		if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());

		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);

		if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;

		if(!noPropagation) {
			for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
			this._trigger("stop", event, this._uiHash());
		}

		this.fromOutside = false;
		return true;

	},

	_trigger: function() {
		if ($.widget.prototype._trigger.apply(this, arguments) === false) {
			this.cancel();
		}
	},

	_uiHash: function(inst) {
		var self = inst || this;
		return {
			helper: self.helper,
			placeholder: self.placeholder || $([]),
			position: self.position,
			absolutePosition: self.positionAbs, //deprecated
			offset: self.positionAbs,
			item: self.currentItem,
			sender: inst ? inst.element : null
		};
	}

}));

$.extend($.ui.sortable, {
	getter: "serialize toArray",
	version: "1.7.2",
	eventPrefix: "sort",
	defaults: {
		appendTo: "parent",
		axis: false,
		cancel: ":input,option",
		connectWith: false,
		containment: false,
		cursor: 'auto',
		cursorAt: false,
		delay: 0,
		distance: 1,
		dropOnEmpty: true,
		forcePlaceholderSize: false,
		forceHelperSize: false,
		grid: false,
		handle: false,
		helper: "original",
		items: '> *',
		opacity: false,
		placeholder: false,
		revert: false,
		scroll: true,
		scrollSensitivity: 20,
		scrollSpeed: 20,
		scope: "default",
		tolerance: "intersect",
		zIndex: 1000
	}
});

})(jQuery);

/*
 * jQuery UI Draggable 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Draggables
 *
 * Depends:
 *	ui.core.js
 */
(function($) {

$.widget("ui.draggable", $.extend({}, $.ui.mouse, {

	_init: function() {

		if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
			this.element[0].style.position = 'relative';

		(this.options.addClasses && this.element.addClass("ui-draggable"));
		(this.options.disabled && this.element.addClass("ui-draggable-disabled"));

		this._mouseInit();

	},

	destroy: function() {
		if(!this.element.data('draggable')) return;
		this.element
			.removeData("draggable")
			.unbind(".draggable")
			.removeClass("ui-draggable"
				+ " ui-draggable-dragging"
				+ " ui-draggable-disabled");
		this._mouseDestroy();
	},

	_mouseCapture: function(event) {

		var o = this.options;

		if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
			return false;

		//Quit if we're not on a valid handle
		this.handle = this._getHandle(event);
		if (!this.handle)
			return false;

		return true;

	},

	_mouseStart: function(event) {

		var o = this.options;

		//Create and append the visible helper
		this.helper = this._createHelper(event);

		//Cache the helper size
		this._cacheHelperProportions();

		//If ddmanager is used for droppables, set the global draggable
		if($.ui.ddmanager)
			$.ui.ddmanager.current = this;

		/*
		 * - Position generation -
		 * This block generates everything position related - it's the core of draggables.
		 */

		//Cache the margins of the original element
		this._cacheMargins();

		//Store the helper's css position
		this.cssPosition = this.helper.css("position");
		this.scrollParent = this.helper.scrollParent();

		//The element's absolute position on the page minus margins
		this.offset = this.element.offset();
		this.offset = {
			top: this.offset.top - this.margins.top,
			left: this.offset.left - this.margins.left
		};

		$.extend(this.offset, {
			click: { //Where the click happened, relative to the element
				left: event.pageX - this.offset.left,
				top: event.pageY - this.offset.top
			},
			parent: this._getParentOffset(),
			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
		});

		//Generate the original position
		this.originalPosition = this._generatePosition(event);
		this.originalPageX = event.pageX;
		this.originalPageY = event.pageY;

		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
		if(o.cursorAt)
			this._adjustOffsetFromHelper(o.cursorAt);

		//Set a containment if given in the options
		if(o.containment)
			this._setContainment();

		//Call plugins and callbacks
		this._trigger("start", event);

		//Recache the helper size
		this._cacheHelperProportions();

		//Prepare the droppable offsets
		if ($.ui.ddmanager && !o.dropBehaviour)
			$.ui.ddmanager.prepareOffsets(this, event);

		this.helper.addClass("ui-draggable-dragging");
		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
		return true;
	},

	_mouseDrag: function(event, noPropagation) {

		//Compute the helpers position
		this.position = this._generatePosition(event);
		this.positionAbs = this._convertPositionTo("absolute");

		//Call plugins and callbacks and use the resulting position if something is returned
		if (!noPropagation) {
			var ui = this._uiHash();
			this._trigger('drag', event, ui);
			this.position = ui.position;
		}

		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);

		return false;
	},

	_mouseStop: function(event) {

		//If we are using droppables, inform the manager about the drop
		var dropped = false;
		if ($.ui.ddmanager && !this.options.dropBehaviour)
			dropped = $.ui.ddmanager.drop(this, event);

		//if a drop comes from outside (a sortable)
		if(this.dropped) {
			dropped = this.dropped;
			this.dropped = false;
		}

		if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
			var self = this;
			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
				self._trigger("stop", event);
				self._clear();
			});
		} else {
			this._trigger("stop", event);
			this._clear();
		}

		return false;
	},

	_getHandle: function(event) {

		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
		$(this.options.handle, this.element)
			.find("*")
			.andSelf()
			.each(function() {
				if(this == event.target) handle = true;
			});

		return handle;

	},

	_createHelper: function(event) {

		var o = this.options;
		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);

		if(!helper.parents('body').length)
			helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));

		if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
			helper.css("position", "absolute");

		return helper;

	},

	_adjustOffsetFromHelper: function(obj) {
		if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;
		if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
		if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;
		if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
	},

	_getParentOffset: function() {

		//Get the offsetParent and cache its position
		this.offsetParent = this.helper.offsetParent();
		var po = this.offsetParent.offset();

		// This is a special case where we need to modify a offset calculated on start, since the following happened:
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
			po.left += this.scrollParent.scrollLeft();
			po.top += this.scrollParent.scrollTop();
		}

		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
			po = { top: 0, left: 0 };

		return {
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
		};

	},

	_getRelativeOffset: function() {

		if(this.cssPosition == "relative") {
			var p = this.element.position();
			return {
				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
			};
		} else {
			return { top: 0, left: 0 };
		}

	},

	_cacheMargins: function() {
		this.margins = {
			left: (parseInt(this.element.css("marginLeft"),10) || 0),
			top: (parseInt(this.element.css("marginTop"),10) || 0)
		};
	},

	_cacheHelperProportions: function() {
		this.helperProportions = {
			width: this.helper.outerWidth(),
			height: this.helper.outerHeight()
		};
	},

	_setContainment: function() {

		var o = this.options;
		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
		if(o.containment == 'document' || o.containment == 'window') this.containment = [
			0 - this.offset.relative.left - this.offset.parent.left,
			0 - this.offset.relative.top - this.offset.parent.top,
			$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
		];

		if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
			var ce = $(o.containment)[0]; if(!ce) return;
			var co = $(o.containment).offset();
			var over = ($(ce).css("overflow") != 'hidden');

			this.containment = [
				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
			];
		} else if(o.containment.constructor == Array) {
			this.containment = o.containment;
		}

	},

	_convertPositionTo: function(d, pos) {

		if(!pos) pos = this.position;
		var mod = d == "absolute" ? 1 : -1;
		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);

		return {
			top: (
				pos.top																	// The absolute mouse position
				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
				- ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
			),
			left: (
				pos.left																// The absolute mouse position
				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
				- ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
			)
		};

	},

	_generatePosition: function(event) {

		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);

		// This is another very weird special case that only happens for relative elements:
		// 1. If the css position is relative
		// 2. and the scroll parent is the document or similar to the offset parent
		// we have to refresh the relative offset during the scroll so there are no jumps
		if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
			this.offset.relative = this._getRelativeOffset();
		}

		var pageX = event.pageX;
		var pageY = event.pageY;

		/*
		 * - Position constraining -
		 * Constrain the position to a mix of grid, containment.
		 */

		if(this.originalPosition) { //If we are not dragging yet, we won't check for options

			if(this.containment) {
				if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
				if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
				if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
				if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
			}

			if(o.grid) {
				var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
				pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;

				var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
				pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
			}

		}

		return {
			top: (
				pageY																// The absolute mouse position
				- this.offset.click.top													// Click offset (relative to the element)
				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
				+ ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
			),
			left: (
				pageX																// The absolute mouse position
				- this.offset.click.left												// Click offset (relative to the element)
				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
				+ ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
			)
		};

	},

	_clear: function() {
		this.helper.removeClass("ui-draggable-dragging");
		if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
		//if($.ui.ddmanager) $.ui.ddmanager.current = null;
		this.helper = null;
		this.cancelHelperRemoval = false;
	},

	// From now on bulk stuff - mainly helpers

	_trigger: function(type, event, ui) {
		ui = ui || this._uiHash();
		$.ui.plugin.call(this, type, [event, ui]);
		if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
		return $.widget.prototype._trigger.call(this, type, event, ui);
	},

	plugins: {},

	_uiHash: function(event) {
		return {
			helper: this.helper,
			position: this.position,
			absolutePosition: this.positionAbs, //deprecated
			offset: this.positionAbs
		};
	}

}));

$.extend($.ui.draggable, {
	version: "1.7.2",
	eventPrefix: "drag",
	defaults: {
		addClasses: true,
		appendTo: "parent",
		axis: false,
		cancel: ":input,option",
		connectToSortable: false,
		containment: false,
		cursor: "auto",
		cursorAt: false,
		delay: 0,
		distance: 1,
		grid: false,
		handle: false,
		helper: "original",
		iframeFix: false,
		opacity: false,
		refreshPositions: false,
		revert: false,
		revertDuration: 500,
		scope: "default",
		scroll: true,
		scrollSensitivity: 20,
		scrollSpeed: 20,
		snap: false,
		snapMode: "both",
		snapTolerance: 20,
		stack: false,
		zIndex: false
	}
});

$.ui.plugin.add("draggable", "connectToSortable", {
	start: function(event, ui) {

		var inst = $(this).data("draggable"), o = inst.options,
			uiSortable = $.extend({}, ui, { item: inst.element });
		inst.sortables = [];
		$(o.connectToSortable).each(function() {
			var sortable = $.data(this, 'sortable');
			if (sortable && !sortable.options.disabled) {
				inst.sortables.push({
					instance: sortable,
					shouldRevert: sortable.options.revert
				});
				sortable._refreshItems();	//Do a one-time refresh at start to refresh the containerCache
				sortable._trigger("activate", event, uiSortable);
			}
		});

	},
	stop: function(event, ui) {

		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
		var inst = $(this).data("draggable"),
			uiSortable = $.extend({}, ui, { item: inst.element });

		$.each(inst.sortables, function() {
			if(this.instance.isOver) {

				this.instance.isOver = 0;

				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)

				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
				if(this.shouldRevert) this.instance.options.revert = true;

				//Trigger the stop of the sortable
				this.instance._mouseStop(event);

				this.instance.options.helper = this.instance.options._helper;

				//If the helper has been the original item, restore properties in the sortable
				if(inst.options.helper == 'original')
					this.instance.currentItem.css({ top: 'auto', left: 'auto' });

			} else {
				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
				this.instance._trigger("deactivate", event, uiSortable);
			}

		});

	},
	drag: function(event, ui) {

		var inst = $(this).data("draggable"), self = this;

		var checkPos = function(o) {
			var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
			var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
			var itemHeight = o.height, itemWidth = o.width;
			var itemTop = o.top, itemLeft = o.left;

			return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
		};

		$.each(inst.sortables, function(i) {

			//Copy over some variables to allow calling the sortable's native _intersectsWith
			this.instance.positionAbs = inst.positionAbs;
			this.instance.helperProportions = inst.helperProportions;
			this.instance.offset.click = inst.offset.click;

			if(this.instance._intersectsWith(this.instance.containerCache)) {

				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
				if(!this.instance.isOver) {

					this.instance.isOver = 1;
					//Now we fake the start of dragging for the sortable instance,
					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
					//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
					this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
					this.instance.options.helper = function() { return ui.helper[0]; };

					event.target = this.instance.currentItem[0];
					this.instance._mouseCapture(event, true);
					this.instance._mouseStart(event, true, true);

					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
					this.instance.offset.click.top = inst.offset.click.top;
					this.instance.offset.click.left = inst.offset.click.left;
					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;

					inst._trigger("toSortable", event);
					inst.dropped = this.instance.element; //draggable revert needs that
					//hack so receive/update callbacks work (mostly)
					inst.currentItem = inst.element;
					this.instance.fromOutside = inst;

				}

				//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
				if(this.instance.currentItem) this.instance._mouseDrag(event);

			} else {

				//If it doesn't intersect with the sortable, and it intersected before,
				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
				if(this.instance.isOver) {

					this.instance.isOver = 0;
					this.instance.cancelHelperRemoval = true;

					//Prevent reverting on this forced stop
					this.instance.options.revert = false;

					// The out event needs to be triggered independently
					this.instance._trigger('out', event, this.instance._uiHash(this.instance));

					this.instance._mouseStop(event, true);
					this.instance.options.helper = this.instance.options._helper;

					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
					this.instance.currentItem.remove();
					if(this.instance.placeholder) this.instance.placeholder.remove();

					inst._trigger("fromSortable", event);
					inst.dropped = false; //draggable revert needs that
				}

			};

		});

	}
});

$.ui.plugin.add("draggable", "cursor", {
	start: function(event, ui) {
		var t = $('body'), o = $(this).data('draggable').options;
		if (t.css("cursor")) o._cursor = t.css("cursor");
		t.css("cursor", o.cursor);
	},
	stop: function(event, ui) {
		var o = $(this).data('draggable').options;
		if (o._cursor) $('body').css("cursor", o._cursor);
	}
});

$.ui.plugin.add("draggable", "iframeFix", {
	start: function(event, ui) {
		var o = $(this).data('draggable').options;
		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
			$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
			.css({
				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
				position: "absolute", opacity: "0.001", zIndex: 1000
			})
			.css($(this).offset())
			.appendTo("body");
		});
	},
	stop: function(event, ui) {
		$("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
	}
});

$.ui.plugin.add("draggable", "opacity", {
	start: function(event, ui) {
		var t = $(ui.helper), o = $(this).data('draggable').options;
		if(t.css("opacity")) o._opacity = t.css("opacity");
		t.css('opacity', o.opacity);
	},
	stop: function(event, ui) {
		var o = $(this).data('draggable').options;
		if(o._opacity) $(ui.helper).css('opacity', o._opacity);
	}
});

$.ui.plugin.add("draggable", "scroll", {
	start: function(event, ui) {
		var i = $(this).data("draggable");
		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
	},
	drag: function(event, ui) {

		var i = $(this).data("draggable"), o = i.options, scrolled = false;

		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {

			if(!o.axis || o.axis != 'x') {
				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
				else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
			}

			if(!o.axis || o.axis != 'y') {
				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
				else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
			}

		} else {

			if(!o.axis || o.axis != 'x') {
				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
			}

			if(!o.axis || o.axis != 'y') {
				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
			}

		}

		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
			$.ui.ddmanager.prepareOffsets(i, event);

	}
});

$.ui.plugin.add("draggable", "snap", {
	start: function(event, ui) {

		var i = $(this).data("draggable"), o = i.options;
		i.snapElements = [];

		$(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
			var $t = $(this); var $o = $t.offset();
			if(this != i.element[0]) i.snapElements.push({
				item: this,
				width: $t.outerWidth(), height: $t.outerHeight(),
				top: $o.top, left: $o.left
			});
		});

	},
	drag: function(event, ui) {

		var inst = $(this).data("draggable"), o = inst.options;
		var d = o.snapTolerance;

		var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;

		for (var i = inst.snapElements.length - 1; i >= 0; i--){

			var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
				t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;

			//Yes, I know, this is insane ;)
			if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
				if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
				inst.snapElements[i].snapping = false;
				continue;
			}

			if(o.snapMode != 'inner') {
				var ts = Math.abs(t - y2) <= d;
				var bs = Math.abs(b - y1) <= d;
				var ls = Math.abs(l - x2) <= d;
				var rs = Math.abs(r - x1) <= d;
				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
			}

			var first = (ts || bs || ls || rs);

			if(o.snapMode != 'outer') {
				var ts = Math.abs(t - y1) <= d;
				var bs = Math.abs(b - y2) <= d;
				var ls = Math.abs(l - x1) <= d;
				var rs = Math.abs(r - x2) <= d;
				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
			}

			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);

		};

	}
});

$.ui.plugin.add("draggable", "stack", {
	start: function(event, ui) {

		var o = $(this).data("draggable").options;

		var group = $.makeArray($(o.stack.group)).sort(function(a,b) {
			return (parseInt($(a).css("zIndex"),10) || o.stack.min) - (parseInt($(b).css("zIndex"),10) || o.stack.min);
		});

		$(group).each(function(i) {
			this.style.zIndex = o.stack.min + i;
		});

		this[0].style.zIndex = o.stack.min + group.length;

	}
});

$.ui.plugin.add("draggable", "zIndex", {
	start: function(event, ui) {
		var t = $(ui.helper), o = $(this).data("draggable").options;
		if(t.css("zIndex")) o._zIndex = t.css("zIndex");
		t.css('zIndex', o.zIndex);
	},
	stop: function(event, ui) {
		var o = $(this).data("draggable").options;
		if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
	}
});

})(jQuery);


/*
 * jQuery UI Slider 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Slider
 *
 * Depends:
 *	ui.core.js
 */

(function($) {

$.widget("ui.slider", $.extend({}, $.ui.mouse, {

	_init: function() {

		var self = this, o = this.options;
		this._keySliding = false;
		this._handleIndex = null;
		this._detectOrientation();
		this._mouseInit();

		this.element
			.addClass("ui-slider"
				+ " ui-slider-" + this.orientation
				+ " ui-widget"
				+ " ui-widget-content"
				+ " ui-corner-all");

		this.range = $([]);

		if (o.range) {

			if (o.range === true) {
				this.range = $('<div></div>');
				if (!o.values) o.values = [this._valueMin(), this._valueMin()];
				if (o.values.length && o.values.length != 2) {
					o.values = [o.values[0], o.values[0]];
				}
			} else {
				this.range = $('<div></div>');
			}

			this.range
				.appendTo(this.element)
				.addClass("ui-slider-range");

			if (o.range == "min" || o.range == "max") {
				this.range.addClass("ui-slider-range-" + o.range);
			}

			// note: this isn't the most fittingly semantic framework class for this element,
			// but worked best visually with a variety of themes
			this.range.addClass("ui-widget-header");

		}

		if ($(".ui-slider-handle", this.element).length == 0)
			$('<a href="#"></a>')
				.appendTo(this.element)
				.addClass("ui-slider-handle");

		if (o.values && o.values.length) {
			while ($(".ui-slider-handle", this.element).length < o.values.length)
				$('<a href="#"></a>')
					.appendTo(this.element)
					.addClass("ui-slider-handle");
		}

		this.handles = $(".ui-slider-handle", this.element)
			.addClass("ui-state-default"
				+ " ui-corner-all");

		this.handle = this.handles.eq(0);

		this.handles.add(this.range).filter("a")
			.click(function(event) {
				event.preventDefault();
			})
			.hover(function() {
				if (!o.disabled) {
					$(this).addClass('ui-state-hover');
				}
			}, function() {
				$(this).removeClass('ui-state-hover');
			})
			.focus(function() {
				if (!o.disabled) {
					$(".ui-slider .ui-state-focus").removeClass('ui-state-focus'); $(this).addClass('ui-state-focus');
				} else {
					$(this).blur();
				}
			})
			.blur(function() {
				$(this).removeClass('ui-state-focus');
			});

		this.handles.each(function(i) {
			$(this).data("index.ui-slider-handle", i);
		});

		this.handles.keydown(function(event) {

			var ret = true;

			var index = $(this).data("index.ui-slider-handle");

			if (self.options.disabled)
				return;

			switch (event.keyCode) {
				case $.ui.keyCode.HOME:
				case $.ui.keyCode.END:
				case $.ui.keyCode.UP:
				case $.ui.keyCode.RIGHT:
				case $.ui.keyCode.DOWN:
				case $.ui.keyCode.LEFT:
					ret = false;
					if (!self._keySliding) {
						self._keySliding = true;
						$(this).addClass("ui-state-active");
						self._start(event, index);
					}
					break;
			}

			var curVal, newVal, step = self._step();
			if (self.options.values && self.options.values.length) {
				curVal = newVal = self.values(index);
			} else {
				curVal = newVal = self.value();
			}

			switch (event.keyCode) {
				case $.ui.keyCode.HOME:
					newVal = self._valueMin();
					break;
				case $.ui.keyCode.END:
					newVal = self._valueMax();
					break;
				case $.ui.keyCode.UP:
				case $.ui.keyCode.RIGHT:
					if(curVal == self._valueMax()) return;
					newVal = curVal + step;
					break;
				case $.ui.keyCode.DOWN:
				case $.ui.keyCode.LEFT:
					if(curVal == self._valueMin()) return;
					newVal = curVal - step;
					break;
			}

			self._slide(event, index, newVal);

			return ret;

		}).keyup(function(event) {

			var index = $(this).data("index.ui-slider-handle");

			if (self._keySliding) {
				self._stop(event, index);
				self._change(event, index);
				self._keySliding = false;
				$(this).removeClass("ui-state-active");
			}

		});

		this._refreshValue();

	},

	destroy: function() {

		this.handles.remove();
		this.range.remove();

		this.element
			.removeClass("ui-slider"
				+ " ui-slider-horizontal"
				+ " ui-slider-vertical"
				+ " ui-slider-disabled"
				+ " ui-widget"
				+ " ui-widget-content"
				+ " ui-corner-all")
			.removeData("slider")
			.unbind(".slider");

		this._mouseDestroy();

	},

	_mouseCapture: function(event) {

		var o = this.options;

		if (o.disabled)
			return false;

		this.elementSize = {
			width: this.element.outerWidth(),
			height: this.element.outerHeight()
		};
		this.elementOffset = this.element.offset();

		var position = { x: event.pageX, y: event.pageY };
		var normValue = this._normValueFromMouse(position);

		var distance = this._valueMax() - this._valueMin() + 1, closestHandle;
		var self = this, index;
		this.handles.each(function(i) {
			var thisDistance = Math.abs(normValue - self.values(i));
			if (distance > thisDistance) {
				distance = thisDistance;
				closestHandle = $(this);
				index = i;
			}
		});

		// workaround for bug #3736 (if both handles of a range are at 0,
		// the first is always used as the one with least distance,
		// and moving it is obviously prevented by preventing negative ranges)
		if(o.range == true && this.values(1) == o.min) {
			closestHandle = $(this.handles[++index]);
		}

		this._start(event, index);

		self._handleIndex = index;

		closestHandle
			.addClass("ui-state-active")
			.focus();
		
		var offset = closestHandle.offset();
		var mouseOverHandle = !$(event.target).parents().andSelf().is('.ui-slider-handle');
		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
			left: event.pageX - offset.left - (closestHandle.width() / 2),
			top: event.pageY - offset.top
				- (closestHandle.height() / 2)
				- (parseInt(closestHandle.css('borderTopWidth'),10) || 0)
				- (parseInt(closestHandle.css('borderBottomWidth'),10) || 0)
				+ (parseInt(closestHandle.css('marginTop'),10) || 0)
		};

		normValue = this._normValueFromMouse(position);
		this._slide(event, index, normValue);
		return true;

	},

	_mouseStart: function(event) {
		return true;
	},

	_mouseDrag: function(event) {

		var position = { x: event.pageX, y: event.pageY };
		var normValue = this._normValueFromMouse(position);
		
		this._slide(event, this._handleIndex, normValue);

		return false;

	},

	_mouseStop: function(event) {

		this.handles.removeClass("ui-state-active");
		this._stop(event, this._handleIndex);
		this._change(event, this._handleIndex);
		this._handleIndex = null;
		this._clickOffset = null;

		return false;

	},
	
	_detectOrientation: function() {
		this.orientation = this.options.orientation == 'vertical' ? 'vertical' : 'horizontal';
	},

	_normValueFromMouse: function(position) {

		var pixelTotal, pixelMouse;
		if ('horizontal' == this.orientation) {
			pixelTotal = this.elementSize.width;
			pixelMouse = position.x - this.elementOffset.left - (this._clickOffset ? this._clickOffset.left : 0);
		} else {
			pixelTotal = this.elementSize.height;
			pixelMouse = position.y - this.elementOffset.top - (this._clickOffset ? this._clickOffset.top : 0);
		}

		var percentMouse = (pixelMouse / pixelTotal);
		if (percentMouse > 1) percentMouse = 1;
		if (percentMouse < 0) percentMouse = 0;
		if ('vertical' == this.orientation)
			percentMouse = 1 - percentMouse;

		var valueTotal = this._valueMax() - this._valueMin(),
			valueMouse = percentMouse * valueTotal,
			valueMouseModStep = valueMouse % this.options.step,
			normValue = this._valueMin() + valueMouse - valueMouseModStep;

		if (valueMouseModStep > (this.options.step / 2))
			normValue += this.options.step;

		// Since JavaScript has problems with large floats, round
		// the final value to 5 digits after the decimal point (see #4124)
		return parseFloat(normValue.toFixed(5));

	},

	_start: function(event, index) {
		var uiHash = {
			handle: this.handles[index],
			value: this.value()
		};
		if (this.options.values && this.options.values.length) {
			uiHash.value = this.values(index);
			uiHash.values = this.values();
		}
		this._trigger("start", event, uiHash);
	},

	_slide: function(event, index, newVal) {

		var handle = this.handles[index];

		if (this.options.values && this.options.values.length) {

			var otherVal = this.values(index ? 0 : 1);

			if ((this.options.values.length == 2 && this.options.range === true) && 
				((index == 0 && newVal > otherVal) || (index == 1 && newVal < otherVal))){
 				newVal = otherVal;
			}

			if (newVal != this.values(index)) {
				var newValues = this.values();
				newValues[index] = newVal;
				// A slide can be canceled by returning false from the slide callback
				var allowed = this._trigger("slide", event, {
					handle: this.handles[index],
					value: newVal,
					values: newValues
				});
				var otherVal = this.values(index ? 0 : 1);
				if (allowed !== false) {
					this.values(index, newVal, ( event.type == 'mousedown' && this.options.animate ), true);
				}
			}

		} else {

			if (newVal != this.value()) {
				// A slide can be canceled by returning false from the slide callback
				var allowed = this._trigger("slide", event, {
					handle: this.handles[index],
					value: newVal
				});
				if (allowed !== false) {
					this._setData('value', newVal, ( event.type == 'mousedown' && this.options.animate ));
				}
					
			}

		}

	},

	_stop: function(event, index) {
		var uiHash = {
			handle: this.handles[index],
			value: this.value()
		};
		if (this.options.values && this.options.values.length) {
			uiHash.value = this.values(index);
			uiHash.values = this.values();
		}
		this._trigger("stop", event, uiHash);
	},

	_change: function(event, index) {
		var uiHash = {
			handle: this.handles[index],
			value: this.value()
		};
		if (this.options.values && this.options.values.length) {
			uiHash.value = this.values(index);
			uiHash.values = this.values();
		}
		this._trigger("change", event, uiHash);
	},

	value: function(newValue) {

		if (arguments.length) {
			this._setData("value", newValue);
			this._change(null, 0);
		}

		return this._value();

	},

	values: function(index, newValue, animated, noPropagation) {

		if (arguments.length > 1) {
			this.options.values[index] = newValue;
			this._refreshValue(animated);
			if(!noPropagation) this._change(null, index);
		}

		if (arguments.length) {
			if (this.options.values && this.options.values.length) {
				return this._values(index);
			} else {
				return this.value();
			}
		} else {
			return this._values();
		}

	},

	_setData: function(key, value, animated) {

		$.widget.prototype._setData.apply(this, arguments);

		switch (key) {
			case 'disabled':
				if (value) {
					this.handles.filter(".ui-state-focus").blur();
					this.handles.removeClass("ui-state-hover");
					this.handles.attr("disabled", "disabled");
				} else {
					this.handles.removeAttr("disabled");
				}
			case 'orientation':

				this._detectOrientation();
				
				this.element
					.removeClass("ui-slider-horizontal ui-slider-vertical")
					.addClass("ui-slider-" + this.orientation);
				this._refreshValue(animated);
				break;
			case 'value':
				this._refreshValue(animated);
				break;
		}

	},

	_step: function() {
		var step = this.options.step;
		return step;
	},

	_value: function() {

		var val = this.options.value;
		if (val < this._valueMin()) val = this._valueMin();
		if (val > this._valueMax()) val = this._valueMax();

		return val;

	},

	_values: function(index) {

		if (arguments.length) {
			var val = this.options.values[index];
			if (val < this._valueMin()) val = this._valueMin();
			if (val > this._valueMax()) val = this._valueMax();

			return val;
		} else {
			return this.options.values;
		}

	},

	_valueMin: function() {
		var valueMin = this.options.min;
		return valueMin;
	},

	_valueMax: function() {
		var valueMax = this.options.max;
		return valueMax;
	},

	_refreshValue: function(animate) {

		var oRange = this.options.range, o = this.options, self = this;

		if (this.options.values && this.options.values.length) {
			var vp0, vp1;
			this.handles.each(function(i, j) {
				var valPercent = (self.values(i) - self._valueMin()) / (self._valueMax() - self._valueMin()) * 100;
				var _set = {}; _set[self.orientation == 'horizontal' ? 'left' : 'bottom'] = valPercent + '%';
				$(this).stop(1,1)[animate ? 'animate' : 'css'](_set, o.animate);
				if (self.options.range === true) {
					if (self.orientation == 'horizontal') {
						(i == 0) && self.range.stop(1,1)[animate ? 'animate' : 'css']({ left: valPercent + '%' }, o.animate);
						(i == 1) && self.range[animate ? 'animate' : 'css']({ width: (valPercent - lastValPercent) + '%' }, { queue: false, duration: o.animate });
					} else {
						(i == 0) && self.range.stop(1,1)[animate ? 'animate' : 'css']({ bottom: (valPercent) + '%' }, o.animate);
						(i == 1) && self.range[animate ? 'animate' : 'css']({ height: (valPercent - lastValPercent) + '%' }, { queue: false, duration: o.animate });
					}
				}
				lastValPercent = valPercent;
			});
		} else {
			var value = this.value(),
				valueMin = this._valueMin(),
				valueMax = this._valueMax(),
				valPercent = valueMax != valueMin
					? (value - valueMin) / (valueMax - valueMin) * 100
					: 0;
			var _set = {}; _set[self.orientation == 'horizontal' ? 'left' : 'bottom'] = valPercent + '%';
			this.handle.stop(1,1)[animate ? 'animate' : 'css'](_set, o.animate);

			(oRange == "min") && (this.orientation == "horizontal") && this.range.stop(1,1)[animate ? 'animate' : 'css']({ width: valPercent + '%' }, o.animate);
			(oRange == "max") && (this.orientation == "horizontal") && this.range[animate ? 'animate' : 'css']({ width: (100 - valPercent) + '%' }, { queue: false, duration: o.animate });
			(oRange == "min") && (this.orientation == "vertical") && this.range.stop(1,1)[animate ? 'animate' : 'css']({ height: valPercent + '%' }, o.animate);
			(oRange == "max") && (this.orientation == "vertical") && this.range[animate ? 'animate' : 'css']({ height: (100 - valPercent) + '%' }, { queue: false, duration: o.animate });
		}

	}
	
}));

$.extend($.ui.slider, {
	getter: "value values",
	version: "1.7.2",
	eventPrefix: "slide",
	defaults: {
		animate: false,
		delay: 0,
		distance: 0,
		max: 100,
		min: 0,
		orientation: 'horizontal',
		range: false,
		step: 1,
		value: 0,
		values: null
	}
});

})(jQuery);

/**
 * jQuery Plugin FlyDOM v3.0
 *
 * Create DOM elements on the fly and automatically append or prepend them to another DOM object.
 * There are also template functions (tplAppend and tplPrepend) that can take a simple HTML structure
 * and apply a JSON object to it to make creating layouts MUCH easier.
 *
 * This plugin was inspired by "Oslow" [http://mg.to/2006/02/27/easy-dom-creation-for-jquery-and-prototype#comment-176],
 * and since I could not get his code to work, I decided I write my own plugin. My hope is that this
 * version will be easier to understand and maintain with future versions of jQuery.
 *
 * Copyright (c) 2007 Ken Stanley [dohpaz at gmail dot com]
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * @version     3.0.5
 *
 * @author      Ken Stanley [dohpaz at gmail dot com]
 * @copyright   (C) 2007. All rights reserved.
 *
 * @license     http://www.opensource.org/licenses/mit-license.php
 * @license     http://www.opensource.org/licenses/gpl-license.php
 *
 * @package     jQuery Plugins
 * @subpackage  FlyDOM
 *
 * @todo        Cache basic elements that are created, and if an already existing basic element is
 *              asked to be created an additional time, use a copy of the cached element to build from.
 */

/**
 * Create DOM elements on the fly and automatically append them to the current DOM obejct
 *
 * @uses    jQuery
 * @uses    function convertCamel()
 *
 * @param   string  element - The name of the DOM element to create (i.e., img, table, a, etc)
 * @param   object  attrs   - An optional object of attributes to apply to the element
 * @param   array   content - An optional array of content (or element children) to append to element
 *
 * @return  jQuery  element - The jQuery object representing the new element
 *
 * @since   1.0
 */
jQuery.fn.createAppend = function(element, attrs, content)
{

    // This helps me remember what 'this' is later on.
    var parentElement = this[0];

    // I *hate* exceptions
    if (jQuery.browser.msie && element == 'input' && attrs.type) {

        // IE will not allow you to modify the type attribute after an element is
        // created, so we must create the input element with the type attribute.
        var element = document.createElement('<' + element + ' type="' + attrs.type + '" />');

    } else {

        // This is for every other element
        var element = document.createElement(element);

    };

    // Check to see if we are using IE, and trying to append a TR to a TABLE.
    if (jQuery.browser.msie && parentElement.nodeName.toLowerCase() == 'table' && element.nodeName.toLowerCase() == 'tr') {

        // Check to see if we already have a tbody element in the table
        if (parentElement.parentNode.getElementsByTagName('tbody')[0]) {

            // Use the existing tbody
            var tbody = parentElement.getElementsByTagName('tbody')[0];

        } else {

            // Create a new tbody
            var tbody = parentElement.appendChild(document.createElement('tbody'));

        };

        // Append our TR to our TBODY and continue
        var element = tbody.appendChild(element);

    } else {

        // Add the element directly to the parentElement
        var element = parentElement.appendChild(element);

    };

    // Parse our attributes into our new element
    element = __FlyDOM_parseAttrs(element, attrs);

    // Determine what to do with our red-headed stepchild.
    if (typeof content == 'object' && content != null) {

        // Loop through content and create child elements
        for (var i = 0; i < content.length; i = i + 3) {

            jQuery(element).createAppend(content[i], content[i + 1] || {}, content[i + 2] || []);

        };

    // Add as text
    } else if (content != null) {

        element = __FlyDOM_setText(element, content);

    };

    // Return the newly appended element to the caller
    return jQuery(element);

}

/**
 * Create DOM elements on the fly and automatically prepend them to the current DOM obejct
 *
 * @uses    jQuery
 * @uses    createAppend()
 *
 * @param   string  element - The name of the DOM element to create (i.e., img, table, a, etc)
 * @param   object  attrs   - An optional object of attributes to apply to the element
 * @param   array   content - An optional array of content (or element children) to append to element
 * @return  jQuery  element - The jQuery object representing the new element
 *
 * @since   1.0
 */
jQuery.fn.createPrepend = function(element, attrs, content)
{

    // Create our DOM element
    var element     = document.createElement(element);

    // If we do not have a child node, just append the new element
    if (this[0].hasChildNodes() == false) {

        var element = this[0].appendChild(element);

    };

    // Parse our attributes into our new element
    element = __FlyDOM_parseAttrs(element, attrs);

    // Determine what to do with our red-headed stepchild.
    if (typeof content == 'object' && content != null) {

        // Loop through the content and append any children
        for (var i = 0; i < content.length; i = i + 3) {

            jQuery(element).createAppend(content[i], content[i + 1] || {}, content[i + 2] || []);

        };

    // Add as text
    } else if (content != null) {

        element = __FlyDOM_setText(element, content);

    };

    // Here we check to see if this element has children, and if so,
    // we will insert it before the first child node.
    if (this[0].hasChildNodes() == true) {

        var element = this[0].insertBefore(element, this[0].firstChild);

    };

    // Return the newly appended element to the caller
    return jQuery(element);

}

/**
 * Create DOM elements on the fly using a simple template system, and then append the new element(s) to
 * the end of the calling object.
 *
 * @uses jQuery
 * @uses createAppend()
 *
 * @param   object  json    - A JSON-formatted object that holds the dynamic data
 * @param   array   tpl     - An array containing the element(s) to append to the caller
 * @return  jQuery  self    - The jQuery object representing the new element(s)
 *
 * @since   2.0
 */
jQuery.fn.tplAppend = function(json, tpl)
{

    // Make sure that we have an array to work with
    if (json.constructor != Array) { json = [ json ]; };

    // Don't try to do anything if we have nothing to do
    if (json.length == 0) { return false; };

    // Loop through our JSON "rows"
    for (var i = 0; i < json.length; i++) {

        // Apply the data to the template and get our results
        var results = tpl.apply(json[i]);

        // Just like with createAppend/createPrepend; this is the best way to
        // loop through and create our new element(s).
        for (var j = 0; j < results.length; j = j + 3) {

            jQuery(this).createAppend(results[j], results[j + 1], results[j + 2]);

        };

    };

    // Return ourself for chaining
    return self;

}
jQuery.fn.tplAppendLang = function(json, tpl, lang)
{

    // Make sure that we have an array to work with
    if (json.constructor != Array) { json = [ json ]; };

    // Don't try to do anything if we have nothing to do
    if (json.length == 0) { return false; };

    // Loop through our JSON "rows"
    for (var i = 0; i < json.length; i++) {

		if (lang != undefined) {
			json[i].lang = lang;
		}
        // Apply the data to the template and get our results
        var results = tpl.apply(json[i]);

        // Just like with createAppend/createPrepend; this is the best way to
        // loop through and create our new element(s).
        for (var j = 0; j < results.length; j = j + 3) {

            jQuery(this).createAppend(results[j], results[j + 1], results[j + 2]);

        };

    };

    // Return ourself for chaining
    return self;

}

/**
 * Create DOM elements on the fly using a simple template system, and then prepend the new element(s) to
 * the beginning of the calling object. The elements will first be appended to a temporary div container,
 * and then prepended before the first child of the parent element.
 *
 * @uses jQuery
 * @uses createAppend()
 *
 * @param   object  json    - A JSON-formatted object that holds the dynamic data
 * @param   array   tpl     - An array containing the element(s) to prepend to the caller
 * @return  jQuery  self    - The jQuery object representing the new element(s)
 *
 * @since   2.0
 */
jQuery.fn.tplPrepend = function(json, tpl) {

    // This will allow 'this' to go inside of a .each() loop
    var self = this[0];

    // Make sure that we have an array to work with
    if (json.constructor != Array) { json = [ json ]; };

    // Don't try to do anything if we have nothing to do
    if (json.length == 0) { return false; };

    // Here we create a div and insert it before the element we're
    // prepending to
    var div = document.createElement('div');

    // Loop through our JSON "rows"
    for (var i = 0; i < json.length; i++) {

        // Apply the data to the template and get our results
        var results = tpl.apply(json[i]);

        // Just like with createAppend/createPrepend; this is the best way to
        // loop through and create our new element(s).
        for (var j = 0; j < results.length; j = j + 3) {

            jQuery(div).createAppend(results[j], results[j + 1], results[j + 2]);

        };

    };

    // Apply each child node of the div container starting from the last one
    // This will ensure that all elements get applied as expected, and still
    // be readable from top to bottom.
    for (i = div.childNodes.length - 1; i >= 0; i--) {

        if (jQuery.browser.msie && self.nodeName.toLowerCase() == 'table' && div.childNodes[i].nodeName.toLowerCase() == 'tr') {

            if (self.getElementsByTagName('tbody')[0]) {

                var tbodyElement = self.getElementsByTagName('tbody')[0];
                tbodyElement.insertBefore(div.childNodes[i], tbodyElement.firstChild);

            } else {

                var tbodyElement = self.insertBefore(document.createElement('tbody'), self.firstChild);
                tbodyElement.appendChild(tbodyElement.appendChild(div.childNodes[i]));

            };
        } else {

            self.insertBefore(div.childNodes[i], self.firstChild);

        };

    };

    // Return ourself for chaining
    return jQuery(self);

};

/**
 * Convert a hyphenated set of words into one camel cased word. For example,
 * the hyphenated set of words 'border-left-width' would turn into 'borderLeftWidth'.
 *
 * @param   string  hyphenatedText  - The text to convert into camel case
 *
 * @return  string
 *
 * @since   3.0
 */
String.prototype.toCamelCase = function()
{

    var self = this;

    if (self.indexOf('-') > 0) {

        var parts = self.split('-');

        // Start the new text with the first word
        self = parts[0];

        // We skip over the first word, and capitalize
        // each word after.
        for (i = 1; i < parts.length; i++) {

            // Uppercase the first letter, and ensure the rest is lowercase.
            self += parts[i].substr(0, 1).toUpperCase() + parts[i].substr(1).toLowerCase();

        };

    };

    return self;

};

/**
 * Trims the whitespace from the beginning and end of a string.
 * This is the same exact method from the jQuery library, but
 * is put here to avoid having to call jQuery to do this one
 * simple thing.
 *
 * @param   string  text    - The text to trim
 *
 * @return  string
 *
 * @since   3.0
 */
String.prototype.trim = function()
{

    return this.replace(/^\s+|\s+$/g, '');

};

/**
 * Parse the attributes of element and return the element modified with
 * attrs.
 *
 * @uses    function toCamelCase()
 * @uses    function trim()
 *
 * @return  element
 *
 * @since   3.0
 */
__FlyDOM_parseAttrs = function(element, attrs)
{

    // Attach any attributes for this element
    for (attr in attrs) {

        // Break the styles up into a parameters array
        var attrName    = attr;
        var attrValue   = attrs[attr];

        switch (attrName) {

            // Styles are special because the DOM holds style information in an object.
            case 'style':

                if (typeof attrValue == 'string') {

                    var params = attrValue.split(';');

                    // Loop through each set of properties
                    for (var i = 0; i < params.length; i++) {

                        // Check to make sure someone (like myself) didn't end the value with a
                        // semi-colon.
                        if (params[i].trim() != '') {

                            // This is just to ease my burden of reading and typing :)
                            var styleName   = params[i].split(':')[0].trim();
                            var styleValue  = params[i].split(':')[1].trim();

                            // Take into account that styles with hyphens in the name need
                            // to be converted into camelCase.
                            styleName = styleName.toCamelCase();

                            // Don't try to apply the style if it is empty (this happens if
                            // the value of the attribute ends with a semi-colon.
                            if (styleName != '') {

                                // Apply each name/value pair, after removing any whitespace
                                element.style[styleName] = styleValue;

                            };

                        };

                    };

                } else if (typeof attrValue == 'object') {

                    for (styleName in attrValue) {

                        // Take into account that styles with hyphens in the name need
                        // to be converted into camelCase.
                        var styleNameCamel = styleName.toCamelCase();

                        if (styleName.trim() != '') {

                            element.style[styleNameCamel] = attrValue[styleName];

                        };

                    };

                };
                break;

            // Other attributes are treated as strings.
            default:

                // Check for any on* events
                if (attrName.substr(0, 2) == 'on') {

                    // Get the type of on event
                    var event = attrName.substr(2);

                    // Determine whether we need to create an anonymous function,
                    // or if the user was kind enough to do it for us.
                    attrValue = (typeof attrValue != 'function') ? eval('function() { ' + attrValue + '}') : attrValue;

                    // Bind the function to the event
                    jQuery(element).bind(event, attrValue);

                } else {

                    // Everything else (I hope) :)
                    element[attrName.toCamelCase()] = attrValue;

                }

        };

    };

    return element;

};

/**
 * Determines whether content should be treated as HTML or plain text,
 * and appended to element.
 *
 * @return  element
 *
 * @since   3.0
 */
__FlyDOM_setText = function(element, content)
{

    // Check for HTML tags or HTML entities.
    var isHtml = /(<\S[^><]*>)|(&.+;)/g;

    // Determine whether the text contains any HTML or entities
    // An exception is made for <textarea></textarea>; all text must be treated as text.
    if (content.match(isHtml) != null && element.tagName.toUpperCase() != 'TEXTAREA') {

        element.innerHTML = content;

    } else {

        // Create a text node from the content
        var textNode = document.createTextNode(content);

        // Add the text node to the element
        element.appendChild(textNode);

    };

    return element;

};
/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * Create a cookie with the given name and value and other optional parameters.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Set the value of a cookie.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 * @desc Create a cookie with all available options.
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Create a session cookie.
 * @example $.cookie('the_cookie', null);
 * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 *       used when the cookie was set.
 *
 * @param String name The name of the cookie.
 * @param String value The value of the cookie.
 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @type undefined
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};
/*	SWFObject v2.2 <http://code.google.com/p/swfobject/> 
	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
*/
var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();
var RegExpLib = {
	zip			:	new RegExp(/(^\d{5}$)|(^\d{5}-\d{4}$)/),
	email		:	new RegExp(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/),
	url			:	new RegExp(/^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/),
	user		:	new RegExp(/^([a-z0-9\_\-])+$/i),
	time_long	:	new RegExp(/^(\d{1,2}):(\d{1,2})+\s+(am|pm)$/i),
	time_short	:	new RegExp(/^(\d{1,2}):(\d{1,2})$/i),
	date_iso	:	new RegExp(/^(\d{2})\/(\d{2})\/(\d{4})$/i)
};
var check = {
	url			:function(str)		{	return RegExpLib.url.test(str);			},
    zip			:function(code)		{	return RegExpLib.zip.test(code);		},	
	email		:function(str)		{	return RegExpLib.email.test(str);		},
	len			:function(str,len)	{	return str.length >= len;				},
	gt			:function(a,b)		{	return a > b;							},
	min_len		:function(str, len)	{	return str.length < len;				},
	max_length	:function(str, len)	{	return str.length > len;				},
	exact_length:function(str, len)	{	return str.length == len;				},
	empty		:function(str)		{	return str.replace(/\s/g,"") == "";		},
	match		:function(one, two)	{	return one == two;						},
	user		:function(str)		{	return RegExpLib.user.test(str);		},
	time_long	:function(str)		{	return RegExpLib.time_long.test(str);	},
	time_short	:function(str)		{	return RegExpLib.time_short.test(str);	},
	date_iso	:function(str)		{	return RegExpLib.date_iso.test(str);	},
	zero		:function(str)		{	return str == 0;						}
}
/* state model */
var StateModel = function ()
{
	var self = this;

	this.log = function(id, msg, type) {
		self.id = "state_handler_wrap";//id;
		/*if (type != undefined) {
			var html = "<div class='s_server_message_holder clearfix'>";
			html += "<div class='s_server_message_"+type+"'>";
			html += "<span class='d_top_left'></span>";
			html += "<span class='d_top_right'></span>";
			html += "<p>"+msg+"</p>";
			html += "<span class='d_bottom_right'></span>";
			html += "</div>";
			html += "</div>";
			$("#"+id).html(html);
		} else {
			$("#"+id).addClass("ui-state-highlight").html(msg);
		}*/
		$("#state_handler_wrap").css({
				width		:	'320px',
				left		:	(clientWidth() / 2 - 120 / 2) + scrollLeft(),
				top			:	(clientHeight() / 2 - 50 / 2 ) + scrollTop(),
				position	:	"absolute",
				'z-index'	:	10001
			}).show();
		$("#state_handler_content").text(msg);
		this._log_timer_ = setTimeout(self.reset_log, 5000);
	};
	this.reset_log = function() {
		//$("#"+self.id).removeClass("ui-state-highlight").empty();
		$("#state_handler_content").text('');
		$("#state_handler_wrap").hide();
	};
	$("#close_state_handler_button").live("click", function(e){
		e.preventDefault();
		self.reset_log();
	});
}
var state_obj = new StateModel();
delete StateModel;
javaEnabled = navigator.javaEnabled() ? 1 : 0;
javaEnabled = 0;

var DownloadModel = function(parent)
{
	var handle	=	this;
	var self	=	this;
	var gate	=	parent.gate;

	this.parent	=	parent;
	
	var log		=	function (obj) {
		state_obj.log(obj.target || '', obj.msg || '', obj.state || 1);
	};

	var remove_file = function (obj) {
		var id = Number(obj.type == "click" ? obj.target.id.split("_")[1] : obj);
		if (id < 0) return;
		var parent = $('#downlad_queue_item_' + id);
		$.post(gate, {act: 'download_remove_file', url: $('.url', parent).text()}, function (data) {
				if (data.state) {
					$('.download_selector', parent).removeAttr('checked');
					$(parent).remove();
					if ($("#download_list_container tr").length < 2){
						self.isQueueWindowOpened = 0;
						self.get_queue_details();
					}
					get_stat();


					//$('#download_queue_stats').html(data.content);
					//if (data.counter < 1) {
					//	self.isQueueWindowOpened = 0;
					//	self.get_queue_details();
					//}
				} else {

				}
			},
			"json"
		);
	};

	this.download_all = function () {
		if ($(".library_item_checkbox:checked").length  == 0) {
			alert(language.validation.please_select_at_list_one_item);
			return;
		}
		var obj = {
			items	:	[]
		};
		$.each($(".library_item_checkbox:checked"), function () {
			var id = $(this).val();
			var item = $('#library_item_' + id);
			var url = $('.url', item).text();
			var url_engine = $('.url_engine', item).text().replace(/\W+/g,' ');
			var title = $('.title', item).text().replace(/\W+/g,' ');
			var description = $('.description', item).text().replace(/\W+/g,' ');
			var artist = $('.artist', item).text().replace(/\W+/g,' ');
			var album = $('.album', item).text().replace(/\W+/g,' ');
			
			var target = $('.download_list_template').clone().appendTo('#download_list_container').removeAttr('class').attr('class', 'download_row');
			var filename = title;
			if (artist != '' && artist != 'n a') {
				var filename = artist + ' - ' + filename;
			}
			if (album != '' && album != 'n a') {
				var filename = filename + ' [' + album + ']';
			}
			if (description != '' && description != 'n a') {
				var filename = filename + ' (' + description + ')';
			}
			$('.url', target).text(url);
			$('.url_engine', target).text(url_engine);
			$('.filename', target).text(filename);
		});
		$("#download_list_wrap, #download_window").css({
					width		:	'500px',
					height		:	'200px',
					left		:	(clientWidth() / 2 - (500 / 2)) + scrollLeft(),
					top			:	(clientHeight() / 2 - (200 / 2)) + scrollTop(),
					position	:	"absolute"
		}).show();
		$("#atdh").unbind("click").click(function(e){
			e.preventDefault();
			self.download_all_hide();
		});
		$("#download_add_to_queue, #button_download_queue").show().unbind("click").click(function(e){
			e.preventDefault();
			self.download_all_queue();
		});
	};

	this.download_all_hide = function() {
		this.item_id	=	null;
		$("#download_list_wrap, #download_window").hide();
		$("#download_add_to_queue, #button_download_queue").hide();
		$("#download_list_container").empty();
		get_stat();
	}

	this.download_all_queue = function() {
		var obj = {
			act		:	'add_to_download_queue',
			items	:	0
		};
		var i = 0;
		$.each($("#download_list_container .download_row"), function () {
			obj['url' + i] = $('.url', this).text();
			obj['engine' + i] = $('.url_engine', this).text();
			obj['format' + i] = $('.format option:selected', this).val();
			obj['filename' + i] = $('.filename', this).text();
			i++;
		});
		obj.items = (i - 1);
		$.post(gate, obj, function (data) {
				if (data.state) {
					self.download_all_hide();
				} else {

				}
			},
			"json"
		);
	};

	this.get_queue_details = function ()
	{
		if (handle.containerBusyMode == 1) return;
		if (handle.quickRefreshMode == 0) {
			if (handle.isQueueWindowOpened == 1) {
				$("#download_queue_wrapper_1")
				.css({
					width	:	"320px",
					left	:	(clientWidth() / 2 - 320 / 2) + scrollLeft(),
					top		:	(clientHeight() / 2 - 100 / 2 ) + scrollTop(),
					position:	"absolute"
				}).show();
				$('#download_queue_list').html(language.msg.loading).show();
				$('#download_applet_wrapper').show();
			} else {
				$("#download_queue_wrapper_1").hide();
				$('#download_queue_list').text('').hide();
				$('#download_applet_wrapper').hide();
			}
		}
		if (handle.isQueueWindowOpened == 1) {
			$.post(gate, {act: 'get_download_queue', javaEnabled:javaEnabled}, function(data) {
					if (data.state) {
						$('#download_queue_list').html(data.content);
						$('#download_applet_wrapper')
							.html('<a href="javascript:;" id="start_downloading_files">'+ data.button +'</a>')
							.hide()
							.removeAttr('class');
					} else {
						$('#download_queue_list').html(data.err);
					}
				},
				'json'
			);
		}
	};
	
	var get_stat = function() {
		$.post(gate, {act: 'get_download_stat'}, function(data) {
				if (data.state) {
					$("#dqt").text(data.total);
					$('#download_queue_stats').html(data.content);
					if (self.isQueueWindowOpened == 1) {
						self.quickRefreshMode = 1;
						self.get_queue_details();
						self.quickRefreshMode = 0;
					}
				} else {

				}
			},
			'json'
		);
	}

	handle.quickRefreshMode = 0;
		handle.containerBusyMode = 0;
		handle.isQueueWindowOpened = 0;
		if (this._timer_ > 0) {
			clearInterval(this._timer_);
		}
		this._timer_ = setInterval(get_stat, 30000);
		get_stat();
		$('#download_queue').live('click', function(e) {
				e.preventDefault();
				handle.isQueueWindowOpened = (handle.isQueueWindowOpened == 0) ? 1 : 0;
				handle.get_queue_details();
			});
		$(".download_all").live('click', function(e){
				e.preventDefault();
				if (conf.user_id != null) {
					handle.download_all();
				}
			});
		$("#dqh").live("click", function(e){
				e.preventDefault();
				handle.containerBusyMode = 0;
				$('.download_selector:checked').removeAttr('checked');
				$('#start_downloading_files').unbind('click');
				$('#download_applet_wrapper').hide();
				$("#download_queue").click();
			});
		$("#download_queue_list a.s_delete").live('click', remove_file);
		$('.download_selector').live('click', function(e) {
				if ($('.download_selector:checked').length > 0) {
					handle.containerBusyMode = 1;
					$('#download_applet_wrapper').show();
				} else {
					handle.containerBusyMode = 0;
					$('#start_downloading_files').unbind('click');
					$('#download_applet_wrapper').hide();
				}
			});
			
		$('#start_downloading_files').live('click', function(e) {
				e.preventDefault();
				var i = 0;
				var items	=	{
					act:"get_download_applet",
					javaEnabled: javaEnabled
				};
				var msg		=	'';
				$.each($(".download_selector:checked"), function () {
					i++;
					var id = $(this).val();
					items['url_' + i] = $('#downlad_queue_item_' + id + ' .url').text();
				});
				items['count'] = i;
				$.post(gate, items, function (data) {
						if (data.state) {
							msg = data.content;
							var j = 0;
							for (var i in data.list) {
								var obj = data.list[i];
								//theURL, name, popW, popH, scrollbars
								/*openBrWindow(
									conf.base_url+'media/download/'+obj.filename+'.'+obj.format,
									"downloadWindow_"+j,
									100,
									100,
									false
								);*/
								j++;
							}
						} else {
							msg = data.err;
						}
						$('#download_applet_wrapper').html(msg);
					},
					'json'
				);
			});
	
/*
		var i = 0;
		var applet = '<applet code="MultiDownload.class" archive="' + conf.base_url + 'js/lib/downloader.jar" width="100%" height="100%">';
		$.each($("#download_list_container .download_row"), function () {
			var url = conf.base_url +'search/download/'+ $('.url_engine', this).text() +'/'+ $('.format option:selected', this).val() +'/'+ $('.url', this).text();
			var filename = $('.filename', this).text() +'.'+ $('.format option:selected', this).val();
			applet += '<param name="File'+ i +'" value="'+ filename +'|sep|'+ url +'">';
			i++;
		});
		applet += '<param name="NumberFiles" value="'+ i +'">';
		applet += '</applet>';
		$('#download_applet_holder')
			.text('')
			.html(applet);
*/
}

/* library */
var PlaylistModel = function (parent)
{
	var handle				=	this;
	var self				=	this;
	var gate				=	parent.gate;
	var parent				=	parent;
	
	this.parent				=	parent;
	this.item_id			=	0;
	this.speed				=	500;
	this.page				=	1;
	this.current_obj		=	{};
	this.albumInfoLoaded	=	null;
	this.lyricsInfoLoaded	=	false;

	this.state_handler				=	state_obj	||	new StateModel();
	
	this.log = function(obj) {
		this.state_handler.log(obj.target || '', obj.msg || '', obj.state || 1);
	};

	this.getParam = function (obj, index) {
		return Number($(obj).attr("id").split("_")[index]);
	}

	this.get_page = function (page) {
		this.current_obj.page = page + 1;
		this.get(this.current_obj);
	};

	this.remove_all = function() {
		var btn = $("#remove_playlist_all");
		var obj = {
			act			:	'removePlaylistItems',
			playlist_id	:	self.current_obj.id,
			items		:	[]
		};
		$.each($(".library_item_checkbox:checked"), function () {
			obj.items.push(Number($(this).val().trim()));
		});
		if (obj.items.length == 0) {
			alert(language.validation.please_select_at_list_one_item);
			return;
		}
		if (confirm(language.msg.confirm)) {
			obj.items = obj.items.join(",");
			$.post(gate, obj, function (data) {
					if (data.state) {
						for (var i in obj.items.split(",")) {
							$("#library_item_"+obj.items.split(",")[i]).remove();
						}
					} else {
						alert(data.err.join("\n"));
					}
					btn.show();
				},
				"json"
			);
			btn.hide();
		}
	};

	/*
	 * Update single playlist items order
	 */
	this.updatePlaylistSort = function (arr) {
		if (arr.length < 1) return;
		var obj = {act:"updatePlaylistOrder", playlist_id: self.current_obj.id, items: []};
		for (var i in arr) {
			var id = arr[i].split("_")[2];
			if (id != undefined) {
				obj.items.push(id);
			}
		}
		obj.items = obj.items.join(",");
		$.post(gate, obj);
	};

	this.updatePlaylistsSort = function (arr) {
		if (arr.length <= 0) return;
		var obj = {
			act:"updatePlaylistsOrder",
			items: []
		};
		for (var i in arr) {
			obj.items.push(arr[i].split("_")[1])
		}
		obj.items = obj.items.join(",");
		$.post(gate, obj);
	};
	
	this.getList = function (obj) {
		$("#"+obj.target+" a").unbind("click");
		$.post(gate, {act:"getPlaylistList"}, function (data) {
				//new
				//$.each($("#"+obj.target+" a"), function(){$(this).unbind("click");});
				$("#"+obj.target+" a").unbind("click");
				handle.my_playlist_list = data.json;
				
				$('#'+obj.target).empty().html(data.content);
				
				//alert(obj.target);

				$("#"+obj.target+" ul").sortable({
					axis: 'y',
					handle	:	'a.drag',
					stop	:	function(event, ui) {
						handle.updatePlaylistsSort($("#"+obj.target+" ul").sortable('toArray'));
					}
				});
				
				//edit
				$(".ep").click(function(e){
					e.preventDefault();
					handle.parent.edit_playlist(e.target.id.split("_")[1]);
				});
				//remove
				$(".rp").click(function(e){
					e.preventDefault();
					handle.remove_playlist(e.target.id.split("_")[1]);
				});
			},
			"json"
		);
		$("#"+obj.target).html("<ul><li><a class='s_drag'>&nbsp;</a><a class='s_playlist'>-msg-</a></li></ul>".replace('-msg-', language.msg.loading));
	};

	this.getFriendsList = function (obj) {
		//$("#"+obj.target+" .vfp").unbind("click");
		$.post(gate, {act:"getFriendsPlaylistList"}, function (data) {
				if (obj.target != undefined) {
					$("#"+obj.target).html(data.content);
				}
				//view
				//$(".vfp").click(function(e){
					//self.get({id:e.target.id.split("_")[1], friend:1});
				//});
			},
			"json"
		);
		$("#"+obj.target).html("<ul><li><a class='s_drag'>&nbsp;</a><a class='s_playlist'>-msg-</a></li></ul>".replace('-msg-', language.msg.loading));
	};

	this.get = function (obj) {
		if (obj.id < 0) return;

		this.current_obj = obj;

		var target = $("#playlist_wrap, #main_holder_content");

		var tab		=	$("#tab_playlist");
		tab.show();

		target = $("#explorer_playlist");
		if (obj.page == undefined) {
			obj.page = 1;
		}
		obj.friend = obj.friend == undefined ? 0 : obj.friend;

		$('a', target).unbind("click");
		
		$.post(gate, {act:"getPlaylist", id:obj.id, friend: obj.friend, page: obj.page}, function (data) {
				if (data.state) {
					target.html(data.content);
					//attach media actions
					$(".atl").unbind("click").click(function(e){
						e.preventDefault()
						handle.parent.add_to_library_second_show(e.target.id.split("_")[1]);
					});
					$(".remove_from_playlist").click(function(){
						var data = $(this).attr("id").split("_");
						handle.remove(Number(data[1]), Number(data[2]), Number(data[3]));
					});

					$(".reload_playlist").click(function(e){
						handle.get({id:e.target.id.split("_")[1]});
					});
					$("#remove_playlist_all").click(function(){
						handle.remove_all();
					});
					$(".rmly").unbind("click").click(function(e){
						parent.rate({id:e.target.id.split("_")[1], vote:'y'});
					});
					$(".rmln").unbind("click").click(function(e){
						parent.rate({id:e.target.id.split("_")[1], vote:'n'});
					});

					$("#add_to_library_form").unbind("submit").submit(function(e){
						e.preventDefault();
						parent.add_to_library();
					});

					if (conf.user_id != null) {
						$(".reordable", target).sortable({
							//axis	:	'y',
							//containment: 'parent',
							handle	:	'a.pldrag',
							start	:	function(e, ui) {
								//$('*', ui.helper).hide();
							},
							stop	:	function(e, ui) {

								//console.log(ui.helper);
								//$('*', ui.helper).show();
								handle.updatePlaylistSort($(".reordable", target).sortable('toArray'));
								parent.fixSClipHover();

							}
						});	
					}
					if (obj.autostart != undefined) {
						player_obj.play_playlist(obj.id);
					}
					parent.fixSClipHover();

					$('#page_item_banner iframe').clone(true).appendTo('#current_playlist_render .s_clip_banner');
					_load_library = true;

				} else {
					handle.log({target:"library_state", msg:data.err.join("\n"), state:2});
				}
			},
			"json"
		);
		if (obj.halt == undefined) {
			MainTabs.select(1);
		}
		//$("#library_state").html(language.msg.loading);
		target.html(language.msg.loading);
	}

	this.getPublicPlaylistItems = function (obj) {
		if (obj.id < 0) return;

		this.current_obj = obj;

		var target = $("#playlist_wrap, #main_holder_content");
		target = $("#explorer_playlist");
		if (obj.page == undefined) {
			obj.page = 1;
		}
		if (obj.friend == undefined) {
			obj.friend = 0;
		}
		$('a', target).unbind("click");

		$.post(gate, {act:"getPublicPlaylist", id:obj.id, friend: obj.friend, page: obj.page}, function (data) {
				if (data.state) {
					target.text('');
					//handle.log({target:"library_state", msg:''});
					target.html(data.content);
					//attach media actions
					$(".atl").unbind("click").click(function(){
						handle.parent.add_to_library_second_show(handle.getParam(this, 1));
					});
					$(".remove_from_playlist").click(function(){
						var data = $(this).attr("id").split("_");
						handle.remove(Number(data[1]), Number(data[2]), Number(data[3]));
					});

					$(".reload_playlist").click(function(e){
						handle.get({id:e.target.id.split("_")[1]});
					});
					$("#remove_playlist_all").click(function(){
						handle.remove_all();
					});
					$(".rmly").unbind("click").click(function(e){
						library_obj.rate({id:e.target.id.split("_")[1], vote:'y'});
					});
					$(".rmln").unbind("click").click(function(e){
						library_obj.rate({id:e.target.id.split("_")[1], vote:'n'});
					});



					$("#add_to_library_form").unbind("submit").submit(function(e){
						e.preventDefault();
						library_obj.add_to_library();
					});

					$(".reordable", target).sortable({
						//axis	:	'y',
						//containment: 'parent',
						handle	:	'a.pldrag',
						start	:	function(e, ui) {
							//$('*', ui.helper).hide();
						},
						stop	:	function(e, ui) {
							//console.log(ui.helper);
							//$('*', ui.helper).show();
							handle.updatePlaylistSort($(".reordable", target).sortable('toArray'));
							parent.fixSClipHover();
						}
					});
					parent.fixSClipHover();
					try {
						if (obj.autostart != undefined && obj.autostart) {
							player_obj.play_playlist(obj.id);
						}
					} catch (e) {
						//alert(e);
					}
					_load_library = true;

				} else {
					handle.log({target:"library_state", msg:data.err.join("\n"), state:2});
				}
			},
			"json"
		);
		MainTabs.select(1);
		//$("#library_state").html(language.msg.loading);
		target.html(language.msg.loading);
	}

	this.remove_playlist = function (playlist_id)
	{
		if (playlist_id < 0) return;
		if (confirm(language.msg.confirm)) {
			$.post(gate, {act:"remove_playlist", playlist_id:playlist_id}, function (data) {
					if (data.state) {
						$("#playlist_"+playlist_id).hide(500).remove();
					} else {
						alert(data.err.join("\n"));
					}
				},
				"json"
			);
		}
	}

	this.remove = function (playlist_id, item_id, ref_id)
	{
		if (playlist_id < 0 || item_id < 0) return;
		if (confirm(language.msg.confirm)) {
			$.post(gate, {act:"remove_from_playlist", playlist_id:playlist_id, item_id:item_id}, function (data) {
					if (data.state) {
						$("#library_item_"+ref_id).remove();
					} else {
						alert(data.err.join("\n"));
					}
				},
				"json"
			);
		}
	}
	this.edit = function (id) {
		if (id == undefined || id < 0) return;
		this.item_id	=	id;
		$.post(gate, {act:"get_playlist_edit", id:id}, function (data) {
				if (data.state) {
					$("#edit_playlist_wrap h2").text(data.data.title);
					$("#title_edit").val(data.data.title);
					$("#description_edit").val(data.data.description);
					if (data.data['public'] == 'yes') {
						$("#public_edit").attr("checked", "checked");
					}
					$("#playlist_edit_btn").show();
				} else {
					alert(data.msg.join("\n"));
				}
			},
			"json"
		);
		$("#title_edit").val('');
		$("#description_edit").val('');
		$("#public_edit").removeAttr("checked");
		$("#playlist_edit_btn").hide();
		$("#edit_playlist_wrap").show();
	};

	this.playlist_hide = function () {
		$("#edit_playlist_wrap").hide();
	};

	this.load_playlists = function (obj) {
		this.getList({target: obj.target || "my_playlist_list_holder"});
	}
	
	this.save = function () {

		if (this.item_id == 0) return;
		$.post(gate, {
				act:"edit_playlist",
				id:this.item_id,
				title:$("#title_edit").val(),
				description:$("#description_edit").val(),
				show:$("#public_edit").is(":checked") ? 'yes' : 'no'
			},
			function (data) {
				if (data.state) {
					$("#playlistreload_" + self.item_id).text($("#title_edit").val());
					$("#vp_"+self.item_id).text($("#title_edit").val());
					self.log({target:"playlist_edit_state", msg:data.msg.join("\n"), state:1});
					parent.edit_playlist_hide();
					self.getList({target:"profile_playlist_wrap"});
				} else {
					alert(data.err.join("\n"));
				}
			},
			"json"
		);
	}

	this.add_to_playlist_show = function(id) {
		this.item_id	=	id;
		$.post(gate, {act:"getItemAndPlaylists", id:id}, function (data) {
				if (data.state) {
					$("#add_to_playlist_up_title").text(data.item.title);
					$("#add_to_playlist_image").css({"background":"url("+data.item.thumbnail+") center center"});
					var html = '';
					for (var i in data.list) {
						var in_list = data.list[i].in_list ? " checked='checked' " : '';
						html +="<span class='s_checkbox'><input type='checkbox' class='s_checkbox add_to_playlist_item' value='"+data.list[i].id+"' " + in_list + " /> "+data.list[i].title+"</span><br />";
					}
					$("#add_to_playlist_playlist_holder").html(html);
					$("add_to_playlist_btn").show();

					$("#add_to_playlist_form").unbind("submit").bind("submit", function (event) {
						event.preventDefault();
						var obj = {
							act		:	'addItemToPlaylist',
							id		:	handle.item_id,
							items	:	[]
						};
						$.each($(".add_to_playlist_item:checked"), function () {
							obj.items.push($(this).val());
						});
						if (obj.items.length > 0) {
							obj.items = obj.items.join(',');
							$.post(gate, obj, function (data) {
									if (data.state) {
										self.add_to_playlist_hide();
										handle.log({target:'add_to_playlist_state', msg:data.msg.join("\n")});
									} else {
										handle.log({target:'add_to_playlist_state', msg:data.err.join("\n")});
									}
								},
								"json"
							);
						}
					});
				}
			},
			"json"
		);
		$("#add_to_playlist_up_title").text('');
		$("#add_to_playlist_playlist_holder").text(language.msg.loading);
		var wrap = $("#add_to_playlist_wrap");
		wrap.css({
			width	:	"320px",
			left	:	(clientWidth() / 2 - 400 / 2) + scrollLeft(),
			top		:	(clientHeight() / 2 - 100 / 2 ) + scrollTop(),
			position:	"absolute"
		}).show();
	};

	this.proxy = function (arr) {
		alert(arr);
		//alert(handle[arr[0] + '_handler']);
		//handle[arr[0] + '_handler'][arr[1]]();
	};
	
	this.add_to_playlist_hide = function(e) {
		try {
			e.preventDefault();
		} catch (e) {
			
		}
		handle.item_id	=	null;
		$("#add_to_playlist_wrap").hide();
		$("#add_to_playlist_up_title, #add_to_playlist_state").text('');
		$("#add_to_playlist_form").unbind("submit");
	};
	
	$("#edit_playlist_form").unbind("submit").bind("submit", function(e) {
		e.preventDefault();
		handle.save();
	});
	$(".add_to_playlist").live('click', function(e){
		handle.add_to_playlist_show(e.target.id.split("_")[1]);
	});
	$("#atph").live('click', handle.add_to_playlist_hide);

	$(".vp").live('click', function(e){
		e.preventDefault();
		handle.get({id:Number(e.target.id.split('_')[1])});
	});
	$(".vfp").live('click', function(e){
		e.preventDefault();
		handle.get({id:Number(e.target.id.split('_')[1]), friend:1});
		//return false;
	});
};

var LibraryModel = function()
{
	var handle		=	this;
	var self		=	this;

	var load_library	=	true;

	
	this.controller =	"library";
	this.speed		=	500;
	this.gate		=	conf.base_url + this.controller + '/gate';
	var gate		=	this.gate;

	this.page		=	1;
	this.item_id	=	null;
	this.mode		=	"list";
	this.word		=	null;
	this.batch		=	[];

	this.filter		=	{
		word	:	null,
		genre	:	null
	};

	this.setFilter = function (arr) {
		try {
			self.filter[arr[0]] = arr[1];
			switch(self.filter[arr[0]]) {
				case "word":
					//$("#library_filters .alpha_wrap > span ").text(arr[1]);
				break;
				case "genre":
					//$("#library_filters .genre_wrap > span ").text(arr[1]);
				break;
			}
		} catch (e) {
			alert(e);
		}
	};

	this.load_public_playlists = function() {
		var target = $("my_playlist_list_holder");
		$.post(gate, {act:"get_public_playlists"}, function(data){
			$("#my_playlist_list_holder").html(data.content);
		},"json");
		target.html(language.msg.loading);
	};

	this.dropFilters = function () {
		for(var i in self.filter) {
			self.filter[i] = null;
		}
	};

	this.addModel = function (obj) {
		this[obj.handler] = obj.model;
	}

	// public state handler
	this.state_handler		=	state_obj || new StateModel();
	this.search_handler		=	search_obj || new SearchModel();
	this.playlist_handler	=	new PlaylistModel(this);
	this.download_handler	=	new DownloadModel(this);

	delete DownloadModel, PlaylistModel;

	//log
	this.log = function (obj) {
		this.state_handler.log(obj.target, obj.msg, obj.state);
	};

	this.render_err  = function (err) {
		for (var i in err) $("#"+i+"_err").text(err[i]).show();
	};

	this.reset_err  = function (err) {
		for (var i in err) $("#"+err[i]+"_err").empty().hide();
	};
	
	var str2url = function (str) {
		return str.toLowerCase().replace(/[^a-zA-Z0-9]+/gi,'-');
	};
	
	this.share_show = function (o) {
		o.preventDefault();
		var id = Number( o.type != undefined ? Number(o.target.id.split('_')[1]) : o);
		var mode = $(this).attr('class') == 's_share' ? 'playlist' : 'item';
		

		if (o.target.id == 'movieclip_share') {
			switch (player_obj.mode) {
				case "library":
					id = player_obj.current_item_id;
				break;
				case "playlist":
					id = player_obj.current_item_id;
				break;
				case "media":
					id = player_obj.current_item_id;
				break;
			}
		}
		if (id < 0) return;
		handle.share_item_id = id;
		var src = $("#library_item_"+id);
		var title = $("#title_"+id).text();
		if (title == '') {
			title = $("#player_current_play").text();
		}
		var image = $("#library_item_"+id+" .thumbnail_url").text();

		//$("#share_item_thumbnail").css("background", $("#pmit_"+id).css("background"));
		$("#share_item_thumbnail").css("background", "url("+image+") center center no-repeat");//$("#pmit_"+id).css("background")
		$("#share_item_title").text(title);
		$("#share_item_description").text($(".description", src).text());
		$("#share_item_duration").text($(".duration", src).text());
		switch (mode) {
			case "item":
				$("#share_item_preview_url").text(conf.base_url + 'preview_' + id + '_' + str2url(title));
			break;
			default:
				$("#share_item_preview_url").text(conf.base_url + conf.user_name + '/' + id);
			break;
		}
		$("#share_wrap").css({
				width	:	'564px',
				left	:	(clientWidth() / 2 - 564 / 2) + scrollLeft(),
				top		:	(clientHeight() / 2 - 600 / 2 ) + scrollTop(),
				position:	"absolute"
			}
		).show();
		$("#share_menu_item").empty().append($("#library_item_"+id).clone().removeAttr("id").attr("id", "share_library_item_"+id)).addClass("s_clip_share");
		//$("#share_library_item_"+id+" .s_checkbox").css("padding","0px 0 0 7px");
		$("#share_library_item_"+id+" .s_checkbox input").attr("id", "share_item_selected_"+id);
		$("#share_item_selected_"+id).hide().remove();
		//attach events

		//link form
		var file = '', text = '';
		switch (mode) {
			case "item":
				file = conf.base_url + "library/export_single/"+id;
				text = '<object width="320" height="240">' + "\n";
				text += '<param name="movie" value="' + conf.base_url + 'media/swf/player.swf"></param>';
				text += '<param name="allowFullScreen" value="true"></param>';
				text += '<param name="allowscriptaccess" value="always"></param>';
				text += '<param name="flashvars" value="file='+file+'&controlbar=over&repeat=list&autostart=true&id=ply&fullscreen=false&backcolor=111111&plugins=gapro"></param>';
				text += '<param name="wmode" value="opaque"></param>';
				text += '<embed height="240" width="320" flashvars="file='+file+'&controlbar=over&repeat=list&autostart=true&id=ply&fullscreen=false&backcolor=111111&plugins=gapro" wmode="opaque" allowscriptaccess="always" allowfullscreen="true" quality="high" bgcolor="#ffffff" name="ply" id="ply" src="'+conf.base_url+'media/swf/player.swf" type="application/x-shockwave-flash"></embed>';
				text += '</object>';
			break;

			case "playlist":
				file = conf.base_url + "library/export/playlist/rss20/playlist_" + id + ".xml";
				text = '<object width="320" height="240">' + "\n";
				text += '<param name="movie" value="' + conf.base_url + 'media/swf/player.swf"></param>';
				text += '<param name="allowFullScreen" value="true"></param>';
				text += '<param name="allowscriptaccess" value="always"></param>';
				text += '<param name="flashvars" value="file='+file+'&controlbar=over&repeat=list&autostart=true&id=ply&fullscreen=false&backcolor=111111&plugins=gapro"></param>';
				text += '<param name="wmode" value="opaque"></param>';
				text += '<embed height="240" width="320" flashvars="file='+file+'&controlbar=over&repeat=list&autostart=true&id=ply&fullscreen=false&backcolor=111111&plugins=gapro" wmode="opaque" allowscriptaccess="always" allowfullscreen="true" quality="high" bgcolor="#ffffff" name="ply" id="ply" src="'+conf.base_url+'media/swf/player.swf" type="application/x-shockwave-flash"></embed>';
				text += '</object>';
			break;

			default:
				text = conf.base_url + conf.user_name + '/' + id;
			break;
		}
		$("#share_form_link_textarea").val(text);
		$("#share_form_link").submit(function(e){
			e.preventDefault();
			var obj = {act:"share_link_send", item_id:handle.share_item_id, link: $("#share_form_link_textarea").val()};
			var submit_btn = $("#share_link_submit_btn");
			if (obj.link == '') return;
			$.post(gate, obj, function (data) {
					if (data.state) {
					} else {
						//handle.log({target:"", msg:"", state:1})
					}
					submit_btn.show();
				},
				"json"
			);
			submit_btn.hide();
		});

		//share single
		$("#share_form_single_textarea").val($("#share_item_preview_url").text());

		//email form
		var share_form_email = $("#share_form_email");
		$("input", share_form_email).val('');
		$("#share_email_name_err, #share_email_email_err").empty();
		share_form_email.submit(function(e){
			e.preventDefault();
			var obj = {
				act:"share_email_send",
				item_id:handle.share_item_id,
				mode:mode,
				total:0,
				share_email_name:$("#share_email_name").val(),
				share_email_email:$("#share_email_email").val()
			};
			$.each($(".share_email"), function() {
				if ($(this).val() != '') {
					obj['email_'+obj.total] = $(this).val();
					obj.total++;
				}
			});
			var submit_btn = $("#share_email_submit_btn");
			if (obj.total == 0) {
				return;
			}
			$.post(handle.gate, obj, function (data) {
					if (data.state) {
						handle.log({target:"share_form_email_state", msg:data.msg.join("\n"), state:1});
						$("input", share_form_email).val('');
					} else {
						handle.render_err(data.err);
					}
					//submit_btn.parent().show();
				},
				"json"
			);
			//submit_btn.parent().hide();

		});
		
		//recommend form
		if (mode != 'item') {
			$("#share_recommend_tab").closest('li').hide();
		} else {
			$("#share_recommend_tab").closest('li').show();
		}
		$("#share_form_recommend").submit(function(e){
			e.preventDefault();
			var obj = {
				act:"share_recommend_send",
				item_id:handle.share_item_id,
				list:[]
			};
			var submit_btn = $("#share_recommend_submit_btn");
			$.each($("#share_form_recommend input:checked"), function(){
				obj.list.push($(this).val());
			});
			if (obj.list.length == 0) {
				return
			} else {
				obj.list = obj.list.join(",");
			}
			$.post(gate, obj, function (data) {
					if (data.state) {
						handle.log({target:"share_form_recommend_state", msg:data.msg.join("\n"), state:1});
						$("#share_form_recommend input:checked").removeAttr("checked");
					} else {
						handle.render_err(data.err);
					}
					submit_btn.show();
				},
				"json"
			);
			submit_btn.hide();

		});

		if (mode == 'item') {
			var twitter_text = "Currently listening to "+$("#share_item_title").text()+" "+$("#share_item_preview_url").text()+".";
		} else {
			var twitter_text = "Currently playing " + $("#vp_" + id).text() + " playlist from " + $("#share_item_preview_url").text();
		}
		$("#share_twitter_text").text(twitter_text);

		$("#share_form_twitter").submit(function(e){
			e.preventDefault();
			var text	=	$("#share_twitter_text").val();
			openBrWindow("http://twitter.com/home?status="+encodeURIComponent(text), "twitter_share", 500, 700, 'yes');
		});
		//end of share twitter

		//facebook form
		$("#share_facebook_new_button").click(function(){
			if (handle.share_item_id == undefined) return;
			openBrWindow("http://www.facebook.com/share.php?u="+encodeURIComponent(conf.base_url + 'preview_' + handle.share_item_id), "facebook_share", 500, 700, 'yes');
		});

		$("#share_form_facebook").submit(function(e){
			e.preventDefault();
			var obj = {
				act		:	"share_facebook_send",
				item_id	:	handle.share_item_id,
				content	:	$("#share_facebook_text").val()
			};
			var submit_btn = $("#share_facebook_submit_btn");
			$.post(
				handle.gate,
				obj,
				function (data) {
					if (data.state) {
						handle.log({target:"share_form_facebook_state", msg:data.msg.join("\n"), state:1});
					} else {
						handle.render_err(data.err);
					}
					submit_btn.show();
				},
				"json"
			);
			submit_btn.hide();

		});
		
		/*/myspace
		var myspace = {
			title	:	'',
			text	:	'',
			url		:	$("#share_item_preview_url").text(),
			embed	:	''
		};
		if (mode == 'item') {
			myspace.title	=	"Currently listening to "+title.split('"').join("&quot;");
			myspace.text	=	"Currently listening to "+title;
		} else {
			myspace.title	=	"Currently playing "+$("#vp_" + id).text().split('"').join("&quot;");
			myspace.text	=	"Currently playing " + $("#vp_" + id).text() + " playlist from " + url;
		}
		$("#post_to_myspace_title").val(myspace.title);
		$("#post_to_myspace_url").val(myspace.url);
		$("#share_myspace_text").text(myspace.text);
		//end of myspace
			*/

		//other
		var other = {
			title	:	'',
			text	:	'',
			url		:	$("#share_item_preview_url").text(),
			embed	:	''
		};
		if (mode == 'item') {
			other.text	=	"Currently listening to \""+title+"\" at " + other.url;
		} else {
			other.text	=	"Currently playing " + $("#vp_" + id).text() + " playlist from " + $("#share_item_preview_url").text();
		}
		$("#share_other_text").text(other.text);
		//end of other

		//common
		$("#smh").click(function(e){
			e.preventDefault();
			handle.share_hide();
		});
	};

	this.show_import_playlist = function() {
		$("#import_playlist_wrap").css({
				position:	"absolute",
				width	:	"340px",
				left	:	(clientWidth() / 2 - 340 / 2) + scrollLeft(),
				top		:	(clientHeight() / 2 - 100 / 2 ) + scrollTop()
			}
		).show();
		$("#iph").click(function(e){
			e.preventDefault();
			self.hide_import_playlist();
			$(this).unbind("click");
		});
		//youtube
		$("#youtube_playlist_import_form").unbind("submit").bind("submit", function(e) {
			e.preventDefault();
			var username = $("#youtube_playlist_import_username").val();
			if (username == '') return;
			
			$("#youtube_playlist_import_form_wrap .pl_wait").show();
			$("#youtube_playlist_import_form").hide();
			$("#youtube_playlist_import_form_items_wrap").show();
			$("#youtube_playlist_import_form_items_inner").empty();
			
			$.post(conf.base_url + 'search/playlist_import',
				{engine:"youtube", query:$("#youtube_playlist_import_username").val(), o:Math.random()},
				function (data) {
					$("#youtube_playlist_import_form_wrap .pl_wait").hide();
					$("#import_youtube_select_cancel").unbind("click").bind("click", function(){
						$("#youtube_playlist_import_form").show();
						$("#youtube_playlist_import_form_items_wrap").hide();
					});
					if (data.state) {
						$("#youtube_playlist_import_form_items_wrap").show();
						$("#youtube_playlist_import_form_items_inner").html(data.content);
					} else {
						alert(data.err.join("\n"));
					}
				},
				"json"
			);
		});
		$("#youtube_playlist_import_form_items").unbind("submit").bind("submit", function(e){
			$("#youtube_playlist_import_form_wrap .pl_wait").show();
			$("#youtube_playlist_import_form_items_wrap").hide();
			e.preventDefault();
			var items = [];
			$.each($("#youtube_playlist_import_form_items_inner input:checked"), function() {
				items.push($(this).val())
			});
			if (items.length <= 0) return;
			items = items.join(",");
			$.post(self.gate, {act:"import_external_playlist", engine:"youtube", items:items},
				function (data) {
					if (data.state) {
						$("#youtube_playlist_import_form_wrap .pl_wait").hide();
						$("#youtube_playlist_import_form_items_wrap").hide();
						$("#youtube_playlist_import_form_items_inner").empty();
						$("#youtube_playlist_import_form").show();
						self.load_playlists();
						self.log({target:"import_youtube_playlists_state", msg:data.msg.join("\n"), state:1});
					} else {
						//alert('no');
					}
				},
				"json"
			);
		});

		//metacafe
		$("#metacafe_playlist_import_form").unbind("submit").bind("submit", function(e) {
			$("#metacafe_playlist_import_form_wrap .pl_wait").show();
			$("#metacafe_playlist_import_form_items_wrap").addClass("hidden");
			$("#metacafe_playlist_import_form_items_inner").empty();
			e.preventDefault();
			$.post(
				conf.base_url + 'search/playlist_import',
				{engine:"metacafe", query:$("#metacafe_playlist_import_username").val(), o:Math.random()},
				function (data) {
					if (data.state) {
						$("#metacafe_playlist_import_form_items_wrap").show();
						$("#metacafe_playlist_import_form").hide();
						$("#metacafe_playlist_import_form_items_inner").html(data.content);
						$("#import_metacafe_select_cancel").unbind("click").bind("click", function(){
							$("#metacafe_playlist_import_form").show();
							$("#metacafe_playlist_import_form_items_inner").empty();
							$("#metacafe_playlist_import_form_items_wrap").hide();
						});
					} else {
						alert(data.err.join("\n"));
					}
				},
				"json"
			);
		});
		
		$("#metacafe_playlist_import_form_items").unbind("submit").bind("submit", function(e){
			e.preventDefault();
			var items = [];
			$.each($("#metacafe_playlist_import_form_items_inner input:checked"), function() {
				items.push($(this).val())
			});
			if (items.length <= 0) return;
			items = items.join(",");
			$.post(self.gate, {engine:"metacafe", act:"import_external_playlist", items:items}, function (data) {
					if (data.state) {
						$("#metacafe_playlist_import_form_items_wrap").hide();
						$("#metacafe_playlist_import_form_items_inner").empty();
						$("#metacafe_playlist_import_form").show();
						self.log({target:"import_metacafe_playlists_state", msg:data.msg.join("\n"), state:1});
					} else {
						//alert('no');
					}
				},
				"json"
			);
		});
	}

	this.hide_import_playlist = function() {
		$("#import_playlist_wrap").draggable('destroy').hide();
	};

	this.playlist_import_success = function() {
		//this.log({target:"", msg:"Playlist imported", state:1});
	};

	this.share_hide = function() {
		$("#share_wrap").hide();
		$("#smh").unbind("click");
	};

	this.getMostListened = function() {
		var target = $("#explorer_library");
		load_library = false;
		MainTabs.select(0);
		$.post(gate, {act:"getMostListened"}, function (data) {
				if (data.state) {
					target.html(data.content);
					handle.attachLibraryItemsAction();
					$('#page_item_banner iframe').clone(true).appendTo('#current_library_render .s_clip_banner');
				} else {
					alert(data.err.join("\n"));
				}
				$("#common_holder #cmlistened").show();
			},
			"json"
		);
	};
	
	this.getTopFavorites = function(e) {
		try { e.preventDefault(); } catch (e) { /* alert(e); */ }
		var target = $("#explorer_library");
		load_library = false;
		MainTabs.select(0);
		$.post(gate, {act:"getTopFavorites"}, function (data) {
				if (data.state) {
					target.html(data.content);
					handle.attachLibraryItemsAction();
					$('#page_item_banner iframe').clone(true).appendTo('#current_library_render .s_clip_banner');
				} else {
					alert(data.err.join("\n"));
				}
				$("#common_holder #cmfavorites").show();
			},
			"json"
		);
	};

	this.getMostPopular = function() {
		var target = $("#explorer_library");
		load_library = false;
		MainTabs.select(0);
		$.post(gate, {act:"getMostPopular"}, function (data) {
				if (data.state) {
					target.html(data.content);
					self.attachLibraryItemsAction();
					$('#page_item_banner iframe').clone(true).appendTo('#current_library_render .s_clip_banner');
				} else {
					alert(data.err.join("\n"));
				}
				$("#common_holder #cmpopular").show();
			},
			"json"
		);
	};
	
	this.getRecentlyAdded = function() {
		var target = $("#explorer_library");
		load_library = false;
		MainTabs.select(0);
		$.post(gate, {act:"getRecentlyAdded"}, function (data) {
				if (data.state) {
					target.html(data.content);
					handle.attachLibraryItemsAction();
					$('#page_item_banner iframe').clone(true).appendTo('#current_library_render .s_clip_banner');
				} else {
					alert(data.err.join("\n"));
				}
				$("#common_holder #cmrecently").show();
			},
			"json"
		);
	};
	
	this.load_common = function() {
		$.post(gate, {act:"getCommon", o:Math.random()}, function (data) {
				if (data.state) {
					//alert(data.content);

					//alert(data.content);
					$("#common_holder").html(data.content);
					//genres
					//$("#common_holder a.genre").click(function(){
						//handle.load_front_genre_list({genre: $(this).attr("id").split("_")[1]});
					//});
				}
			},
			"json"
		);
	};
	
	this.rate  = function (obj) {
		if (obj.id < 0 || (obj.vote != 'y' && obj.vote != 'n')) return;
		$("#rmwp_"+obj.id).show();
		$("#rmw_"+obj.id).hide();
		$.post(gate, {act:"vote", item_id:obj.id, vote:obj.vote}, function (data) {
				if (data.state) {
					handle.log({target:"vote_state", msg:data.msg.join("\n"), state:1});
					
				} else {
					handle.log({target:"vote_state", msg:data.err.join("\n"), state:2});
					
				}
				$("#rmwp_"+obj.id).hide();
				$("#rmw_"+obj.id).show();
			},
			"json"
		);
	};
	
	this.attachActions = function () {
		$("#add_playlist_show, #button_add_playlist, .create_new_playlist").click(function(){
			handle.add_playlist_show();
		});
		$("#lmp, #button_my_playlists").click(function(){
			handle.load_playlists();
		});
		
		$("#import_playlist, #button_import_playlist").click(function(){
			handle.show_import_playlist();
		});
		/*$("#button_import_playlist, #button_import_playlist_guest").hover(function(e){
			//console.log(e);
			//alert('over');
			$(".s_tooltip", $(this).parent()).show();
		},function(){
			$(".s_tooltip", $(this).parent()).hide();
		});*/

		$("#load_friend_playlists, #button_friends_playlists").click(function(){
			handle.load_friends_playlists();
		});
		$("#reload_my_library").click(function(){
			handle.load_library();
		});
	};

	function resetAddToLibrary () {
		$("#title_add").val('');
		$("#add_to_library_up_title").text('');
		$("#add_to_playlist_image").attr("src", '');
		$("#add_to_library_state").text('');
	}

	this.add_to_library_show = function (data) { //key
		resetAddToLibrary();
		var src = $("#"+data.engine+"_search_item_"+data.index);
		var wrap = $("#add_to_library_wrap");
		$("#thumbnail_add", wrap).text($(".thumbnail_url", src).text());
		$("#duration_add", wrap).text($(".duration", src).text());
		$("#url_add", wrap).text($(".url", src).text());
		$("#engine_add", wrap).text($(".engine", src).text());
		$("#title_library_add", wrap).val($(".title", src).text().trim());
		$("#add_to_library_up_title", wrap).text($(".title", src).text());
		$("#add_to_playlist_thumbnail_hold", wrap).css("background", "url("+$(".thumbnail_url", src).text()+") center center");
		$("#playlist_new_add", wrap).val('');
		//playlist
		$.post(gate, {act:"getPlaylistList"}, function (data) {
				$("#add_to_library_playlists_hold")
					.empty()
					.tplAppend(
						data.json,
						function () {
							return [
								'label', {className:"s_checkbox s_inline"}, [
									'input', {type:"checkbox", className:"s_checkbox", id: 'addtolibraryplaylist_' + this.id, value:this.id}, '',
									'i', {}, this.title
								]
							];
						}
					);
					$("#add_to_library_form").unbind("submit").submit(function(e){
						e.preventDefault();
						self.add_to_library();
					});
			},
			"json"
		);
		wrap.css({
			position : "absolute",
			width : '600px',
			left:	(clientWidth() / 2 - (600 / 2)) + scrollLeft(),
			top:	(clientHeight() / 2 - (600 / 2)) + scrollTop()
		});
		$("#add_to_library_wrap").show();
	};

	this.add_to_library_second_show = function (id) { //key
		if (conf.user_id == null) return;
		resetAddToLibrary();
		var src = $("#library_item_"+id);
		var wrap = $("#add_to_library_wrap");
		var thumbnail	=	$(".thumbnail_url", src).text();
		var title		=	$(".title", src).text().trim();
		$("#add_to_library_form #thumbnail_add").text(thumbnail);
		$("#add_to_library_form #duration_add").text($(".duration", src).text().trim());
		$("#add_to_library_form #url_add").text($(".url", src).text());
		$("#add_to_library_form #engine_add").text($(".url_engine", src).text());
		$("#add_to_library_form #title_library_add").val(title);
		//
		$("#add_to_library_form #album_add").val($("#library_item_"+id+" .album").text().trim());
		$("#add_to_library_form #artist_add").val($("#library_item_"+id+" .artist").text().trim());
		//
		$("#add_to_library_up_title").text(title);
		$("#add_to_playlist_thumbnail_hold").css("background", "url(" + thumbnail + ") center center");
		wrap.css({
			position : "absolute",
			width : '600px',
			left:	(clientWidth() / 2 - (600 / 2)) + scrollLeft(),
			top:	(clientHeight() / 2 - (600 / 2)) + scrollTop()
		});
		//playlist
		$.post(gate, {act:"getPlaylistList"}, function (data) {
				$("#add_to_library_playlists_hold")
					.empty()
					.tplAppend(
						data.json,
						function () {
							return [
								'label', {className:"s_checkbox s_inline"}, [
									'input', {type:"checkbox", className:"s_checkbox", id: 'addtolibraryplaylist_' + this.id, value:this.id}, '',
									'i', {}, this.title
								]
							];
						}
					);
					$("#add_to_library_form").unbind("submit").submit(function(e){
						e.preventDefault();
						self.add_to_library();
					});
			},
			"json"
		);
		$("#add_to_library_form").unbind("submit").submit(function(e){
			e.preventDefault();
			self.add_to_library();
		});
		wrap.show();
	};

	this.load_single_library_item = function (id) {
		if (id < 0) return;
		$.post(gate, {act:"getSingleItemInfo", id:id}, function (data) {},"json");
	}

	this.add_playlist_show = function () {
		var target	=	$("#add_playlist_wrap");
		var form	=	$("#add_playlist_form");
		handle.reset_err(['title']);
		target.css({
			width	:	'360px',
			left	:	(clientWidth() / 2 - 360 / 2) + scrollLeft(),
			top		:	(clientHeight() / 2 - 100 / 2 ) + scrollTop(),
			position:	"absolute"
		}).show();
		form.unbind("submit").submit(function (e) {
					e.preventDefault();
					handle.add_playlist();
				}
			);
		$("#aph").unbind("click").click(function(e){
			e.preventDefault();
			handle.add_playlist_hide();
			$(this).unbind("click");
		});
	};

	this.add_playlist = function() {
		var o = {
			act			:	"add_playlist",
			title		:	$("#title_add").val(),
			description	:	$("#description_add").val(),
			show		:	$("#public_add").is(":checked") ? 'yes' : 'no'
		};
		$.post(gate, o, function (data) {
				if (data.state) {
					$("#add_playlist_wrap #title_add").val('');
					$("#add_playlist_wrap #description_add").val('');
					handle.playlist_handler.getList({target:"my_playlist_list_holder"});
					handle.log({target:"add_playlist_state", msg:data.msg.join("\n"), state:1});
					handle.reset_err(['title']);
					self.add_playlist_hide();
				} else {
					try {
						if(data.err.fly != undefined) {
							handle.log({target:'', msg:data.err.fly, state:1});
							self.add_playlist_hide();
						}
					} catch (e) {
						//alert(e);
					}
					handle.render_err(data.err);
					
				}
			},
			"json"
		);
	};

	this.add_to_library_hide = function(e) {
		if (e != undefined) e.preventDefault();
		self.item_id	=	null;
		$("#title_library_add, #description_library_add, #artist_add, #album_add, #tags_add").val('');
		$("#add_to_library_genre_list_wrap input:checked").removeAttr("checked");
		$("#add_to_library_wrap").hide();
		$("#add_to_library_form").unbind("submit");
		
	};

	this.add_playlist_hide = function() {
		$("#title_add").val('');
		$("#description_add").val('');
		$("#add_playlist_wrap").hide();
	};

	this.add_to_library = function () {
		var genre_list = [];
		$.each($("#add_to_library_genre_list_wrap input:checked"),function(){
			genre_list.push($(this).val());
		});
		genre_list = genre_list.join(":");
		//
		var pl_list = [];
		$.each($("#add_to_library_playlists_hold input:checked"),function(){
			pl_list.push($(this).val());
		});
		pl_list = pl_list.join(",");

		var url = $("#url_add").text();
		var engine = $("#engine_add").text();
		$.post(gate, {
				act			:	"add_to_library",
				url			:	url,
				title		:	$("#title_library_add").val(),
				description	:	$("#description_library_add").val(),
				duration	:	$("#duration_add").text(),
				engine		:	engine,
				artist		:	$("#artist_add").val(),
				album		:	$("#album_add").val(),
				tags		:	$("#tags_add").val(),
				thumbnail	:	$("#thumbnail_add").text(),
				genre		:	genre_list,
				playlist	:	pl_list,
				playlist_new:	$("#playlist_new_add").val().trim()
			},
			function (data) {
				if (data.state) {
					if ($("#playlist_new_add").val().trim() != '') {
						handle.load_playlists();
					}
					handle.log({target:"add_to_library_state", msg:data.msg.join("\n"), state:1});
					$.each($("#"+engine+"_search_wrap .s_clip"), function() {
						if ($(".url", this).text() == url) {
							$(".clip_actions ul", this).empty();
						}
					});
					self.add_to_library_hide();
				} else {
					handle.log({target:"add_to_library_state", msg:data.err.join("\n"), state:2});
				}
			},
			"json"
		);
	};
	
	this.get_page = function (page) {
		self.page = page;
		self.load_library();
	};

	this.get_alpha_page = function (page) {
		this.page = page;
		this.load_front_alpha_list({page:this.page});
	};
	
	this.get_genre_page = function (page) {
		this.page = page;
		this.load_front_genre_list({page:this.page});
	};

	/*this.load_library = function () {
		var target = $("#playlist_wrap, #main_holder_content");
		$.post(
			this.gate,
			{act:"getLibrary", page:this.page},
			function (data) {
				if (data.state) {
					target.html(data.content);
					library_obj.attachLibraryItemsAction();
				} else {
					handle.log({target:'library_hold_state', msg:'sas', state:1});
				}
			},
			"json"
		);
	}*/

	//local
	this.load_playlist = function (id) {
		this.playlist_handler.get({id:id});
	};

	this.load_playlists = function() {
		$("#my_playlist_list_holder_wrap").show();
		$("#friends_playlist_list_holder_wrap").hide();
		this.playlist_handler.getList({target:"my_playlist_list_holder"});
	};

	this.load_friends_playlists = function() {
		$("#my_playlist_list_holder_wrap").hide();
		$("#friends_playlist_list_holder_wrap").show();
		this.playlist_handler.getFriendsList({target:"friends_playlist_list_holder"});
	};

	this.edit_playlist = function (id) {
		$("#edit_playlist_hide").click(function(e){
			e.preventDefault();
			handle.edit_playlist_hide();
		});
		var target = $("#edit_playlist_wrap");
		target.css({
			width	:	"400px",
			position:	"absolute",
			left	:	(clientWidth() / 2 - 400 / 2) + scrollLeft(),
			top		:	(clientHeight() / 2 - 100 / 2 ) + scrollTop()
		}).show();
		this.playlist_handler.edit(id);
	}
	this.edit_playlist_hide = function () {
		this.playlist_handler.playlist_hide();
	}
	this.edit_details_show = function (id) {
		if (id == undefined || id < 0) return;
		this.item_id = id;
		$("#edit_details_wrap").css({
				width	:	"500px",
				left	:	(clientWidth() / 2 - 400 / 2) + scrollLeft(),
				top		:	(clientHeight() / 2 - 100 / 2 ) + scrollTop(),
				position:	"absolute"
			}
		).show();
		$("#edit_details_btn").hide();
		$("#edit_details_form").unbind("submit").bind("submit", function (e) {
				e.preventDefault();
				var genre = [];
				$.each($("#detail_edit_genre_list_wrap input:checked"),function(){
					genre.push($(this).val());
				});
				genre = genre.join(":");

				var o = {
					act			: "saveDetails",
					id			: handle.item_id,
					title		: $("#detail_title_edit").val(),
					description	: $("#detail_description_edit").val(),
					artist		: $("#detail_artist_edit").val(),
					album		: $("#detail_album_edit").val(),
					genre		: genre
				};

				$.post(handle.gate, o, function (data) {
						if (data.state) {
							var src = $("#library_item_" + handle.item_id);
							$(".title", src).text(o.title);
							$(".description", src).text(o.description);
							$(".artist", src).text(o.artist);
							$(".album", src).text(o.album);
							if (o.artist != '' && o.album != '') {
								$(".artist_album_sep", src).show();
							} else {
								$(".artist_album_sep", src).hide();
							}
							handle.log({target:"edit_details_state", msg:data.msg.join("\n"), state:1});
							self.edit_details_hide();
						} else {
							handle.render_err(data.err);

						}
					},
					"json"
				);
			});
		$.post(
			this.gate,
			{act:"get_details", id:id},
			function (data) {
				if (data.state) {
					$("#edit_details_image").css({"background":"url("+data.data.thumbnail+") center center"});
					$("#edut").text(data.data.title);
					$("#detail_title_edit").val(data.data.title);
					$("#detail_description_edit").val(data.data.description);
					$("#detail_artist_edit").val(data.data.artist);
					$("#detail_album_edit").val(data.data.album);
					$("#detail_edit_genre_list_wrap").html(data.genre_list_html);
					$("#edit_details_btn").show();

				}
			},
			"json"
		);
		$("#edh").click(function(e){
			e.preventDefault();
			handle.edit_details_hide();
			$(this).unbind("click");
		});
		$("#detail_title_edit, #detail_description_edit, #detail_artist_edit, #detail_album_edit").val('');
		$("#detail_edit_genre_list_wrap").empty();
	};

	this.edit_details_hide = function () {
		$("#edit_details_wrap").hide();
		$("#edit_details_form").unbind("submit");
	};

	this.remove = function (id) {
		if (id == undefined || id < 0) return;
		if(confirm(language.msg.confirm)){
			$.post(
				this.gate,
				{act:"remove", id:id},
				function (data) {
					if (data.state) {
						$("#library_item_"+id).remove();
					} else {
						alert(data.err.join("\n"));
						//handle.log();
					}
				},
				"json"
			);
		}
	};
	
	this.remove_all = function (e) {
		e.preventDefault();
		
		var btn = $("#remove_all");
		var obj = {
			act		:	'removeItems',
			items	:	[]
		};
		$.each($(".library_item_checkbox:checked"), function (e) {
			obj.items.push(Number($(this).val().trim()));
		});
		if (obj.items.length == 0) {
			try {
				alert(language.validation.please_select_at_list_one_item);
			} catch (e) {
				alert(e);
			}
			return;
		}
		if (confirm(language.msg.confirm)) {
			obj.items = obj.items.join(",");
			$.post(gate, obj, function (data) {
					if (data.state) {
						for (var i in obj.items.split(",")) {
							$("#library_item_"+obj.items.split(",")[i]).remove();
						}
					} else {

					}
					btn.show();
				},
				"json"
			);
			btn.hide();
		}
	};

	this.load_alpha_list = function() {
		/*$.post(gate, {act:"getCommonAlphaList", o:Math.random()}, function (data) {
			if (data.state) {
				$(".s_alphabet_index").append(data.content);
				$(".s_alphabet_index a.alpha").click(function(){
					self.load_front_alpha_list({page:1, word: $(this).text()});
				});
			}
		},
		"json");*/
	}
	
	this.load_front_alpha_list = function (data) {
		if (data.word != undefined) this.word = data.word;
		this.list_mode = "alpha";
		var target = $("#playlist_wrap, #main_holder_content");
		var page = data.page == undefined ? this.page : data.page;
		var obj = {act:"getList", page:page, mode:"alpha", word:this.word};

		$('a', target).unbind("click");

		$.post(gate, obj, function (data) {
				if (data.state) {
					target.empty().append(data.content);
					library_obj.attachLibraryItemsAction();
					$(".get_page_alpha").unbind("click").click(function (e) {
						//alert(e.target.id.split("_")[1]);
					});
					$(".get_page_alpha_next").unbind("click").click(function (e) {
						//alert(e.target.id.split("_")[1]);
					});
					$(".get_page_alpha_last").unbind("click").click(function (e) {
						//alert(e.target.id.split("_")[1]);
					});
					$(".get_page_alpha_prev").unbind("click").click(function (e) {
						//alert(e.target.id.split("_")[1]);
					});
					$(".get_page_alpha_first").unbind("click").click(function (e) {
						//alert(e.target.id.split("_")[1]);
					});
				} else {
					library_obj.log({target:'library_hold_state', msg:'error', state:1});
				}
			},
			"json"
		);
		//clean old events
		target.html(language.msg.loading);
	};

	this.load_front_genre_list = function (data) {
		if (data.genre != undefined) this.genre = data.genre;
		this.list_mode = "genre";
		var target = $("#playlist_wrap, #main_holder_content");
		var page = data.page == undefined ? 1 : data.page;
		var obj = {act:"getList", page:page, mode:"genre", genre:this.genre};

		$.each($('a', target),function(){$(this).unbind("click");});
		
		$.post(
			this.gate,
			obj,
			function (data) {
				if (data.state) {
					target.empty().append(data.content);
					library_obj.attachLibraryItemsAction();
				} else {
					library_obj.log({target:'library_hold_state', msg:'error', state:1});
				}
			},
			"json"
		);
		target.html(language.msg.loading);
	};

	this.artist_info_show = function (artist) {
		var target = $("#artist_info_wrap");
		$("#aih").click(function(e){
			e.preventDefault();
			target.hide();
			$("#artist_info_name, #artist_info_genre, #artist_info_content, #artist_info_state").empty();
			$("#artist_info_image").removeAttr("src");
			$(this).unbind("click");
		});
		$(".plwait").show();
		$("#artist_info_hold").hide();
		$.post(this.gate, {act:"getArtistInfo", artist: artist}, function (data) {
				if (data.state) {
					if (data.data.name != undefined) {
						$("#artist_info_name").text(data.data.name);
						$("#artist_info_genre").text(data.data.genre);
						$("#artist_info_image").attr("src", data.data.image);
						$("#artist_info_content").html(data.data.content);
					} else {
						$("#artist_info_state").text(data.err.join("\n"));
					}
					$("#artist_info_content").show();
				} else {
					$("#artist_info_state").text(data.err.join("\n"));
				}
				$(".plwait").hide();
				$("#artist_info_hold").show();
			},
			"json"
		);
		target.css({
			width		:	'600px',
			left		:	(clientWidth() / 2 - 600 / 2) + scrollLeft(),
			top			:	scrollTop() + 10,
			position	:	"absolute"
		}).show();

	};
	
	this.album_info_template_load = function(arr) {
		$.post(this.gate, {act:"getAlbumInfoTemplate", o:Math.random()}, function (data) {
				$("#template_wrapper").append(data.content);
				$(".s_draggable").draggable({handle:'h2'});
				handle.albumInfoLoaded = 1;
				handle.album_info_show(arr);
			},
			"json"
		)
	};

	this.album_info_show = function (arr) {
		var target = $("#album_info_wrap");
		if (handle.albumInfoLoaded == null) {
			this.album_info_template_load(arr);
			return;
		} else {
			$(".plwait").show();
			$("#album_info_hold").hide();
			$("#aiha").click(function(e){
				e.preventDefault();
				target.hide();
				$("#album_info_link").removeAttr("href");
				$("#album_info_image").removeAttr("src");
				$("#album_info_album, #album_info_artist, #album_info_release, #album_info_songs, #album_info_state").empty();
				$(this).unbind("click");
			});
			$.post(
				this.gate,
				{act:"getAlbumInfo", album: arr[0], artist: arr[1], song: arr[2]},
				function (data) {
					$(".plwait").hide();
					$("#album_info_hold").show();
					if (data.state) {
						$("#album_info_album").text(data.data[0].album);
						$("#album_info_artist").text(data.data[0].artist);
						$("#album_info_release").text(data.data[0].release);
						$("#album_info_link").show().attr("href", data.data[0].link);
						$("#album_info_image").attr("src", data.data[0].image);
						var discs = [];
						for (var i = 0; i < data.data.length; i++) {
							var diskId = data.data[i].disc;
							if (discs[diskId] == undefined) {
								discs[diskId] = [];
							}
							discs[diskId].push("<li>"+ data.data[i].song + "</li>");
						}
						for (var j = 0; j < discs.length; j++) {
							var currentDisk = (discs.length > 1) ? "<p>Disk " + (j+1) + "</p>" : '';
							$("#album_info_songs").append( currentDisk + "<ol>"+ discs[j].join("\n") + "</ol>");
						}
					} else {
						$("#album_info_link").hide();
						$("#album_info_state").text(data.err.join("\n"));
					}
				},
				"json"
			);
			target
				.css({
						width		:	'600px',
						
						left		:	(clientWidth() / 2 - 600 / 2) + scrollLeft(),
						top			:	scrollTop() + 10,
						position	:	"absolute"
					})
				.show();
		}
	};
	this.lyrics_info_template_load = function(arr) {
		$.post(
			this.gate,
			{act:"getLyricsInfoTemplate", o:Math.random()},
			function (data) {
				$("#template_wrapper").append(data.content);
				$(".s_draggable").draggable({handle:'h2'});
				handle.lyricsInfoLoaded = 1;
				handle.lyrics_info_show(arr);
			},
			"json"
		)
	};

	this.lyrics_info_show = function (arr) {
		var target = $("#lyrics_info_wrap");
		if (handle.lyricsInfoLoaded == null) {
			this.lyrics_info_template_load(arr);
			return;
		} else {
			$(".plwait").show();
			$("#lyrics_info_state").text('');
			$("#lyrics_info_hold").show();
			$("#liha").click(function(e){
				e.preventDefault();
				target.hide();
				$("#lyrics_info_album, #lyrics_info_artist, #lyrics_info_release, #lyrics_info_song, #lyrics_info_state, #lyrics_info_content").empty();
				$("#lyrics_buy_link").hide().attr("href", "javascript:;");
				$("#lyrics_info_image").hide().removeAttr("src");
				$(this).unbind("click");
			});
			$.post(gate, {act:"getLyricsInfo", album: arr[0], artist: arr[1], song: arr[2]}, function (data) {
					if (data.state) {
						$("#lyrics_info_album").text(data.data.album);
						$("#lyrics_info_artist").text(data.data.artist);
						$("#lyrics_info_song").text(data.data.song);
						$("#lyrics_info_release").text(data.data.release);
						$("#lyrics_buy_link").show().attr("href", data.data.link);
						$("#lyrics_info_image").show().attr("src", data.data.image);
						$("#lyrics_buy_link").show().attr("href", data.data.link);
						$("#lyrics_info_content").html(data.data.lyric);
					} else {
						/* copy sam go tova ot click eventa na #liha */
						$("#lyrics_info_album, #lyrics_info_artist, #lyrics_info_release, #lyrics_info_song, #lyrics_info_state, #lyrics_info_content").empty();
						$("#lyrics_buy_link").hide().attr("href", "javascript:;");
						$("#lyrics_info_image").hide().removeAttr("src");
						$("#lyrics_info_state").text(data.err.join("\n"));
					}
					$(".plwait").hide();
				},
				"json"
			);
			target.css({
				width		:	'600px',
				left		:	(clientWidth() / 2 - 600 / 2) + scrollLeft(),
				top			:	scrollTop() + 10,
				position	:	"absolute"
			}).show();
		}
	};
	
	this.load_library = function (select) {
		
		if (!load_library) return;
		var target = $("#playlist_wrap, #main_holder_content");
		target = $("#explorer_library");
		
		if (select == undefined) {
			MainTabs.select(0);
		}

		var obj = {act:"getLibrary", page:self.page};
		if (self.mode == "word") {
			obj.word = self.word;
		}
		if (self.filter.word != null) obj.word = self.filter.word;
		if (self.filter.genre != null) obj.genre = self.filter.genre;
		$.post(gate, obj, function (data) {
				if (data.state) {
					target.empty().append(data.content);
					//self.load_alpha_list();
					self.attachLibraryItemsAction();
					$('#page_item_banner iframe').clone(true).appendTo('#current_library_render .s_clip_banner');
				} else {
					self.log({target:'library_hold_state', msg:'error', state:1});
				}
			},
			"json"
		);
		//clean old events
		//$.each($("#main_holder_content a"), function(){$(this).unbind("click");});
		//$(".add_to_playlist, .edit_details_show, .remove_from_library").unbind("click");
		target.html(language.msg.loading);
		target.hide();
	};

	this.recommend_accept = function(obj) {
		var id = Number( obj.type != undefined ? Number(obj.target.id.split('_')[1]) : obj);
		if (id < 0) return;
		$.post(gate, {act:"acceptRecommendMedia", id:id}, function (data) {
				if (data.state) {
					self.load_library();
				} else {
					self.log({target:'library_state', msg:data.err.join("\n"), state:2});
				}
			},
			"json"
		);
	};
	
	this.getParam = function (obj, index) {
		return Number($(obj).attr("id").split("_")[index]);
	};

	this.recommend_reject = function (obj) {
		var id = Number(obj.type != undefined ? Number(obj.target.id.split('_')[1]) : obj);
		if (id < 0) return;
		$.post(gate, {act:"rejectRecommendMedia", id:id}, function (data) {
				if (data.state) {
					self.load_library();
				} else {
					self.log({target:'library_state', msg:data.err.join("\n"), state:2});
				}
			},
			"json"
		);
	};

	this.add_to_batch = function (obj) {
		this.batch.push(obj);
	};
	
	this.attachLibraryItemsAction = function() {
		
		$("#reload_list").unbind("click", function(e){
			e.preventDefault();
			switch(self.list_mode) {
				case "alpha":
					self.load_front_alpha_list({});
				break;
				case "genre":
					self.load_front_genre_list({});
				break;
			}
		});
		$("#add_to_library_form").unbind("submit").submit(function(e){
			e.preventDefault();
			handle.add_to_library();
		});
		self.fixSClipHover();
		$("#explorer_library").show();
	};
	
	this.fixSClipHover = function () {
		//alert('fix');
		/*var index = 100;
		$.each(
			$("#current_library_render > li"),
			function(){
				$(this).css("z-index", index);
				index--;
			}
		);*/
		$("#current_playlist_render > li").removeClass("s_clip_last").removeAttr("style");
		var total = $("#current_playlist_render > li").length - 1;
		if (total > 4) {
			$("#current_playlist_render > li").eq(total-1).addClass("s_clip_last");
			$("#current_playlist_render > li").eq(total).addClass("s_clip_last");
		}

		/*index = 300;
		$.each(
			$("#current_library_render > li"),
			function(){
				var className = $(this).attr("class");
				if (className == "s_clip s_clip_nodrag s_clip_last" || className == "s_clip  s_clip_last") {
					$(this).css("z-index", 300);
				} else {
					$(this).css("z-index", index);
				}
				index--;
			}
		);*/
		//if ($.browser.msie || 1) {
			$(".s_clip").hover(function() {
				$(this).addClass("s_clip_hover");
			}, function() {
				$(this).removeClass("s_clip_hover");
			});
		//}
	};
	
	function init () {
		handle.attachActions();

		$("#library_filters a.alpha").live("click", function(e){
			e.preventDefault();
			self.setFilter(["word",$(this).text()]);
			self.setFilter(["genre",null]);
			self.load_library();
		});

		$("#library_filters a.genre").live("click", function(e){
			e.preventDefault();
			self.setFilter(["genre",Number(e.target.id.split("_")[1])]);
			self.setFilter(["word",null]);
			self.load_library();
		});

		$("#library_filters .drop_library_filter span").live("click", function(e){
			e.preventDefault();
			self.dropFilters();
			self.load_library();
		});

		$(".rmly").live("click", function(e){
			e.preventDefault();
			self.rate({id:e.target.id.split("_")[1], vote:'y'});
		});
		$(".rmln").live("click", function(e){
			e.preventDefault();
			self.rate({id:e.target.id.split("_")[1], vote:'n'});
		});
		$(".back_to_library").live("click", function(e){
			e.preventDefault();
			load_library = true;
			self.load_library(0);
		});
		$(".edit_details_show").live('click', function(e) {
			e.preventDefault();
			handle.edit_details_show($(this).attr("id").split("_")[1]);
		});
		$(".remove_from_library").unbind("click").live('click', function(e){
			e.preventDefault();
			handle.remove(e.target.id.split("_")[1]);
		});
		$(".share_all").live('click', function(e){
			e.preventDefault();
			handle.share_all();
		});
		$("#share_form_single_textarea").live('click', function(e){
			e.preventDefault();
			$(this).select();
		});
		//change this to direct map
		$(".viewartistinfo").live('click', function (e) {
			e.preventDefault();
			var id = Number(e.target.id.split("_")[1]);
			var item = '';
			$.each(
				$("#library_item_"+id+" span.artist"),
				function() {
					if (item == '') {
						item = $(this).text();
					}
				}
			);
			handle.artist_info_show(item);
		});
		
		$(".viewalbuminfo").live('click', function(e) {
			e.preventDefault();
			var id = Number(e.target.id.split("_")[1]);
			var artist	=	'';
			var album	=	'';
			var song	=	'';
			$.each($("#library_item_"+id+" span.artist"), function() {
					if (artist == '') {
						artist = $(this).text();
					}
				}
			);
			$.each($("#library_item_"+id+" span.album"), function() {
					if (album == '') {
						album = $(this).text();
					}
				}
			);
			$.each($("#title_"+id), function() {
					if (song == '') {
						song = $(this).text();
					}
				}
			);
			handle.album_info_show([album, artist, song]);
		});
		

		
		$("#add_to_library_form").submit(function(e){
			e.preventDefault();
			handle.add_to_library();
		});
		//live events
		$("#atlh").live('click', handle.add_to_library_hide);
		$("#remove_all").live('click', handle.remove_all);

		$(".share").live('click', handle.share_show);
		$(".s_share").live('click', handle.share_show);
		//$(".s_share").live("click", handle.share_show);
		//$(".share").live("click", handle.share_show);
		//alert( typeof handle.share_show);


		$(".recommend_accept").live('click', handle.recommend_accept);
		$(".recommend_reject").live('click', handle.recommend_reject);

		$(".reload_library").live('click', function() {
			//alert('op');
			MainTabs.select(0);
		});
		$(".reload_mostPopular").live('click', handle.getMostPopular);
		$(".reload_topFavorites").live('click', handle.getTopFavorites);
		$(".reload_mostListened").live('click', handle.getMostListened);
		$(".reload_recentlyAdded").live('click', handle.getRecentlyAdded);

		$(".view_lyrics").live('click', function (e) {
			e.preventDefault();
			var id = Number(e.target.id.split("_")[1]);
			var target = $("#library_item_" + id);
			handle.lyrics_info_show([$(".album", target).text(), $(".artist", target).text(), $("#title_"+id, target).text()]);
		});
		
		$(".view_lyrics_item").live('click', function (e) {
			e.preventDefault();
			var target, album, artist, title;
			switch (player_obj.mode) {
				case "media":
					/*var id = Number(player_obj.current_item_id);
					target = $("#library_item_" + id);
					album	=	$(".album", target).text();
					artist	=	$(".artist", target).text();
					title	=	$("#title_"+id, target).text();*/
					album	=	player_obj.current_item_album;
					artist	=	player_obj.current_item_artist;
					title	=	player_obj.current_item_title;
				break;
				case "playlist":
					target = $("#current_playlist_render li").eq(player_obj.current_index);
					album	=	$(".album", target).text();
					artist	=	$(".artist", target).text();
					title	=	$(".title", target).text();
				break;
				case "library":
					target = $("#current_library_render li").eq(player_obj.current_index);
					album	=	$(".album", target).text();
					artist	=	$(".artist", target).text();
					title	=	$(".title", target).text();
				break;
				case "search":
					album	=	'';
					artist	=	'';
					title	=	$("#player_current_play").text();
			}

			//alert(player_obj.mode+':'+album+':'+artist+':'+title);

//			if (title != '' && (artist != '' || album != '')) {
			if (title != '') {
				handle.lyrics_info_show([album, artist, title]);
			}
		});

		$(".library_page").live("click", function(e){
			e.preventDefault();
			self.get_page(e.target.id.split("_")[1]);
		});
		//search
		$(".search_all_add_to_Library").live('click', function(e){
			e.preventDefault();
			if ($(".search_item_checkbox:checked").length == 0) return;
			var obj		=	{
				act:"add_to_library_complex",
				total:0
			};
			var j		=	0;
			$.each($(".search_item_checkbox:checked"), function() {
				var data = $(this).attr("id").split("_");
				var item = $("#"+data[1]+"_search_item_"+data[2]);
				obj['duration_'+j]	=	$(".duration", item).text();
				obj['engine_'+j]	=	$(".engine", item).text();
				obj['thumbnail_'+j]	=	$(".thumbnail_url", item).text();
				obj['title_'+j]		=	$(".title", item).text();
				obj['url_'+j]		=	$(".url", item).text();
				j++;
			});

			obj.total = j;
			if (obj.total == 0) {
				try {
					alert(language.validation.please_select_at_list_one_item);
				} catch (e) {
					alert(e);
				}
				return;
			}
			$.post(gate, obj, function (data) {
				if (data.state) {
					self.log({msg:data.msg.join("\n"), state:1});
				} else {
					self.log({msg:data.err.join("\n"), state:1});
				}
			}, "json");
		});
		$(".play_tour").live("click", function(e){
			e.preventDefault();
			$.post(gate, {act:"getTourUrl"}, function(data) {
				if (data.state) {
					try {
						player_obj.play_url(data.url);
					} catch (e) {
						//alert(e);
					}
				}
			},"json");
		});
	}
	init();
	//live common
	$("#common_holder #cmfavorites").live("click", self.getTopFavorites);
	$("#common_holder #cmpopular").live("click", function(e){
		e.preventDefault();
		self.getMostPopular();
	});
	$("#common_holder #cmrecently").live("click", function(e){
		e.preventDefault();
		self.getRecentlyAdded();
	});
	$("#common_holder #cmlistened").live("click", function(e){
		e.preventDefault();
		self.getMostListened();
	});
}

/* search  */
var SearchModel = function()
{
	var self		=	this;
	//var gate		=	;

	this.controller =	"search";
	this.speed		=	500;
	this.gate		=	conf.full_url + this.controller + '/gate';
	var gate		=	conf.full_url + this.controller + '/gate';
	this.page		=	1;
	this.temp		=	[];
	this.cache		=	{};
	this.q			=	'';
	this.pages		=	[];
	this.tab_list	=	null;
	this.tab_key	=	{};
	this.tabSelected = null;

	var searchWraperHeight	=	380;
	var genreWrapperHeight	=	0;
	var search_word			=	'';
	
	//public library handler
	// public state handler
	this.state_handler				=	state_obj || new StateModel();

	//this.player_handler				=	player_obj;
	
	this.log = function(msg, state) {
		this.state_handler.log(this.controller + "_out", msg, state);
	};

	this.getItemById = function (id) {
		var out = '';
		for (var i in search_obj.cache) {
			for (var j in search_obj.cache[i]) {
				if (search_obj.cache[i][j].id == id) {
					out = search_obj.cache[i][j];
				}
			}
		}
		return out;
	};

	this.get_page = function (engine, page) {
		this.page = page > 0 ? page : 1;
		this.getSearchResult({q:this.q, page:this.page, key:engine});
	};

	this.load_search_form_wrapper = function() {
		var target = $("#main_holder_content");
		target = $("#search_result_wrapper_wrap");
		$.post(
			self.gate,
			{act:"getSearchFromWrapper"},
			function (data) {
				if (data.state) {
					self.tab_list = data.tab_list;
					for(var i in self.tab_list) {
						self.tab_key[self.tab_list[i]] = Number(i);
					}
					target.html(data.content);
					try {
						SearchTabs = new TabModel("#search_result_wrapper .search_tabulation");
						SearchTabs.init('normal');
					} catch (e) {
						alert(e);
					}
				} else {
					alert("error loading search handler");
				}
				self.search();
			},
			"json"
		);
		target.html(language.msg.loading);
	};

	function wow() {
		
	}

	this.search = function () {
		genreWrapperHeight = $("#search_genre_wrap").height();
		update();
		//reset search page
		this.page = 1;
		
		if (typeof $("#search_result_wrapper").attr('id') == "undefined") {
			this.load_search_form_wrapper();
			return;
		} else {
			var items	=	[];
			var genre	=	[];
			
			this.q		=	$("#search_term").val();

			var obj = {q:this.q, page:this.page}
			$.each($("input.search_locations:checked"), function() {
				items.push($(this).attr("id").split("_")[1]);
			});
			$.each($("input.search_genres:checked"), function() {
				genre.push($(this).attr("id").split("_")[1]);
			});
			
			for (var i in this.temp) {
				$("#"+this.temp[i]+"_result_hold a").unbind("click");
				$("#"+this.temp[i]+"_result_hold, ."+this.temp[i]+"_result_pagination").html('');
			}
			
			if (genre.length > 0) {
				obj.genre = genre.join(",");
			}
			//hide tabs
			//select the first next
			var selected_index	=	self.tab_key[items[0]];
			var selected_engine	=	self.tab_list[selected_index];
			
			SearchTabs.select(selected_index);

			/*for (var k in self.tab_list) {
				//for(var m in items) {
					//if (alert(self.tab_list[k]);
				}
			}*/
			for (var m in items) {
				obj.key = items[m];
				this.temp.push(items[m]);
				this.getSearchResult(obj);
			}
		}
	};

	this.getSearchResult = function (obj) {
		var index = obj.key;
		var target = $("#"+obj.key+"_result_hold");
		var data = {act:"get_search_single", page:this.page, q:obj.q, engine:obj.key};
		if (obj.genre != undefined) {
			data.genre = obj.genre;
		}
		$("#"+obj.key+"_result_hold a").unbind("click");
		target.html(language.msg.loading);
		$.post(gate, data, function (data) {
				for (var m in self.tab_list) {
					if (self.tab_list[m] === index) {
						//$("#search_tab_" + self.tab_list[m]).show();
						//$("#"+self.tab_list[m]+"_hold").show();
						//Tabs.enable(m);
					}
				}
				self.cache[obj.key] = data.items;
				//alert(data.content);
				target.html(data.content);
				//pagination
				/*var pagination_target = $("."+obj.key+"_result_pagination");
				pagination_target.html(data.pagination);*/
				if (data.searches_left != undefined) {
					$('#search_warning_count').text(data.searches_left);
				}
				$("a.pager", target).click(function(e){
					var data = e.target.id.split("_");
					self.get_page(data[1], Number(data[2]));
				});
				$(".play_media_local").unbind("click").click(function(e){
					e.preventDefault();
					player_obj.play_library_item(Number(e.target.id.split("_")[1]));
				});
				$(".add_to_library", target).click(function(e){
					e.preventDefault();
					var data	=	e.target.id.split("_");
					library_obj.add_to_library_show({engine:data[3], index:Number(data[4])});
				});
				/*$(".rate_media", target).click(function(){
					var data = $(this).attr("id").split("_");
					$("#rmw_"+data[1]+"_"+data[2]).show();
					$(".rmly", target).click(function(e){
						library_obj.rate({id:$(this).attr("id").split("_")[1], vote:'y'});
					});
					$(".rmln", target).click(function(e){
						library_obj.rate({id:$(this).attr("id").split("_")[1], vote:'n'});
					});
				});*/
				update();
				$('#page_item_banner iframe').clone(true).appendTo('#' + index + '_search_wrap .s_clip_banner');
			},
			"json"
		);
	};

	var update = function() {
		
		$(".search_result_wrappers").height(searchWraperHeight - genreWrapperHeight);
	}

	genreWrapperHeight = $('#search_genre_wrap').height();

	this.init = function() {

		$("#search_form").submit(function(e) {
			e.preventDefault();
			if ($('#label_local').attr('checked')) {
				genreWrapperHeight = $('#search_genre_wrap').height();
			}

			if (search_word == $("#search_term").val()) return;

			if ($("input.search_locations:checked").length == 0 || $("#search_term").val() == '') {
				return;
			}

			self.search();
			if ($("#search_result_wrapper").attr("id") != undefined ) {
				e.preventDefault();
			}
		});
		
		//attach all button
		$("#label_all").click(function (e) {
			if (e.target.checked) {
				$("input.search_locations").attr("checked", "checked");
				genreWrapperHeight = $("#search_genre_wrap").height();
				update();
				$('#search_genre_wrap').show();
			} else {
				$("input.search_locations").removeAttr("checked");
				genreWrapperHeight = 0;
				update();
				$('#search_genre_wrap').hide();
			}
			update();
		});

		$("#label_local").click(function (e) {
			if (e.target.checked) {
				genreWrapperHeight = $("#search_genre_wrap").height();
				update();
				$("#search_genre_wrap").show();
			} else {
				genreWrapperHeight = 0;
				update();
				$("#search_genre_wrap").hide();
			}
		});

		$(".play_media_search").live('click', function (e) {
			e.preventDefault();
			play_rand	=	false;
			var data	=	e.target.id.split("_");
			var url		=	$("#" + data[1] + "_search_item_"+data[2]+" .url").text();
			var title	=	$("#" + data[1] + "_search_item_"+data[2]+" h3").text();
			var image	=	$("img#pm_" + data[1] + "_"+data[2]).attr("src");
			try {
				player_obj.mode = "search";
				player_obj.play_encoded_url({engine:data[1], url:url, title:title, image:image, engine_title:data[1]});//$("#"+obj.key+"_hold > h2").text()});
			} catch (e) {
				//alert('search init err ' + e);
			}
		});
		//
		search_word = conf.default_search_string;
		
		$("#search_term").bind("blur", function(){
			if ($(this).val() == "") {
				$(this).val(search_word);
			}
		});
		$("#search_term").bind("focus", function(){
			if ($(this).val() == search_word) {
				$(this).val('');
			}
		});

		if ($('#label_local').attr('checked')) {
			$('#search_genre_wrap').show();
		}

		//search results
		$(".select_all_search_results").live('click', function (e) {
			if (e.target.checked) {
				$(".select_all_search_results").not("checked").attr("checked","checked");
				$(".search_item_checkbox").attr("checked", "checked");
			} else {
				$(".select_all_search_results").removeAttr("checked");
				$(".search_item_checkbox").removeAttr("checked");
			}
		});
		//tag handle
		$(".tag_handle").live("click", function(e){
			e.preventDefault();
			MainTabs.select(3);
			$("#search_where input").removeAttr("checked");
			$("#label_local").attr("checked", "checked");
			$('#search_genre_wrap').show();
			genreWrapperHeight = $("#search_genre_wrap").height();
			var str = $("span", this).text();
			$("#search_term").val(str);
			$("#search_form").submit();
		});
		update();
	};
	this.init();
};

/* user */
var FriendModel = function (par)
{
	var handle	=	this;
	var parent	=	par || par;
	var lang	=	language || null;
	
	this.parent = par;
	this.page = 0;

	this.getParam = function (obj, index) {
		return 	$(obj).attr("id").split("_")[index];
	};
	
	this.add = function (id)
	{
		if (id < 0) return;
		$.post(this.parent.gate, {act:"addFriend", friend_id:id}, function (data) {
				if (data.state) {
					alert(data.msg.join("\n"));
				} else {
					alert(data.err.join("\n"));
				}
				//$("#atf_"+id).show();
			},
			"json"
		);
	};

	this.remove = function (id) {
		if (id < 0) return;
		if (confirm(lang.msg.confirm)) {
			$.post(this.parent.gate, {act:"removeFriend", friend_id:id}, function (data) {
					if (data.state) {
						$("#friend_hold_"+id).remove();
						handle.parent.log({target:"friend_state", msg:data.msg.join("\n"), state:1});
					} else {
						handle.parent.log({target:"friend_state", msg:data.err.join("\n"), state:2});
					}
				},
				"json"
			);
		}
	};

	var accept = function (o) {
		try {
			o.preventDefault();
		} catch (e) {

		}
		var id = Number(o.type == "click" ? o.target.id.split("_")[1] : o);
		if (id < 0) return;
		$.post(parent.gate, {act:"acceptFriendRequest", friend_id:id}, function (data) {
				if (data.state) {
					$("#pending_hold_"+id).remove();
					$("#friend_item_info_"+id).remove();
					if ($("#user_pending_friend_list ul li").length == 0) {
						$("#user_pending_friend_list").remove();
						handle.getList();
					}
				} else {
					alert(data.err.join("\n"));
				}
			},
			"json"
		);
		
	};

	var reject = function (o) {
		try {
			o.preventDefault();
		} catch (e) {
			//alert(e);
		}
		var id = Number(o.type == "click" ? o.target.id.split("_")[1] : o);
		if (id < 0) return;
		$.post(parent.gate, {act:"rejectFriendRequest", friend_id:id}, function (data) {
				if (data.state) {
					$("#pending_hold_"+id).hide().remove();
					$("#friend_item_info_"+id).remove();
					if ($("#user_pending_friend_list ul li").length == 0) {
						$("#user_pending_friend_list").remove();
						handle.getList();
					}
				} else {
					alert(data.err.join("\n"));
				}
			},
			"json"
		);
	};

	this.getList = function (select) {
		var target = $("#user_friend_list_hold, #main_holder_content");
		target = $("#explorer_friends");

		if (select == undefined) {
			MainTabs.select(2);
		}
		target.html(lang.msg.loading);
		
		$('a', target).unbind("click");
		$.post(parent.gate, {act:"getFriendList"}, function (data) {
				if (data.state) {
					target.html(data.content);
					$(".cfr").click(function(e){
						var id = e.target.id.split("_")[1];
						$.post(
							parent.gate,
							{act:"cancelFriendRequest", friend_id:id},
							function (data) {
								if (data.state) {
									parent.log({target:"friend_state", msg:data.msg.join("\n"), state:1});
									$("#friend_hold_"+id).remove();
								} else {
									parent.log({target:"friend_state", msg:data.err.join("\n"), state:2});
								}
							},
							"json"
						);
					});
					$(".reject_friend_request").click(function(e){
						handle.reject(e.target.id.split('_')[1]);
					});
					$(".remove_from_friends").click(function(e){
						handle.remove(e.target.id.split('_')[1]);
					});
				} else {
					alert(data.err.join("\n"));
				}
			},
			"json"
		);
		
	};
	//
	$(".afr").live('click', accept);
	$(".rfr").live('click', reject);
	$(".friend_list_reload").live('click', this.getList);
};
var UserModel = function()
{
	var handle		=	this;
	var self		=	this;
	var lang		=	language || null;
	var gate		=	conf.base_url + "profile/gate";
	var current		=	{
		user_id:0
	}
	
	this.getCurrent = function() {
		return current;
	}

	this.controller =	"user";
	this.speed		=	500;
	this.page		=	0;
	this.gate		=	conf.base_url + "profile/gate";

	
	this.clean		=	[];

	this.isProfilesLoaded = false;

	this.friend_handler = new FriendModel(this);

	// public state handler
	this.state_handler				=	state_obj || new StateModel;
	this.log = function (obj) {
		this.state_handler.log(obj.target, obj.msg, obj.state);
	};

	this.loadAvatar = function() {
		$.post(gate, {act:"getAvatar"}, function (data) {
				if (data.avatar != undefined) {
					//$("#avatar_image").attr("src", data.avatar);
					$(".s_avatar > div").css("background", "url("+data.avatar+") no-repeat center center");
				}
			},
			"json"
		);
	};

	this.load_profiles = function(select) {
		//var target = $("#profiles_wrap, #main_holder_content");
		var target = $("#explorer_profiles");
		if (select == undefined) {
			MainTabs.select(4);
		}
		$('a', target).unbind("click");
		$.post(gate, {act:"userList", page:handle.page}, function (data) {
				if (data.state) {
					//new
					$("#profiles_list_hold", target).html(data.content);
					//assign action
					$("#friend_search_form_form").submit(function(e) {
						e.preventDefault();
						handle.search();
					});
					
					if (conf.user_id == null) {
						$(".addtofriend").hide();
					} else {
						$(".addtofriend").click(function(e){
							handle.friend_handler.add(e.target.id.split("_")[1]);
							$(this).hide();
						});
					}
				} else {
					alert(data.err.join("\n"));
				}
			},
			"json"
		);
		try {
			//handle.unbindListActions();
		} catch (e) {
			alert(e);
		}
		$("#profiles_list_hold").html(lang.msg.loading);
	};

	this.load_user_profile = function (o) {
		self.halt_profile_load = true;

		var username = o.type != undefined ? Number(o.target.id.split("_")[1]) : o;

		var target	=	$("#profiles_wrap, #main_holder_content");
		var tab		=	$("#tab_profile");
		target		=	$("#explorer_profile");
		//
		target.show();
		tab.show();
		//
		MainTabs.select(5);
		$('a', target).unbind("click");

		$.post(gate, {act:"get_profile_info", username:username}, function (data) {
				if (data.state) {
					//new
					$(target).html(data.content);
					$("#modify_profile_data").unbind("submit").submit(function(e){
						alert('here');
						e.preventDefault();
						$.post(handle.gate, {
								act:"profileModifyData",
								profile_username:$("#profile_modify_username").val(),
								profile_email:$("#profile_modify_email").val(),
								profile_private: $("#profile_modify_private").is(":checked") ? 'yes' : 'no'
							}, function (data) {
								if (data.state) {
									handle.log({target:"modify_profile_data_state", msg:data.msg.join("\n"), state:1});
								} else {
									handle.render_err(data.err);
								}
							},
							"json"
						);
					});
					$("#modify_account_settings").unbind("submit").submit(function(e){
						e.preventDefault();
						for (var i in handle.clean) {
							$("#"+i+"_err").text('').hide();
						}
						$.post(handle.gate, {
								act:"profileModifySettings",
								setting_password:$("#setting_password").val(),
								setting_passconf:$("#setting_passconf").val()
							},
							function (data) {
								if (data.state) {
									handle.log({target:"modify_account_settings_state", msg:data.msg.join("\n"), state:1});
								} else {
									handle.render_err(data.err);
								}
							},
							"json"
						);
					});
					_load_library = true;
				} else {
					alert(data.err.join("\n"));
				}
				self.halt_profile_load = false;
			},
			"json"
		);
		target.html(lang.msg.loading);
	};

	this.load_user_profile_new = function (o) {
		if (current.user_id > 0) {
			$(".friend_item_info_" + current.user_id).hide();

			$("#friend_hold_"+current.user_id+" .s_user_status").hide()
			$("#friend_hold_"+current.user_id+" .s_stats").hide();
			
			$(".friend_item_info_hold_" + current.user_id).hide().empty();
			$(".friend_hold_email_"+current.user_id).hide()
		}
		//self.halt_profile_load = true;

		var username = o.type != undefined ? Number(o.target.id.split("_")[1]) : o;

		current.user_id = username;

		
		//var target	=	$("#profiles_wrap, #main_holder_content");
		//var tab		=	$("#tab_profile");
		target		=	$(".friend_item_info_" + current.user_id);
		target_info	=	$(".friend_item_info_hold_" + current.user_id);
		target.show();
		$("#friend_hold_email_"+current.user_id).show();
		//
		//target.show();
		
		//tab.show();
		//
		//MainTabs.select(5);
		//$('a', target).unbind("click");

		$.post(gate, {act:"get_profile_info_new", username:username}, function (data) {
				if (data.state) {
					//new
					$(".friend_hold_"+username+" .s_desc", target).hide();
					$("#friend_hold_"+current.user_id+" .s_user_status").show();
					$("#friend_hold_"+current.user_id+" .s_stats").show();
					$(target_info).html(data.content).show();
				} else {
					alert(data.err.join("\n"));
				}
				//self.halt_profile_load = false;
			},
			"json"
		);
		target_info.html(lang.msg.loading);
	};
	
	this.load_profile = function (select) {
		//self.user_panel_show();

		var target = $("#profiles_wrap, #main_holder_content");
		target = $("#explorer_profile");
		
		if (select == undefined) {
			MainTabs.select(5);
		}
		
		if (self.halt_profile_load) {
			return;
		}
		$('a', target).unbind("click");
		$.post(gate, {act:"get_profile"}, function (data) {
				if (data.state) {
					//new
					//$(target).ready(function(){alert('sddasdas');});
					$(target).html(data.content);
					SubTabs.init('normal');
					$("#modify_profile_data").unbind("submit").submit(function(e){
						e.preventDefault();
						$.post(handle.gate, {
							act:"profileModifyData",
							profile_first_name:$("#profile_modify_first_name").val(),
							profile_username:$("#profile_modify_username").val(),
							profile_email:$("#profile_modify_email").val(),
							profile_description: $("#profile_modify_description").val(),
							profile_private: $("#profile_modify_private").is(":checked") ? 'yes' : 'no'
							}, function (data) {
								if (data.state) {
									$("#user_panel_description").text($("#profile_modify_description").val());
									handle.log({target:"modify_profile_data_state", msg:data.msg.join("\n"), state:1});
								} else {
									
								}
							},
							"json"
						);
					});
					$("#modify_account_settings").unbind("submit").submit(function(e){
						e.preventDefault();
						for (var i in handle.clean) {
							$("#"+i+"_err").text('').hide();
						}
						$.post(
							handle.gate,
							{
								act:"profileModifySettings",
								setting_email:$("#setting_email").val(),
								setting_password:$("#setting_password").val(),
								setting_passconf:$("#setting_passconf").val()
							},
							function (data) {
								if (data.state) {
									handle.log({target:"modify_account_settings_state", msg:data.msg.join("\n"), state:1});
								} else {
									handle.render_err(data.err);
								}
							},
							"json"
						);
					});
				} else {
					alert(data.err.join("\n"));
				}
			},
			"json"
		);
		try {
			//handle.unbindListActions();
		} catch (e) {
			alert(e);
		}
		target.html(lang.msg.loading);
	};


	this.get_search_page = function (page) {
		this.page = page;
		this.search();
	};
	
	

	this.search = function()
	{
		var obj = {
			act	:	"search",
			page:	this.page,
			q	:	$("#friend_search_query").val()
		};
		//if (obj.q == '') return;

		var target = $("#profiles_wrap, #main_holder_content");
		target = $("#explorer_profiles");

		$('a', target).unbind("click");

		$.post(gate, obj, function (data) {
				//search form
				$("#profiles_list_hold", target).empty().html(data.content);
				//action
				$("#friend_search_form_form").unbind("submit").submit(function(e) {
					e.preventDefault();
					handle.search();
				});
			},
			"json"
		);
		$("#profiles_list_hold", target).html(lang.msg.loading);
	};

	this.bindListActions = function () {

	};
	
	this.init_friends = function (select) {
		try {
			handle.friend_handler.getList(select);
		} catch (e) {
			alert(e);
		}
	};

	this.render_err = function (err) {
		for (var i in err) {
			this.clean[i] = 1;
			$("#"+i+"_err").text(err[i]).show();
		}
	};
	
	this.user_panel_hide = function () {
		$("#user_panel").slideUp(500);
	};

	this.user_panel_show = function() {
		$("#user_panel").slideDown(500);
	};

	this.homepage_redirect = function() {
		document.location = conf.base_url;
	};

	this.init = function() {
		$("#tiny_register_btn").unbind("click").click(function(e){
			$("#trfc").click(function(){
				$("#tiny_register_form_wrap").hide();
				$("#form_register").unbind("submit");
				$("#username, #password").val('');
				$("#username_err, #password_err").text('');
				$(this).unbind("click");
			});
			var register_btn = $("#form_register_submit_btn");
			e.preventDefault();
			$("#tiny_register_form_wrap").css({
				width	:	"400px",
				left	:	(clientWidth() / 2 - 400 / 2) + scrollLeft(),
				top		:	(clientHeight() / 2 - 400 / 2 ) + scrollTop(),
				position:"absolute"
			}).show();
			$("#form_register").unbind("submit").submit(function(e){
				if (handle.clean != undefined) {
					for (var i in handle.clean) {
						$("#"+i+"_err").text('').hide();
					}
					handle.clean = [];
				}
				register_btn.parent().hide();
				e.preventDefault();
				$.post(handle.gate, {
						act:"register",
						register_username	:	$("#register_username").val(),
						first_name			:	$("#first_name").val(),
						email				:	$("#email").val(),
						password			:	$("#register_password").val(),
						passconf			:	$("#passconf").val(),
						captcha				:	$("#captcha").val(),
						terms				:	$("#terms").attr("checked") ? 1 : 0
					},
					function (data) {
						if (data.state) {
							$("#tiny_register_form_wrap_former").hide();
							$("#tiny_register_form_wrap_success").show();
						} else {
							handle.render_err(data.err);
						}
						register_btn.parent().show();
					},
					"json"
				);
			});
		});
		
		$("#tiny_login_btn").unbind("click").click(function(e){
			$("#tlfc").click(function(){
				$("#tiny_login_form_wrap").hide();
				$("#form_login").unbind("submit");
				$("#username, #password").val('');
				$("#username_err, #password_err").text('');
				$(this).unbind("click");
				//$("#tiny_password_recovery").unbind("click");
			});

			

			var login_btn = $("#form_login_submit_btn");
			e.preventDefault();
			$("#invalid_login").hide();
			$("#tiny_login_form_wrap")
				.css({
					width	:	"400px",
					height	:	"140px",
					left	:	(clientWidth() / 2 - 400 / 2) + scrollLeft(),
					top		:	(clientHeight() / 2 - 100 / 2 ) + scrollTop(),
					position:	"absolute"
				}).show();
			$("#form_login").unbind("submit").submit(function (e) {
				var invalid_login = $("#invalid_login");
				invalid_login.addClass("hidden");
				if (handle.clean != undefined) {
					for (var i in handle.clean) {
						$("#"+i+"_err").text('').hide();
					}
					handle.clean = [];
				}
				//login_btn.parent().hide();
				e.preventDefault();
				$.post(
					handle.gate,
					{act:"login", username: $("#login_username").val(), password:$("#login_password").val()},
					function (data) {
						if (data.state) {
							$("#tiny_login_form_wrap_former").hide();
							$("#tiny_login_form_wrap_success").show();
							setTimeout("user_obj.homepage_redirect();", 3000);
						} else {
							invalid_login.show();
							//alert(data.err.join("\n"));
							handle.render_err(data.err);
						}
						login_btn.parent().show();
					},
					"json"
				);
			});
		});
		//recovery
		$("#tiny_password_recovery").click(function(){
			var form = $("#tiny_recovery_form_wrap");
			var recovery_btn = $("#recovery_submit_btn");
			$("#trefc").click(function(){
				$("#form_recovery").unbind("submit");
				form.hide();
				$("#recovery_email").val("");
				$("#recovery_email_err").empty();
				$(this).unbind("click");
			});

			form.css({
					width	:	"400px",
					height	:	"140px",
					left	:	(clientWidth() / 2 - 400 / 2) + scrollLeft(),
					top		:	(clientHeight() / 2 - 100 / 2 ) + scrollTop(),
					position:	"absolute"
			}).show();

			$("#form_recovery").unbind("submit").submit(function(e){
				if (handle.clean != undefined) {
					for (var i in handle.clean) {
						$("#"+i+"_err").text('');
					}
					handle.clean = [];
				}
				recovery_btn.parent().hide();
				e.preventDefault();
				$.post(
					handle.gate,
					{act:"recovery", recovery_email: $("#recovery_email").val()},
					function (data) {
						if (data.state) {
							$("#tiny_recovery_form_wrap_former").hide();
							$("#tiny_recovery_form_wrap_success").show();
							//setTimeout("user_obj.homepage_redirect();", 3000);
						} else {
							self.render_err(data.err);
						}
						recovery_btn.parent().show();
					},
					"json"
				);
			});
		});
		
		//$(".load_profiles").live('click', handle.load_profiles);
		//$(".friends").live('click', handle.init_friends);
		//$(".viewuserdetails").live('click', handle.load_user_profile);
	};
	this.init();
	$(".load_profiles").live('click', function(){
		MainTabs.select(4);
	});
	$(".friends").live('click', function() {
		MainTabs.select(2);
	});
	$(".viewuserdetails").live('click', handle.load_user_profile);
	$(".viewuserdetailsnew").live('click', handle.load_user_profile_new);
	$("#view_profile").live("click", function(e) {
		e.preventDefault();
		$("#user_panel").show();
		MainTabs.select(5);
	});
	$("#uph").live("click", handle.user_panel_hide);
	///
	$(".need_user_auth, #button_my_playlists_guest, #button_friends_playlists_guest, #button_add_playlist_guest, #button_import_playlist_guest").live("click", function(){
		$("#tiny_login_message_form_wrap").css({
			width	:	"500px",
			left	:	(clientWidth() / 2 - 400 / 2) + scrollLeft(),
			top		:	(clientHeight() / 2 - 100 / 2 ) + scrollTop(),
			position:	"absolute"
		}).show();
	});

	$(".addtofriend").live('click', function(e){
			self.friend_handler.add(e.target.id.split("_")[1]);
			$(this).hide();
		});

	this.restore_search_input = function() {
		$('.goto_search_tab').show();
		$('#search_term').removeClass('search_input_bordering');
	}

	$(".goto_search_tab").live("click", function(){
		if (MainTabs.selectedTab() == 3) {
			$('.goto_search_tab').hide();
			$('#search_term').addClass('search_input_bordering');
			setTimeout("user_obj.restore_search_input()", 1000);
		} else {
			MainTabs.select(3);
		}
	});

	var hideLoginRegisterMsg = function(e) {
		e.preventDefault();
		$("#tiny_login_message_form_wrap").hide();
	}
	$("#tlrmc").bind("click", hideLoginRegisterMsg);
	$(".tiny_register_btn_1").live("click", function(e){
		e.preventDefault();
		hideLoginRegisterMsg(e);
		$("#tiny_register_btn").click();
	});
	$(".tiny_login_btn_1").live('click', function(e){
		e.preventDefault();
		hideLoginRegisterMsg(e);
		$("#tiny_login_btn").click();
	});
};
/* core */
var CoreModel = function (obj)
{
	var library			=	obj.library_obj || null;
	var user			=	obj.user_obj	|| null;
	this.detachBindings = function() {
		$("#main_holder_content a").unbind("click");
	};

	this.init = function () {
		//this.library_handler.load_library();
		var action = conf.batch.match(/^profile_([^_]+)_([a-z0-9\_\.\-]+)$/i);
		if (conf.user_id == null || conf.user_id == 'null') {
			MainTabs.select(3);
			//attach login and register action
			if (action != null) {
				switch (action[1]) {
					case 'view':
						_load_library = false;
						user.load_user_profile(action[2]);
					break;
					case 'pl':
						_load_library = false;
						library.playlist_handler.getPublicPlaylistItems({id:action[2], autostart:true});
					break;
				}
			}
			//library.load_public_playlists();
			if (conf.batch != "tag") {
				$.post(conf.base_url + 'library/gate', {act: 'getLibrary', page: 1, recently_total:10}, function (data) {
					if (data.state) {
						$('#search_result_wrapper_wrap').empty().append(data.content);
					} else {
						//self.log({target:'library_hold_state', msg:'error', state:1});
					}
				},
				"json"
				);
			} else {
				search_obj.search();
			}
			//version 1.8 fix last fix
			_load_library = false;

		} else if (conf.user_id > 0) {
			//MainTabs.select(3);
			//_load_library = false;
			library.load_playlists();
			//this.library_handler.load_friends_playlists();

			//batch
			if (conf.batch != null && conf.batch != 'null') {
				if (action == null) {
					switch (conf.batch) {
						case "user_profile":
							_load_library = false;
							user.load_profile();
						break;
					}
				} else {
					switch (action[1]) {
						case 'view':
							_load_library = false;
							user.load_user_profile(action[2]);
						break;
						case 'pl':
							_load_library = false;
							library.playlist_handler.get({id:action[2], friend:1});
						break;
					}
				}
				
			}
			///load etc in search holder
		}
		if (conf.batch != null) {
			//common
			if (/common_(most_popular|top_favorites|recently_added|most_listened)/.test(conf.batch)) {
				_load_library = false;
				var act = conf.batch.match(/common_(most_popular|top_favorites|recently_added|most_listened)/);
				switch (act[1]) {
					case "most_popular":
						library.getMostPopular();
					break;
					case "top_favorites":
						library.getTopFavorites({});
					break;
					case "recently_added":
						library.getRecentlyAdded();
					break;
					case "most_listened":
						library.getMostListened();
					break;
				}
			}
			//media
			else if (/^playmedia_([a-z0-9\_\.\-])+$/.test(conf.batch)) {
				var id = conf.batch.replace(/playmedia_/g, '');
				try {
					_load_library = false;
					library.add_to_batch({obj:"player", act:"play_library_item", id:id});
					MainTabs.select(1);
					if (conf.current_playlist_id > 0) {
						library.playlist_handler.get({id:conf.current_playlist_id, friend:1});
					}
				} catch (e) {
					//alert(e);
				}
			}
		}
		if (_load_library) {
			library.load_library();
		}

		//_load_library = true;

		$(".close_bnt").live('click', function (e) {
			var close_handlers = {
				pswc:"player_obj.player_share_hide"
			}
			try {
				if (close_handlers[e.target.id] != undefined) {
					eval(close_handlers[e.target.id]);
				}
			} catch (e) {
				alert(e);
			}
		});
		_load_library = true;
	}
	this.init();
	//attach drag
}
var _load_library	=	true;
/* Tabs */
function AdvModel () {
	var items = [{target:"banner_info"}];
	var gate	=	conf.base_url + 'adv/gate';
	this.load = function (index) {
		$.post(gate, {act:"get", index:index}, function(data){
			$("#"+items[index].target).html(data.content);
		}, "json");
	}
}

var TabRef = [];
function TabModel (idx)
{
	var self = this;

	this.idx	=	idx;
	this.tabs	=	'';
	this.conf	=	{
		media_convert:{
			/*select:function(event,ui){
				media.set_convert_mode(ui.index);
			}*/
		},
		normal:{
		},
		main:{
			select:function(event, ui){
				//alert(ui.index);
				switch(ui.index) {
					case 0:
						try {
							if (_load_library) {
								library_obj.load_library(0);
							}
						} catch (e) {
							//alert(e);
						}
					break;
					case 1:
						try {
							//current_playlist_id != 0 &&
							if (player_obj.playlist_id == 0 && (library_obj.playlist_handler.current_obj.id == undefined || library_obj.playlist_handler.current_obj.id == "undefined")) {
								var id = $("#my_playlist_list_holder ul li:first").attr("id").split("_")[1];
								if (id > 0) {
									library_obj.playlist_handler.get({id:id, friend:1});
									if (player_obj != null) {
										if (player_obj.mode == null) {
											player_obj.play_playlist(id);
										}
									}
								}
							}
						} catch (e) {
							//alert(e);
						}
					break;
					case 2:
						try {
							user_obj.init_friends(0);
						} catch (e) {
							//alert(e);
						}
					break;
					case 4:
						try {
							if (user_obj.getCurrent().user_id == 0) {
								user_obj.load_profiles(0);
							}
						} catch (e) {
							//alert(e);
						}
					break;
					case 5:
						if (conf.user_id != null) {
							user_obj.load_profile(0);
						}
					break;
				}
			}
		}
	};

	this.init = function (mode) {
		try {
			this.tabs = $(this.idx);
			this.tabs.tabs(this.conf[mode]);
		} catch (e) {
			alert(e);
		}
	};

	this.select = function(index)
	{
		if (this.selectedTab != index) {
			this.tabs.tabs('enable', index);
			if (Number(this.tabs.data('selected.tabs')) != index) {
				this.tabs.tabs('select', index);
			}
		}
	};

	this.selectedTab = function() {
		return Number(this.tabs.data('selected.tabs'));
	};
	this.selectOnly = function(index) {
		this.select(index);
		for (var i = 0;i < this.tabs.tabs('length'); i++) {
			if ( i != index ) {
				this.tabs.tabs('disable', i);
			}
		}
	};

	this.disable = function(index)
	{
		this.tabs.tabs('disable', index);
	};

	this.enable = function(index)
	{
		this.tabs.tabs('enable', index);
	};

	this.add = function(url, label)
	{
		this.tabs.tabs('add', url, label);
	};

	this.destroy = function() {
		this.tabs.tabs('destroy');
	};
}
//SubTabs = new TabModel('.sub_tabulation');
/* AC_OETags */
function MySortableHelper() {
	this.update_right_box_sort = function (list) {
		$.post(conf.full_url+'profile/update_right_tools_order', {line:list.join(',')});
	};
	this.update_left_box_sort = function (list) {
		$.post(conf.full_url+'tools/update_left_tools_order', {line:list.join(',')});
	};
	this.update_center_box_sort = function (list) {
		$.post(conf.full_url+'tools/update_center_tools_order', {line:list.join(',')});
	};
}
/* tinyMceControll */
function tinyMceControll()
{
	this.add = function(controll) {
		var o = {
			mode:"specific_textareas",
			editor_selector:"mceEditor",
			theme:"advanced",
/*			plugins								:	"safari,pagebreak,layer,table,advhr,advimage,advlink,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,noneditable,visualchars,nonbreaking,xhtmlxtras",*/
			plugins								:	"safari,table,advhr,advimage,advlink,media,searchreplace,contextmenu,paste,visualchars,xhtmlxtras",
			theme_advanced_buttons1				:	"cleanup,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontselect,fontsizeselect,|,forecolor,backcolor",
			theme_advanced_buttons2				:	"attribs,|,link,unlink,anchor,image,media,|,bullist,numlist,|,outdent,indent,blockquote,|cite,abbr,acronym,del,ins,|,undo,redo,|,search,replace,|,pastetext,pasteword",
			theme_advanced_buttons3				:	"tablecontrols,|,sub,sup,charmap,|,hr,advhr,removeformat,visualaid,|,code",
			theme_advanced_toolbar_location 	:	"top",
			theme_advanced_toolbar_align		:	"left",
			theme_advanced_statusbar_location	:	"bottom",
			theme_advanced_resizing				:	true,
			content_css							:	conf.base_url+'css/tiny_mce/content.css',
			remove_script_host					:	false,
			convert_urls						:	true,
			relative_urls						:	false,
			document_base_url					:	conf.base_url	
		};
		if (controll != undefined || controll != null) {
			o.external_image_list_url	=	conf.base_url+"ajax/multimedia/lists/image/"+controll;
			o.media_external_list_url	=	conf.base_url+"ajax/multimedia/lists/media/"+controll;
			o.external_link_list_url	=	conf.base_url+"ajax/multimedia/lists/link/"+controll;
		}
		tinyMCE.init(o);
	};
}
function setCookie (name, value, expires, path, domain, secure)
{
	var today = new Date();
	today.setTime(today.getTime());
	if (expires) {
		expires = expires * 1000 * 60 * 60 * 24;
	}
	var expires_date = new Date( today.getTime() + (expires) );
	document.cookie = name + "=" +escape( value ) +
	( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
	( ( path ) ? ";path=" + path : "" ) +
	( ( domain ) ? ";domain=" + domain : "" ) +
	( ( secure ) ? ";secure" : "" );
}

function init()
{
	//thickbox
	//tb_init('a.thickbox');
	//imgLoader		=	new Image();
	//imgLoader.src	=	conf.base_url+"media/icon/ajax-loader.gif";
	//tabs
	Tabs = new TabModel('.tabulation');
	Tabs.init('normal');

	SubTabs = new TabModel('.sub_tabulation');
	SubTabs.init('normal');
	
	MainTabs = new TabModel('#explorer_box');
	MainTabs.init('main');
	
	//assign confirm
	$("a.confirm").click(function(e){
			return confirm(language.msg.confirm);
		}
	);
	//assign clockpick
//	/$(".clockpick").clockpick();
	//tinymce
	//tinyMce_obj = new tinyMceControll();
	function resize_window() {
		var w = $("html").width();
		if ( w < 1100) {
			$("body").addClass("size_1024");
			$("body").removeClass("size_1280");
			$("body").removeClass("size_1600");
			setCookie("body_class", "size_1024", 31536000);
		}
		if ( (w > 1100) && (w < 1550) ) {
			$("body").addClass("size_1280");
			$("body").removeClass("size_1024");
			$("body").removeClass("size_1600");
			setCookie("body_class", "size_1280", 31536000);
		}
		if (w > 1550) {
			$("body").addClass("size_1600");
			$("body").removeClass("size_1024");
			$("body").removeClass("size_1280");
			setCookie("body_class", "size_1600", 31536000);
		}
	}
	//resize_window();
	$(window).bind("resize", function() {
		resize_window();
	});

	$("div.top_menu ul li, div#user_menu a").hover(
		function()
		{
			var div_id = $(this).attr('id').replace('_item_', '_desc_');
			$('#section_desc, #section_desc #'+div_id)
				.css('display','block');
			return false;
		},
		function()
		{
			$('#section_desc, #section_desc p')
				.css('display','none');
			return false;
		}
	);
	//main init
	conf.mouseX = 0;
	conf.mouseY = 0;

	//player_obj		=	null;
	search_obj		=	new SearchModel();
	library_obj		=	new LibraryModel();
	user_obj		=	new UserModel();
	core			=	new CoreModel({library_obj:library_obj, user_obj:user_obj});

	try {
		//SearchModel = LibraryModel = FriendModel = PlaylistModel = null;
		//DownloadModel = MediaModel = null;
	} catch (e) {
		//alert('error ' + e);
		
	}
	//alert( typeof search_obj );
	/*core = new CoreModel(
		{
			conf:conf,
			model:[]
		}
	);*/
	//batch execute
	for (var i in batch) {
		eval(batch[i]);
	}
	conf.mouseX = 0;
	conf.mouseY = 0;
   /*$().mousemove(function(e) {
		conf.mouseX = e.pageX;
		conf.mouseY = e.pageY;
    });*/
	/*/global key handler //not working with chrome //may crash
	$().keypress(function (e) {
		switch(e.keyCode) {
			case 27:
				//alert('escape');
			break;
		}
     });*/
	//$("#playlists_controls a").blend({speed:300});
	//$("#playlists_controls a").blend({speed:300});
	//$("#player_controls a span").blend({speed:300});

	$("#seek_bar_control").draggable({
		containment: 'parent',
		axis: 'x',
		start:function() {
			isPlayerTimeDragging = true;
		},
		stop:function(event, ui) {
			isPlayerTimeDragging = false;
			var percent = Number((ui.position.left / 330)*100);
			try {
				player_obj.seekPercent(percent);
			} catch (e) {
				//alert(e);
			}
			//alert(ui.position.left);
		}
	});
	//drag
	$(".s_draggable").draggable({handle:'div.s_window_head', cursor: 'move', iframeFix: true});

	//var adv_obj = new AdvModel();
	//AdvModel = null;
	//adv_obj.load(0);
	$("#top_played_stats").hide();
	
}
$(document).ready(init);

function pl_import_complete () {
	try {
		library_obj.hide_import_playlist();
		library_obj.load_playlists();
	} catch (e) {
		//alert(e);
	}
}
//share my space
function GetThis(title, content, url, location) {
	var targetUrl = 'http://www.myspace.com/Modules/PostTo/Pages/?' + 't=' + encodeURIComponent(title) + '&c=' + encodeURIComponent(content) + '&u=' + encodeURIComponent(url) + '&l=' + location;
	window.open(targetUrl);
}
function openBrWindow(theURL, name, popW, popH, scrollbars) {
	if (!(theURL.length>0)) return false;
	var winleft=(screen.width - popW) / 2;
	var wintop=(screen.height - popH) / 2;
	popFullH=popH + 60;
	popFullW=popW + 24;
	winProp='width='+popFullH+',height='+popFullW+',left='+winleft+',top='+wintop+',scrollbars='+(scrollbars?1:0)+',status=1,resizable=1';
	name = window.open(theURL, name, winProp);
	name.focus();
	return true;
}

function scrollTop() {
	try {
		return (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0 ) ;
	} catch (e) { alert(e); }
}
function clientWidth() {
	try {
		return Number( window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth || 0 );
	} catch (e) { alert(e); }
}
function scrollLeft() {
	try {
		return Number( window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0 );
	} catch (e) { alert(e); }
}
function clientHeight() {
	try {
		return Number( window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight || 0 );
	} catch (e) { alert(e); }
}

///* media sortable */
/*cleanTinyMCE = function() {
	if (typeof( tinyMCE ) != undefined ){
		for( var n in tinyMCE.editors ){
			if( tinyMCE.editors[ n ] != undefined ){
				tinyMCE.execCommand('mceFocus', false, n);
				tinyMCE.execCommand('mceRemoveControl', true, n);
			}
		}
	}
};*/
//error catch
function errorSuppressor()
{
	var msg = 'msg: '+arguments[0]+'\nin loc: '+arguments[1]+'\nat at: '+arguments[2];
	$('#error_list_hold').text(msg);
	return true;
}
window.onerror = errorSuppressor;
