PageSourceSearch

https://www.meccanodirect.fr/media/js/9cbf835545e258872b75706f0bd8a61f.js

js meccanodirect.fr collected 2026-10-07 17:12:33 UTC 665,890 bytes, 15,140 lines download raw bytes

vendor: 1,570 bytes, line 1
1!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){function t(e,t){return t.toUpperCase()}var f=[],h=C.document,c=f.slice,m=f.concat,s=f.push,i=f.indexOf,n={},r=n.toString,g=n.hasOwnProperty,v={},o="1.12.1",E=function(e,t){return new E.fn.init(e,t)},a=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,u=/^-ms-/,l=/-([\da-z])/gi;function d(e){var t=!!e&&"length"in e&&e.length,n=E.type(e);return"function"!==n&&!E.isWindow(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}E.fn=E.prototype={jquery:o,constructor:E,selector:"",length:0,toArray:function(){return c.call(this)},get:function(e){return null!=e?e<0?this[e+this.length]:this[e]:c.call(this)},pushStack:function(e){var t=E.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e){return E.each(this,e)},map:function(n){return this.pushStack(E.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(c.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:f.sort,splice:f.splice},E.extend=E.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{}
1,s++),"object"==typeof a||E.isFunction(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(i=arguments[s]))for(r in i)e=a[r],n=i[r],"__proto__"!==r&&a!==n&&(l&&n&&(E.isPlainObject(n)||(t=E.isArray(n)))?(o=t?(t=!1,e&&E.isArray(e)?e:[]):e&&E.isPlainObject(e)?e:{},a[r]=E.extend(l,o,n)):void 0!==n&&(a[r]=n));return a},E.extend({expando:"jQuery"+(o+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return"function"===E.type(e)},isArray:Array.isArray||function(e){return"array"===E.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){var t=e&&e.toString();return!E.isArray(e)&&0<=t-parseFloat(t)+1},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},isPlainObject:function(e){var t;if(!e||"object"!==E.type(e)||e.nodeType||E.isWindow(e))return!1;try{if(e.constructor&&!g.call(e,"constructor")&&!g.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(e){return!1}if(!v.ownFirst)for(t in e)return g.call(e,t);for(t in e);return void 0===t||g.call(e,t)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[r.call(e)]||"object":typeof e},globalEval:function(e){e&&E.trim(e)&&(C.execScript||function(e){C.eval.call(C,e)})(e)},camelCase:function(e){return e.replace(u,"ms-").replace(l,t)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var n,r=0;if(d(e))for(n=e.length;r<n&&!1!==t.call(e[r],r,e[r]);r++);else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(a,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(d(Object(e))?E.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(i)return i.call(t,e,n);for(r=t.length,n=n?n<0?Math.max(0,r+n):n:0;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;)e[i++]=t[r++];if(n!=n)for(;void 0!==t[r];)e[i++]=t[r++];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!=a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(d(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return m.apply([],a)},guid:1,proxy:function(e,t){var n,r,i;if("string"==typeof t&&(i=e[t],t=e,e=i),E.isFunction(e))return n=c.call(arguments,2),(r=function(){return e.apply(t||this,n.concat(c.call(arguments)))}).guid=e.guid=e.guid||E.guid++,r},now:function(){return+new Date},support:v}),"function"==typeof Symbol&&(E.fn[Symbol.iterator]=f[Symbol.iterator]),E.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var p=function(n){function f(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(65536+r):String.fromCharCode(r>>10|55296,1023&r|56320)}function i(){T()}var e,h,b,o,a,m,d,g,w,u,l,T,C,s,E,v,c,p,y,N="sizzle"+ +new Date,x=n.document,k=0,r=0,S=ie(),A=ie(),D=ie(),L=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],H=t.pop,q=t.push,_=t.push,M=t.slice,F=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},O="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",R="[\\x20\\t\\r\\n\\f]",P="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",B="\\["+R+"*("+P+")(?:"+R+"*([*^$|!~]?=)"+R+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+P+"))|)"+R+"*\\]",W=":("+P+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+B+")*)|.*)\\)|)",I=new RegExp(R+"+","g"),$=new RegExp("^"+R+"+|((?:^|[^\\\\])(?:\\\\.)*)"+R+"+$","g"),z=new RegExp("^"+R+"*,"+R+"*"),X=new RegExp("^"+R+"*([>+~]|"+R+")"+R+"*"),U=new RegExp("="+R+"*([^\\]'\"]*?)"+R+"*\\]","g"),V=new RegExp(W),Y=new RegExp("^"+P+"$"),J={ID:new RegExp("^#("+P+")"),CLASS:new RegExp("^\\.("+P+")"),TAG:new RegExp("^("+P+"|[*])"),ATTR:new RegExp("^"+B),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+O+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=/'|\\/g,ne=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig");try{_.apply(t=M.call(x.childNodes),x.childNodes),t[x.childNodes.length].nodeType}
vendor: 23,272 bytes, line 1
1catch(e){_={apply:t.length?function(e,t){q.apply(e,M.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function re(e,t,n,r){var i,o,a,s,u,l,c,f,d=t&&t.ownerDocument,p=t?t.nodeType:9;if(n=n||[],"string"!=typeof e||!e||1!==p&&9!==p&&11!==p)return n;if(!r&&((t?t.ownerDocument||t:x)!==C&&T(t),t=t||C,E)){if(11!==p&&(l=Z.exec(e)))if(i=l[1]){if(9===p){if(!(a=t.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(d&&(a=d.getElementById(i))&&y(t,a)&&a.id===i)return n.push(a),n}else{if(l[2])return _.apply(n,t.getElementsByTagName(e)),n;if((i=l[3])&&h.getElementsByClassName&&t.getElementsByClassName)return _.apply(n,t.getElementsByClassName(i)),n}if(h.qsa&&!D[e+" "]&&(!v||!v.test(e))){if(1!==p)d=t,f=e;else if("object"!==t.nodeName.toLowerCase()){for((s=t.getAttribute("id"))?s=s.replace(te,"\\$&"):t.setAttribute("id",s=N),o=(c=m(e)).length,u=Y.test(s)?"#"+s:"[id='"+s+"']";o--;)c[o]=u+" "+he(c[o]);f=c.join(","),d=ee.test(e)&&de(t.parentNode)||t}if(f)try{return _.apply(n,d.querySelectorAll(f)),n}catch(e){}finally{s===N&&t.removeAttribute("id")}}}return g(e.replace($,"$1"),t,n,r)}function ie(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function oe(e){return e[N]=!0,e}function ae(e){var t=C.createElement("div");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function se(e,t){for(var n=e.split("|"),r=n.length;r--;)b.attrHandle[n[r]]=t}function ue(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||1<<31)-(~e.sourceIndex||1<<31);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function le(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function ce(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function fe(a){return oe(function(o){return o=+o,oe(function(e,t){for(var n,r=a([],e.length,o),i=r.length;i--;)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function de(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in h=re.support={},a=re.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},T=re.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:x;return r!==C&&9===r.nodeType&&r.documentElement&&(s=(C=r).documentElement,E=!a(C),(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",i,!1):n.attachEvent&&n.attachEvent("onunload",i)),h.attributes=ae(function(e){return e.className="i",!e.getAttribute("className")}),h.getElementsByTagName=ae(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),h.getElementsByClassName=K.test(C.getElementsByClassName),h.getById=ae(function(e){return s.appendChild(e).id=N,!C.getElementsByName||!C.getElementsByName(N).length}),h.getById?(b.find.ID=function(e,t){if(void 0!==t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}},b.filter.ID=function(e){var t=e.replace(ne,f);return function(e){return e.getAttribute("id")===t}}):(delete b.find.ID,b.filter.ID=function(e){var n=e.replace(ne,f);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}}),b.find.TAG=h.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):h.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"!==e)return o;for(;n=o[i++];)1===n.nodeType&&r.push(n);return r},b.find.CLASS=h.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&E)return t.getElementsByClassName(e)},c=[],v=[],(h.qsa=K.test(C.querySelectorAll))&&(ae(function(e){s.appendChild(e).innerHTML="<a id='"+N+"'></a><select id='"+N+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+R+"*(?:value|"+O+")"),e.querySelectorAll("[id~="+N+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+N+"+*").length||v.push(".#.+[+~]")}),ae(function(e){var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+R+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(h.matchesSelector=K.test(p=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ae(function(e){h.disconnectedMatch=p.call(e,"div"),p.call(e,"[s!='']:x"),c.push("!=",W)}),v=v.length&&new RegExp(v.join("|")),c=c.length&&new RegExp(c.join("|")),t=K.test(s.compareDocumentPosition),y=t||K.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},L=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!h.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===x&&y(x,e)?-1:t===C||t.ownerDocument===x&&y(x,t)?1:u?F(u,e)-F(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?F(u,e)-F(u,t):0;if(i===o)return ue(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?ue(a[r],s[r]):a[r]===x?-1:s[r]===x?1:0}),C},re.matches=function(e,t){return re(e,null,null,t)},re.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),t=t.replace(U,"='$1']"),h.matchesSelector&&E&&!D[t+" "]&&(!c||!c.test(t))&&(!v||!v.test(t)))try{var n=p.call(e,t);if(n||h.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){}return 0<re(t,C,null,[e]).length},re.contains=function(e,t){return(e.ownerDocument||e)!==C&&T(e),y(e,t)},re.attr=function(e,t){(e.ownerDocument||e)!==C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&j.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:h.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},re.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},re.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!h.detectDuplicates,u=!h.sortStable&&e.slice(0),e.sort(L),l){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return u=null,e},o=re.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=o(t);return n},(b=re.selectors={cacheLength:50,createPseudo:oe,match:J,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ne,f),e[3]=(e[3]||e[4]||e[5]||"").replace(ne,f),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||re.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&re.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return J.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=m(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ne,f).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=S[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&S(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=re.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(I," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,m,g){var v="nth"!==h.slice(0,3),y="last"!==h.slice(-4),x="of-type"===e;return 1===m&&0===g?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=v!=y?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),d=!n&&!x,p=!1;if(c){if(v){for(;l;){for(a=e;a=a[l];)if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[y?c.firstChild:c.lastChild],y&&d){for(p=(s=(r=(i=(o=(a=c)[N]||(a[N]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];a=++s&&a&&a[l]||(p=s=0)||u.pop();)if(1===a.nodeType&&++p&&a===e){i[h]=[k,s,p];break}}else if(d&&(p=s=(r=(i=(o=(a=e)[N]||(a[N]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===p)for(;(a=++s&&a&&a[l]||(p=s=0)||u.pop())&&((x?a.nodeName.toLowerCase()!==f:1!==a.nodeType)||!++p||(d&&((i=(o=a[N]||(a[N]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,p]),a!==e)););return(p-=g)===m||p%m==0&&0<=p/m}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||re.error("unsupported pseudo: "+e);return a[N]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?oe(function(e,t){for(var n,r=a(e,o),i=r.length;i--;)e[n=F(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:oe(function(e){var r=[],i=[],s=d(e.replace($,"$1"));return s[N]?oe(function(e,t,n,r){for(var i,o=s(e,null,r,[]),a=e.length;a--;)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:oe(function(t){return function(e){return 0<re(t,e).length}}),contains:oe(function(t){return t=t.replace(ne,f),function(e){return-1<(e.textContent||e.innerText||o(e)).indexOf(t)}}),lang:oe(function(n){return Y.test(n||"")||re.error("unsupported lang: "+n),n=n.replace(ne,f).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===s},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return!1===e.disabled},disabled:function(e){return!0===e.disabled},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:fe(function(){return[0]}),last:fe(function(e,t){return[t-1]}),eq:fe(function(e,t,n){return[n<0?n+t:n]}),even:fe(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:fe(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:fe(function(e,t,n){for(var r=n<0?n+t:n;0<=--r;)e.push(r);return e}),gt:fe(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=le(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=ce(e);function pe(){}function he(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function me(s,e,t){var u=e.dir,l=t&&"parentNode"===u,c=r++;return e.first?function(e,t,n){for(;e=e[u];)if(1===e.nodeType||l)return s(e,t,n)}:function(e,t,n){var r,i,o,a=[k,c];if(n){for(;e=e[u];)if((1===e.nodeType||l)&&s(e,t,n))return!0}else for(;e=e[u];)if(1===e.nodeType||l){if((r=(i=(o=e[N]||(e[N]={}))[e.uniqueID]||(o[e.uniqueID]={}))[u])&&r[0]===k&&r[1]===c)return a[2]=r[2];if((i[u]=a)[2]=s(e,t,n))return!0}}}function ge(i){return 1<i.length?function(e,t,n){for(var r=i.length;r--;)if(!i[r](e,t,n))return!1;return!0}:i[0]}function ve(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function ye(p,h,m,g,v,e){return g&&!g[N]&&(g=ye(g)),v&&!v[N]&&(v=ye(v,e)),oe(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)re(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!p||!e&&h?c:ve(c,s,p,n,r),d=m?v||(e?p:l||g)?[]:t:f;if(m&&m(f,d,n,r),g)for(i=ve(d,u),g(i,[],n,r),o=i.length;o--;)(a=i[o])&&(d[u[o]]=!(f[u[o]]=a));if(e){if(v||p){if(v){for(i=[],o=d.length;o--;)(a=d[o])&&i.push(f[o]=a);v(null,d=[],i,r)}for(o=d.length;o--;)(a=d[o])&&-1<(i=v?F(e,a):s[o])&&(e[i]=!(t[i]=a))}}else d=ve(d===t?d.splice(l,d.length):d),v?v(null,t,d,r):_.apply(t,d)})}function xe(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=me(function(e){return e===i},a,!0),l=me(function(e){return-1<F(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u:l)(e,t,n);return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[me(ge(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[N]){for(n=++s;n<r&&!b.relative[e[n].type];n++);return ye(1<s&&ge(c),1<s&&he(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace($,"$1"),t,s<n&&xe(e.slice(s,n)),n<r&&xe(e=e.slice(n)),n<r&&he(e))}c.push(t)}return ge(c)}function be(g,v){function e(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],d=w,p=e||x&&b.find.TAG("*",i),h=k+=null==d?1:Math.random()||.1,m=p.length;for(i&&(w=t===C||t||i);l!==m&&null!=(o=p[l]);l++){if(x&&o){for(a=0,t||o.ownerDocument===C||(T(o),n=!E);s=g[a++];)if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}y&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,y&&l!==u){for(a=0;s=v[a++];)s(c,f,t,n);if(e){if(0<u)for(;l--;)c[l]||f[l]||(f[l]=H.call(r));f=ve(f)}_.apply(r,f),i&&!e&&0<f.length&&1<u+v.length&&re.uniqueSort(r)}return i&&(k=h,w=d),c}var y=0<v.length,x=0<g.length;return y?oe(e):e}return pe.prototype=b.filters=b.pseudos,b.setFilters=new pe,m=re.tokenize=function(e,t){var n,r,i,o,a,s,u,l=A[e+" "];if(l)return t?0:l.slice(0);for(a=e,s=[],u=b.preFilter;a;){for(o in n&&!(r=z.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=X.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($," ")}),a=a.slice(n.length)),b.filter)!(r=J[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?re.error(e):A(e,s).slice(0)},d=re.compile=function(e,t){var n,r=[],i=[],o=D[e+" "];if(!o){for(n=(t=t||m(e)).length;n--;)(o=xe(t[n]))[N]?r.push(o):i.push(o);(o=D(e,be(i,r))).selector=e}return o},g=re.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&m(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&h.getById&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(ne,f),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=J.needsContext.test(e)?0:o.length;i--&&(a=o[i],!b.relative[s=a.type]);)if((u=b.find[s])&&(r=u(a.matches[0].replace(ne,f),ee.test(o[0].type)&&de(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&he(o)))return _.apply(n,r),n;break}}return(l||d(e,c))(r,t,!E,n,!t||ee.test(e)&&de(t.parentNode)||t),n},h.sortStable=N.split("").sort(L).join("")===N,h.detectDuplicates=!!l,T(),h.sortDetached=ae(function(e){return 1&e.compareDocumentPosition(C.createElement("div"))}),ae(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||se("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),h.attributes&&ae(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||se("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ae(function(e){return null==e.getAttribute("disabled")})||se(O,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),re}(C);E.find=p,E.expr=p.selectors,E.expr[":"]=E.expr.pseudos,E.uniqueSort=E.unique=p.uniqueSort,E.text=p.getText,E.isXMLDoc=p.isXML,E.contains=p.contains;function y(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&E(e).is(n))break;r.push(e)}return r}function x(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}var b=E.expr.match.needsContext,w=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,T=/^.[^:#\[\.,]*$/;function N(e,n,r){if(E.isFunction(n))return E.grep(e,function(e,t){return!!n.call(e,t,e)!==r});if(n.nodeType)return E.grep(e,function(e){return e===n!==r});if("string"==typeof n){if(T.test(n))return E.filter(n,e,r);n=E.filter(n,e)}return E.grep(e,function(e){return-1<E.inArray(e,n)!==r})}E.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?E.find.matchesSelector(r,e)?[r]:[]:E.find.matches(e,E.grep(t,function(e){return 1===e.nodeType}))},E.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(E(e).filter(function(){for(t=0;t<i;t++)if(E.contains(r[t],this))return!0}));for(t=0;t<i;t++)E.find(e,r[t],n);return(n=this.pushStack(1<i?E.unique(n):n)).selector=this.selector?this.selector+" "+e:e,n},filter:function(e){return this.pushStack(N(this,e||[],!1))},not:function(e){return this.pushStack(N(this,e||[],!0))},is:function(e){return!!N(this,"string"==typeof e&&b.test(e)?E(e):e||[],!1).length}});var k,S=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;(E.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"!=typeof e)return e.nodeType?(this.context=this[0]=e,this.length=1,this):E.isFunction(e)?void 0!==n.ready?n.ready(e):e(E):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),E.makeArray(e,this));if(!(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof E?t[0]:t,E.merge(this,E.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:h,!0)),w.test(r[1])&&E.isPlainObject(t))for(r in t)E.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}if((i=h.getElementById(r[2]))&&i.parentNode){if(i.id!==r[2])return k.find(e);this.length=1,this[0]=i}return this.context=h,this.selector=e,this}).prototype=E.fn,k=E(h);var A=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};function L(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}E.fn.extend({has:function(e){var t,n=E(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(E.contains(this,n[t]))return!0})},closest:function(e,t){for(var n,r=0,i=this.length,o=[],a=b.test(e)||"string"!=typeof e?E(e,t||this.context):0;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&E.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?E.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?E.inArray(this[0],E(e)):E.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(E.uniqueSort(E.merge(this.get(),E(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),E.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return y(e,"parentNode")},parentsUntil:function(e,t,n){return y(e,"parentNode",n)},next:function(e){return L(e,"nextSibling")},prev:function(e){return L(e,"previousSibling")},nextAll:function(e){return y(e,"nextSibling")},prevAll:function(e){return y(e,"previousSibling")},nextUntil:function(e,t,n){return y(e,"nextSibling",n)},prevUntil:function(e,t,n){return y(e,"previousSibling",n)},siblings:function(e){return x((e.parentNode||{}).firstChild,e)},children:function(e){return x(e.firstChild)},contents:function(e){return E.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:E.merge([],e.childNodes)}},function(r,i){E.fn[r]=function(e,t){var n=E.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=E.filter(t,n)),1<this.length&&(D[r]||(n=E.uniqueSort(n)),A.test(r)&&(n=n.reverse())),this.pushStack(n)}});var j,H,q=/\S+/g;function _(){h.addEventListener?(h.removeEventListener("DOMContentLoaded",M),C.removeEventListener("load",M)):(h.detachEvent("onreadystatechange",M),C.detachEvent("onload",M))}function M(){!h.addEventListener&&"load"!==C.event.type&&"complete"!==h.readyState||(_(),E.ready())}for(H in E.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},E.each(e.match(q)||[],function(e,t){n[t]=!0}),n):E.extend({},r);function i(){for(s=r.once,a=o=!0;l.length;c=-1)for(t=l.shift();++c<u.length;)!1===u[c].apply(t[0],t[1])&&r.stopOnFalse&&(c=u.length,t=!1);r.memory||(t=!1),o=!1,s&&(u=t?[]:"")}var o,t,a,s,u=[],l=[],c=-1,f={add:function(){return u&&(t&&!o&&(c=u.length-1,l.push(t)),function n(e){E.each(e,function(e,t){E.isFunction(t)?r.unique&&f.has(t)||u.push(t):t&&t.length&&"string"!==E.type(t)&&n(t)})}(arguments),t&&!o&&i()),this},remove:function(){return E.each(arguments,function(e,t){for(var n;-1<(n=E.inArray(t,u,n));)u.splice(n,1),n<=c&&c--}),this},has:function(e){return e?-1<E.inArray(e,u):0<u.length},empty:function(){return u=u&&[],this},disable:function(){return s=l=[],u=t="",this},disabled:function(){return!u},lock:function(){return s=!0,t||f.disable(),this},locked:function(){return!!s},fireWith:function(e,t){return s||(t=[e,(t=t||[]).slice?t.slice():t],l.push(t),o||i()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!a}};return f},E.extend({Deferred:function(e){var o=[["resolve","done",E.Callbacks("once memory"),"resolved"],["reject","fail",E.Callbacks("once memory"),"rejected"],["notify","progress",E.Callbacks("memory")]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},then:function(){var i=arguments;return E.Deferred(function(r){E.each(o,function(e,t){var n=E.isFunction(i[e])&&i[e];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&E.isFunction(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this===a?r.promise():this,n?[e]:arguments)})}),i=null}).promise()},promise:function(e){return null!=e?E.extend(e,a):a}},s={};return a.pipe=a.then,E.each(o,function(e,t){var n=t[2],r=t[3];a[t[1]]=n.add,r&&n.add(function(){i=r},o[1^e][2].disable,o[2][2].lock),s[t[0]]=function(){return s[t[0]+"With"](this===s?a:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){function t(t,n,r){return function(e){n[t]=this,r[t]=1<arguments.length?c.call(arguments):e,r===i?l.
1notifyWith(n,r):--u||l.resolveWith(n,r)}}var i,n,r,o=0,a=c.call(arguments),s=a.length,u=1!==s||e&&E.isFunction(e.promise)?s:0,l=1===u?e:E.Deferred();if(1<s)for(i=new Array(s),n=new Array(s),r=new Array(s);o<s;o++)a[o]&&E.isFunction(a[o].promise)?a[o].promise().progress(t(o,n,i)).done(t(o,r,a)).fail(l.reject):--u;return u||l.resolveWith(r,a),l.promise()}}),E.fn.ready=function(e){return E.ready.promise().done(e),this},E.extend({isReady:!1,readyWait:1,holdReady:function(e){e?E.readyWait++:E.ready(!0)},ready:function(e){(!0===e?--E.readyWait:E.isReady)||(E.isReady=!0)!==e&&0<--E.readyWait||(j.resolveWith(h,[E]),E.fn.triggerHandler&&(E(h).triggerHandler("ready"),E(h).off("ready")))}}),E.ready.promise=function(e){if(!j)if(j=E.Deferred(),"complete"===h.readyState||"loading"!==h.readyState&&!h.documentElement.doScroll)C.setTimeout(E.ready);else if(h.addEventListener)h.addEventListener("DOMContentLoaded",M),C.addEventListener("load",M);else{h.attachEvent("onreadystatechange",M),C.attachEvent("onload",M);var n=!1;try{n=null==C.frameElement&&h.documentElement}catch(e){}n&&n.doScroll&&!function t(){if(!E.isReady){try{n.doScroll("left")}catch(e){return C.setTimeout(t,50)}_(),E.ready()}}()}return j.promise(e)},E.ready.promise(),E(v))break;v.ownFirst="0"===H,v.inlineBlockNeedsLayout=!1,E(function(){var e,t,n,r;(n=h.getElementsByTagName("body")[0])&&n.style&&(t=h.createElement("div"),(r=h.createElement("div")).style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",n.appendChild(r).appendChild(t),void 0!==t.style.zoom&&(t.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",v.inlineBlockNeedsLayout=e=3===t.offsetWidth,e&&(n.style.zoom=1)),n.removeChild(r))}),function(){var e=h.createElement("div");v.deleteExpando=!0;try{delete e.test}catch(e){v.deleteExpando=!1}e=null}();function F(e){var t=E.noData[(e.nodeName+" ").toLowerCase()],n=+e.nodeType||1;return(1===n||9===n)&&(!t||!0!==t&&e.getAttribute("classid")===t)}var O,R=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,P=/([A-Z])/g;function B(e,t,n){if(void 0===n&&1===e.nodeType){var r="data-"+t.replace(P,"-$1").toLowerCase();if("string"==typeof(n=e.getAttribute(r))){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:R.test(n)?E.parseJSON(n):n)}catch(e){}E.data(e,t,n)}else n=void 0}return n}function W(e){var t;for(t in e)if(("data"!==t||!E.isEmptyObject(e[t]))&&"toJSON"!==t)return;return 1}function I(e,t,n,r){if(F(e)){var i,o,a=E.expando,s=e.nodeType,u=s?E.cache:e,l=s?e[a]:e[a]&&a;if(l&&u[l]&&(r||u[l].data)||void 0!==n||"string"!=typeof t)return u[l=l||(s?e[a]=f.pop()||E.guid++:a)]||(u[l]=s?{}:{toJSON:E.noop}),"object"!=typeof t&&"function"!=typeof t||(r?u[l]=E.extend(u[l],t):u[l].data=E.extend(u[l].data,t)),o=u[l],r||(o.data||(o.data={}),o=o.data),void 0!==n&&(o[E.camelCase(t)]=n),"string"==typeof t?null==(i=o[t])&&(i=o[E.camel
1Case(t)]):i=o,i}}function $(e,t,n){if(F(e)){var r,i,o=e.nodeType,a=o?E.cache:e,s=o?e[E.expando]:E.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){i=(t=E.isArray(t)?t.concat(E.map(t,E.camelCase)):t in r||(t=E.camelCase(t))in r?[t]:t.split(" ")).length;for(;i--;)delete r[t[i]];if(n?!W(r):!E.isEmptyObject(r))return}(n||(delete a[s].data,W(a[s])))&&(o?E.cleanData([e],!0):v.deleteExpando||a!=a.window?delete a[s]:a[s]=void 0)}}}E.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return!!(e=e.nodeType?E.cache[e[E.expando]]:e[E.expando])&&!W(e)},data:function(e,t,n){return I(e,t,n)},removeData:function(e,t){return $(e,t)},_data:function(e,t,n){return I(e,t,n,!0)},_removeData:function(e,t){return $(e,t,!0)}}),E.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0!==e)return"object"==typeof e?this.each(function(){E.data(this,e)}):1<arguments.length?this.each(function(){E.data(this,e,t)}):o?B(o,e,E.data(o,e)):void 0;if(this.length&&(i=E.data(o),1===o.nodeType&&!E._data(o,"parsedAttrs"))){for(n=a.length;n--;)a[n]&&0===(r=a[n].name).indexOf("data-")&&B(o,r=E.camelCase(r.slice(5)),i[r]);E._data(o,"parsedAttrs",!0)}return i},removeData:function(e){return this.each(function(){E.removeData(this,e)})}}),E.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=E._data(e,t),n&&(!r||E.isArray(n)?r=E._data(e,t,E.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=E.queue(e,t),r=n.length,i=n.shift(),o=E._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){E.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return E._data(e,n)||E._data(e,n,{empty:E.Callbacks("once memory").add(function(){E._removeData(e,t+"queue"),E._removeData(e,n)})})}}),E.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?E.queue(this[0],t):void 0===n?this:this.each(function(){var e=E.queue(this,t,n);E._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&E.dequeue(this,t)})},dequeue:function(e){return this.each(function(){E.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){function n(){--i||o.resolveWith(a,[a])}var r,i=1,o=E.Deferred(),a=this,s=this.length;for("string"!=typeof e&&(t=e,e=void 0),e=e||"fx";s--;)(r=E._data(a[s],e+"queueHooks"))&&r.empty&&(i++,r.empty.add(n));return n(),o.promise(t)}}),v.shrinkWrapBlocks=function(){return null!=O?O:(O=!1,(t=h.getElementsByTagName("body")[0])&&t.style?(e=h.createElement("div"),(n=h.createElement("div")).style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",t.appendChild(n).appendChild(e),void 0!==e.style.zoom&&(e.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",e.appendChild(h.createElement("div")).style.width="5px",O=3!==e.offsetWidth),t.removeChild(n),O):void 0);var e,t,n};function z(e,t){return e=t||e,"none"===E.css(e,"display")||!E.contains(e.ownerDocument,e)}var X=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=new RegExp("^(?:([+-])=|)("+X+")([a-z%]*)$","i"),V=["Top","Right","Bottom","Left"];function Y(e,t,n,r){var i,o=1,a=20,s=r?function(){return r.cur()}:function(){return E.css(e,t,"")},u=s(),l=n&&n[3]||(E.cssNumber[t]?"":"px"),c=(E.cssNumber[t]||"px"!==l&&+u)&&U.exec(E.css(e,t));if(c&&c[3]!==l)for(l=l||c[3],n=n||[],c=+u||1;c/=o=o||".5",E.style(e,t,c+l),o!==(o=s()/u)&&1!==o&&--a;);return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var J,G,Q,K=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===E.type(n))for(s in i=!0,n)K(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,E.isFunction(r)||(a=!0),l&&(t=a?(t.call(e,r),null):(l=t,function(e,t,n){return l.call(E(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},Z=/^(?:checkbox|radio)$/i,ee=/<([\w:-]+)/,te=/^$|\/(?:java|ecma)script/i,ne=/^\s+/,re="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ie(e){var t=re.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}J=h.createElement("div"),G=h.createDocumentFragment(),Q=h.createElement("input"),J.innerHTML="  <link/><table></table><a href='/a'>a</a>
1<input type='checkbox'/>",v.leadingWhitespace=3===J.firstChild.nodeType,v.tbody=!J.getElementsByTagName("tbody").length,v.htmlSerialize=!!J.getElementsByTagName("link").length,v.html5Clone="<:nav></:nav>"!==h.createElement("nav").cloneNode(!0).outerHTML,Q.type="checkbox",Q.checked=!0,G.appendChild(Q),v.appendChecked=Q.checked,J.innerHTML="<textarea>x</textarea>",v.noCloneChecked=!!J.cloneNode(!0).lastChild.defaultValue,G.appendChild(J),(Q=h.createElement("input")).setAttribute("type","radio"),Q.setAttribute("checked","checked"),Q.setAttribute("name","t"),J.appendChild(Q),v.checkClone=J.cloneNode(!0).cloneNode(!0).lastChild.checked,v.noCloneEvent=!!J.addEventListener,J[E.expando]=1,v.attributes=!J.getAttribute(E.expando);var oe={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:v.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]};function ae(e,t){var n,r,i=0,o=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(r=n[i]);i++)!t||E.nodeName(r,t)?o.push(r):E.merge(o,ae(r,t));return void 0===t||t&&E.nodeName(e,t)?E.merge([e],o):o}function se(e,t){for(var n,r=0;null!=(n=e[r]);r++)E._data(n,"globalEval",!t||E._data(t[r],"globalEval"))}oe.optgroup=oe.option,oe.tbody=oe.tfoot=oe.colgroup=oe.caption=oe.thead,oe.th=oe.td;var ue=/<|&#?\w+;/,le=/<tbody/i;function ce(e){Z.test(e.type)&&(e.defaultChecked=e.checked)}function fe(e,t,n,r,i){for(var o,a,s,u,l,c,f,d=e.length,p=ie(t),h=[],m=0;m<d;m++)if((a=e[m])||0===a)if("object"===E.type(a))E.merge(h,a.nodeType?[a]:a);else if(ue.test(a)){for(u=u||p.appendChild(t.createElement("div")),l=(ee.exec(a)||["",""])[1].toLowerCase(),f=oe[l]||oe._default,u.innerHTML=f[1]+E.htmlPrefilter(a)+f[2],o=f[0];o--;)u=u.lastChild;if(!v.leadingWhitespace&&ne.test(a)&&h.push(t.createTextNode(ne.exec(a)[0])),!v.tbody)for(o=(a="table"!==l||le.test(a)?"<table>"!==f[1]||le.test(a)?0:u:u.firstChild)&&a.childNodes.length;o--;)E.nodeName(c=a.childNodes[o],"tbody")&&!c.childNodes.length&&a.removeChild(c);for(E.merge(h,u.childNodes),u.textContent="";u.firstChild;)u.removeChild(u.firstChild);u=p.lastChild}else h.push(t.createTextNode(a));for(u&&p.removeChild(u),v.appendChecked||E.grep(ae(h,"input"),ce),m=0;a=h[m++];)if(r&&-1<E.inArray(a,r))i&&i.push(a);else if(s=E.contains(a.ownerDocument,a),u=ae(p.appendChild(a),"script"),s&&se(u),n)for(o=0;a=u[o++];)te.test(a.type||"")&&n.push(a);return u=null,p}!function(){var e,t,n=h.createElement("div");for(e in{submit:!0,change:!0,focusin:!0})t="on"+e,(v[e]=t in C)||(n.setAttribute(t,"t"),v[e]=!1===n.attributes[t].expando);n=null}();var de=/^(?:input|select|textarea)$/i,pe=/^key/,he=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,me=/^(?:focusinfocus|focusoutblur)$/,ge=/^([^.]*)(?:\.(.+)|)/;function ve(){return!0}function ye(){return!1}function xe(){try{return h.activeElement}catch(e){}}function be(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)be(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ye;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return E().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=E.guid++)),e.each(function(){E.event.add(this,t,i,r,n)})}E.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,m,g=E._data(e);if(g){for(n.handler&&(n=(u=n).handler,i=u.selector),n.guid||(n.guid=E.guid++),(a=g.events)||(a=g.events={}),(c=g.handle)||((c=g.handle=function(e){return void 0===E||e&&E.event.triggered===e.type?void 0:E.event.dispatch.apply(c.elem,arguments)}).elem=e),s=(t=(t||"").match(q)||[""]).length;s--;)p=m=(o=ge.exec(t[s])||[])[1],h=(o[2]||"").split(".").sort(),p&&(l=E.event.special[p]||{},p=(i?l.delegateType:l.bindType)||p,l=E.event.special[p]||{},f=E.extend({type:p,origType:m,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&E.expr.match.needsContext.test(i),namespace:h.join(".")}
1,u),(d=a[p])||((d=a[p]=[]).delegateCount=0,l.setup&&!1!==l.setup.call(e,r,h,c)||(e.addEventListener?e.addEventListener(p,c,!1):e.attachEvent&&e.attachEvent("on"+p,c))),l.add&&(l.add.call(e,f),f.handler.guid||(f.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,f):d.push(f),E.event.global[p]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,m,g=E.hasData(e)&&E._data(e);if(g&&(c=g.events)){for(l=(t=(t||"").match(q)||[""]).length;l--;)if(p=m=(s=ge.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),p){for(f=E.event.special[p]||{},d=c[p=(r?f.delegateType:f.bindType)||p]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=d.length;o--;)a=d[o],!i&&m!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(d.splice(o,1),a.selector&&d.delegateCount--,f.remove&&f.remove.call(e,a));u&&!d.length&&(f.teardown&&!1!==f.teardown.call(e,h,g.handle)||E.removeEvent(e,p,g.handle),delete c[p])}else for(p in c)E.event.remove(e,p+t[l],n,r,!0);E.isEmptyObject(c)&&(delete g.handle,E._removeData(e,"events"))}},trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f=[n||h],d=g.call(e,"type")?e.type:e,p=g.call(e,"namespace")?e.namespace.split("."):[];if(a=l=n=n||h,3!==n.nodeType&&8!==n.nodeType&&!me.test(d+E.event.triggered)&&(-1<d.indexOf(".")&&(d=(p=d.split(".")).shift(),p.sort()),o=d.indexOf(":")<0&&"on"+d,(e=e[E.expando]?e:new E.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=p.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:E.makeArray(t,[e]),u=E.event.special[d]||{},r||!u.trigger||!1!==u.trigger.apply(n,t))){if(!r&&!u.noBubble&&!E.isWindow(n)){for(s=u.delegateType||d,me.test(s+d)||(a=a.parentNode);a;a=a.parentNode)f.push(a),l=a;l===(n.ownerDocument||h)&&f.push(l.defaultView||l.parentWindow||C)}for(c=0;(a=f[c++])&&!e.isPropagationStopped();)e.type=1<c?s:u.bindType||d,(i=(E._data(a,"events")||{})[e.type]&&E._data(a,"handle"))&&i.apply(a,t),(i=o&&a[o])&&i.apply&&F(a)&&(e.result=i.apply(a,t),!1===e.result&&e.preventDefault());if(e.type=d,!r&&!e.isDefaultPrevented()&&(!u._default||!1===u._default.apply(f.pop(),t))&&F(n)&&o&&n[d]&&!E.isWindow(n)){(l=n[o])&&(n[o]=null),E.event.triggered=d;try{n[d]()}catch(e){}E.event.triggered=void 0,l&&(n[o]=l)}return e.result}},dispatch:function(e){e=E.event.fix(e);var t,n,r,i,o,a,s=c.call(arguments),u=(E._data(this,"events")||{})[e.type]||[],l=E.event.special[e.type]||{};if((s[0]=e).delegateTarget=this,!l.preDispatch||!1!==l.preDispatch.call(this,e)){for(a=E.event.handlers.call(this,e,u),t=0;(i=a[t++])&&!e.isPropagationStopped();)for(e.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!e.isImmediatePropagationStopped();)e.rnamespace&&!e.rnamespace.test(o.namespace)||(e.handleObj=o,e.data=o.data,void 0!==(r=((E.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(e.result=r)&&(e.preventDefault(),e.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,a=[],s=t.delegateCount,u=e.target;if(s&&u.nodeType&&("click"!==e.type||isNaN(e.button)||e.button<1))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(!0!==u.disabled||"click"!==e.type)){for(r=[],n=0;n<s;n++)void 0===r[i=(o=t[n]).selector+" "]&&(r[i]=o.needsContext?-1<E(i,this).index(u):E.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&a.push({elem:u,handlers:r})}return s<t.length&&a.push({elem:this,handlers:t.slice(s)}),a},fix:function(e){if(e[E.expando])return e;var t,n,r,i=e.type,o=e,a=this.fixHooks[i];for(a||(this.fixHooks[i]=a=he.test(i)?this.mouseHooks:pe.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new E.Event(o),t=r.length;t--;)e[n=r[t]]=o[n];return e.target||(e.target=o.srcElement||h),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,a.filter?a.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{}
1,keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,t){var n,r,i,o=t.button,a=t.fromElement;return null==e.pageX&&null!=t.clientX&&(i=(r=e.target.ownerDocument||h).documentElement,n=r.body,e.pageX=t.clientX+(i&&i.scrollLeft||n&&n.scrollLeft||0)-(i&&i.clientLeft||n&&n.clientLeft||0),e.pageY=t.clientY+(i&&i.scrollTop||n&&n.scrollTop||0)-(i&&i.clientTop||n&&n.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?t.toElement:a),e.which||void 0===o||(e.which=1&o?1:2&o?3:4&o?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xe()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){if(this===xe()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if(E.nodeName(this,"input")&&"checkbox"===this.type&&this.click)return this.click(),!1},_default:function(e){return E.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n){var r=E.extend(new E.Event,n,{type:e,isSimulated:!0});E.event.trigger(r,null,t),r.isDefaultPrevented()&&n.preventDefault()}},E.removeEvent=h.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)}:function(e,t,n){var r="on"+t;e.detachEvent&&(void 0===e[r]&&(e[r]=null),e.detachEvent(r,n))},E.Event=function(e,t){if(!(this instanceof E.Event))return new E.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?ve:ye):this.type=e,t&&E.extend(this,t),this.timeStamp=e&&e.timeStamp||E.now(),this[E.expando]=!0},E.Event.prototype={constructor:E.Event,isDefaultPrevented:ye,isPropagationStopped:ye,isImmediatePropagationStopped:ye,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=ve,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=ve,e&&!this.isSimulated&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=ve,e&&e.stopImmediatePropagation&&e.stopImmediatePropagation(),this.stopPropagation()}}
1,E.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){E.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||E.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),v.submit||(E.event.special.submit={setup:function(){if(E.nodeName(this,"form"))return!1;E.event.add(this,"click._submit keypress._submit",function(e){var t=e.target,n=E.nodeName(t,"input")||E.nodeName(t,"button")?E.prop(t,"form"):void 0;n&&!E._data(n,"submit")&&(E.event.add(n,"submit._submit",function(e){e._submitBubble=!0}),E._data(n,"submit",!0))})},postDispatch:function(e){e._submitBubble&&(delete e._submitBubble,this.parentNode&&!e.isTrigger&&E.event.simulate("submit",this.parentNode,e))},teardown:function(){if(E.nodeName(this,"form"))return!1;E.event.remove(this,"._submit")}}),v.change||(E.event.special.change={setup:function(){if(de.test(this.nodeName))return"checkbox"!==this.type&&"radio"!==this.type||(E.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._justChanged=!0)}),E.event.add(this,"click._change",function(e){this._justChanged&&!e.isTrigger&&(this._justChanged=!1),E.event.simulate("change",this,e)})),!1;E.event.add(this,"beforeactivate._change",function(e){var t=e.target;de.test(t.nodeName)&&!E._data(t,"change")&&(E.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||E.event.simulate("change",this.parentNode,e)}),E._data(t,"change",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||"radio"!==t.type&&"checkbox"!==t.type)return e.handleObj.handler.apply(this,arguments)},teardown:function(){return E.event.remove(this,"._change"),!de.test(this.nodeName)}}),v.focusin||E.each({focus:"focusin",blur:"focusout"},function(n,r){function i(e){E.event.simulate(r,e.target,E.event.fix(e))}E.event.special[r]={setup:function(){var e=this.ownerDocument||this,t=E._data(e,r);t||e.addEventListener(n,i,!0),E._data(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this,t=E._data(e,r)-1;t?E._data(e,r,t):(e.removeEventListener(n,i,!0),E._removeData(e,r))}}}),E.fn.extend({on:function(e,t,n,r){return be(this,e,t,n,r)},one:function(e,t,n,r){return be(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,E(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"!=typeof e)return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=ye),this.each(function(){E.event.remove(this,e,n,t)});for(i in e)this.off(i,t,e[i]);return this},trigger:function(e,t){return this.each(function(){E.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return E.event.trigger(e,t,n,!0)}});var we=/ jQuery\d+="(?:null|\d+)"/g,Te=new RegExp("<(?:"+re+")[\\s/>]","i"),Ce=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,Ee=/<script|<style|<link/i,Ne=/checked\s*(?:[^=]|=\s*.checked.)/i,ke=/^true\/(.*)/,Se=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Ae=ie(h).appendChild(h.createElement("div"));function De(e,t){return E.nodeName(e,"table")&&E.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Le(e){return e.type=(null!==E.find.attr(e,"type"))+"/"+e.type,e}function je(e){var t=ke.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function He(e,t){if(1===t.nodeType&&E.hasData(e)){var n,r,i,o=E._data(e),a=E._data(t,o),s=o.events;if(s)for(n in delete a.handle,a.events={},s)for(r=0,i=s[n].length;r<i;r++)E.event.add(t,n,s[n][r]);a.data&&(a.data=E.extend({},a.data))}}function qe(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!v.noCloneEvent&&t[E.expando]){for(r in(i=E._data(t)).events)E.removeEvent(t,r,i.handle);t.removeAttribute(E.expando)}"script"===n&&t.text!==e.text?(Le(t).text=e.text,je(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),v.html5Clone&&e.innerHTML&&!E.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Z.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:"input"!==n&&"textarea"!==n||(t.defaultValue=e.defaultValue)}}function _e(n,r,i,o){r=m.apply([],r);var e,t,a,s,u,l,c=0,f=n.length,d=f-1,p=r[0],h=E.isFunction(p);if(h||1<f&&"string"==typeof p&&!v.checkClone&&Ne.test(p))return n.each(function(e){var t=n.eq(e);h&&(r[0]=p.call(this,e,t.html())),_e(t,r,i,o)});if(f&&(e=(l=fe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===l.childNodes.length&&(l=e),e||o)){for(a=(s=E.map(ae(l,"script"),Le)).length;c<f;c++)t=l,c!==d&&(t=E.clone(t,!0,!0),a&&E.merge(s,ae(t,"script"))),i.call(n[c],t,c);if(a)for(u=s[s.length-1].ownerDocument,E.map(s,je),c=0;c<a;c++)t=s[c],te.test(t.type||"")&&!E._data(t,"globalEval")&&E.contains(u,t)&&(t.src?E._evalUrl&&E._evalUrl(t.src):E.globalEval((t.text||t.textContent||t.innerHTML||"").replace(Se,"")));l=e=null}return n}function Me(e,t,n){for(var r,i=t?E.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||E.cleanData(ae(r)),r.parentNode&&(n&&E.contains(r.ownerDocument,r)&&se(ae(r,"script")),r.parentNode.removeChild(r));return e}E.extend({htmlPrefilter:function(e){return e.replace(Ce,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s,u=E.contains(e.ownerDocument,e);if(v.html5Clone||E.isXMLDoc(e)||!Te.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Ae.innerHTML=e.outerHTML,Ae.removeChild(o=Ae.firstChild)),!(v.noCloneEvent&&v.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||E.isXMLDoc(e)))for(r=ae(o),s=ae(e),a=0;null!=(i=s[a]);++a)r[a]&&qe(i,r[a]);if(t)if(n)for(s=s||ae(e),r=r||ae(o),a=0;null!=(i=s[a]);a++)He(i,r[a]);else He(e,o);return 0<(r=ae(o,"script")).length&&se(r,!u&&ae(e,"script")),r=s=i=null,o},cleanData:function(e,t){for(var n,r,i,o,a=0,s=E.expando,u=E.cache,l=v.attributes,c=E.event.special;null!=(n=e[a]);a++)if((t||F(n))&&(o=(i=n[s])&&u[i])){if(o.events)for(r in o.events)c[r]?E.event.remove(n,r):E.removeEvent(n,r,o.handle);u[i]&&(delete u[i],l||void 0===n.removeAttribute?n[s]=void 0:n.removeAttribute(s),f.push(i))}}}),E.fn.extend({domManip:_e,detach:function(e){return Me(this,e,!0)},remove:function(e){return Me(this,e)},text:function(e){return K(this,function(e){return void 0===e?E.text(this):this.empty().append((this[0]&&this[0].ownerDocument||h).createTextNode(e))},null,e,arguments.length)},append:function(){return _e(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||De(this,e).appendChild(e)})},prepend:function(){return _e(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=De(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return _e(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return _e(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++){for(1===e.nodeType&&E.cleanData(ae(e,!1));e.firstChild;)e.removeChild(e.firstChild);e.options&&E.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return E.clone(this,e,t)})},html:function(e){return K(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e)return 1===t.nodeType?t.innerHTML.replace(we,""):void 0;if("string"==typeof e&&!Ee.test(e)&&(v.htmlSerialize||!Te.test(e))&&(v.leadingWhitespace||!ne.test(e))&&!oe[(ee.exec(e)||["",""])[1].toLowerCase()]){e=E.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(E.cleanData(ae(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return _e(this,arguments,function(e){var t=this.parentNode;E.inArray(this,n)<0&&(E.cleanData(ae(this)),t&&t.replaceChild(e,this))},n)}}),E.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){E.fn[e]=function(e){for(var t,n=0,r=[],i=E(e),o=i.length-1;n<=o;n++)t=n===o?this:this.clone(!0),E(i[n])[a](t),s.apply(r,t.get());return this.pushStack(r)}});var Fe,Oe={HTML:"block",BODY:"block"};function Re(e,t){var n=E(t.createElement(e)).appendTo(t.body),r=E.css(n[0],"display");return n.detach(),r}function Pe(e){var t=h,n=Oe[e];return n||("none"!==(n=Re(e,t))&&n||((t=((Fe=(Fe||E("<iframe frameborder='0' width='0' height='0'/>")).appendTo(t.documentElement))[0].contentWindow||Fe[0].contentDocument).document).write(),t.close(),n=Re(e,t),Fe.detach()),Oe[e]=n),n}function Be(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];for(o in i=n.apply(e,r||[]),t)e.style[o]=a[o];return i}var We,Ie,$e,ze,Xe,Ue,Ve,Ye,Je=/^margin/,Ge=new RegExp("^("+X+")(?!px)[a-z%]+$","i"),Qe=h.documentElement;function Ke(){var e,t,n=h.documentElement;n.appendChild(Ve),Ye.style.cssText="-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",We=$e=Ue=!1,Ie=Xe=!0,C.getComputedStyle&&(t=C.getComputedStyle(Ye),We="1%"!==(t||{}).top,Ue="2px"===(t||{}).marginLeft,$e="4px"===(t||{width:"4px"}).width,Ye.style.marginRight="50%",Ie="4px"===(t||{marginRight:"4px"}).marginRight,(e=Ye.appendChild(h.createElement("div"))).style.cssText=Ye.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",e.style.marginRight=e.style.width="0",Ye.style.width="1px",Xe=!parseFloat((C.getComputedStyle(e)||{}).marginRight),Ye.removeChild(e)),Ye.style.display="none",(ze=0===Ye.getClientRects().length)&&(Ye.style.display="",Ye.innerHTML="<table><tr><td></td><td>t</td></tr></table>",(e=Ye.getElementsByTagName("td"))[0].style.cssText="margin:0;border:0;padding:0;display:none",(ze=0===e[0].offsetHeight)&&(e[0].style.display="",e[1].style.display="none",ze=0===e[0].offsetHeight)),n.removeChild(Ve)}Ve=h.createElement("div"),(Ye=h.createElement("div")).style&&(Ye.style.cssText="float:left;opacity:.5",v.opacity="0.5"===Ye.style.opacity,v.cssFloat=!!Ye.style.cssFloat,Ye.style.backgroundClip="content-box",Ye.cloneNode(!0).style.backgroundClip="",v.clearCloneStyle="content-box"===Ye.style.backgroundClip,(Ve=h.createElement("div")).style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",Ye.innerHTML="",Ve.appendChild(Ye),v.boxSizing=""===Ye.style.boxSizing||""===Ye.style.MozBoxSizing||""===Ye.style.WebkitBoxSizing,E.extend(v,{reliableHiddenOffsets:function(){return null==We&&Ke(),ze},boxSizingReliable:function(){return null==We&&Ke(),$e},pixelMarginRight:function(){return null==We&&Ke(),Ie},pixelPosition:function(){return null==We&&Ke(),We},reliableMarginRight:function(){return null==We&&Ke(),Xe},reliableMarginLeft:function(){return null==We&&Ke(),Ue}}));var Ze,et,tt=/^(top|right|bottom|left)$/;function nt(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}C.getComputedStyle?(Ze=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},et=function(e,t,n){var r,i,o,a,s=e.style;return""!==(a=(n=n||Ze(e))?n.getPropertyValue(t)||n[t]:void 0)&&void 0!==a||E.contains(e.ownerDocument,e)||(a=E.style(e,t)),n&&!v.pixelMarginRight()&&Ge.test(a)&&Je.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o),void 0===a?a:a+""}):Qe.currentStyle&&(Ze=function(e){return e.currentStyle},et=function(e,t,n){var r,i,o,a,s=e.style;return null==(a=(n=n||Ze(e))?n[t]:void 0)&&s&&s[t]&&(a=s[t]),Ge.test(a)&&!tt.test(t)&&(r=s.left,(o=(i=e.runtimeStyle)&&i.left)&&(i.left
1=e.currentStyle.left),s.left="fontSize"===t?"1em":a,a=s.pixelLeft+"px",s.left=r,o&&(i.left=o)),void 0===a?a:a+""||"auto"});var rt=/alpha\([^)]*\)/i,it=/opacity\s*=\s*([^)]*)/i,ot=/^(none|table(?!-c[ea]).+)/,at=new RegExp("^("+X+")(.*)$","i"),st={position:"absolute",visibility:"hidden",display:"block"},ut={letterSpacing:"0",fontWeight:"400"},lt=["Webkit","O","Moz","ms"],ct=h.createElement("div").style;function ft(e){if(e in ct)return e;for(var t=e.charAt(0).toUpperCase()+e.slice(1),n=lt.length;n--;)if((e=lt[n]+t)in ct)return e}function dt(e,t){for(var n,r,i,o=[],a=0,s=e.length;a<s;a++)(r=e[a]).style&&(o[a]=E._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&z(r)&&(o[a]=E._data(r,"olddisplay",Pe(r.nodeName)))):(i=z(r),(n&&"none"!==n||!i)&&E._data(r,"olddisplay",i?n:E.css(r,"display"))));for(a=0;a<s;a++)(r=e[a]).style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}function pt(e,t,n){var r=at.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function ht(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;o<4;o+=2)"margin"===n&&(a+=E.css(e,n+V[o],!0,i)),r?("content"===n&&(a-=E.css(e,"padding"+V[o],!0,i)),"margin"!==n&&(a-=E.css(e,"border"+V[o]+"Width",!0,i))):(a+=E.css(e,"padding"+V[o],!0,i),"padding"!==n&&(a+=E.css(e,"border"+V[o]+"Width",!0,i)));return a}function mt(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Ze(e),a=v.boxSizing&&"border-box"===E.css(e,"boxSizing",!1,o);if(h.msFullscreenElement&&C.top!==C&&e.getClientRects().length&&(i=Math.round(100*e.getBoundingClientRect()[t])),i<=0||null==i){if(((i=et(e,t,o))<0||null==i)&&(i=e.style[t]),Ge.test(i))return i;r=a&&(v.boxSizingReliable()||i===e.style[t]),i=parseFloat(i)||0}return i+ht(e,t,n||(a?"border":"content"),r,o)+"px"}function gt(e,t,n,r,i){return new gt.prototype.init(e,t,n,r,i)}E.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=et(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{float:v.cssFloat?"cssFloat":"styleFloat"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=E.camelCase(t),u=e.style;if(t=E.cssProps[s]||(E.cssProps[s]=ft(s)||s),a=E.cssHooks[t]||E.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:u[t];if("string"===(o=typeof n)&&(i=U.exec(n))&&i[1]&&(n=Y(e,t,i),o="number"),null!=n&&n==n&&("number"===o&&(n+=i&&i[3]||(E.cssNumber[s]?"":"px")),v.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),!(a&&"set"in a&&void 0===(n=a.set(e,n,r)))))try{u[t]=n}catch(e){}}},css:function(e,t,n,r){var i,o,a,s=E.camelCase(t);return t=E.cssProps[s]||(E.cssProps[s]=ft(s)||s),(a=E.cssHooks[t]||E.cssHooks[s])&&"get"in a&&(o=a.get(e,!0,n)),void 0===o&&(o=et(e,t,r)),"normal"===o&&t in ut&&(o=ut[t]),""===n||n?(i=parseFloat(o),!0===n||isFinite(i)?i||0:o):o}}),E.each(["height","width"],function(e,i){E.cssHooks[i]={get:function(e,t,n){if(t)return ot.test(E.css(e,"display"))&&0===e.offsetWidth?Be(e,st,function(){return mt(e,i,n)}):mt(e,i,n)},set:function(e,t,n){var r=n&&Ze(e);return pt(0,t,n?ht(e,i,n,v.boxSizing&&"border-box"===E.css(e,"boxSizing",!1,r),r):0)}}}),v.opacity||(E.cssHooks.opacity={get:function(e,t){return it.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=E.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";((n.zoom=1)<=t||""===t)&&""===E.trim(o.replace(rt,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=rt.test(o)?o.replace(rt,i):o+" "+i)}}),E.cssHooks.marginRight=nt(v.reliableMarginRight,function(e,t){if(t)return Be(e,{display:"inline-block"},et,[e,"marginRight"])}),E.cssHooks.marginLeft=nt(v.reliableMarginLeft,function(e,t){if(t)return(parseFloat(et(e,"marginLeft"))||(E.contains(e.ownerDocument,e)?e.getBoundingClientRect().left-Be(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}):0))+"px"}),E.each({margin:"",padding:"",border:"Width"},function(i,o){E.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+V[t]+o]=r[t]||r[t-2]||r[0];return n}},Je.test(i)||(E.cssHooks[i+o].set=pt)}),E.fn.extend({css:function(e,t){return K(this,function(e,t,n){var r,i,o={},a=0;if(E.isArray(t)){for(r=Ze(e),i=t.length;a<i;a++)o[t[a]]=E.css(e,t[a],!1,r);return o}return void 0!==n?E.style(e,t,n):E.css(e,t)},e,t,1<arguments.length)},show:function(){return dt(this,!0)},hide:function(){return dt(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){z(this)?E(this).show():E(this).hide()})}}),((E.Tween=gt).prototype={constructor:gt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||E.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(E.cssNumber[n]?"":"px")},cur:function(){var e=gt.propHooks[this.prop];return e&&e.get?e.get(this):gt.propHooks._default.get(this)},run:function(e){var t,n=gt.propHooks[this.prop];return this.options.duration?this.pos=t=E.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):gt.propHooks._default.set(this),this}}).init.prototype=gt.prototype,(gt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=E.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){E.fx.step[e.prop]?E.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[E.cssProps[e.prop]]&&!E.cssHooks[e.prop]?e.elem[e.prop]=e.now:E.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=gt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},E.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},E.fx=gt.prototype.init,E.fx.step={};var vt,yt,xt,bt,wt,Tt,Ct,Et=/^(?:toggle|show|hide)$/,Nt=/queueHooks$/;function kt(){return C.setTimeout(function(){vt=void 0}),vt=E.now()}function St(e,t){var n,r={height:e},i=0;for(t=t?1:0;i<4;i+=2-t)r["margin"+(n=V[i])]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function At(e,t,n){for(var r,i=(Dt.tweeners[t]||[]).concat(Dt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function Dt(o,e,t){var n,a,r=0,i=Dt.prefilters.length,s=E.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=vt||kt(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:E.extend({},e),opts:E.extend(!0,{specialEasing:{},easing:E.easing._default},t),originalProperties:e,originalOptions:t,startTime:vt||kt(),duration:t.duration,tweens:[],createTween:function(e,t){var n=E.Tween(o,l.o
vendor: 5,464 bytes, line 1
1pts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=E.camelCase(n)],o=e[n],E.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=E.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=Dt.prefilters[r].call(l,o,c,l.opts))return E.isFunction(n.stop)&&(E._queueHooks(l.elem,l.opts.queue).stop=E.proxy(n.stop,n)),n;return E.map(c,At,l),E.isFunction(l.opts.start)&&l.opts.start.call(o,l),E.fx.timer(E.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}E.Animation=E.extend(Dt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return Y(n.elem,e,U.exec(t),n),n}]},tweener:function(e,t){for(var n,r=0,i=(e=E.isFunction(e)?(t=e,["*"]):e.match(q)).length;r<i;r++)n=e[r],Dt.tweeners[n]=Dt.tweeners[n]||[],Dt.tweeners[n].unshift(t)},prefilters:[function(t,e,n){var r,i,o,a,s,u,l,c=this,f={},d=t.style,p=t.nodeType&&z(t),h=E._data(t,"fxshow");for(r in n.queue||(null==(s=E._queueHooks(t,"fx")).unqueued&&(s.unqueued=0,u=s.empty.fire,s.empty.fire=function(){s.unqueued||u()}),s.unqueued++,c.always(function(){c.always(function(){s.unqueued--,E.queue(t,"fx").length||s.empty.fire()})})),1===t.nodeType&&("height"in e||"width"in e)&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],"inline"===("none"===(l=E.css(t,"display"))?E._data(t,"olddisplay")||Pe(t.nodeName):l)&&"none"===E.css(t,"float")&&(v.inlineBlockNeedsLayout&&"inline"!==Pe(t.nodeName)?d.zoom=1:d.display="inline-block")),n.overflow&&(d.overflow="hidden",v.shrinkWrapBlocks()||c.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]})),e)if(i=e[r],Et.exec(i)){if(delete e[r],o=o||"toggle"===i,i===(p?"hide":"show")){if("show"!==i||!h||void 0===h[r])continue;p=!0}f[r]=h&&h[r]||E.style(t,r)}else l=void 0;if(E.isEmptyObject(f))"inline"===("none"===l?Pe(t.nodeName):l)&&(d.display=l);else for(r in h?"hidden"in h&&(p=h.hidden):h=E._data(t,"fxshow",{}),o&&(h.hidden=!p),p?E(t).show():c.done(function(){E(t).hide()}),c.done(function(){var e;for(e in E._removeData(t,"fxshow"),f)E.style(t,e,f[e])}),f)a=At(p?h[r]:0,r,c),r in h||(h[r]=a.start,p&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}],prefilter:function(e,t){t?Dt.prefilters.unshift(e):Dt.prefilters.push(e)}}),E.speed=function(e,t,n){var r=e&&"object"==typeof e?E.extend({},e):{complete:n||!n&&t||E.isFunction(e)&&e,duration:e,easing:n&&t||t&&!E.isFunction(t)&&t};return r.duration=E.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in E.fx.speeds?E.fx.speeds[r.duration]:E.fx.speeds._default,null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){E.isFunction(r.old)&&r.old.call(this),r.queue&&E.dequeue(this,r.queue)},r},E.fn.extend({fadeTo:function(e,t,n,r){return this.filter(z).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){function i(){var e=Dt(this,E.extend({},t),a);(o||E._data(this,"finish"))&&e.stop(!0)}var o=E.isEmptyObject(t),a=E.speed(e,n,r);return i.finish=i,o||!1===a.queue?this.each(i):this.queue(a.queue,i)},stop:function(i,e,o){function a(e){var t=e.stop;delete e.stop,t(o)}return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&!1!==i&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=E.timers,r=E._data(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&Nt.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||E.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=E._data(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=E.timers,o=n?n.length:0;for(t.finish=!0,E.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),E.each(["toggle","show","hide"],function(e,r){var i=E.fn[r];E.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(St(r,!0),e,t,n)}}),E.each({slideDown:St("show"),slideUp:St("hide"),slideToggle:St("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){E.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),E.timers=[],E.fx.tick=function(){var e,t=E.timers,n=0;for(vt=E.now();n<t.length;n++)(e=t[n])()||t[n]!==e||t.splice(n--,1);t.length||E.fx.stop(),vt=void 0},E.fx.timer=function(e){E.timers.push(e),e()?E.fx.start():E.timers.pop()},E.fx.interval=13,E.fx.start=function(){yt=yt||C.setInterval(E.fx.tick,E.fx.interval)},E.fx.stop=function(){C.clearInterval(yt),yt=null},E.fx.speeds={slow:600,fast:200,_default:400},E.fn.delay=function(r,e){return r=E.fx&&E.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},bt=h.createElement("input"),wt=h.createElement("div"),Tt=h.createElement("select"),Ct=Tt.appendChild(h.createElement("option")),(wt=h.createElement("div")).setAttribute("className","t"),wt.innerHTML="  <link/><table></table><a href='/a'>a</a>
1<input type='checkbox'/>",xt=wt.getElementsByTagName("a")[0],bt.setAttribute("type","checkbox"),wt.appendChild(bt),(xt=wt.getElementsByTagName("a")[0]).style.cssText="top:1px",v.getSetAttribute="t"!==wt.className,v.style=/top/.test(xt.getAttribute("style")),v.hrefNormalized="/a"===xt.getAttribute("href"),v.checkOn=!!bt.value,v.optSelected=Ct.selected,v.enctype=!!h.createElement("form").enctype,Tt.disabled=!0,v.optDisabled=!Ct.disabled,(bt=h.createElement("input")).setAttribute("value",""),v.input=""===bt.getAttribute("value"),bt.value="t",bt.setAttribute("type","radio"),v.radioValue="t"===bt.value;var Lt=/\r/g;E.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=E.isFunction(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,E(this).val()):n)?t="":"number"==typeof t?t+="":E.isArray(t)&&(t=E.map(t,function(e){return null==e?"":e+""})),(r=E.valHooks[this.type]||E.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=E.valHooks[t.type]||E.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(Lt,""):null==e?"":e:void 0}}),E.extend({valHooks:{option:{get:function(e){var t=E.find.attr(e,"value");return null!=t?t:E.trim(E.text(e))}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||i<0,a=o?null:[],s=o?i+1:r.length,u=i<0?s:o?i:0;u<s;u++)if(((n=r[u]).selected||u===i)&&(v.optDisabled?!n.disabled:null===n.getAttribute("disabled"))&&(!n.parentNode.disabled||!E.nodeName(n.parentNode,"optgroup"))){if(t=E(n).val(),o)return t;a.push(t)}return a}
1,set:function(e,t){for(var n,r,i=e.options,o=E.makeArray(t),a=i.length;a--;)if(r=i[a],0<=E.inArray(E.valHooks.option.get(r),o))try{r.selected=n=!0}catch(e){r.scrollHeight}else r.selected=!1;return n||(e.selectedIndex=-1),i}}}}),E.each(["radio","checkbox"],function(){E.valHooks[this]={set:function(e,t){if(E.isArray(t))return e.checked=-1<E.inArray(E(e).val(),t)}},v.checkOn||(E.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var jt,Ht,qt=E.expr.attrHandle,_t=/^(?:checked|selected)$/i,Mt=v.getSetAttribute,Ft=v.input;E.fn.extend({attr:function(e,t){return K(this,E.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){E.removeAttr(this,e)})}}),E.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?E.prop(e,t,n):(1===o&&E.isXMLDoc(e)||(t=t.toLowerCase(),i=E.attrHooks[t]||(E.expr.match.bool.test(t)?Ht:jt)),void 0!==n?null===n?void E.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=E.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!v.radioValue&&"radio"===t&&E.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(q);if(o&&1===e.nodeType)for(;n=o[i++];)r=E.propFix[n]||n,E.expr.match.bool.test(n)?Ft&&Mt||!_t.test(n)?e[r]=!1:e[E.camelCase("default-"+n)]=e[r]=!1:E.attr(e,n,""),e.removeAttribute(Mt?n:r)}}),Ht={set:function(e,t,n){return!1===t?E.removeAttr(e,n):Ft&&Mt||!_t.test(n)?e.setAttribute(!Mt&&E.propFix[n]||n,n):e[E.camelCase("default-"+n)]=e[n]=!0,n}},E.each(E.expr.match.bool.source.match(/\w+/g),function(e,t){var o=qt[t]||E.find.attr;Ft&&Mt||!_t.test(t)?qt[t]=function(e,t,n){var r,i;return n||(i=qt[t],qt[t]=r,r=null!=o(e,t,n)?t.toLowerCase():null,qt[t]=i),r}:qt[t]=function(e,t,n){if(!n)return e[E.camelCase("default-"+t)]?t.toLowerCase():null}}),Ft&&Mt||(E.attrHooks.value={set:function(e,t,n){if(!E.nodeName(e,"input"))return jt&&jt.set(e,t,n);e.defaultValue=t}}),Mt||(jt={set:function(e,t,n){var r=e.getAttributeNode(n);if(r||e.setAttributeNode(r=e.ownerDocument.createAttribute(n)),r.value=t+="","value"===n||t===e.getAttribute(n))return t}},qt.id=qt.name=qt.coords=function(e,t,n){var r;if(!n)return(r=e.getAttributeNode(t))&&""!==r.value?r.value:null},E.valHooks.button={get:function(e,t){var n=e.getAttributeNode(t);if(n&&n.specified)return n.value},set:jt.set},E.attrHooks.contenteditable={set:function(e,t,n){jt.set(e,""!==t&&t,n)}},E.each(["width","height"],function(e,n){E.attrHooks[n]={set:function(e,t){if(""===t)return e.setAttribute(n,"auto"),t}}})),v.style||(E.attrHooks.style={get:function(e){return e.style.cssText||void 0},set:function(e,t){return e.style.cssText=t+""}});var Ot=/^(?:input|select|textarea|button|object)$/i,Rt=/^(?:a|area)$/i;E.fn.extend({prop:function(e,t){return K(this,E.prop,e,t,1<arguments.length)},removeProp:function(e){return e=E.propFix[e]||e,this.each(function(){try{this[e]=void 0,delete this[e]}catch(e){}})}}),E.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&E.isXMLDoc(e)||(t=E.propFix[t]||t,i=E.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=E.find.attr(e,"tabindex");return t?parseInt(t,10):Ot.test(e.nodeName)||Rt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),v.hrefNormalized||E.each(["href","src"],function(e,t){E.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),v.optSelected||(E.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),E.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){E.propFix[this.toLowerCase()]=this}),v.enctype||(E.propFix.enctype="encoding");var Pt=/[\t\r\n\f]/g;function Bt(e){return E.attr(e,"class")||""}E.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(E.isFunction(t))return this.each(function(e){E(this).addClass(t.call(this,e,Bt(this)))});if("string"==typeof t&&t)for(e=t.match(q)||[];n=this[u++];)if(i=Bt(n),r=1===n.nodeType&&(" "+i+" ").replace(Pt," ")){for(a=0;o=e[a++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=E.trim(r))&&E.attr(n,"class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(E.isFunction(t))return this.each(function(e){E(this).removeClass(t.call(this,e,Bt(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof t&&t)for(e=t.match(q)||[];n=this[u++];)if(i=Bt(n),r=1===n.nodeType&&(" "+i+" ").replace(Pt," ")){for(a=0;o=e[a++];)for(;-1<r.indexOf(" "+o+" ");)r=r.replace(" "+o+" "," ");i!==(s=E.trim(r))&&E.attr(n,"class",s)}return this},toggleClass:function(i,t){var o=typeof i;return"boolean"==typeof t&&"string"==o?t?this.addClass(i):this.removeClass(i):E.isFunction(i)?this.each(function(e){E(this).toggleClass(i.
1call(this,e,Bt(this),t),t)}):this.each(function(){var e,t,n,r;if("string"==o)for(t=0,n=E(this),r=i.match(q)||[];e=r[t++];)n.hasClass(e)?n.removeClass(e):n.addClass(e);else void 0!==i&&"boolean"!=o||((e=Bt(this))&&E._data(this,"__className__",e),E.attr(this,"class",e||!1===i?"":E._data(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&-1<(" "+Bt(n)+" ").replace(Pt," ").indexOf(t))return!0;return!1}}),E.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,n){E.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}}),E.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}});var Wt=C.location,It=E.now(),$t=/\?/,zt=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;E.parseJSON=function(e){if(C.JSON&&C.JSON.parse)return C.JSON.parse(e+"");var i,o=null,t=E.trim(e+"");return t&&!E.trim(t.replace(zt,function(e,t,n,r){return i&&t&&(o=0),0===o?e:(i=n||t,o+=!r-!n,"")}))?Function("return "+t)():E.error("Invalid JSON: "+e)},E.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{C.DOMParser?t=(new C.DOMParser).parseFromString(e,"text/xml"):((t=new C.ActiveXObject("Microsoft.XMLDOM")).async="false",t.loadXML(e))}catch(e){t=void 0}return t&&t.documentElement&&!t.getElementsByTagName("parsererror").length||E.error("Invalid XML: "+e),t};var Xt=/#.*$/,Ut=/([?&])_=[^&]*/,Vt=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Yt=/^(?:GET|HEAD)$/,Jt=/^\/\//,Gt=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Qt={},Kt={},Zt="*/".concat("*"),en=Wt.href,tn=Gt.exec(en.toLowerCase())||[];function nn(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(q)||[];if(E.isFunction(t))for(;n=i[r++];)"+"===n.charAt(0)?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function rn(t,i,o,a){var s={},u=t===Kt;function l(e){var r;return s[e]=!0,E.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function on(e,t){var n,r,i=E.ajaxSettings.flatOptions||{};for(r in t)void 0!==t[r]&&((i[r]?e:n=n||{})[r]=t[r]);return n&&E.extend(!0,e,n),e}E.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:en,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(tn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Zt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":E.parseJSON,"text xml":E.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?on(on(e,E.ajaxSettings),t):on(E.ajaxSettings,e)},ajaxPrefilter:nn(Qt),ajaxTransport:nn(Kt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var n,r,c,f,d,p,h,i,m=E.ajaxSetup({},t),g=m.context||m,v=m.context&&(g.nodeType||g.jquery)?E(g):E.event,y=E.Deferred(),x=E.Callbacks("once memory"),b=m.statusCode||{},o={},a={},w=0,s="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(2===w){if(!i)for(i={};t=Vt.exec(f);)i[t[1].toLowerCase()]=t[2];t=i[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===w?f:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return w||(e=a[n]=a[n]||e,o[e]=t),this},overrideMimeType:function(e){return w||(m.mimeType=e),this},statusCode:function(e){var t;if(e)if(w<2)for(t in e)b[t]=[b[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||s;return h&&h.abort(t),u(0,t),this}};if(y.promise(T).complete=x.add,T.success=T.done,T.error=T.fail,m.url=((e||m.url||en)+"").replace(Xt,"").replace(Jt,tn[1]+"//"),m.type=t.method||t.type||m.method||m.type,m.dataTypes=E.trim(m.dataType||"*").toLowerCase().match(q)||[""],null==m.crossDomain&&(n=Gt.exec(m.url.toLowerCase()),m.crossDomain=!(!n||n[1]===tn[1]&&n[2]===tn[2]&&(n[3]||("http:"===n[1]?"80":"443"))===(tn[3]||("http:"===tn[1]?"80":"443")))),m.data&&m.processData&&"string"!=typeof m.data&&(m.data=E.param(m.data,m.traditional)),rn(Qt,m,t,T),2===w)return T;for(r in(p=E.event&&m.global)&&0==E.active++&&E.event.trigger("ajaxStart"),m.type=m.type.toUpperCase(),m.hasContent=!Yt.test(m.type),c=m.url,m.hasContent||(m.data&&(c=m.url+=($t.test(c)?"&":"?")+m.data,delete m.data),!1===m.cache&&(m.url=Ut.test(c)?c.replace(Ut,"$1_="+It++):c+($t.test(c)?"&":"?")+"_="+It++)),m.ifModified&&(E.lastModified[c]&&T.setRequestHeader("If-Modified-Since",E.lastModified[c]),E.etag[c]&&T.setRequestHeader("If-None-Match",E.etag[c])),(m.data&&m.hasContent&&!1!==m.contentType||t.contentType)&&T.setRequestHeader("Content-Type",m.contentType),T.setRequestHeader("Accept",m.dataTypes[0]&&m.accepts[m.dataTypes[0]]?m.accepts[m.dataTypes[0]]+("*"!==m.dataTypes[0]?", "+Zt+"; q=0.01":""):m.accepts["*"]),m.headers)T.setRequestHeader(r,m.headers[r]);
1if(m.beforeSend&&(!1===m.beforeSend.call(g,T,m)||2===w))return T.abort();for(r in s="abort",{success:1,error:1,complete:1})T[r](m[r]);if(h=rn(Kt,m,t,T)){if(T.readyState=1,p&&v.trigger("ajaxSend",[T,m]),2===w)return T;m.async&&0<m.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},m.timeout));try{w=1,h.send(o,u)}catch(e){if(!(w<2))throw e;u(-1,e)}}else u(-1,"No Transport");function u(e,t,n,r){var i,o,a,s,u,l=t;2!==w&&(w=2,d&&C.clearTimeout(d),h=void 0,f=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;"*"===u[0];)u.shift(),void 0===i&&(i=e.mimeType||t.getResponseHeader("Content-Type"));if(i)for(a in s)if(s[a]&&s[a].test(i)){u.unshift(a);break}if(u[0]in n)o=u[0];else{for(a in n){if(!u[0]||e.converters[a+" "+u[0]]){o=a;break}r=r||a}o=o||r}if(o)return o!==u[0]&&u.unshift(o),n[o]}(m,T,n)),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(m,s,T,i),i?(m.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(E.lastModified[c]=u),(u=T.getResponseHeader("etag"))&&(E.etag[c]=u)),204===e||"HEAD"===m.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?y.resolveWith(g,[o,l,T]):y.rejectWith(g,[T,l,a]),T.statusCode(b),b=void 0,p&&v.trigger(i?"ajaxSuccess":"ajaxError",[T,m,i?o:a]),x.fireWith(g,[T,l]),p&&(v.trigger("ajaxComplete",[T,m]),--E.active||E.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return E.get(e,t,n,"json")},getScript:function(e,t){return E.get(e,void 0,t,"script")}}),E.each(["get","post"],function(e,i){E[i]=function(e,t,n,r){return E.isFunction(t)&&(r=r||n,n=t,t=void 0),E.ajax(E.extend({url:e,type:i,dataType:r,data:t,success:n},E.isPlainObject(e)&&e))}}),E._evalUrl=function(e){return E.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},E.fn.extend({wrapAll:function(t){if(E.isFunction(t))return this.each(function(e){E(this).wrapAll(t.call(this,e))});if(this[0]){var e=E(t,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&e.insertBefore(this[0]),e.map(function(){for(var e=this;e.firstChild&&1===e.firstChild.nodeType;)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(n){return E.isFunction(n)?this.each(function(e){E(this).wrapInner(n.call(this,e))}):this.each(function(){var e=E(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=E.isFunction(t);return this.each(function(e){E(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(){return this.parent().each(function(){E.nodeName(this,"body")||E(this).replaceWith(this.childNodes)}).end()}}),E.expr.filters.hidden=function(e){return v.reliableHiddenOffsets()?e.offsetWidth<=0&&e.offsetHeight<=0&&!e.getClientRects().length:function(e){for(;e&&1===e.nodeType;){if("none"===((t=e).style&&t.style.display||E.css(t,"display"))||"hidden"===e.type)return!0;e=e.parentNode}var t;return!1}(e)},E.expr.filters.visible=function(e){return!E.expr.filters.hidden(e)};var an=/%20/g,sn=/\[\]$/,un=/\r?\n/g,ln=/^(?:submit|button|image|reset|file)$/i,cn=/^(?:input|select|textarea|keygen)/i;function fn(n,e,r,i){var t;if(E.isArray(e))E.each(e,function(e,t){r||sn.test(n)?i(n,t):fn(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==E.type(e))i(n,e);else for(t in e)fn(n+"["+t+"]",e[t],r,i)}E.param=function(e,t){function n(e,t){t=E.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)}var r,i=[];if(void 0===t&&(t=E.ajaxSettings&&E.ajaxSettings.traditional),E.isArray(e)||e.jquery&&!E.isPlainObject(e))E.each(e,function(){n(this.name,this.value)});else for(r in e)fn(r,e[r],t,n);return i.join("&").replace(an,"+")},E.fn.extend({serialize:function(){return E.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=E.prop(this,"elements");return e?E.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!E(this).is(":disabled")&&cn.test(this.nodeName)&&!ln.test(e)&&(this.checked||!Z.test(e))}).map(function(e,t){var n=E(this).val();return null==n?null:E.isArray(n)?E.map(n,function(e){return{name:t.name,value:e.replace(un,"\r\n")}}):{name:t.name,value:n.replace(un,"\r\n")}}).get()}}),E.ajaxSettings.xhr=void 0!==C.ActiveXObject?function(){return this.isLocal?gn():8<h.documentMode?mn():/^(get|post|head|put|delete|options)$/i.test(this.t
1ype)&&mn()||gn()}:mn;var dn=0,pn={},hn=E.ajaxSettings.xhr();function mn(){try{return new C.XMLHttpRequest}catch(e){}}function gn(){try{return new C.ActiveXObject("Microsoft.XMLHTTP")}catch(e){}}C.attachEvent&&C.attachEvent("onunload",function(){for(var e in pn)pn[e](void 0,!0)}),v.cors=!!hn&&"withCredentials"in hn,(hn=v.ajax=!!hn)&&E.ajaxTransport(function(u){var l;if(!u.crossDomain||v.cors)return{send:function(e,o){var t,a=u.xhr(),s=++dn;if(a.open(u.type,u.url,u.async,u.username,u.password),u.xhrFields)for(t in u.xhrFields)a[t]=u.xhrFields[t];for(t in u.mimeType&&a.overrideMimeType&&a.overrideMimeType(u.mimeType),u.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)void 0!==e[t]&&a.setRequestHeader(t,e[t]+"");a.send(u.hasContent&&u.data||null),l=function(e,t){var n,r,i;if(l&&(t||4===a.readyState))if(delete pn[s],l=void 0,a.onreadystatechange=E.noop,t)4!==a.readyState&&a.abort();else{i={},n=a.status,"string"==typeof a.responseText&&(i.text=a.responseText);try{r=a.statusText}catch(e){r=""}n||!u.isLocal||u.crossDomain?1223===n&&(n=204):n=i.text?200:404}i&&o(n,r,i,a.getAllResponseHeaders())},u.async?4===a.readyState?C.setTimeout(l):a.onreadystatechange=pn[s]=l:l()},abort:function(){l&&l(void 0,!0)}}}),E.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),E.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return E.globalEval(e),e}}}),E.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),E.ajaxTransport("script",function(t){if(t.crossDomain){var r,i=h.head||E("head")[0]||h.documentElement;return{send:function(e,n){(r=h.createElement("script")).async=!0,t.scriptCharset&&(r.charset=t.scriptCharset),r.src=t.url,r.onload=r.onreadystatechange=function(e,t){!t&&r.readyState&&!/loaded|complete/.test(r.readyState)||(r.onload=r.onreadystatechange=null,r.parentNode&&r.parentNode.removeChild(r),r=null,t||n(200,"success"))},i.insertBefore(r,i.firstChild)},abort:function(){r&&r.onload(void 0,!0)}}}});var vn=[],yn=/(=)\?(?=&|$)|\?\?/;E.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=vn.pop()||E.expando+"_"+It++;return this[e]=!0,e}}),E.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(yn.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&yn.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=E.isFunction(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(yn,"$1"+r):!1!==e.jsonp&&(e.url+=($t.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||E.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?E(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,vn.push(r)),o&&E.isFunction(i)&&i(o[0]),o=i=void 0}),"script"}),v.createHTMLDocument=function(){if(!h.implementation.createHTMLDocument)return!1;var e=h.implementation.createHTMLDocument("");return e.body.innerHTML="<form></form><form></form>",2===e.body.childNodes.length}(),E.parseHTML=function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||(v.createHTMLDocument?h.implementation.createHTMLDocument(""):h);var r=w.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=fe([e],t,i),i&&i.length&&E(i).remove(),E.merge([],r.childNodes))};var xn=E.fn.load;function bn(e){return E.isWindow(e)?e:9===e.nodeType&&(e.defaultView||e.parentWindow)}E.fn.load=function(e,t,n){if("string"!=typeof e&&xn)return xn.apply(this,arguments);var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=E.trim(e.slice(s,e.length)),e=e.slice(0,s)),E.isFunction(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&E.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?E("<div>").append(E.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(a,o||[e.responseText,t,e])})}),this},E.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){E.fn[t]=function(e){return this.on(t,e)}}),E.expr.filters.animated=function(t){return E.grep(E.timers,function(e){return t===e.elem}).length},E.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=E.css(e,"position"),c=E(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=E.css(e,"to
1p"),u=E.css(e,"left"),i=("absolute"===l||"fixed"===l)&&-1<E.inArray("auto",[o,u])?(a=(r=c.position()).top,r.left):(a=parseFloat(o)||0,parseFloat(u)||0),E.isFunction(t)&&(t=t.call(e,n,E.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},E.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){E.offset.setOffset(this,t,e)});var e,n,r={top:0,left:0},i=this[0],o=i&&i.ownerDocument;return o?(e=o.documentElement,E.contains(e,i)?(void 0!==i.getBoundingClientRect&&(r=i.getBoundingClientRect()),n=bn(o),{top:r.top+(n.pageYOffset||e.scrollTop)-(e.clientTop||0),left:r.left+(n.pageXOffset||e.scrollLeft)-(e.clientLeft||0)}):r):void 0},position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===E.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),E.nodeName(e[0],"html")||(n=e.offset()),n.top+=E.css(e[0],"borderTopWidth",!0),n.left+=E.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-E.css(r,"marginTop",!0),left:t.left-n.left-E.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&!E.nodeName(e,"html")&&"static"===E.css(e,"position");)e=e.offsetParent;return e||Qe})}}),E.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o=/Y/.test(i);E.fn[t]=function(e){return K(this,function(e,t,n){var r=bn(e);if(void 0===n)return r?i in r?r[i]:r.document.documentElement[t]:e[t];r?r.scrollTo(o?E(r).scrollLeft():n,o?n:E(r).scrollTop()):e[t]=n},t,e,arguments.length,null)}}),E.each(["top","left"],function(e,n){E.cssHooks[n]=nt(v.pixelPosition,function(e,t){if(t)return t=et(e,n),Ge.test(t)?E(e).position()[n]+"px":t})}),E.each({Height:"height",Width:"width"},function(o,a){E.each({padding:"inner"+o,content:a,"":"outer"+o},function(r,e){E.fn[e]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return K(this,function(e,t,n){var r;return E.isWindow(e)?e.document.documentElement["client"+o]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+o],r["scroll"+o],e.body["offset"+o],r["offset"+o],r["client"+o])):void 0===n?E.css(e,t,i):E.style(e,t,n,i)},a,n?e:void 0,n,null)}})}),E.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),E.fn.size=function(){return this.length},E.fn.andSelf=E.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return E});var wn=C.jQuery,Tn=C.$;return E.noConflict=function(e){return C.$===E&&(C.$=Tn),e&&C.jQuery===E&&(C.jQuery=wn),E},e||(C.jQuery=C.$=E),E});
2//# sourceMappingURL=jquery-1.12.1.min.map
3
4var $j = jQuery.noConflict();
5/*  Prototype JavaScript framework, version 1.7
6 *  (c) 2005-2010 Sam Stephenson
7 *
8 *  Prototype is freely distributable under the terms of an MIT-style license.
9 *  For details, see the Prototype web site: http://www.prototypejs.org/
10 *
11 *--------------------------------------------------------------------------*/
12if ('NodeList' in window) {
13  if (!NodeList.prototype.each && NodeList.prototype.forEach) {
14    NodeList.prototype.each = NodeList.prototype.forEach;
15  }
16}
17var Prototype = {
18
19  Version: '1.7',
20
21  Browser: (function(){
22    var ua = navigator.userAgent;
23    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
24    return {
25      IE:             !!window.attachEvent && !isOpera,
26      Opera:          isOpera,
27      WebKit:         ua.indexOf('AppleWebKit/') > -1,
28      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
29      MobileSafari:   /Apple.*Mobile/.test(ua)
30    }
31  })(),
32
33  BrowserFeatures: {
34    XPath: !!document.evaluate,
35
36    SelectorsAPI: !!document.querySelector,
37
38    ElementExtensions: (function() {
39      var constructor = window.Element || window.HTMLElement;
40      return !!(constructor && constructor.prototype);
41    })(),
42    SpecificElementExtensions: (function() {
43      if (typeof window.HTMLDivElement !== 'undefined')
44        return true;
45
46      var div = document.createElement('div'),
47          form = document.createElement('form'),
48          isSupported = false;
49
50      if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
51        isSupported = true;
52      }
53
54      div = form = null;
55
56      return isSupported;
57    })()
58  },
59
60  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
61  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
62
63  emptyFunction: function() { },
64
65  K: function(x) { return x }
66};
67
68if (Prototype.Browser.MobileSafari)
69  Prototype.BrowserFeatures.SpecificElementExtensions = false;
70
71
72var Abstract = { };
73
74
75var Try = {
76  these: function() {
77    var returnValue;
78
79    for (var i = 0, length = arguments.length; i < length; i++) {
80      var lambda = arguments[i];
81      try {
82        returnValue = lambda();
83        break;
84      } catch (e) { }
85    }
86
87    return returnValue;
88  }
89};
90
91/* Based on Alex Arnell's inheritance implementation. */
92
93var Class = (function() {
94
95  var IS_DONTENUM_BUGGY = (function(){
96    for (var p in { toString: 1 }) {
97      if (p === 'toString') return false;
98    }
99    return true;
100  })();
101
102  function subclass() {};
103  function create() {
104    var parent = null, properties = $A(arguments);
105    if (Object.isFunction(properties[0]))
106      parent = properties.shift();
107
108    function klass() {
109      this.initialize.apply(this, arguments);
110    }
111
112    Object.extend(klass, Class.Methods);
113    klass.superclass = parent;
114    klass.subclasses = [];
115
116    if (parent) {
117      subclass.prototype = parent.prototype;
118      klass.prototype = new subclass;
119      parent.subclasses.push(klass);
120    }
121
122    for (var i = 0, length = properties.length; i < length; i++)
123      klass.addMethods(properties[i]);
124
125    if (!klass.prototype.initialize)
126      klass.prototype.initialize = Prototype.emptyFunction;
127
128    klass.prototype.constructor = klass;
129    return klass;
130  }
131
132  function addMethods(source) {
133    var ancestor   = this.superclass && this.superclass.prototype,
134        properties = Object.keys(source);
135
136    if (IS_DONTENUM_BUGGY) {
137      if (source.toString != Object.prototype.toString)
138        properties.push("toString");
139      if (source.valueOf != Object.prototype.valueOf)
140        properties.push("valueOf");
141    }
142
143    for (var i = 0, length = properties.length; i < length; i++) {
144      var property = properties[i], value = source[property];
145      if (ancestor && Object.isFunction(value) &&
146          value.argumentNames()[0] == "$super") {
147        var method = value;
148        value = (function(m) {
149          return function() { return ancestor[m].apply(this, arguments); };
150        })(property).wrap(method);
151
152        value.valueOf = method.valueOf.bind(method);
153        value.toString = method.toString.bind(method);
154      }
155      this.prototype[property] = value;
156    }
157
158    return this;
159  }
160
161  return {
162    create: create,
163    Methods: {
164      addMethods: addMethods
165    }
166  };
167})();
168(function() {
169
170  var _toString = Object.prototype.toString,
171      NULL_TYPE = 'Null',
172      UNDEFINED_TYPE = 'Undefined',
173      BOOLEAN_TYPE = 'Boolean',
174      NUMBER_TYPE = 'Number',
175      STRING_TYPE = 'String',
176      OBJECT_TYPE = 'Object',
177      FUNCTION_CLASS = '[object Function]',
178      BOOLEAN_CLASS = '[object Boolean]',
179      NUMBER_CLASS = '[object Number]',
180      STRING_CLASS = '[object String]',
181      ARRAY_CLASS = '[object Array]',
182      DATE_CLASS = '[object Date]',
183      NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
184        typeof JSON.stringify === 'function' &&
185        JSON.stringify(0) === '0' &&
186        typeof JSON.stringify(Prototype.K) === 'undefined';
187
188  function Type(o) {
189    switch(o) {
190      case null: return NULL_TYPE;
191      case (void 0): return UNDEFINED_TYPE;
192    }
193    var type = typeof o;
194    switch(type) {
195      case 'boolean': return BOOLEAN_TYPE;
196      case 'number':  return NUMBER_TYPE;
197      case 'string':  return STRING_TYPE;
198    }
199    return OBJECT_TYPE;
200  }
201
202  function extend(destination, source) {
203    for (var property in source)
204      destination[property] = source[property];
205    return destination;
206  }
207
208  function inspect(object) {
209    try {
210      if (isUndefined(object)) return 'undefined';
211      if (object === null) return 'null';
212      return object.inspect ? object.inspect() : String(object);
213    } catch (e) {
214      if (e instanceof RangeError) return '...';
215      throw e;
216    }
217  }
218
219  function toJSON(value) {
220    return Str('', { '': value }, []);
221  }
222
223  function Str(key, holder, stack) {
224    var value = holder[key],
225        type = typeof value;
226
227    if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
228      value = value.toJSON(key);
229    }
230
231    var _class = _toString.call(value);
232
233    switch (_class) {
234      case NUMBER_CLASS:
235      case BOOLEAN_CLASS:
236      case STRING_CLASS:
237        value = value.valueOf();
238    }
239
240    switch (value) {
241      case null: return 'null';
242      case true: return 'true';
243      case false: return 'false';
244    }
245
246    type = typeof value;
247    switch (type) {
248      case 'string':
249        return value.inspect(true);
250      case 'number':
251        return isFinite(value) ? String(value) : 'null';
252      case 'object':
253
254        for (var i = 0, length = stack.length; i < length; i++) {
255          if (stack[i] === value) { throw new TypeError(); }
256        }
257        stack.push(value);
258
259        var partial = [];
260        if (_class === ARRAY_CLASS) {
261          for (var i = 0, length = value.length; i < length; i++) {
262            var str = Str(i, value, stack);
263            partial.push(typeof str === 'undefined' ? 'null' : str);
264          }
265          partial = '[' + partial.join(',') + ']';
266        } else {
267          var keys = Object.keys(value);
268          for (var i = 0, length = keys.length; i < length; i++) {
269            var key = keys[i], str = Str(key, value, stack);
270            if (typeof str !== "undefined") {
271               partial.push(key.inspect(true)+ ':' + str);
272             }
273          }
274          partial = '{' + partial.join(',') + '}';
275        }
276        stack.pop();
277        return partial;
278    }
279  }
280
281  function stringify(object) {
282    return JSON.stringify(object);
283  }
284
285  function toQueryString(object) {
286    return $H(object).toQueryString();
287  }
288
289  function toHTML(object) {
290    return object && object.toHTML ? object.toHTML() : String.interpret(object);
291  }
292
293  function keys(object) {
294    if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
295    var results = [];
296    for (var property in object) {
297      if (object.hasOwnProperty(property)) {
298        results.push(property);
299      }
300    }
301    return results;
302  }
303
304  function values(object) {
305    var results = [];
306    for (var property in object)
307      results.push(object[property]);
308    return results;
309  }
310
311  function clone(object) {
312    return extend({ }, object);
313  }
314
315  function isElement(object) {
316    return !!(object && object.nodeType == 1);
317  }
318
319  function isArray(object) {
320    return _toString.call(object) === ARRAY_CLASS;
321  }
322
323  var hasNativeIsArray = (typeof Array.isArray == 'function')
324    && Array.isArray([]) && !Array.isArray({});
325
326  if (hasNativeIsArray) {
327    isArray = Array.isArray;
328  }
329
330  function isHash(object) {
331    return object instanceof Hash;
332  }
333
334  function isFunction(object) {
335    return _toString.call(object) === FUNCTION_CLASS;
336  }
337
338  function isString(object) {
339    return _toString.call(object) === STRING_CLASS;
340  }
341
342  function isNumber(object) {
343    return _toString.call(object) === NUMBER_CLASS;
344  }
345
346  function isDate(object) {
347    return _toString.call(object) === DATE_CLASS;
348  }
349
350  function isUndefined(object) {
351    return typeof object === "undefined";
352  }
353
354  extend(Object, {
355    extend:        extend,
356    inspect:       inspect,
357    toJSON:        NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
358    toQueryString: toQueryString,
359    toHTML:        toHTML,
360    keys:          Object.keys || keys,
361    values:        values,
362    clone:         clone,
363    isElement:     isElement,
364    isArray:       isArray,
365    isHash:        isHash,
366    isFunction:    isFunction,
367    isString:      isString,
368    isNumber:      isNumber,
369    isDate:        isDate,
370    isUndefined:   isUndefined
371  });
372})();
373Object.extend(Function.prototype, (function() {
374  var slice = Array.prototype.slice;
375
376  function update(array, args) {
377    var arrayLength = array.length, length = args.length;
378    while (length--) array[arrayLength + length] = args[length];
379    return array;
380  }
381
382  function merge(array, args) {
383    array = slice.call(array, 0);
384    return update(array, args);
385  }
386
387  function argumentNames() {
388    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
389      .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
390      .replace(/\s+/g, '').split(',');
391    return names.length == 1 && !names[0] ? [] : names;
392  }
393
394  function bind(context) {
395    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
396    var __method = this, args = slice.call(arguments, 1);
397    return function() {
398      var a = merge(args, arguments);
399      return __method.apply(context, a);
400    }
401  }
402
403  function bindAsEventListener(context) {
404    var __method = this, args = slice.call(arguments, 1);
405    return function(event) {
406      var a = update([event || window.event], args);
407      return __method.apply(context, a);
408    }
409  }
410
411  function curry() {
412    if (!arguments.length) return this;
413    var __method = this, args = slice.call(arguments, 0);
414    return function() {
415      var a = merge(args, arguments);
416      return __method.apply(this, a);
417    }
418  }
419
420  function delay(timeout) {
421    var __method = this, args = slice.call(arguments, 1);
422    timeout = timeout * 1000;
423    return window.setTimeout(function() {
424      return __method.apply(__method, args);
425    }, timeout);
426  }
427
428  function defer() {
429    var args = update([0.01], arguments);
430    return this.delay.apply(this, args);
431  }
432
433  function wrap(wrapper) {
434    var __method = this;
435    return function() {
436      var a = update([__method.bind(this)], arguments);
437      return wrapper.apply(this, a);
438    }
439  }
440
441  function methodize() {
442    if (this._methodized) return this._methodized;
443    var __method = this;
444    return this._methodized = function() {
445      var a = update([this], arguments);
446      return __method.apply(null, a);
447    };
448  }
449
450  return {
451    argumentNames:       argumentNames,
452    bind:                bind,
453    bindAsEventListener: bindAsEventListener,
454    curry:               curry,
455    delay:               delay,
456    defer:               defer,
457    wrap:                wrap,
458    methodize:           methodize
459  }
460})());
461
462
463
464(function(proto) {
465
466
467  function toISOString() {
468    return this.getUTCFullYear() + '-' +
469      (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
470      this.getUTCDate().toPaddedString(2) + 'T' +
471      this.getUTCHours().toPaddedString(2) + ':' +
472      this.getUTCMinutes().toPaddedString(2) + ':' +
473      this.getUTCSeconds().toPaddedString(2) + 'Z';
474  }
475
476
477  function toJSON() {
478    return this.toISOString();
479  }
480
481  if (!proto.toISOString) proto.toISOString = toISOString;
482  if (!proto.toJSON) proto.toJSON = toJSON;
483
484})(Date.prototype);
485
486
487RegExp.prototype.match = RegExp.prototype.test;
488
489RegExp.escape = function(str) {
490  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
491};
492var PeriodicalExecuter = Class.create({
493  initialize: function(callback, frequency) {
494    this.callback = callback;
495    this.frequency = frequency;
496    this.currentlyExecuting = false;
497
498    this.registerCallback();
499  },
500
501  registerCallback: function() {
502    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
503  },
504
505  execute: function() {
506    this.callback(this);
507  },
508
509  stop: function() {
510    if (!this.timer) return;
511    clearInterval(this.timer);
512    this.timer = null;
513  },
514
515  onTimerEvent: function() {
516    if (!this.currentlyExecuting) {
517      try {
518        this.currentlyExecuting = true;
519        this.execute();
520        this.currentlyExecuting = false;
521      } catch(e) {
522        this.currentlyExecuting = false;
523        throw e;
524      }
525    }
526  }
527});
528Object.extend(String, {
529  interpret: function(value) {
530    return value == null ? '' : String(value);
531  },
532  specialChar: {
533    '\b': '\\b',
534    '\t': '\\t',
535    '\n': '\\n',
536    '\f': '\\f',
537    '\r': '\\r',
538    '\\': '\\\\'
539  }
540});
541
542Object.extend(String.prototype, (function() {
543  var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
544    typeof JSON.parse === 'function' &&
545    JSON.parse('{"test": true}').test;
546
547  function prepareReplacement(replacement) {
548    if (Object.isFunction(replacement)) return replacement;
549    var template = new Template(replacement);
550    return function(match) { return template.evaluate(match) };
551  }
552
553  function gsub(pattern, replacement) {
554    var result = '', source = this, match;
555    replacement = prepareReplacement(replacement);
556
557    if (Object.isString(pattern))
558      pattern = RegExp.escape(pattern);
559
560    if (!(pattern.length || pattern.source)) {
561      replacement = replacement('');
562      return replacement + source.split('').join(replacement) + replacement;
563    }
564
565    while (source.length > 0) {
566      if (match = source.match(pattern)) {
567        result += source.slice(0, match.index);
568        result += String.interpret(replacement(match));
569        source  = source.slice(match.index + match[0].length);
570      } else {
571        result += source, source = '';
572      }
573    }
574    return result;
575  }
576
577  function sub(pattern, replacement, count) {
578    replacement = prepareReplacement(replacement);
579    count = Object.isUndefined(count) ? 1 : count;
580
581    return this.gsub(pattern, function(match) {
582      if (--count < 0) return match[0];
583      return replacement(match);
584    });
585  }
586
587  function scan(pattern, iterator) {
588    this.gsub(pattern, iterator);
589    return String(this);
590  }
591
592  function truncate(length, truncation) {
593    length = length || 30;
594    truncation = Object.isUndefined(truncation) ? '...' : truncation;
595    return this.length > length ?
596      this.slice(0, length - truncation.length) + truncation : String(this);
597  }
598
599  function strip() {
600    return this.replace(/^\s+/, '').replace(/\s+$/, '');
601  }
602
603  function stripTags() {
604    return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
605  }
606
607  function stripScripts() {
608    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
609  }
610
611  function extractScripts() {
612    var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
613        matchOne = new RegExp(Prototype.ScriptFragment, 'im');
614    return (this.match(matchAll) || []).map(function(scriptTag) {
615      return (scriptTag.match(matchOne) || ['', ''])[1];
616    });
617  }
618
619  function evalScripts() {
620    return this.extractScripts().map(function(script) { return eval(script) });
621  }
622
623  function escapeHTML() {
624    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
625  }
626
627  function unescapeHTML() {
628    return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
629  }
630
631
632  function toQueryParams(separator) {
633    var match = this.strip().match(/([^?#]*)(#.*)?$/);
634    if (!match) return { };
635
636    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
637      if ((pair = pair.split('='))[0]) {
638        var key = decodeURIComponent(pair.shift()),
639            value = pair.length > 1 ? pair.join('=') : pair[0];
640
641        if (value != undefined) value = decodeURIComponent(value);
642
643        if (key in hash) {
644          if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
645          hash[key].push(value);
646        }
647        else hash[key] = value;
648      }
649      return hash;
650    });
651  }
652
653  function toArray() {
654    return this.split('');
655  }
656
657  function succ() {
658    return this.slice(0, this.length - 1) +
659      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
660  }
661
662  function times(count) {
663    return count < 1 ? '' : new Array(count + 1).join(this);
664  }
665
666  function camelize() {
667    return this.replace(/-+(.)?/g, function(match, chr) {
668      return chr ? chr.toUpperCase() : '';
669    });
670  }
671
672  function capitalize() {
673    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
674  }
675
676  function underscore() {
677    return this.replace(/::/g, '/')
678               .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
679               .replace(/([a-z\d])([A-Z])/g, '$1_$2')
680               .replace(/-/g, '_')
681               .toLowerCase();
682  }
683
684  function dasherize() {
685    return this.replace(/_/g, '-');
686  }
687
688  function inspect(useDoubleQuotes) {
689    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(ch
689aracter) {
690      if (character in String.specialChar) {
691        return String.specialChar[character];
692      }
693      return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
694    });
695    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
696    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
697  }
698
699  function unfilterJSON(filter) {
700    return this.replace(filter || Prototype.JSONFilter, '$1');
701  }
702
703  function isJSON() {
704    var str = this;
705    if (str.blank()) return false;
706    str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
707    str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
708    str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
709    return (/^[\],:{}\s]*$/).test(str);
710  }
711
712  function evalJSON(sanitize) {
713    var json = this.unfilterJSON(),
714        cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
715    if (cx.test(json)) {
716      json = json.replace(cx, function (a) {
717        return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
718      });
719    }
720    try {
721      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
722    } catch (e) { }
723    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
724  }
725
726  function parseJSON() {
727    var json = this.unfilterJSON();
728    return JSON.parse(json);
729  }
730
731  function include(pattern) {
732    return this.indexOf(pattern) > -1;
733  }
734
735  function startsWith(pattern) {
736    return this.lastIndexOf(pattern, 0) === 0;
737  }
738
739  function endsWith(pattern) {
740    var d = this.length - pattern.length;
741    return d >= 0 && this.indexOf(pattern, d) === d;
742  }
743
744  function empty() {
745    return this == '';
746  }
747
748  function blank() {
749    return /^\s*$/.test(this);
750  }
751
752  function interpolate(object, pattern) {
753    return new Template(this, pattern).evaluate(object);
754  }
755
756  return {
757    gsub:           gsub,
758    sub:            sub,
759    scan:           scan,
760    truncate:       truncate,
761    strip:          String.prototype.trim || strip,
762    stripTags:      stripTags,
763    stripScripts:   stripScripts,
764    extractScripts: extractScripts,
765    evalScripts:    evalScripts,
766    escapeHTML:     escapeHTML,
767    unescapeHTML:   unescapeHTML,
768    toQueryParams:  toQueryParams,
769    parseQuery:     toQueryParams,
770    toArray:        toArray,
771    succ:           succ,
772    times:          times,
773    camelize:       camelize,
774    capitalize:     capitalize,
775    underscore:     underscore,
776    dasherize:      dasherize,
777    inspect:        inspect,
778    unfilterJSON:   unfilterJSON,
779    isJSON:         isJSON,
780    evalJSON:       NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
781    include:        include,
782    startsWith:     startsWith,
783    endsWith:       endsWith,
784    empty:          empty,
785    blank:          blank,
786    interpolate:    interpolate
787  };
788})());
789
790var Template = Class.create({
791  initialize: function(template, pattern) {
792    this.template = template.toString();
793    this.pattern = pattern || Template.Pattern;
794  },
795
796  evaluate: function(object) {
797    if (object && Object.isFunction(object.toTemplateReplacements))
798      object = object.toTemplateReplacements();
799
800    return this.template.gsub(this.pattern, function(match) {
801      if (object == null) return (match[1] + '');
802
803      var before = match[1] || '';
804      if (before == '\\') return match[2];
805
806      var ctx = object, expr = match[3],
807          pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
808
809      match = pattern.exec(expr);
810      if (match == null) return before;
811
812      while (match != null) {
813        var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
814        ctx = ctx[comp];
815        if (null == ctx || '' == match[3]) break;
816        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
817        match = pattern.exec(expr);
818      }
819
820      return before + String.interpret(ctx);
821    });
822  }
823});
824Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
825
826var $break = { };
827
828var Enumerable = (function() {
829  function each(iterator, context) {
830    var index = 0;
831    try {
832      this._each(function(value) {
833        iterator.call(context, value, index++);
834      });
835    } catch (e) {
836      if (e != $break) throw e;
837    }
838    return this;
839  }
840
841  function eachSlice(number, iterator, context) {
842    var index = -number, slices = [], array = this.toArray();
843    if (number < 1) return array;
844    while ((index += number) < array.length)
845      slices.push(array.slice(index, index+number));
846    return slices.collect(iterator, context);
847  }
848
849  function all(iterator, context) {
850    iterator = iterator || Prototype.K;
851    var result = true;
852    this.each(function(value, index) {
853      result = result && !!iterator.call(context, value, index);
854      if (!result) throw $break;
855    });
856    return result;
857  }
858
859  function any(iterator, context) {
860    iterator = iterator || Prototype.K;
861    var result = false;
862    this.each(function(value, index) {
863      if (result = !!iterator.call(context, value, index))
864        throw $break;
865    });
866    return result;
867  }
868
869  function collect(iterator, context) {
870    iterator = iterator || Prototype.K;
871    var results = [];
872    this.each(function(value, index) {
873      results.push(iterator.call(context, value, index));
874    });
875    return results;
876  }
877
878  function detect(iterator, context) {
879    var result;
880    this.each(function(value, index) {
881      if (iterator.call(context, value, index)) {
882        result = value;
883        throw $break;
884      }
885    });
886    return result;
887  }
888
889  function findAll(iterator, context) {
890    var results = [];
891    this.each(function(value, index) {
892      if (iterator.call(context, value, index))
893        results.push(value);
894    });
895    return results;
896  }
897
898  function grep(filter, iterator, context) {
899    iterator = iterator || Prototype.K;
900    var results = [];
901
902    if (Object.isString(filter))
903      filter = new RegExp(RegExp.escape(filter));
904
905    this.each(function(value, index) {
906      if (filter.match(value))
907        results.push(iterator.call(context, value, index));
908    });
909    return results;
910  }
911
912  function include(object) {
913    if (Object.isFunction(this.indexOf))
914      if (this.indexOf(object) != -1) return true;
915
916    var found = false;
917    this.each(function(value) {
918      if (value == object) {
919        found = true;
920        throw $break;
921      }
922    });
923    return found;
924  }
925
926  function inGroupsOf(number, fillWith) {
927    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
928    return this.eachSlice(number, function(slice) {
929      while(slice.length < number) slice.push(fillWith);
930      return slice;
931    });
932  }
933
934  function inject(memo, iterator, context) {
935    this.each(function(value, index) {
936      memo = iterator.call(context, memo, value, index);
937    });
938    return memo;
939  }
940
941  function invoke(method) {
942    var args = $A(arguments).slice(1);
943    return this.map(function(value) {
944      return value[method].apply(value, args);
945    });
946  }
947
948  function max(iterator, context) {
949    iterator = iterator || Prototype.K;
950    var result;
951    this.each(function(value, index) {
952      value = iterator.call(context, value, index);
953      if (result == null || value >= result)
954        result = value;
955    });
956    return result;
957  }
958
959  function min(iterator, context) {
960    iterator = iterator || Prototype.K;
961    var result;
962    this.each(function(value, index) {
963      value = iterator.call(context, value, index);
964      if (result == null || value < result)
965        result = value;
966    });
967    return result;
968  }
969
970  function partition(iterator, context) {
971    iterator = iterator || Prototype.K;
972    var trues = [], falses = [];
973    this.each(function(value, index) {
974      (iterator.call(context, value, index) ?
975        trues : falses).push(value);
976    });
977    return [trues, falses];
978  }
979
980  function pluck(property) {
981    var results = [];
982    this.each(function(value) {
983      results.push(value[property]);
984    });
985    return results;
986  }
987
988  function reject(iterator, context) {
989    var results = [];
990    this.each(function(value, index) {
991      if (!iterator.call(context, value, index))
992        results.push(value);
993    });
994    return results;
995  }
996
997  function sortBy(iterator, context) {
998    return this.map(function(value, index) {
999      return {
1000        value: value,
1001        criteria: iterator.call(context, value, index)
1002      };
1003    }).sort(function(left, right) {
1004      var a = left.criteria, b = right.criteria;
1005      return a < b ? -1 : a > b ? 1 : 0;
1006    }).pluck('value');
1007  }
1008
1009  function toArray() {
1010    return this.map();
1011  }
1012
1013  function zip() {
1014    var iterator = Prototype.K, args = $A(arguments);
1015    if (Object.isFunction(args.last()))
1016      iterator = args.pop();
1017
1018    var collections = [this].concat(args).map($A);
1019    return this.map(function(value, index) {
1020      return iterator(collections.pluck(index));
1021    });
1022  }
1023
1024  function size() {
1025    return this.toArray().length;
1026  }
1027
1028  function inspect() {
1029    return '#<Enumerable:' + this.toArray().inspect() + '>';
1030  }
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040  return {
1041    each:       each,
1042    eachSlice:  eachSlice,
1043    all:        all,
1044    every:      all,
1045    any:        any,
1046    some:       any,
1047    collect:    collect,
1048    map:        collect,
1049    detect:     detect,
1050    findAll:    findAll,
1051    select:     findAll,
1052    filter:     findAll,
1053    grep:       grep,
1054    include:    include,
1055    member:     include,
1056    inGroupsOf: inGroupsOf,
1057    inject:     inject,
1058    invoke:     invoke,
1059    max:        max,
1060    min:        min,
1061    partition:  partition,
1062    pluck:      pluck,
1063    reject:     reject,
1064    sortBy:     sortBy,
1065    toArray:    toArray,
1066    entries:    toArray,
1067    zip:        zip,
1068    size:       size,
1069    inspect:    inspect,
1070    find:       detect
1071  };
1072})();
1073
1074function $A(iterable) {
1075  if (!iterable) return [];
1076  if ('toArray' in Object(iterable)) return iterable.toArray();
1077  var length = iterable.length || 0, results = new Array(length);
1078  while (length--) results[length] = iterable[length];
1079  return results;
1080}
1081
1082
1083function $w(string) {
1084  if (!Object.isString(string)) return [];
1085  string = string.strip();
1086  return string ? string.split(/\s+/) : [];
1087}
1088
1089Array.from = $A;
1090
1091
1092(function() {
1093  var arrayProto = Array.prototype,
1094      slice = arrayProto.slice,
1095      _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
1096
1097  function each(iterator, context) {
1098    for (var i = 0, length = this.length >>> 0; i < length; i++) {
1099      if (i in this) iterator.call(context, this[i], i, this);
1100    }
1101  }
1102  if (!_each) _each = each;
1103
1104  function clear() {
1105    this.length = 0;
1106    return this;
1107  }
1108
1109  function first() {
1110    return this[0];
1111  }
1112
1113  function last() {
1114    return this[this.length - 1];
1115  }
1116
1117  function compact() {
1118    return this.select(function(value) {
1119      return value != null;
1120    });
1121  }
1122
1123  function flatten() {
1124    return this.inject([], function(array, value) {
1125      if (Object.isArray(value))
1126        return array.concat(value.flatten());
1127      array.push(value);
1128      return array;
1129    });
1130  }
1131
1132  function without() {
1133    var values = slice.call(arguments, 0);
1134    return this.select(function(value) {
1135      return !values.include(value);
1136    });
1137  }
1138
1139  function reverse(inline) {
1140    return (inline === false ? this.toArray() : this)._reverse();
1141  }
1142
1143  function uniq(sorted) {
1144    return this.inject([], function(array, value, index) {
1145      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
1146        array.push(value);
1147      return array;
1148    });
1149  }
1150
1151  function intersect(array) {
1152    return this.uniq().findAll(function(item) {
1153      return array.detect(function(value) { return item === value });
1154    });
1155  }
1156
1157
1158  function clone() {
1159    return slice.call(this, 0);
1160  }
1161
1162  function size() {
1163    return this.length;
1164  }
1165
1166  function inspect() {
1167    return '[' + this.map(Object.inspect).join(', ') + ']';
1168  }
1169
1170  function indexOf(item, i) {
1171    i || (i = 0);
1172    var length = this.length;
1173    if (i < 0) i = length + i;
1174    for (; i < length; i++)
1175      if (this[i] === item) return i;
1176    return -1;
1177  }
1178
1179  function lastIndexOf(item, i) {
1180    i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
1181    var n = this.slice(0, i).reverse().indexOf(item);
1182    return (n < 0) ? n : i - n - 1;
1183  }
1184
1185  function concat() {
1186    var array = slice.call(this, 0), item;
1187    for (var i = 0, length = arguments.length; i < length; i++) {
1188      item = arguments[i];
1189      if (Object.isArray(item) && !('callee' in item)) {
1190        for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
1191          array.push(item[j]);
1192      } else {
1193        array.push(item);
1194      }
1195    }
1196    return array;
1197  }
1198
1199  Object.extend(arrayProto, Enumerable);
1200
1201  if (!arrayProto._reverse)
1202    arrayProto._reverse = arrayProto.reverse;
1203
1204  Object.extend(arrayProto, {
1205    _each:     _each,
1206    clear:     clear,
1207    first:     first,
1208    last:      last,
1209    compact:   compact,
1210    flatten:   flatten,
1211    without:   without,
1212    reverse:   reverse,
1213    uniq:      uniq,
1214    intersect: intersect,
1215    clone:     clone,
1216    toArray:   clone,
1217    size:      size,
1218    inspect:   inspect
1219  });
1220
1221  var CONCAT_ARGUMENTS_BUGGY = (function() {
1222    return [].concat(arguments)[0][0] !== 1;
1223  })(1,2)
1224
1225  if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
1226
1227  if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
1228  if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
1229})();
1230function $H(object) {
1231  return new Hash(object);
1232};
1233
1234var Hash = Class.create(Enumerable, (function() {
1235  function initialize(object) {
1236    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
1237  }
1238
1239
1240  function _each(iterator) {
1241    for (var key in this._object) {
1242      var value = this._object[key], pair = [key, value];
1243      pair.key = key;
1244      pair.value = value;
1245      iterator(pair);
1246    }
1247  }
1248
1249  function set(key, value) {
1250    return this._object[key] = value;
1251  }
1252
1253  function get(key) {
1254    if (this._object[key] !== Object.prototype[key])
1255      return this._object[key];
1256  }
1257
1258  function unset(key) {
1259    var value = this._object[key];
1260    delete this._object[key];
1261    return value;
1262  }
1263
1264  function toObject() {
1265    return Object.clone(this._object);
1266  }
1267
1268
1269
1270  function keys() {
1271    return this.pluck('key');
1272  }
1273
1274  function values() {
1275    return this.pluck('value');
1276  }
1277
1278  function index(value) {
1279    var match = this.detect(function(pair) {
1280      return pair.value === value;
1281    });
1282    return match && match.key;
1283  }
1284
1285  function merge(object) {
1286    return this.clone().update(object);
1287  }
1288
1289  function update(object) {
1290    return new Hash(object).inject(this, function(result, pair) {
1291      result.set(pair.key, pair.value);
1292      return result;
1293    });
1294  }
1295
1296  function toQueryPair(key, value) {
1297    if (Object.isUndefined(value)) return key;
1298    return key + '=' + encodeURIComponent(String.interpret(value));
1299  }
1300
1301  function toQueryString() {
1302    return this.inject([], function(results, pair) {
1303      var key = encodeURIComponent(pair.key), values = pair.value;
1304
1305      if (values && typeof values == 'object') {
1306        if (Object.isArray(values)) {
1307          var queryValues = [];
1308          for (var i = 0, len = values.length, value; i < len; i++) {
1309            value = values[i];
1310            queryValues.push(toQueryPair(key, value));
1311          }
1312          return results.concat(queryValues);
1313        }
1314      } else results.push(toQueryPair(key, values));
1315      return results;
1316    }).join('&');
1317  }
1318
1319  function inspect() {
1320    return '#<Hash:{' + this.map(function(pair) {
1321      return pair.map(Object.inspect).join(': ');
1322    }).join(', ') + '}>';
1323  }
1324
1325  function clone() {
1326    return new Hash(this);
1327  }
1328
1329  return {
1330    initialize:             initialize,
1331    _each:                  _each,
1332    set:                    set,
1333    get:                    get,
1334    unset:                  unset,
1335    toObject:               toObject,
1336    toTemplateReplacements: toObject,
1337    keys:                   keys,
1338    values:                 values,
1339    index:                  index,
1340    merge:                  merge,
1341    update:                 update,
1342    toQueryString:          toQueryString,
1343    inspect:                inspect,
1344    toJSON:                 toObject,
1345    clone:                  clone
1346  };
1347})());
1348
1349Hash.from = $H;
1350Object.extend(Number.prototype, (function() {
1351  function toColorPart() {
1352    return this.toPaddedString(2, 16);
1353  }
1354
1355  function succ() {
1356    return this + 1;
1357  }
1358
1359  function times(iterator, context) {
1360    $R(0, this, true).each(iterator, context);
1361    return this;
1362  }
1363
1364  function toPaddedString(length, radix) {
1365    var string = this.toString(radix || 10);
1366    return '0'.times(length - string.length) + string;
1367  }
1368
1369  function abs() {
1370    return Math.abs(this);
1371  }
1372
1373  function round() {
1374    return Math.round(this);
1375  }
1376
1377  function ceil() {
1378    return Math.ceil(this);
1379  }
1380
1381  function floor() {
1382    return Math.floor(this);
1383  }
1384
1385  return {
1386    toColorPart:    toColorPart,
1387    succ:           succ,
1388    times:          times,
1389    toPaddedString: toPaddedString,
1390    abs:            abs,
1391    round:          round,
1392    ceil:           ceil,
1393    floor:          floor
1394  };
1395})());
1396
1397function $R(start, end, exclusive) {
1398  return new ObjectRange(start, end, exclusive);
1399}
1400
1401var ObjectRange = Class.create(Enumerable, (function() {
1402  function initialize(start, end, exclusive) {
1403    this.start = start;
1404    this.end = end;
1405    this.exclusive = exclusive;
1406  }
1407
1408  function _each(iterator) {
1409    var value = this.start;
1410    while (this.include(value)) {
1411      iterator(value);
1412      value = value.succ();
1413    }
1414  }
1415
1416  function include(value) {
1417    if (value < this.start)
1418      return false;
1419    if (this.exclusive)
1420      return value < this.end;
1421    return value <= this.end;
1422  }
1423
1424  return {
1425    initialize: initialize,
1426    _each:      _each,
1427    include:    include
1428  };
1429})());
1430
1431
1432
1433var Ajax = {
1434  getTransport: function() {
1435    return Try.these(
1436      function() {return new XMLHttpRequest()},
1437      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
1438      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
1439    ) || false;
1440  },
1441
1442  activeRequestCount: 0
1443};
1444
1445Ajax.Responders = {
1446  responders: [],
1447
1448  _each: function(iterator) {
1449    this.responders._each(iterator);
1450  },
1451
1452  register: function(responder) {
1453    if (!this.include(responder))
1454      this.responders.push(responder);
1455  },
1456
1457  unregister: function(responder) {
1458    this.responders = this.responders.without(responder);
1459  },
1460
1461  dispatch: function(callback, request, transport, json) {
1462    this.each(function(responder) {
1463      if (Object.isFunction(responder[callback])) {
1464        try {
1465          responder[callback].apply(responder, [request, transport, json]);
1466        } catch (e) { }
1467      }
1468    });
1469  }
1470};
1471
1472Object.extend(Ajax.Responders, Enumerable);
1473
1474Ajax.Responders.register({
1475  onCreate:   function() { Ajax.activeRequestCount++ },
1476  onComplete: function() { Ajax.activeRequestCount-- }
1477});
1478Ajax.Base = Class.create({
1479  initialize: function(options) {
1480    this.options = {
1481      method:       'post',
1482      asynchronous: true,
1483      contentType:  'application/x-www-form-urlencoded',
1484      encoding:     'UTF-8',
1485      parameters:   '',
1486      evalJSON:     true,
1487      evalJS:       true
1488    };
1489    Object.extend(this.options, options || { });
1490
1491    this.options.method = this.options.method.toLowerCase();
1492
1493    if (Object.isHash(this.options.parameters))
1494      this.options.parameters = this.options.parameters.toObject();
1495  }
1496});
1497Ajax.Request = Class.create(Ajax.Base, {
1498  _complete: false,
1499
1500  initialize: function($super, url, options) {
1501    $super(options);
1502    this.transport = Ajax.getTransport();
1503    this.request(url);
1504  },
1505
1506  request: function(url) {
1507    this.url = url;
1508    this.method = this.options.method;
1509    var params = Object.isString(this.options.parameters) ?
1510          this.options.parameters :
1511          Object.toQueryString(this.options.parameters);
1512
1513    if (!['get', 'post'].include(this.method)) {
1514      params += (params ? '&' : '') + "_method=" + this.method;
1515      this.method = 'post';
1516    }
1517
1518    if (params && this.method === 'get') {
1519      this.url += (this.url.include('?') ? '&' : '?') + params;
1520    }
1521
1522    this.parameters = params.toQueryParams();
1523
1524    try {
1525      var response = new Ajax.Response(this);
1526      if (this.options.onCreate) this.options.onCreate(response);
1527      Ajax.Responders.dispatch('onCreate', this, response);
1528
1529      this.transport.open(this.method.toUpperCase(), this.url,
1530        this.options.asynchronous);
1531
1532      if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
1533
1534      this.transport.onreadystatechange = this.onStateChange.bind(this);
1535      this.setRequestHeaders();
1536
1537      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
1538      this.transport.send(this.body);
1539
1540      /* Force Firefox to handle ready state 4 for synchronous requests */
1541      if (!this.options.asynchronous && this.transport.overrideMimeType)
1542        this.onStateChange();
1543
1544    }
1545    catch (e) {
1546      this.dispatchException(e);
1547    }
1548  },
1549
1550  onStateChange: function() {
1551    var readyState = this.transport.readyState;
1552    if (readyState > 1 && !((readyState == 4) && this._complete))
1553      this.respondToReadyState(this.transport.readyState);
1554  },
1555
1556  setRequestHeaders: function() {
1557    var headers = {
1558      'X-Requested-With': 'XMLHttpRequest',
1559      'X-Prototype-Version': Prototype.Version,
1560      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
1561    };
1562
1563    if (this.method == 'post') {
1564      headers['Content-type'] = this.options.contentType +
1565        (this.options.encoding ? '; charset=' + this.options.encoding : '');
1566
1567      /* Force "Connection: close" for older Mozilla browsers to work
1568       * around a bug where XMLHttpRequest sends an incorrect
1569       * Content-length header. See Mozilla Bugzilla #246651.
1570       */
1571      if (this.transport.overrideMimeType &&
1572          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
1573            headers['Connection'] = 'close';
1574    }
1575
1576    if (typeof this.options.requestHeaders == 'object') {
1577      var extras = this.options.requestHeaders;
1578
1579      if (Object.isFunction(extras.push))
1580        for (var i = 0, length = extras.length; i < length; i += 2)
1581          headers[extras[i]] = extras[i+1];
1582      else
1583        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
1584    }
1585
1586    for (var name in headers)
1587      this.transport.setRequestHeader(name, headers[name]);
1588  },
1589
1590  success: function() {
1591    var status = this.getStatus();
1592    return !status || (status >= 200 && status < 300) || status == 304;
1593  },
1594
1595  getStatus: function() {
1596    try {
1597      if (this.transport.status === 1223) return 204;
1598      return this.transport.status || 0;
1599    } catch (e) { return 0 }
1600  },
1601
1602  respondToReadyState: function(readyState) {
1603    var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
1604
1605    if (state == 'Complete') {
1606      try {
1607        this._complete = true;
1608        (this.options['on' + response.status]
1609         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
1610         || Prototype.emptyFunction)(response, response.headerJSON);
1611      } catch (e) {
1612        this.dispatchException(e);
1613      }
1614
1615      var contentType = response.getHeader('Content-type');
1616      if (this.options.evalJS == 'force'
1617          || (this.options.evalJS && this.isSameOrigin() && contentType
1618          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
1619        this.evalResponse();
1620    }
1621
1622    try {
1623      (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
1624      Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
1625    } catch (e) {
1626      this.dispatchException(e);
1627    }
1628
1629    if (state == 'Complete') {
1630      this.transport.onreadystatechange = Prototype.emptyFunction;
1631    }
1632  },
1633
1634  isSameOrigin: function() {
1635    var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
1636    return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
1637      protocol: location.protocol,
1638      domain: document.domain,
1639      port: location.port ? ':' + location.port : ''
1640    }));
1641  },
1642
1643  getHeader: function(name) {
1644    try {
1645      return this.transport.getResponseHeader(name) || null;
1646    } catch (e) { return null; }
1647  },
1648
1649  evalResponse: function() {
1650    try {
1651      return eval((this.transport.responseText || '').unfilterJSON());
1652    } catch (e) {
1653      this.dispatchException(e);
1654    }
1655  },
1656
1657  dispatchException: function(exception) {
1658    (this.options.onException || Prototype.emptyFunction)(this, exception);
1659    Ajax.Responders.dispatch('onException', this, exception);
1660  }
1661});
1662
1663Ajax.Request.Events =
1664  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
1665
1666
1667
1668
1669
1670
1671
1672
1673Ajax.Response = Class.create({
1674  initialize: function(request){
1675    this.request = request;
1676    var transport  = this.transport  = request.transport,
1677        readyState = this.readyState = transport.readyState;
1678
1679    if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
1680      this.status       = this.getStatus();
1681      this.statusText   = this.getStatusText();
1682      this.responseText = String.interpret(transport.responseText);
1683      this.headerJSON   = this._getHeaderJSON();
1684    }
1685
1686    if (readyState == 4) {
1687      var xml = transport.responseXML;
1688      this.responseXML  = Object.isUndefined(xml) ? null : xml;
1689      this.responseJSON = this._getResponseJSON();
1690    }
1691  },
1692
1693  status:      0,
1694
1695  statusText: '',
1696
1697  getStatus: Ajax.Request.prototype.getStatus,
1698
1699  getStatusText: function() {
1700    try {
1701      return this.transport.statusText || '';
1702    } catch (e) { return '' }
1703  },
1704
1705  getHeader: Ajax.Request.prototype.getHeader,
1706
1707  getAllHeaders: function() {
1708    try {
1709      return this.getAllResponseHeaders();
1710    } catch (e) { return null }
1711  },
1712
1713  getResponseHeader: function(name) {
1714    return this.transport.getResponseHeader(name);
1715  },
1716
1717  getAllResponseHeaders: function() {
1718    return this.transport.getAllResponseHeaders();
1719  },
1720
1721  _getHeaderJSON: function() {
1722    var json = this.getHeader('X-JSON');
1723    if (!json) return null;
1724    json = decodeURIComponent(escape(json));
1725    try {
1726      return json.evalJSON(this.request.options.sanitizeJSON ||
1727        !this.request.isSameOrigin());
1728    } catch (e) {
1729      this.request.dispatchException(e);
1730    }
1731  },
1732
1733  _getResponseJSON: function() {
1734    var options = this.request.options;
1735    if (!options.evalJSON || (options.evalJSON != 'force' &&
1736      !(this.getHeader('Content-type') || '').include('application/json')) ||
1737        this.responseText.blank())
1738          return null;
1739    try {
1740      return this.responseText.evalJSON(options.sanitizeJSON ||
1741        !this.request.isSameOrigin());
1742    } catch (e) {
1743      this.request.dispatchException(e);
1744    }
1745  }
1746});
1747
1748Ajax.Updater = Class.create(Ajax.Request, {
1749  initialize: function($super, container, url, options) {
1750    this.container = {
1751      success: (container.success || container),
1752      failure: (container.failure || (container.success ? null : container))
1753    };
1754
1755    options = Object.clone(options);
1756    var onComplete = options.onComplete;
1757    options.onComplete = (function(response, json) {
1758      this.updateContent(response.responseText);
1759      if (Object.isFunction(onComplete)) onComplete(response, json);
1760    }).bind(this);
1761
1762    $super(url, options);
1763  },
1764
1765  updateContent: function(responseText) {
1766    var receiver = this.container[this.success() ? 'success' : 'failure'],
1767        options = this.options;
1768
1769    if (!options.evalScripts) responseText = responseText.stripScripts();
1770
1771    if (receiver = $(receiver)) {
1772      if (options.insertion) {
1773        if (Object.isString(options.insertion)) {
1774          var insertion = { }; insertion[options.insertion] = responseText;
1775          receiver.insert(insertion);
1776        }
1777        else options.insertion(receiver, responseText);
1778      }
1779      else receiver.update(responseText);
1780    }
1781  }
1782});
1783
1784Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
1785  initialize: function($super, container, url, options) {
1786    $super(options);
1787    this.onComplete = this.options.onComplete;
1788
1789    this.frequency = (this.options.frequency || 2);
1790    this.decay = (this.options.decay || 1);
1791
1792    this.updater = { };
1793    this.container = container;
1794    this.url = url;
1795
1796    this.start();
1797  },
1798
1799  start: function() {
1800    this.options.onComplete = this.updateComplete.bind(this);
1801    this.onTimerEvent();
1802  },
1803
1804  stop: function() {
1805    this.updater.options.onComplete = undefined;
1806    clearTimeout(this.timer);
1807    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
1808  },
1809
1810  updateComplete: function(response) {
1811    if (this.options.decay) {
1812      this.decay = (response.responseText == this.lastText ?
1813        this.decay * this.options.decay : 1);
1814
1815      this.lastText = response.responseText;
1816    }
1817    this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
1818  },
1819
1820  onTimerEvent: function() {
1821    this.updater = new Ajax.Updater(this.container, this.url, this.options);
1822  }
1823});
1824
1825
1826function $(element) {
1827  if (arguments.length > 1) {
1828    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
1829      elements.push($(arguments[i]));
1830    return elements;
1831  }
1832  if (Object.isString(element))
1833    element = document.getElementById(element);
1834  return Element.extend(element);
1835}
1836
1837if (Prototype.BrowserFeatures.XPath) {
1838  document._getElementsByXPath = function(expression, parentElement) {
1839    var results = [];
1840    var query = document.evaluate(expression, $(parentElement) || document,
1841      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
1842    for (var i = 0, length = query.snapshotLength; i < length; i++)
1843      results.push(Element.extend(query.snapshotItem(i)));
1844    return results;
1845  };
1846}
1847
1848/*--------------------------------------------------------------------------*/
1849
1850if (!Node) var Node = { };
1851
1852if (!Node.ELEMENT_NODE) {
1853  Object.extend(Node, {
1854    ELEMENT_NODE: 1,
1855    ATTRIBUTE_NODE: 2,
1856    TEXT_NODE: 3,
1857    CDATA_SECTION_NODE: 4,
1858    ENTITY_REFERENCE_NODE: 5,
1859    ENTITY_NODE: 6,
1860    PROCESSING_INSTRUCTION_NODE: 7,
1861    COMMENT_NODE: 8,
1862    DOCUMENT_NODE: 9,
1863    DOCUMENT_TYPE_NODE: 10,
1864    DOCUMENT_FRAGMENT_NODE: 11,
1865    NOTATION_NODE: 12
1866  });
1867}
1868
1869
1870
1871(function(global) {
1872  function shouldUseCache(tagName, attributes) {
1873    if (tagName === 'select') return false;
1874    if ('type' in attributes) return false;
1875    return true;
1876  }
1877
1878  var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
1879    try {
1880      var el = document.createElement('<input name="x">');
1881      return el.tagName.toLowerCase() === 'input' && el.name === 'x';
1882    }
1883    catch(err) {
1884      return false;
1885    }
1886  })();
1887
1888  var element = global.Element;
1889
1890  global.Element = function(tagName, attributes) {
1891    attributes = attributes || { };
1892    tagName = tagName.toLowerCase();
1893    var cache = Element.cache;
1894
1895    if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
1896      tagName = '<' + tagName + ' name="' + attributes.name + '">';
1897      delete attributes.name;
1898      return Element.writeAttribute(document.createElement(tagName), attributes);
1899    }
1900
1901    if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
1902
1903    var node = shouldUseCache(tagName, attributes) ?
1904     cache[tagName].cloneNode(false) : document.createElement(tagName);
1905
1906    return Element.writeAttribute(node, attributes);
1907  };
1908
1909  Object.extend(global.Element, element || { });
1910  if (element) global.Element.prototype = element.prototype;
1911
1912})(this);
1913
1914Element.idCounter = 1;
1915Element.cache = { };
1916
1917Element._purgeElement = function(element) {
1918  var uid = element._prototypeUID;
1919  if (uid) {
1920    Element.stopObserving(element);
1921    element._prototypeUID = void 0;
1922    delete Element.Storage[uid];
1923  }
1924}
1925
1926Element.Methods = {
1927  visible: function(element) {
1928    return $(element).style.display != 'none';
1929  },
1930
1931  toggle: function(element) {
1932    element = $(element);
1933    Element[Element.visible(element) ? 'hide' : 'show'](element);
1934    return element;
1935  },
1936
1937  hide: function(element) {
1938    element = $(element);
1939    element.style.display = 'none';
1940    return element;
1941  },
1942
1943  show: function(element) {
1944    element = $(element);
1945    element.style.display = '';
1946    return element;
1947  },
1948
1949  remove: function(element) {
1950    element = $(element);
1951    element.parentNode.removeChild(element);
1952    return element;
1953  },
1954
1955  update: (function(){
1956
1957    var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
1958      var el = document.createElement("select"),
1959          isBuggy = true;
1960      el.innerHTML = "<option value=\"test\">test</option>";
1961      if (el.options && el.options[0]) {
1962        isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
1963      }
1964      el = null;
1965      return isBuggy;
1966    })();
1967
1968    var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
1969      try {
1970        var el = document.createElement("table");
1971        if (el && el.tBodies) {
1972          el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
1973          var isBuggy = typeof el.tBodies[0] == "undefined";
1974          el = null;
1975          return isBuggy;
1976        }
1977      } catch (e) {
1978        return true;
1979      }
1980    })();
1981
1982    var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
1983      try {
1984        var el = document.createElement('div');
1985        el.innerHTML = "<link>";
1986        var isBuggy = (el.childNodes.length === 0);
1987        el = null;
1988        return isBuggy;
1989      } catch(e) {
1990        return true;
1991      }
1992    })();
1993
1994    var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
1995     TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;
1996
1997    var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
1998      var s = document.createElement("script"),
1999          isBuggy = false;
2000      try {
2001        s.appendChild(document.createTextNode(""));
2002        isBuggy = !s.firstChild ||
2003          s.firstChild && s.firstChild.nodeType !== 3;
2004      } catch (e) {
2005        isBuggy = true;
2006      }
2007      s = null;
2008      return isBuggy;
2009    })();
2010
2011
2012    function update(element, content) {
2013      element = $(element);
2014      var purgeElement = Element._purgeElement;
2015
2016      var descendants = element.getElementsByTagName('*'),
2017       i = descendants.length;
2018      while (i--) purgeElement(descendants[i]);
2019
2020      if (content && content.toElement)
2021        content = content.toElement();
2022
2023      if (Object.isElement(content))
2024        return element.update().insert(content);
2025
2026      content = Object.toHTML(content);
2027
2028      var tagName = element.tagName.toUpperCase();
2029
2030      if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
2031        element.text = content;
2032        return element;
2033      }
2034
2035      if (ANY_INNERHTML_BUGGY) {
2036        if (tagName in Element._insertionTranslations.tags) {
2037          while (element.firstChild) {
2038            element.removeChild(element.firstChild);
2039          }
2040          Element._getContentFromAnonymousElement(tagName, content.stripScripts())
2041            .each(function(node) {
2042              element.appendChild(node)
2043            });
2044        } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) {
2045          while (element.firstChild) {
2046            element.removeChild(element.firstChild);
2047          }
2048          var nodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts(), true);
2049          nodes.each(function(node) { element.appendChild(node) });
2050        }
2051        else {
2052          element.innerHTML = content.stripScripts();
2053        }
2054      }
2055      else {
2056        element.innerHTML = content.stripScripts();
2057      }
2058
2059      content.evalScripts.bind(content).defer();
2060      return element;
2061    }
2062
2063    return update;
2064  })(),
2065
2066  replace: function(element, content) {
2067    element = $(element);
2068    if (content && content.toElement) content = content.toElement();
2069    else if (!Object.isElement(content)) {
2070      content = Object.toHTML(content);
2071      var range = element.ownerDocument.createRange();
2072      range.selectNode(element);
2073      content.evalScripts.bind(content).defer();
2074      content = range.createContextualFragment(content.stripScripts());
2075    }
2076    element.parentNode.replaceChild(content, element);
2077    return element;
2078  },
2079
2080  insert: function(element, insertions) {
2081    element = $(element);
2082
2083    if (Object.isString(insertions) || Object.isNumber(insertions) ||
2084        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
2085          insertions = {bottom:insertions};
2086
2087    var content, insert, tagName, childNodes;
2088
2089    for (var position in insertions) {
2090      content  = insertions[position];
2091      position = position.toLowerCase();
2092      insert = Element._insertionTranslations[position];
2093
2094      if (content && content.toElement) content = content.toElement();
2095      if (Object.isElement(content)) {
2096        insert(element, content);
2097        continue;
2098      }
2099
2100      content = Object.toHTML(content);
2101
2102      tagName = ((position == 'before' || position == 'after')
2103        ? element.parentNode : element).tagName.toUpperCase();
2104
2105      childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
2106
2107      if (position == 'top' || position == 'after') childNodes.reverse();
2108      childNodes.each(insert.curry(element));
2109
2110      content.evalScripts.bind(content).defer();
2111    }
2112
2113    return element;
2114  },
2115
2116  wrap: function(element, wrapper, attributes) {
2117    element = $(element);
2118    if (Object.isElement(wrapper))
2119      $(wrapper).writeAttribute(attributes || { });
2120    else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
2121    else wrapper = new Element('div', wrapper);
2122    if (element.parentNode)
2123      element.parentNode.replaceChild(wrapper, element);
2124    wrapper.appendChild(element);
2125    return wrapper;
2126  },
2127
2128  inspect: function(element) {
2129    element = $(element);
2130    var result = '<' + element.tagName.toLowerCase();
2131    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
2132      var property = pair.first(),
2133          attribute = pair.last(),
2134          value = (element[property] || '').toString();
2135      if (value) result += ' ' + attribute + '=' + value.inspect(true);
2136    });
2137    return result + '>';
2138  },
2139
2140  recursivelyCollect: function(element, property, maximumLength) {
2141    element = $(element);
2142    maximumLength = maximumLength || -1;
2143    var elements = [];
2144
2145    while (element = element[property]) {
2146      if (element.nodeType == 1)
2147        elements.push(Element.extend(element));
2148      if (elements.length == maximumLength)
2149        break;
2150    }
2151
2152    return elements;
2153  },
2154
2155  ancestors: function(element) {
2156    return Element.recursivelyCollect(element, 'parentNode');
2157  },
2158
2159  descendants: function(element) {
2160    return Element.select(element, "*");
2161  },
2162
2163  firstDescendant: function(element) {
2164    element = $(element).firstChild;
2165    while (element && element.nodeType != 1) element = element.nextSibling;
2166    return $(element);
2167  },
2168
2169  immediateDescendants: function(element) {
2170    var results = [], child = $(element).firstChild;
2171    while (child) {
2172      if (child.nodeType === 1) {
2173        results.push(Element.extend(child));
2174      }
2175      child = child.nextSibling;
2176    }
2177    return results;
2178  },
2179
2180  previousSiblings: function(element, maximumLength) {
2181    return Element.recursivelyCollect(element, 'previousSibling');
2182  },
2183
2184  nextSiblings: function(element) {
2185    return Element.recursivelyCollect(element, 'nextSibling');
2186  },
2187
2188  siblings: function(element) {
2189    element = $(element);
2190    return Element.previousSiblings(element).reverse()
2191      .concat(Element.nextSiblings(element));
2192  },
2193
2194  match: function(element, selector) {
2195    element = $(element);
2196    if (Object.isString(selector))
2197      return Prototype.Selector.match(element, selector);
2198    return selector.match(element);
2199  },
2200
2201  up: function(element, expression, index) {
2202    element = $(element);
2203    if (arguments.length == 1) return $(element.parentNode);
2204    var ancestors = Element.ancestors(element);
2205    return Object.isNumber(expression) ? ancestors[expression] :
2206      Prototype.Selector.find(ancestors, expression, index);
2207  },
2208
2209  down: function(element, expression, index) {
2210    element = $(element);
2211    if (arguments.length == 1) return Element.firstDescendant(element);
2212    return Object.isNumber(expression) ? Element.descendants(element)[expression] :
2213      Element.select(element, expression)[index || 0];
2214  },
2215
2216  previous: function(element, expression, index) {
2217    element = $(element);
2218    if (Object.isNumber(expression)) index = expression, expression = false;
2219    if (!Object.isNumber(index)) index = 0;
2220
2221    if (expression) {
2222      return Prototype.Selector.find(element.previousSiblings(), expression, index);
2223    } else {
2224      return element.recursivelyCollect("previousSibling", index + 1)[index];
2225    }
2226  },
2227
2228  next: function(element, expression, index) {
2229    element = $(element);
2230    if (Object.isNumber(expression)) index = expression, expression = false;
2231    if (!Object.isNumber(index)) index = 0;
2232
2233    if (expression) {
2234      return Prototype.Selector.find(element.nextSiblings(), expression, index);
2235    } else {
2236      var maximumLength = Object.isNumber(index) ? index + 1 : 1;
2237      return element.recursivelyCollect("nextSibling", index + 1)[index];
2238    }
2239  },
2240
2241
2242  select: function(element) {
2243    element = $(element);
2244    var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
2245    return Prototype.Selector.select(expressions, element);
2246  },
2247
2248  adjacent: function(element) {
2249    element = $(element);
2250    var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
2251    return Prototype.Selector.select(expressions, element.parentNode).without(element);
2252  },
2253
2254  identify: function(element) {
2255    element = $(element);
2256    var id = Element.readAttribute(element, 'id');
2257    if (id) return id;
2258    do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
2259    Element.writeAttribute(element, 'id', id);
2260    return id;
2261  },
2262
2263  readAttribute: function(element, name) {
2264    element = $(element);
2265    if (Prototype.Browser.IE) {
2266      var t = Element._attributeTranslations.read;
2267      if (t.values[name]) return t.values[name](element, name);
2268      if (t.names[name]) name = t.names[name];
2269      if (name.include(':')) {
2270        return (!element.attributes || !element.attributes[name]) ? null :
2271         element.attributes[name].value;
2272      }
2273    }
2274    return element.getAttribute(name);
2275  },
2276
2277  writeAttribute: function(element, name, value) {
2278    element = $(element);
2279    var attributes = { }, t = Element._attributeTranslations.write;
2280
2281    if (typeof name == 'object') attributes = name;
2282    else attributes[name] = Object.isUndefined(value) ? true : value;
2283
2284    for (var attr in attributes) {
2285      name = t.names[attr] || attr;
2286      value = attributes[attr];
2287      if (t.values[attr]) name = t.values[attr](element, value);
2288      if (value === false || value === null)
2289        element.removeAttribute(name);
2290      else if (value === true)
2291        element.setAttribute(name, name);
2292      else element.setAttribute(name, value);
2293    }
2294    return element;
2295  },
2296
2297  getHeight: function(element) {
2298    return Element.getDimensions(element).height;
2299  },
2300
2301  getWidth: function(element) {
2302    return Element.getDimensions(element).width;
2303  },
2304
2305  classNames: function(element) {
2306    return new Element.ClassNames(element);
2307  },
2308
2309  hasClassName: function(element, className) {
2310    if (!(element = $(element))) return;
2311    var elementClassName = element.className;
2312    return (elementClassName.length > 0 && (elementClassName == className ||
2313      new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
2314  },
2315
2316  addClassName: function(element, className) {
2317    if (!(element = $(element))) return;
2318    if (!Element.hasClassName(element, className))
2319      element.className += (element.className ? ' ' : '') + className;
2320    return element;
2321  },
2322
2323  removeClassName: function(element, className) {
2324    if (!(element = $(element))) return;
2325    element.className = element.className.replace(
2326      new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
2327    return element;
2328  },
2329
2330  toggleClassName: function(element, className) {
2331    if (!(element = $(element))) return;
2332    return Element[Element.hasClassName(element, className) ?
2333      'removeClassName' : 'addClassName'](element, className);
2334  },
2335
2336  cleanWhitespace: function(element) {
2337    element = $(element);
2338    var node = element.firstChild;
2339    while (node) {
2340      var nextNode = node.nextSibling;
2341      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
2342        element.removeChild(node);
2343      node = nextNode;
2344    }
2345    return element;
2346  },
2347
2348  empty: function(element) {
2349    return $(element).innerHTML.blank();
2350  },
2351
2352  descendantOf: function(element, ancestor) {
2353    element = $(element), ancestor = $(ancestor);
2354
2355    if (element.compareDocumentPosition)
2356      return (element.compareDocumentPosition(ancestor) & 8) === 8;
2357
2358    if (ancestor.contains)
2359      return ancestor.contains(element) && ancestor !== element;
2360
2361    while (element = element.parentNode)
2362      if (element == ancestor) return true;
2363
2364    return false;
2365  },
2366
2367  scrollTo: function(element) {
2368    element = $(element);
2369    var pos = Element.cumulativeOffset(element);
2370    window.scrollTo(pos[0], pos[1]);
2371    return element;
2372  },
2373
2374  getStyle: function(element, style) {
2375    element = $(element);
2376    style = style == 'float' ? 'cssFloat' : style.camelize();
2377    var value = element.style[style];
2378    if (!value || value == 'auto') {
2379      var css = document.defaultView.getComputedStyle(element, null);
2380      value = css ? css[style] : null;
2381    }
2382    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
2383    return value == 'auto' ? null : value;
2384  },
2385
2386  getOpacity: function(element) {
2387    return $(element).getStyle('opacity');
2388  },
2389
2390  setStyle: function(element, styles) {
2391    element = $(element);
2392    var elementStyle = element.style, match;
2393    if (Object.isString(styles)) {
2394      element.style.cssText += ';' + styles;
2395      return styles.include('opacity') ?
2396        element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
2397    }
2398    for (var property in styles)
2399      if (property == 'opacity') element.setOpacity(styles[property]);
2400      else
2401        elementStyle[(property == 'float' || property == 'cssFloat') ?
2402          (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
2403            property] = styles[property];
2404
2405    return element;
2406  },
2407
2408  setOpacity: function(element, value) {
2409    element = $(element);
2410    element.style.opacity = (value == 1 || value === '') ? '' :
2411      (value < 0.00001) ? 0 : value;
2412    return element;
2413  },
2414
2415  makePositioned: function(element) {
2416    element = $(element);
2417    var pos = Element.getStyle(element, 'position');
2418    if (pos == 'static' || !pos) {
2419      element._madePositioned = true;
2420      element.style.position = 'relative';
2421      if (Prototype.Browser.Opera) {
2422        element.style.top = 0;
2423        element.style.left = 0;
2424      }
2425    }
2426    return element;
2427  },
2428
2429  undoPositioned: function(element) {
2430    element = $(element);
2431    if (element._madePositioned) {
2432      element._madePositioned = undefined;
2433      element.style.position =
2434        element.style.top =
2435        element.style.left =
2436        element.style.bottom =
2437        element.style.right = '';
2438    }
2439    return element;
2440  },
2441
2442  makeClipping: function(element) {
2443    element = $(element);
2444    if (element._overflow) return element;
2445    element._overflow = Element.getStyle(element, 'overflow') || 'auto';
2446    if (element._overflow !== 'hidden')
2447      element.style.overflow = 'hidden';
2448    return element;
2449  },
2450
2451  undoClipping: function(element) {
2452    element = $(element);
2453    if (!element._overflow) return element;
2454    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
2455    element._overflow = null;
2456    return element;
2457  },
2458
2459  clonePosition: function(element, source) {
2460    var options = Object.extend({
2461      setLeft:    true,
2462      setTop:     true,
2463      setWidth:   true,
2464      setHeight:  true,
2465      offsetTop:  0,
2466      offsetLeft: 0
2467    }, arguments[2] || { });
2468
2469    source = $(source);
2470    var p = Element.viewportOffset(source), delta = [0, 0], parent = null;
2471
2472    element = $(element);
2473
2474    if (Element.getStyle(element, 'position') == 'absolute') {
2475      parent = Element.getOffsetParent(element);
2476      delta = Element.viewportOffset(parent);
2477    }
2478
2479    if (parent == document.body) {
2480      delta[0] -= document.body.offsetLeft;
2481      delta[1] -= document.body.offsetTop;
2482    }
2483
2484    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
2485    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
2486    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
2487    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
2488    return element;
2489  }
2490};
2491
2492Object.extend(Element.Methods, {
2493  getElementsBySelector: Element.Methods.select,
2494
2495  childElements: Element.Methods.immediateDescendants
2496});
2497
2498Element._attributeTranslations = {
2499  write: {
2500    names: {
2501      className: 'class',
2502      htmlFor:   'for'
2503    },
2504    values: { }
2505  }
2506};
2507
2508if (Prototype.Browser.Opera) {
2509  Element.Methods.getStyle = Element.Methods.getStyle.wrap(
2510    function(proceed, element, style) {
2511      switch (style) {
2512        case 'height': case 'width':
2513          if (!Element.visible(element)) return null;
2514
2515          var dim = parseInt(proceed(element, style), 10);
2516
2517          if (dim !== element['offset' + style.capitalize()])
2518            return dim + 'px';
2519
2520          var properties;
2521          if (style === 'height') {
2522            properties = ['border-top-width', 'padding-top',
2523             'padding-bottom', 'border-bottom-width'];
2524          }
2525          else {
2526            properties = ['border-left-width', 'padding-left',
2527             'padding-right', 'border-right-width'];
2528          }
2529          return properties.inject(dim, function(memo, property) {
2530            var val = proceed(element, property);
2531            return val === null ? memo : memo - parseInt(val, 10);
2532          }) + 'px';
2533        default: return proceed(element, style);
2534      }
2535    }
2536  );
2537
2538  Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
2539    function(proceed, element, attribute) {
2540      if (attribute === 'title') return element.title;
2541      return proceed(element, attribute);
2542    }
2543  );
2544}
2545
2546else if (Prototype.Browser.IE) {
2547  Element.Methods.getStyle = function(element, style) {
2548    element = $(element);
2549    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
2550    var value = element.style[style];
2551    if (!value && element.currentStyle) value = element.currentStyle[style];
2552
2553    if (style == 'opacity') {
2554      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
2555        if (value[1]) return parseFloat(value[1]) / 100;
2556      return 1.0;
2557    }
2558
2559    if (value == 'auto') {
2560      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
2561        return element['offset' + style.capitalize()] + 'px';
2562      return null;
2563    }
2564    return value;
2565  };
2566
2567  Element.Methods.setOpacity = function(element, value) {
2568    function stripAlpha(filter){
2569      return filter.replace(/alpha\([^\)]*\)/gi,'');
2570    }
2571    element = $(element);
2572    var currentStyle = element.currentStyle;
2573    if ((currentStyle && !currentStyle.hasLayout) ||
2574      (!currentStyle && element.style.zoom == 'normal'))
2575        element.style.zoom = 1;
2576
2577    var filter = element.getStyle('filter'), style = element.style;
2578    if (value == 1 || value === '') {
2579      (filter = stripAlpha(filter)) ?
2580        style.filter = filter : style.removeAttribute('filter');
2581      return element;
2582    } else if (value < 0.00001) value = 0;
2583    style.filter = stripAlpha(filter) +
2584      'alpha(opacity=' + (value * 100) + ')';
2585    return element;
2586  };
2587
2588  Element._attributeTranslations = (function(){
2589
2590    var classProp = 'className',
2591        forProp = 'for',
2592        el = document.createElement('div');
2593
2594    el.setAttribute(classProp, 'x');
2595
2596    if (el.className !== 'x') {
2597      el.setAttribute('class', 'x');
2598      if (el.className === 'x') {
2599        classProp = 'class';
2600      }
2601    }
2602    el = null;
2603
2604    el = document.createElement('label');
2605    el.setAttribute(forProp, 'x');
2606    if (el.htmlFor !== 'x') {
2607      el.setAttribute('htmlFor', 'x');
2608      if (el.htmlFor === 'x') {
2609        forProp = 'htmlFor';
2610      }
2611    }
2612    el = null;
2613
2614    return {
2615      read: {
2616        names: {
2617          'class':      classProp,
2618          'className':  classProp,
2619          'for':        forProp,
2620          'htmlFor':    forProp
2621        },
2622        values: {
2623          _getAttr: function(element, attribute) {
2624            return element.getAttribute(attribute);
2625          },
2626          _getAttr2: function(element, attribute) {
2627            return element.getAttribute(attribute, 2);
2628          },
2629          _getAttrNode: function(element, attribute) {
2630            var node = element.getAttributeNode(attribute);
2631            return node ? node.value : "";
2632          },
2633          _getEv: (function(){
2634
2635            var el = document.createElement('div'), f;
2636            el.onclick = Prototype.emptyFunction;
2637            var value = el.getAttribute('onclick');
2638
2639            if (String(value).indexOf('{') > -1) {
2640              f = function(element, attribute) {
2641                attribute = element.getAttribute(attribute);
2642                if (!attribute) return null;
2643                attribute = attribute.toString();
2644                attribute = attribute.split('{')[1];
2645                attribute = attribute.split('}')[0];
2646                return attribute.strip();
2647              };
2648            }
2649            else if (value === '') {
2650              f = function(element, attribute) {
2651                attribute = element.getAttribute(attribute);
2652                if (!attribute) return null;
2653                return attribute.strip();
2654              };
2655            }
2656            el = null;
2657            return f;
2658          })(),
2659          _flag: function(element, attribute) {
2660            return $(element).hasAttribute(attribute) ? attribute : null;
2661          },
2662          style: function(element) {
2663            return element.style.cssText.toLowerCase();
2664          },
2665          title: function(element) {
2666            return element.title;
2667          }
2668        }
2669      }
2670    }
2671  })();
2672
2673  Element._attributeTranslations.write = {
2674    names: Object.extend({
2675      cellpadding: 'cellPadding',
2676      cellspacing: 'cellSpacing'
2677    }, Element._attributeTranslations.read.names),
2678    values: {
2679      checked: function(element, value) {
2680        element.checked = !!value;
2681      },
2682
2683      style: function(element, value) {
2684        element.style.cssText = value ? value : '';
2685      }
2686    }
2687  };
2688
2689  Element._attributeTranslations.has = {};
2690
2691  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
2692      'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
2693    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
2694    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
2695  });
2696
2697  (function(v) {
2698    Object.extend(v, {
2699      href:        v._getAttr2,
2700      src:         v._getAttr2,
2701      type:        v._getAttr,
2702      action:      v._getAttrNode,
2703      disabled:    v._flag,
2704      checked:     v._flag,
2705      readonly:    v._flag,
2706      multiple:    v._flag,
2707      onload:      v._getEv,
2708      onunload:    v._getEv,
2709      onclick:     v._getEv,
2710      ondblclick:  v._getEv,
2711      onmousedown: v._getEv,
2712      onmouseup:   v._getEv,
2713      onmouseover: v._getEv,
2714      onmousemove: v._getEv,
2715      onmouseout:  v._getEv,
2716      onfocus:     v._getEv,
2717      onblur:      v._getEv,
2718      onkeypress:  v._getEv,
2719      onkeydown:   v._getEv,
2720      onkeyup:     v._getEv,
2721      onsubmit:    v._getEv,
2722      onreset:     v._getEv,
2723      onselect:    v._getEv,
2724      onchange:    v._getEv
2725    });
2726  })(Element._attributeTranslations.read.values);
2727
2728  if (Prototype.BrowserFeatures.ElementExtensions) {
2729    (function() {
2730      function _descendants(element) {
2731        var nodes = element.getElementsByTagName('*'), results = [];
2732        for (var i = 0, node; node = nodes[i]; i++)
2733          if (node.tagName !== "!") // Filter out comment nodes.
2734            results.push(node);
2735        return results;
2736      }
2737
2738      Element.Methods.down = function(element, expression, index) {
2739        element = $(element);
2740        if (arguments.length == 1) return element.firstDescendant();
2741        return Object.isNumber(expression) ? _descendants(element)[expression] :
2742          Element.select(element, expression)[index || 0];
2743      }
2744    })();
2745  }
2746
2747}
2748
2749else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
2750  Element.Methods.setOpacity = function(element, value) {
2751    element = $(element);
2752    element.style.opacity = (value == 1) ? 0.999999 :
2753      (value === '') ? '' : (value < 0.00001) ? 0 : value;
2754    return element;
2755  };
2756}
2757
2758else if (Prototype.Browser.WebKit) {
2759  Element.Methods.setOpacity = function(element, value) {
2760    element = $(element);
2761    element.style.opacity = (value == 1 || value === '') ? '' :
2762      (value < 0.00001) ? 0 : value;
2763
2764    if (value == 1)
2765      if (element.tagName.toUpperCase() == 'IMG' && element.width) {
2766        element.width++; element.width--;
2767      } else try {
2768        var n = document.createTextNode(' ');
2769        element.appendChild(n);
2770        element.removeChild(n);
2771      } catch (e) { }
2772
2773    return element;
2774  };
2775}
2776
2777if ('outerHTML' in document.documentElement) {
2778  Element.Methods.replace = function(element, content) {
2779    element = $(element);
2780
2781    if (content && content.toElement) content = content.toElement();
2782    if (Object.isElement(content)) {
2783      element.parentNode.replaceChild(content, element);
2784      return element;
2785    }
2786
2787    content = Object.toHTML(content);
2788    var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
2789
2790    if (Element._insertionTranslations.tags[tagName]) {
2791      var nextSibling = element.next(),
2792          fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
2793      parent.removeChild(element);
2794      if (nextSibling)
2795        fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
2796      else
2797        fragments.each(function(node) { parent.appendChild(node) });
2798    }
2799    else element.outerHTML = content.stripScripts();
2800
2801    content.evalScripts.bind(content).defer();
2802    return element;
2803  };
2804}
2805
2806Element._returnOffset = function(l, t) {
2807  var result = [l, t];
2808  result.left = l;
2809  result.top = t;
2810  return result;
2811};
2812
2813Element._getContentFromAnonymousElement = function(tagName, html, force) {
2814  var div = new Element('div'),
2815      t = Element._insertionTranslations.tags[tagName];
2816
2817  var workaround = false;
2818  if (t) workaround = true;
2819  else if (force) {
2820    workaround = true;
2821    t = ['', '', 0];
2822  }
2823
2824  if (workaround) {
2825    div.innerHTML = '&nbsp;' + t[0] + html + t[1];
2826    div.removeChild(div.firstChild);
2827    for (var i = t[2]; i--; ) {
2828      div = div.firstChild;
2829    }
2830  }
2831  else {
2832    div.innerHTML = html;
2833  }
2834  return $A(div.childNodes);
2835};
2836
2837Element._insertionTranslations = {
2838  before: function(element, node) {
2839    element.parentNode.insertBefore(node, element);
2840  },
2841  top: function(element, node) {
2842    element.insertBefore(node, element.firstChild);
2843  },
2844  bottom: function(element, node) {
2845    element.appendChild(node);
2846  },
2847  after: function(element, node) {
2848    element.parentNode.insertBefore(node, element.nextSibling);
2849  },
2850  tags: {
2851    TABLE:  ['<table>',                '</table>',                   1],
2852    TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
2853    TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
2854    TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
2855    SELECT: ['<select>',               '</select>',                  1]
2856  }
2857};
2858
2859(function() {
2860  var tags = Element._insertionTranslations.tags;
2861  Object.extend(tags, {
2862    THEAD: tags.TBODY,
2863    TFOOT: tags.TBODY,
2864    TH:    tags.TD
2865  });
2866})();
2867
2868Element.Methods.Simulated = {
2869  hasAttribute: function(element, attribute) {
2870    attribute = Element._attributeTranslations.has[attribute] || attribute;
2871    var node = $(element).getAttributeNode(attribute);
2872    return !!(node && node.specified);
2873  }
2874};
2875
2876Element.Methods.ByTag = { };
2877
2878Object.extend(Element, Element.Methods);
2879
2880(function(div) {
2881
2882  if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
2883    window.HTMLElement = { };
2884    window.HTMLElement.prototype = div['__proto__'];
2885    Prototype.BrowserFeatures.ElementExtensions = true;
2886  }
2887
2888  div = null;
2889
2890})(document.createElement('div'));
2891
2892Element.extend = (function() {
2893
2894  function checkDeficiency(tagName) {
2895    if (typeof window.Element != 'undefined') {
2896      var proto = window.Element.prototype;
2897      if (proto) {
2898        var id = '_' + (Math.random()+'').slice(2),
2899            el = document.createElement(tagName);
2900        proto[id] = 'x';
2901        var isBuggy = (el[id] !== 'x');
2902        delete proto[id];
2903        el = null;
2904        return isBuggy;
2905      }
2906    }
2907    return false;
2908  }
2909
2910  function extendElementWith(element, methods) {
2911    for (var property in methods) {
2912      var value = methods[property];
2913      if (Object.isFunction(value) && !(property in element))
2914        element[property] = value.methodize();
2915    }
2916  }
2917
2918  var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
2919
2920  if (Prototype.BrowserFeatures.SpecificElementExtensions) {
2921    if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
2922      return function(element) {
2923        if (element && typeof element._extendedByPrototype == 'undefined') {
2924          var t = element.tagName;
2925          if (t && (/^(?:object|applet|embed)$/i.test(t))) {
2926            extendElementWith(element, Element.Methods);
2927            extendElementWith(element, Element.Methods.Simulated);
2928            extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
2929          }
2930        }
2931        return element;
2932      }
2933    }
2934    return Prototype.K;
2935  }
2936
2937  var Methods = { }, ByTag = Element.Methods.ByTag;
2938
2939  var extend = Object.extend(function(element) {
2940    if (!element || typeof element._extendedByPrototype != 'undefined' ||
2941        element.nodeType != 1 || element == window) return element;
2942
2943    var methods = Object.clone(Methods),
2944        tagName = element.tagName.toUpperCase();
2945
2946    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
2947
2948    extendElementWith(element, methods);
2949
2950    element._extendedByPrototype = Prototype.emptyFunction;
2951    return element;
2952
2953  }, {
2954    refresh: function() {
2955      if (!Prototype.BrowserFeatures.ElementExtensions) {
2956        Object.extend(Methods, Element.Methods);
2957        Object.extend(Methods, Element.Methods.Simulated);
2958      }
2959    }
2960  });
2961
2962  extend.refresh();
2963  return extend;
2964})();
2965
2966if (document.documentElement.hasAttribute) {
2967  Element.hasAttribute = function(element, attribute) {
2968    return element.hasAttribute(attribute);
2969  };
2970}
2971else {
2972  Element.hasAttribute = Element.Methods.Simulated.hasAttribute;
2973}
2974
2975Element.addMethods = function(methods) {
2976  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
2977
2978  if (!methods) {
2979    Object.extend(Form, Form.Methods);
2980    Object.extend(Form.Element, Form.Element.Methods);
2981    Object.extend(Element.Methods.ByTag, {
2982      "FORM":     Object.clone(Form.Methods),
2983      "INPUT":    Object.clone(Form.Element.Methods),
2984      "SELECT":   Object.clone(Form.Element.Methods),
2985      "TEXTAREA": Object.clone(Form.Element.Methods),
2986      "BUTTON":   Object.clone(Form.Element.Methods)
2987    });
2988  }
2989
2990  if (arguments.length == 2) {
2991    var tagName = methods;
2992    methods = arguments[1];
2993  }
2994
2995  if (!tagName) Object.extend(Element.Methods, methods || { });
2996  else {
2997    if (Object.isArray(tagName)) tagName.each(extend);
2998    else extend(tagName);
2999  }
3000
3001  function extend(tagName) {
3002    tagName = tagName.toUpperCase();
3003    if (!Element.Methods.ByTag[tagName])
3004      Element.Methods.ByTag[tagName] = { };
3005    Object.extend(Element.Methods.ByTag[tagName], methods);
3006  }
3007
3008  function copy(methods, destination, onlyIfAbsent) {
3009    onlyIfAbsent = onlyIfAbsent || false;
3010    for (var property in methods) {
3011      var value = methods[property];
3012      if (!Object.isFunction(value)) continue;
3013      if (!onlyIfAbsent || !(property in destination))
3014        destination[property] = value.methodize();
3015    }
3016  }
3017
3018  function findDOMClass(tagName) {
3019    var klass;
3020    var trans = {
3021      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
3022      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
3023      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
3024      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
3025      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
3026      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
3027      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
3028      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
3029      "FrameSet", "IFRAME": "IFrame"
3030    };
3031    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
3032    if (window[klass]) return window[klass];
3033    klass = 'HTML' + tagName + 'Element';
3034    if (window[klass]) return window[klass];
3035    klass = 'HTML' + tagName.capitalize() + 'Element';
3036    if (window[klass]) return window[klass];
3037
3038    var element = document.createElement(tagName),
3039        proto = element['__proto__'] || element.constructor.prototype;
3040
3041    element = null;
3042    return proto;
3043  }
3044
3045  var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
3046   Element.prototype;
3047
3048  if (F.ElementExtensions) {
3049    copy(Element.Methods, elementPrototype);
3050    copy(Element.Methods.Simulated, elementPrototype, true);
3051  }
3052
3053  if (F.SpecificElementExtensions) {
3054    for (var tag in Element.Methods.ByTag) {
3055      var klass = findDOMClass(tag);
3056      if (Object.isUndefined(klass)) continue;
3057      copy(T[tag], klass.prototype);
3058    }
3059  }
3060
3061  Object.extend(Element, Element.Methods);
3062  delete Element.ByTag;
3063
3064  if (Element.extend.refresh) Element.extend.refresh();
3065  Element.cache = { };
3066};
3067
3068
3069document.viewport = {
3070
3071  getDimensions: function() {
3072    return { width: this.getWidth(), height: this.getHeight() };
3073  },
3074
3075  getScrollOffsets: function() {
3076    return Element._returnOffset(
3077      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
3078      window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop);
3079  }
3080};
3081
3082(function(viewport) {
3083  var B = Prototype.Browser, doc = document, element, property = {};
3084
3085  function getRootElement() {
3086    if (B.WebKit && !doc.evaluate)
3087      return document;
3088
3089    if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
3090      return document.body;
3091
3092    return document.documentElement;
3093  }
3094
3095  function define(D) {
3096    if (!element) element = getRootElement();
3097
3098    property[D] = 'client' + D;
3099
3100    viewport['get' + D] = function() { return element[property[D]] };
3101    return viewport['get' + D]();
3102  }
3103
3104  viewport.getWidth  = define.curry('Width');
3105
3106  viewport.getHeight = define.curry('Height');
3107})(document.viewport);
3108
3109
3110Element.Storage = {
3111  UID: 1
3112};
3113
3114Element.addMethods({
3115  getStorage: function(element) {
3116    if (!(element = $(element))) return;
3117
3118    var uid;
3119    if (element === window) {
3120      uid = 0;
3121    } else {
3122      if (typeof element._prototypeUID === "undefined")
3123        element._prototypeUID = Element.Storage.UID++;
3124      uid = element._prototypeUID;
3125    }
3126
3127    if (!Element.Storage[uid])
3128      Element.Storage[uid] = $H();
3129
3130    return Element.Storage[uid];
3131  },
3132
3133  store: function(element, key, value) {
3134    if (!(element = $(element))) return;
3135
3136    if (arguments.length === 2) {
3137      Element.getStorage(element).update(key);
3138    } else {
3139      Element.getStorage(element).set(key, value);
3140    }
3141
3142    return element;
3143  },
3144
3145  retrieve: function(element, key, defaultValue) {
3146    if (!(element = $(element))) return;
3147    var hash = Element.getStorage(element), value = hash.get(key);
3148
3149    if (Object.isUndefined(value)) {
3150      hash.set(key, defaultValue);
3151      value = defaultValue;
3152    }
3153
3154    return value;
3155  },
3156
3157  clone: function(element, deep) {
3158    if (!(element = $(element))) return;
3159    var clone = element.cloneNode(deep);
3160    clone._prototypeUID = void 0;
3161    if (deep) {
3162      var descendants = Element.select(clone, '*'),
3163          i = descendants.length;
3164      while (i--) {
3165        descendants[i]._prototypeUID = void 0;
3166      }
3167    }
3168    return Element.extend(clone);
3169  },
3170
3171  purge: function(element) {
3172    if (!(element = $(element))) return;
3173    var purgeElement = Element._purgeElement;
3174
3175    purgeElement(element);
3176
3177    var descendants = element.getElementsByTagName('*'),
3178     i = descendants.length;
3179
3180    while (i--) purgeElement(descendants[i]);
3181
3182    return null;
3183  }
3184});
3185
3186(function() {
3187
3188  function toDecimal(pctString) {
3189    var match = pctString.match(/^(\d+)%?$/i);
3190    if (!match) return null;
3191    return (Number(match[1]) / 100);
3192  }
3193
3194  function getPixelValue(value, property, context) {
3195    var element = null;
3196    if (Object.isElement(value)) {
3197      element = value;
3198      value = element.getStyle(property);
3199    }
3200
3201    if (value === null) {
3202      return null;
3203    }
3204
3205    if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
3206      return window.parseFloat(value);
3207    }
3208
3209    var isPercentage = value.include('%'), isViewport = (context === document.viewport);
3210
3211    if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
3212      var style = element.style.left, rStyle = element.runtimeStyle.left;
3213      element.runtimeStyle.left = element.currentStyle.left;
3214      element.style.left = value || 0;
3215      value = element.style.pixelLeft;
3216      element.style.left = style;
3217      element.runtimeStyle.left = rStyle;
3218
3219      return value;
3220    }
3221
3222    if (element && isPercentage) {
3223      context = context || element.parentNode;
3224      var decimal = toDecimal(value);
3225      var whole = null;
3226      var position = element.getStyle('position');
3227
3228      var isHorizontal = property.include('left') || property.include('right') ||
3229       property.include('width');
3230
3231      var isVertical =  property.include('top') || property.include('bottom') ||
3232        property.include('height');
3233
3234      if (context === document.viewport) {
3235        if (isHorizontal) {
3236          whole = document.viewport.getWidth();
3237        } else if (isVertical) {
3238          whole = document.viewport.getHeight();
3239        }
3240      } else {
3241        if (isHorizontal) {
3242          whole = $(context).measure('width');
3243        } else if (isVertical) {
3244          whole = $(context).measure('height');
3245        }
3246      }
3247
3248      return (whole === null) ? 0 : whole * decimal;
3249    }
3250
3251    return 0;
3252  }
3253
3254  function toCSSPixels(number) {
3255    if (Object.isString(number) && number.endsWith('px')) {
3256      return number;
3257    }
3258    return number + 'px';
3259  }
3260
3261  function isDisplayed(element) {
3262    var originalElement = element;
3263    while (element && element.parentNode) {
3264      var display = element.getStyle('display');
3265      if (display === 'none') {
3266        return false;
3267      }
3268      element = $(element.parentNode);
3269    }
3270    return true;
3271  }
3272
3273  var hasLayout = Prototype.K;
3274  if ('currentStyle' in document.documentElement) {
3275    hasLayout = function(element) {
3276      if (!element.currentStyle.hasLayout) {
3277        element.style.zoom = 1;
3278      }
3279      return element;
3280    };
3281  }
3282
3283  function cssNameFor(key) {
3284    if (key.include('border')) key = key + '-width';
3285    return key.camelize();
3286  }
3287
3288  Element.Layout = Class.create(Hash, {
3289    initialize: function($super, element, preCompute) {
3290      $super();
3291      this.element = $(element);
3292
3293      Element.Layout.PROPERTIES.each( function(property) {
3294        this._set(property, null);
3295      }, this);
3296
3297      if (preCompute) {
3298        this._preComputing = true;
3299        this._begin();
3300        Element.Layout.PROPERTIES.each( this._compute, this );
3301        this._end();
3302        this._preComputing = false;
3303      }
3304    },
3305
3306    _set: function(property, value) {
3307      return Hash.prototype.set.call(this, property, value);
3308    },
3309
3310    set: function(property, value) {
3311      throw "Properties of Element.Layout are read-only.";
3312    },
3313
3314    get: function($super, property) {
3315      var value = $super(property);
3316      return value === null ? this._compute(property) : value;
3317    },
3318
3319    _begin: function() {
3320      if (this._prepared) return;
3321
3322      var element = this.element;
3323      if (isDisplayed(element)) {
3324        this._prepared = true;
3325        return;
3326      }
3327
3328      var originalStyles = {
3329        position:   element.style.position   || '',
3330        width:      element.style.width      || '',
3331        visibility: element.style.visibility || '',
3332        display:    element.style.display    || ''
3333      };
3334
3335      element.store('prototype_original_styles', originalStyles);
3336
3337      var position = element.getStyle('position'),
3338       width = element.getStyle('width');
3339
3340      if (width === "0px" || width === null) {
3341        element.style.display = 'block';
3342        width = element.getStyle('width');
3343      }
3344
3345      var context = (position === 'fixed') ? document.viewport :
3346       element.parentNode;
3347
3348      element.setStyle({
3349        position:   'absolute',
3350        visibility: 'hidden',
3351        display:    'block'
3352      });
3353
3354      var positionedWidth = element.getStyle('width');
3355
3356      var newWidth;
3357      if (width && (positionedWidth === width)) {
3358        newWidth = getPixelValue(element, 'width', context);
3359      } else if (position === 'absolute' || position === 'fixed') {
3360        newWidth = getPixelValue(element, 'width', context);
3361      } else {
3362        var parent = element.parentNode, pLayout = $(parent).getLayout();
3363
3364        newWidth = pLayout.get('width') -
3365         this.get('margin-left') -
3366         this.get('border-left') -
3367         this.get('padding-left') -
3368         this.get('padding-right') -
3369         this.get('border-right') -
3370         this.get('margin-right');
3371      }
3372
3373      element.setStyle({ width: newWidth + 'px' });
3374
3375      this._prepared = true;
3376    },
3377
3378    _end: function() {
3379      var element = this.element;
3380      var originalStyles = element.retrieve('prototype_original_styles');
3381      element.store('prototype_original_styles', null);
3382      element.setStyle(originalStyles);
3383      this._prepared = false;
3384    },
3385
3386    _compute: function(property) {
3387      var COMPUTATIONS = Element.Layout.COMPUTATIONS;
3388      if (!(property in COMPUTATIONS)) {
3389        throw "Property not found.";
3390      }
3391
3392      return this._set(property, COMPUTATIONS[property].call(this, this.element));
3393    },
3394
3395    toObject: function() {
3396      var args = $A(arguments);
3397      var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3398       args.join(' ').split(' ');
3399      var obj = {};
3400      keys.each( function(key) {
3401        if (!Element.Layout.PROPERTIES.include(key)) return;
3402        var value = this.get(key);
3403        if (value != null) obj[key] = value;
3404      }, this);
3405      return obj;
3406    },
3407
3408    toHash: function() {
3409      var obj = this.toObject.apply(this, arguments);
3410      return new Hash(obj);
3411    },
3412
3413    toCSS: function() {
3414      var args = $A(arguments);
3415      var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3416       args.join(' ').split(' ');
3417      var css = {};
3418
3419      keys.each( function(key) {
3420        if (!Element.Layout.PROPERTIES.include(key)) return;
3421        if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
3422
3423        var value = this.get(key);
3424        if (value != null) css[cssNameFor(key)] = value + 'px';
3425      }, this);
3426      return css;
3427    },
3428
3429    inspect: function() {
3430      return "#<Element.Layout>";
3431    }
3432  });
3433
3434  Object.extend(Element.Layout, {
3435    PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'),
3436
3437    COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
3438
3439    COMPUTATIONS: {
3440      'height': function(element) {
3441        if (!this._preComputing) this._begin();
3442
3443        var bHeight = this.get('border-box-height');
3444        if (bHeight <= 0) {
3445          if (!this._preComputing) this._end();
3446          return 0;
3447        }
3448
3449        var bTop = this.get('border-top'),
3450         bBottom = this.get('border-bottom');
3451
3452        var pTop = this.get('padding-top'),
3453         pBottom = this.get('padding-bottom');
3454
3455        if (!this._preComputing) this._end();
3456
3457        return bHeight - bTop - bBottom - pTop - pBottom;
3458      },
3459
3460      'width': function(element) {
3461        if (!this._preComputing) this._begin();
3462
3463        var bWidth = this.get('border-box-width');
3464        if (bWidth <= 0) {
3465          if (!this._preComputing) this._end();
3466          return 0;
3467        }
3468
3469        var bLeft = this.get('border-left'),
3470         bRight = this.get('border-right');
3471
3472        var pLeft = this.get('padding-left'),
3473         pRight = this.get('padding-right');
3474
3475        if (!this._preComputing) this._end();
3476
3477        return bWidth - bLeft - bRight - pLeft - pRight;
3478      },
3479
3480      'padding-box-height': function(element) {
3481        var height = this.get('height'),
3482         pTop = this.get('padding-top'),
3483         pBottom = this.get('padding-bottom');
3484
3485        return height + pTop + pBottom;
3486      },
3487
3488      'padding-box-width': function(element) {
3489        var width = this.get('width'),
3490         pLeft = this.get('padding-left'),
3491         pRight = this.get('padding-right');
3492
3493        return width + pLeft + pRight;
3494      },
3495
3496      'border-box-height': function(element) {
3497        if (!this._preComputing) this._begin();
3498        var height = element.offsetHeight;
3499        if (!this._preComputing) this._end();
3500        return height;
3501      },
3502
3503      'border-box-width': function(element) {
3504        if (!this._preComputing) this._begin();
3505        var width = element.offsetWidth;
3506        if (!this._preComputing) this._end();
3507        return width;
3508      },
3509
3510      'margin-box-height': function(element) {
3511        var bHeight = this.get('border-box-height'),
3512         mTop = this.get('margin-top'),
3513         mBottom = this.get('margin-bottom');
3514
3515        if (bHeight <= 0) return 0;
3516
3517        return bHeight + mTop + mBottom;
3518      },
3519
3520      'margin-box-width': function(element) {
3521        var bWidth = this.get('border-box-width'),
3522         mLeft = this.get('margin-left'),
3523         mRight = this.get('margin-right');
3524
3525        if (bWidth <= 0) return 0;
3526
3527        return bWidth + mLeft + mRight;
3528      },
3529
3530      'top': function(element) {
3531        var offset = element.positionedOffset();
3532        return offset.top;
3533      },
3534
3535      'bottom': function(element) {
3536        var offset = element.positionedOffset(),
3537         parent = element.getOffsetParent(),
3538         pHeight = parent.measure('height');
3539
3540        var mHeight = this.get('border-box-height');
3541
3542        return pHeight - mHeight - offset.top;
3543      },
3544
3545      'left': function(element) {
3546        var offset = element.positionedOffset();
3547        return offset.left;
3548      },
3549
3550      'right': function(element) {
3551        var offset = element.positionedOffset(),
3552         parent = element.getOffsetParent(),
3553         pWidth = parent.measure('width');
3554
3555        var mWidth = this.get('border-box-width');
3556
3557        return pWidth - mWidth - offset.left;
3558      },
3559
3560      'padding-top': function(element) {
3561        return getPixelValue(element, 'paddingTop');
3562      },
3563
3564      'padding-bottom': function(element) {
3565        return getPixelValue(element, 'paddingBottom');
3566      },
3567
3568      'padding-left': function(element) {
3569        return getPixelValue(element, 'paddingLeft');
3570      },
3571
3572      'padding-right': function(element) {
3573        return getPixelValue(element, 'paddingRight');
3574      },
3575
3576      'border-top': function(element) {
3577        return getPixelValue(element, 'borderTopWidth');
3578      },
3579
3580      'border-bottom': function(element) {
3581        return getPixelValue(element, 'borderBottomWidth');
3582      },
3583
3584      'border-left': function(element) {
3585        return getPixelValue(element, 'borderLeftWidth');
3586      },
3587
3588      'border-right': function(element) {
3589        return getPixelValue(element, 'borderRightWidth');
3590      },
3591
3592      'margin-top': function(element) {
3593        return getPixelValue(element, 'marginTop');
3594      },
3595
3596      'margin-bottom': function(element) {
3597        return getPixelValue(element, 'marginBottom');
3598      },
3599
3600      'margin-left': function(element) {
3601        return getPixelValue(element, 'marginLeft');
3602      },
3603
3604      'margin-right': function(element) {
3605        return getPixelValue(element, 'marginRight');
3606      }
3607    }
3608  });
3609
3610  if ('getBoundingClientRect' in document.documentElement) {
3611    Object.extend(Element.Layout.COMPUTATIONS, {
3612      'right': function(element) {
3613        var parent = hasLayout(element.getOffsetParent());
3614        var rect = element.getBoundingClientRect(),
3615         pRect = parent.getBoundingClientRect();
3616
3617        return (pRect.right - rect.right).round();
3618      },
3619
3620      'bottom': function(element) {
3621        var parent = hasLayout(element.getOffsetParent());
3622        var rect = element.getBoundingClientRect(),
3623         pRect = parent.getBoundingClientRect();
3624
3625        return (pRect.bottom - rect.bottom).round();
3626      }
3627    });
3628  }
3629
3630  Element.Offset = Class.create({
3631    initialize: function(left, top) {
3632      this.left = left.round();
3633      this.top  = top.round();
3634
3635      this[0] = this.left;
3636      this[1] = this.top;
3637    },
3638
3639    relativeTo: function(offset) {
3640      return new Element.Offset(
3641        this.left - offset.left,
3642        this.top  - offset.top
3643      );
3644    },
3645
3646    inspect: function() {
3647      return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
3648    },
3649
3650    toString: function() {
3651      return "[#{left}, #{top}]".interpolate(this);
3652    },
3653
3654    toArray: function() {
3655      return [this.left, this.top];
3656    }
3657  });
3658
3659  function getLayout(element, preCompute) {
3660    return new Element.Layout(element, preCompute);
3661  }
3662
3663  function measure(element, property) {
3664    return $(element).getLayout().get(property);
3665  }
3666
3667  function getDimensions(element) {
3668    element = $(element);
3669    var display = Element.getStyle(element, 'display');
3670
3671    if (display && display !== 'none') {
3672      return { width: element.offsetWidth, height: element.offsetHeight };
3673    }
3674
3675    var style = element.style;
3676    var originalStyles = {
3677      visibility: style.visibility,
3678      position:   style.position,
3679      display:    style.display
3680    };
3681
3682    var newStyles = {
3683      visibility: 'hidden',
3684      display:    'block'
3685    };
3686
3687    if (originalStyles.position !== 'fixed')
3688      newStyles.position = 'absolute';
3689
3690    Element.setStyle(element, newStyles);
3691
3692    var dimensions = {
3693      width:  element.offsetWidth,
3694      height: element.offsetHeight
3695    };
3696
3697    Element.setStyle(element, originalStyles);
3698
3699    return dimensions;
3700  }
3701
3702  function getOffsetParent(element) {
3703    element = $(element);
3704
3705    if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
3706      return $(document.body);
3707
3708    var isInline = (Element.getStyle(element, 'display') === 'inline');
3709    if (!isInline && element.offsetParent) return $(element.offsetParent);
3710
3711    while ((element = element.parentNode) && element !== document.body) {
3712      if (Element.getStyle(element, 'position') !== 'static') {
3713        return isHtml(element) ? $(document.body) : $(element);
3714      }
3715    }
3716
3717    return $(document.body);
3718  }
3719
3720
3721  function cumulativeOffset(element) {
3722    element = $(element);
3723    var valueT = 0, valueL = 0;
3724    if (element.parentNode) {
3725      do {
3726        valueT += element.offsetTop  || 0;
3727        valueL += element.offsetLeft || 0;
3728        element = element.offsetParent;
3729      } while (element);
3730    }
3731    return new Element.Offset(valueL, valueT);
3732  }
3733
3734  function positionedOffset(element) {
3735    element = $(element);
3736
3737    var layout = element.getLayout();
3738
3739    var valueT = 0, valueL = 0;
3740    do {
3741      valueT += element.offsetTop  || 0;
3742      valueL += element.offsetLeft || 0;
3743      element = element.offsetParent;
3744      if (element) {
3745        if (isBody(element)) break;
3746        var p = Element.getStyle(element, 'position');
3747        if (p !== 'static') break;
3748      }
3749    } while (element);
3750
3751    valueL -= layout.get('margin-top');
3752    valueT -= layout.get('margin-left');
3753
3754    return new Element.Offset(valueL, valueT);
3755  }
3756
3757  function cumulativeScrollOffset(element) {
3758    var valueT = 0, valueL = 0;
3759    do {
3760      valueT += element.scrollTop  || 0;
3761      valueL += element.scrollLeft || 0;
3762      element = element.parentNode;
3763    } while (element);
3764    return new Element.Offset(valueL, valueT);
3765  }
3766
3767  function viewportOffset(forElement) {
3768    element = $(element);
3769    var valueT = 0, valueL = 0, docBody = document.body;
3770
3771    var element = forElement;
3772    do {
3773      valueT += element.offsetTop  || 0;
3774      valueL += element.offsetLeft || 0;
3775      if (element.offsetParent == docBody &&
3776        Element.getStyle(element, 'position') == 'absolute') break;
3777    } while (element = element.offsetParent);
3778
3779    element = forElement;
3780    do {
3781      if (element != docBody) {
3782        valueT -= element.scrollTop  || 0;
3783        valueL -= element.scrollLeft || 0;
3784      }
3785    } while (element = element.parentNode);
3786    return new Element.Offset(valueL, valueT);
3787  }
3788
3789  function absolutize(element) {
3790    element = $(element);
3791
3792    if (Element.getStyle(element, 'position') === 'absolute') {
3793      return element;
3794    }
3795
3796    var offsetParent = getOffsetParent(element);
3797    var eOffset = element.viewportOffset(),
3798     pOffset = offsetParent.viewportOffset();
3799
3800    var offset = eOffset.relativeTo(pOffset);
3801    var layout = element.getLayout();
3802
3803    element.store('prototype_absolutize_original_styles', {
3804      left:   element.getStyle('left'),
3805      top:    element.getStyle('top'),
3806      width:  element.getStyle('width'),
3807      height: element.getStyle('height')
3808    });
3809
3810    element.setStyle({
3811      position: 'absolute',
3812      top:    offset.top + 'px',
3813      left:   offset.left + 'px',
3814      width:  layout.get('width') + 'px',
3815      height: layout.get('height') + 'px'
3816    });
3817
3818    return element;
3819  }
3820
3821  function relativize(element) {
3822    element = $(element);
3823    if (Element.getStyle(element, 'position') === 'relative') {
3824      return element;
3825    }
3826
3827    var originalStyles =
3828     element.retrieve('prototype_absolutize_original_styles');
3829
3830    if (originalStyles) element.setStyle(originalStyles);
3831    return element;
3832  }
3833
3834  if (Prototype.Browser.IE) {
3835    getOffsetParent = getOffsetParent.wrap(
3836      function(proceed, element) {
3837        element = $(element);
3838
3839        if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
3840          return $(document.body);
3841
3842        var position = element.getStyle('position');
3843        if (position !== 'static') return proceed(element);
3844
3845        element.setStyle({ position: 'relative' });
3846        var value = proceed(element);
3847        element.setStyle({ position: position });
3848        return value;
3849      }
3850    );
3851
3852    positionedOffset = positionedOffset.wrap(function(proceed, element) {
3853      element = $(element);
3854      if (!element.parentNode) return new Element.Offset(0, 0);
3855      var position = element.getStyle('position');
3856      if (position !== 'static') return proceed(element);
3857
3858      var offsetParent = element.getOffsetParent();
3859      if (offsetParent && offsetParent.getStyle('position') === 'fixed')
3860        hasLayout(offsetParent);
3861
3862      element.setStyle({ position: 'relative' });
3863      var value = proceed(element);
3864      element.setStyle({ position: position });
3865      return value;
3866    });
3867  } else if (Prototype.Browser.Webkit) {
3868    cumulativeOffset = function(element) {
3869      element = $(element);
3870      var valueT = 0, valueL = 0;
3871      do {
3872        valueT += element.offsetTop  || 0;
3873        valueL += element.offsetLeft || 0;
3874        if (element.offsetParent == document.body)
3875          if (Element.getStyle(element, 'position') == 'absolute') break;
3876
3877        element = element.offsetParent;
3878      } while (element);
3879
3880      return new Element.Offset(valueL, valueT);
3881    };
3882  }
3883
3884
3885  Element.addMethods({
3886    getLayout:              getLayout,
3887    measure:                measure,
3888    getDimensions:          getDimensions,
3889    getOffsetParent:        getOffsetParent,
3890    cumulativeOffset:       cumulativeOffset,
3891    positionedOffset:       positionedOffset,
3892    cumulativeScrollOffset: cumulativeScrollOffset,
3893    viewportOffset:         viewportOffset,
3894    absolutize:             absolutize,
3895    relativize:             relativize
3896  });
3897
3898  function isBody(element) {
3899    return element.nodeName.toUpperCase() === 'BODY';
3900  }
3901
3902  function isHtml(element) {
3903    return element.nodeName.toUpperCase() === 'HTML';
3904  }
3905
3906  function isDocument(element) {
3907    return element.nodeType === Node.DOCUMENT_NODE;
3908  }
3909
3910  function isDetached(element) {
3911    return element !== document.body &&
3912     !Element.descendantOf(element, document.body);
3913  }
3914
3915  if ('getBoundingClientRect' in document.documentElement) {
3916    Element.addMethods({
3917      viewportOffset: function(element) {
3918        element = $(element);
3919        if (isDetached(element)) return new Element.Offset(0, 0);
3920
3921        var rect = element.getBoundingClientRect(),
3922         docEl = document.documentElement;
3923        return new Element.Offset(rect.left - docEl.clientLeft,
3924         rect.top - docEl.clientTop);
3925      }
3926    });
3927  }
3928})();
3929window.$$ = function() {
3930  var expression = $A(arguments).join(', ');
3931  return Prototype.Selector.select(expression, document);
3932};
3933
3934Prototype.Selector = (function() {
3935
3936  function select() {
3937    throw new Error('Method "Prototype.Selector.select" must be defined.');
3938  }
3939
3940  function match() {
3941    throw new Error('Method "Prototype.Selector.match" must be defined.');
3942  }
3943
3944  function find(elements, expression, index) {
3945    index = index || 0;
3946    var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
3947
3948    for (i = 0; i < length; i++) {
3949      if (match(elements[i], expression) && index == matchIndex++) {
3950        return Element.extend(elements[i]);
3951      }
3952    }
3953  }
3954
3955  function extendElements(elements) {
3956    for (var i = 0, length = elements.length; i < length; i++) {
3957      Element.extend(elements[i]);
3958    }
3959    return elements;
3960  }
3961
3962
3963  var K = Prototype.K;
3964
3965  return {
3966    select: select,
3967    match: match,
3968    find: find,
3969    extendElements: (Element.extend === K) ? K : extendElements,
3970    extendElement: Element.extend
3971  };
3972})();
3973Prototype._original_property = window.Sizzle;
3974/*!
3975 * Sizzle CSS Selector Engine - v1.0
3976 *  Copyright 2009, The Dojo Foundation
3977 *  Released under the MIT, BSD, and GPL Licenses.
3978 *  More information: http://sizzlejs.com/
3979 */
3980(function(){
3981
3982var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3983	done = 0,
3984	toString = Object.prototype.toString,
3985	hasDuplicate = false,
3986	baseHasDuplicate = true;
3987
3988[0, 0].sort(function(){
3989	baseHasDuplicate = false;
vendor: 5,874 bytes, lines 3990-4246
3990	return 0;
3991});
3992
3993var Sizzle = function(selector, context, results, seed) {
3994	results = results || [];
3995	var origContext = context = context || document;
3996
3997	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3998		return [];
3999	}
4000
4001	if ( !selector || typeof selector !== "string" ) {
4002		return results;
4003	}
4004
4005	var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
4006		soFar = selector;
4007
4008	while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
4009		soFar = m[3];
4010
4011		parts.push( m[1] );
4012
4013		if ( m[2] ) {
4014			extra = m[3];
4015			break;
4016		}
4017	}
4018
4019	if ( parts.length > 1 && origPOS.exec( selector ) ) {
4020		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
4021			set = posProcess( parts[0] + parts[1], context );
4022		} else {
4023			set = Expr.relative[ parts[0] ] ?
4024				[ context ] :
4025				Sizzle( parts.shift(), context );
4026
4027			while ( parts.length ) {
4028				selector = parts.shift();
4029
4030				if ( Expr.relative[ selector ] )
4031					selector += parts.shift();
4032
4033				set = posProcess( selector, set );
4034			}
4035		}
4036	} else {
4037		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
4038				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
4039			var ret = Sizzle.find( parts.shift(), context, contextXML );
4040			context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
4041		}
4042
4043		if ( context ) {
4044			var ret = seed ?
4045				{ expr: parts.pop(), set: makeArray(seed) } :
4046				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
4047			set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
4048
4049			if ( parts.length > 0 ) {
4050				checkSet = makeArray(set);
4051			} else {
4052				prune = false;
4053			}
4054
4055			while ( parts.length ) {
4056				var cur = parts.pop(), pop = cur;
4057
4058				if ( !Expr.relative[ cur ] ) {
4059					cur = "";
4060				} else {
4061					pop = parts.pop();
4062				}
4063
4064				if ( pop == null ) {
4065					pop = context;
4066				}
4067
4068				Expr.relative[ cur ]( checkSet, pop, contextXML );
4069			}
4070		} else {
4071			checkSet = parts = [];
4072		}
4073	}
4074
4075	if ( !checkSet ) {
4076		checkSet = set;
4077	}
4078
4079	if ( !checkSet ) {
4080		throw "Syntax error, unrecognized expression: " + (cur || selector);
4081	}
4082
4083	if ( toString.call(checkSet) === "[object Array]" ) {
4084		if ( !prune ) {
4085			results.push.apply( results, checkSet );
4086		} else if ( context && context.nodeType === 1 ) {
4087			for ( var i = 0; checkSet[i] != null; i++ ) {
4088				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
4089					results.push( set[i] );
4090				}
4091			}
4092		} else {
4093			for ( var i = 0; checkSet[i] != null; i++ ) {
4094				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4095					results.push( set[i] );
4096				}
4097			}
4098		}
4099	} else {
4100		makeArray( checkSet, results );
4101	}
4102
4103	if ( extra ) {
4104		Sizzle( extra, origContext, results, seed );
4105		Sizzle.uniqueSort( results );
4106	}
4107
4108	return results;
4109};
4110
4111Sizzle.uniqueSort = function(results){
4112	if ( sortOrder ) {
4113		hasDuplicate = baseHasDuplicate;
4114		results.sort(sortOrder);
4115
4116		if ( hasDuplicate ) {
4117			for ( var i = 1; i < results.length; i++ ) {
4118				if ( results[i] === results[i-1] ) {
4119					results.splice(i--, 1);
4120				}
4121			}
4122		}
4123	}
4124
4125	return results;
4126};
4127
4128Sizzle.matches = function(expr, set){
4129	return Sizzle(expr, null, null, set);
4130};
4131
4132Sizzle.find = function(expr, context, isXML){
4133	var set, match;
4134
4135	if ( !expr ) {
4136		return [];
4137	}
4138
4139	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
4140		var type = Expr.order[i], match;
4141
4142		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4143			var left = match[1];
4144			match.splice(1,1);
4145
4146			if ( left.substr( left.length - 1 ) !== "\\" ) {
4147				match[1] = (match[1] || "").replace(/\\/g, "");
4148				set = Expr.find[ type ]( match, context, isXML );
4149				if ( set != null ) {
4150					expr = expr.replace( Expr.match[ type ], "" );
4151					break;
4152				}
4153			}
4154		}
4155	}
4156
4157	if ( !set ) {
4158		set = context.getElementsByTagName("*");
4159	}
4160
4161	return {set: set, expr: expr};
4162};
4163
4164Sizzle.filter = function(expr, set, inplace, not){
4165	var old = expr, result = [], curLoop = set, match, anyFound,
4166		isXMLFilter = set && set[0] && isXML(set[0]);
4167
4168	while ( expr && set.length ) {
4169		for ( var type in Expr.filter ) {
4170			if ( (match = Expr.match[ type ].exec( expr )) != null ) {
4171				var filter = Expr.filter[ type ], found, item;
4172				anyFound = false;
4173
4174				if ( curLoop == result ) {
4175					result = [];
4176				}
4177
4178				if ( Expr.preFilter[ type ] ) {
4179					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4180
4181					if ( !match ) {
4182						anyFound = found = true;
4183					} else if ( match === true ) {
4184						continue;
4185					}
4186				}
4187
4188				if ( match ) {
4189					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
4190						if ( item ) {
4191							found = filter( item, match, i, curLoop );
4192							var pass = not ^ !!found;
4193
4194							if ( inplace && found != null ) {
4195								if ( pass ) {
4196									anyFound = true;
4197								} else {
4198									curLoop[i] = false;
4199								}
4200							} else if ( pass ) {
4201								result.push( item );
4202								anyFound = true;
4203							}
4204						}
4205					}
4206				}
4207
4208				if ( found !== undefined ) {
4209					if ( !inplace ) {
4210						curLoop = result;
4211					}
4212
4213					expr = expr.replace( Expr.match[ type ], "" );
4214
4215					if ( !anyFound ) {
4216						return [];
4217					}
4218
4219					break;
4220				}
4221			}
4222		}
4223
4224		if ( expr == old ) {
4225			if ( anyFound == null ) {
4226				throw "Syntax error, unrecognized expression: " + expr;
4227			} else {
4228				break;
4229			}
4230		}
4231
4232		old = expr;
4233	}
4234
4235	return curLoop;
4236};
4237
4238var Expr = Sizzle.selectors = {
4239	order: [ "ID", "NAME", "TAG" ],
4240	match: {
4241		ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
4242		CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
4243		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
4244		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
4245		TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
4246		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
4247		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
4248		PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
4249	},
4250	leftMatch: {},
4251	attrMap: {
4252		"class": "className",
4253		"for": "htmlFor"
4254	},
4255	attrHandle: {
4256		href: function(elem){
4257			return elem.getAttribute("href");
4258		}
4259	},
4260	relative: {
4261		"+": function(checkSet, part, isXML){
4262			var isPartStr = typeof part === "string",
4263				isTag = isPartStr && !/\W/.test(part),
4264				isPartStrNotTag = isPartStr && !isTag;
4265
4266			if ( isTag && !isXML ) {
4267				part = part.toUpperCase();
4268			}
4269
4270			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4271				if ( (elem = checkSet[i]) ) {
4272					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4273
4274					checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
4275						elem || false :
4276						elem === part;
4277				}
4278			}
4279
4280			if ( isPartStrNotTag ) {
4281				Sizzle.filter( part, checkSet, true );
4282			}
4283		},
4284		">": function(checkSet, part, isXML){
4285			var isPartStr = typeof part === "string";
4286
4287			if ( isPartStr && !/\W/.test(part) ) {
4288				part = isXML ? part : part.toUpperCase();
4289
4290				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4291					var elem = checkSet[i];
4292					if ( elem ) {
4293						var parent = elem.parentNode;
4294						checkSet[i] = parent.nodeName === part ? parent : false;
4295					}
4296				}
4297			} else {
4298				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4299					var elem = checkSet[i];
4300					if ( elem ) {
4301						checkSet[i] = isPartStr ?
4302							elem.parentNode :
4303							elem.parentNode === part;
4304					}
4305				}
4306
4307				if ( isPartStr ) {
4308					Sizzle.filter( part, checkSet, true );
4309				}
4310			}
4311		},
4312		"": function(checkSet, part, isXML){
4313			var doneName = done++, checkFn = dirCheck;
4314
4315			if ( !/\W/.test(part) ) {
4316				var nodeCheck = part = isXML ? part : part.toUpperCase();
4317				checkFn = dirNodeCheck;
4318			}
4319
4320			checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
4321		},
4322		"~": function(checkSet, part, isXML){
4323			var doneName = done++, checkFn = dirCheck;
4324
4325			if ( typeof part === "string" && !/\W/.test(part) ) {
4326				var nodeCheck = part = isXML ? part : part.toUpperCase();
4327				checkFn = dirNodeCheck;
4328			}
4329
4330			checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
4331		}
4332	},
4333	find: {
4334		ID: function(match, context, isXML){
4335			if ( typeof context.getElementById !== "undefined" && !isXML ) {
4336				var m = context.getElementById(match[1]);
4337				return m ? [m] : [];
4338			}
4339		},
4340		NAME: function(match, context, isXML){
4341			if ( typeof context.getElementsByName !== "undefined" ) {
4342				var ret = [], results = context.getElementsByName(match[1]);
4343
4344				for ( var i = 0, l = results.length; i < l; i++ ) {
4345					if ( results[i].getAttribute("name") === match[1] ) {
4346						ret.push( results[i] );
4347					}
4348				}
4349
4350				return ret.length === 0 ? null : ret;
4351			}
4352		},
4353		TAG: function(match, context){
4354			return context.getElementsByTagName(match[1]);
4355		}
4356	},
4357	preFilter: {
4358		CLASS: function(match, curLoop, inplace, result, not, isXML){
4359			match = " " + match[1].replace(/\\/g, "") + " ";
4360
4361			if ( isXML ) {
4362				return match;
4363			}
4364
4365			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4366				if ( elem ) {
4367					if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
4368						if ( !inplace )
4369							result.push( elem );
4370					} else if ( inplace ) {
4371						curLoop[i] = false;
4372					}
4373				}
4374			}
4375
4376			return false;
4377		},
4378		ID: function(match){
4379			return match[1].replace(/\\/g, "");
4380		},
4381		TAG: function(match, curLoop){
4382			for ( var i = 0; curLoop[i] === false; i++ ){}
4383			return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
4384		},
4385		CHILD: function(match){
4386			if ( match[1] == "nth" ) {
4387				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
4388					match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
4389					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4390
4391				match[2] = (test[1] + (test[2] || 1)) - 0;
4392				match[3] = test[3] - 0;
4393			}
4394
4395			match[0] = done++;
4396
4397			return match;
4398		},
4399		ATTR: function(match, curLoop, inplace, result, not, isXML){
4400			var name = match[1].replace(/\\/g, "");
4401
4402			if ( !isXML && Expr.attrMap[name] ) {
4403				match[1] = Expr.attrMap[name];
4404			}
4405
4406			if ( match[2] === "~=" ) {
4407				match[4] = " " + match[4] + " ";
4408			}
4409
4410			return match;
4411		},
4412		PSEUDO: function(match, curLoop, inplace, result, not){
4413			if ( match[1] === "not" ) {
4414				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4415					match[3] = Sizzle(match[3], null, null, curLoop);
4416				} else {
4417					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4418					if ( !inplace ) {
4419						result.push.apply( result, ret );
4420					}
4421					return false;
4422				}
4423			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4424				return true;
4425			}
4426
4427			return match;
4428		},
4429		POS: function(match){
4430			match.unshift( true );
4431			return match;
4432		}
4433	},
4434	filters: {
4435		enabled: function(elem){
4436			return elem.disabled === false && elem.type !== "hidden";
4437		},
4438		disabled: function(elem){
4439			return elem.disabled === true;
4440		},
4441		checked: function(elem){
4442			return elem.checked === true;
4443		},
4444		selected: function(elem){
4445			elem.parentNode.selectedIndex;
4446			return elem.selected === true;
4447		},
4448		parent: function(elem){
4449			return !!elem.firstChild;
4450		},
4451		empty: function(elem){
4452			return !elem.firstChild;
4453		},
4454		has: function(elem, i, match){
4455			return !!Sizzle( match[3], elem ).length;
4456		},
4457		header: function(elem){
4458			return /h\d/i.test( elem.nodeName );
4459		},
4460		text: function(elem){
4461			return "text" === elem.type;
4462		},
4463		radio: function(elem){
4464			return "radio" === elem.type;
4465		},
4466		checkbox: function(elem){
4467			return "checkbox" === elem.type;
4468		},
4469		file: function(elem){
4470			return "file" === elem.type;
4471		},
4472		password: function(elem){
4473			return "password" === elem.type;
4474		},
4475		submit: function(elem){
4476			return "submit" === elem.type;
4477		},
4478		image: function(elem){
4479			return "image" === elem.type;
4480		},
4481		reset: function(elem){
4482			return "reset" === elem.type;
4483		},
4484		button: function(elem){
4485			return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
4486		},
4487		input: function(elem){
4488			return /input|select|textarea|button/i.test(elem.nodeName);
4489		}
4490	},
4491	setFilters: {
4492		first: function(elem, i){
4493			return i === 0;
4494		},
4495		last: function(elem, i, match, array){
4496			return i === array.length - 1;
4497		},
4498		even: function(elem, i){
4499			return i % 2 === 0;
4500		},
4501		odd: function(elem, i){
4502			return i % 2 === 1;
4503		},
4504		lt: function(elem, i, match){
4505			return i < match[3] - 0;
4506		},
4507		gt: function(elem, i, match){
4508			return i > match[3] - 0;
4509		},
4510		nth: function(elem, i, match){
4511			return match[3] - 0 == i;
4512		},
4513		eq: function(elem, i, match){
4514			return match[3] - 0 == i;
4515		}
4516	},
4517	filter: {
4518		PSEUDO: function(elem, match, i, array){
4519			var name = match[1], filter = Expr.filters[ name ];
4520
4521			if ( filter ) {
4522				return filter( elem, i, match, array );
4523			} else if ( name === "contains" ) {
4524				return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
4525			} else if ( name === "not" ) {
4526				var not = match[3];
4527
4528				for ( var i = 0, l = not.length; i < l; i++ ) {
4529					if ( not[i] === elem ) {
4530						return false;
4531					}
4532				}
4533
4534				return true;
4535			}
4536		},
4537		CHILD: function(elem, match){
4538			var type = match[1], node = elem;
4539			switch (type) {
4540				case 'only':
4541				case 'first':
4542					while ( (node = node.previousSibling) )  {
4543						if ( node.nodeType === 1 ) return false;
4544					}
4545					if ( type == 'first') return true;
4546					node = elem;
4547				case 'last':
4548					while ( (node = node.nextSibling) )  {
4549						if ( node.nodeType === 1 ) return false;
4550					}
4551					return true;
4552				case 'nth':
4553					var first = match[2], last = match[3];
4554
4555					if ( first == 1 && last == 0 ) {
4556						return true;
4557					}
4558
4559					var doneName = match[0],
4560						parent = elem.parentNode;
4561
4562					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4563						var count = 0;
4564						for ( node = parent.firstChild; node; node = node.nextSibling ) {
4565							if ( node.nodeType === 1 ) {
4566								node.nodeIndex = ++count;
4567							}
4568						}
4569						parent.sizcache = doneName;
4570					}
4571
4572					var diff = elem.nodeIndex - last;
4573					if ( first == 0 ) {
4574						return diff == 0;
4575					} else {
4576						return ( diff % first == 0 && diff / first >= 0 );
4577					}
4578			}
4579		},
4580		ID: function(elem, match){
4581			return elem.nodeType === 1 && elem.getAttribute("id") === match;
4582		},
4583		TAG: function(elem, match){
4584			return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
4585		},
4586		CLASS: function(elem, match){
4587			return (" " + (elem.className || elem.getAttribute("class")) + " ")
4588				.indexOf( match ) > -1;
4589		},
4590		ATTR: function(elem, match){
4591			var name = match[1],
4592				result = Expr.attrHandle[ name ] ?
4593					Expr.attrHandle[ name ]( elem ) :
4594					elem[ name ] != null ?
4595						elem[ name ] :
4596						elem.getAttribute( name ),
4597				value = result + "",
4598				type = match[2],
4599				check = match[4];
4600
4601			return result == null ?
4602				type === "!=" :
4603				type === "=" ?
4604				value === check :
4605				type === "*=" ?
4606				value.indexOf(check) >= 0 :
4607				type === "~=" ?
4608				(" " + value + " ").indexOf(check) >= 0 :
4609				!check ?
4610				value && result !== false :
4611				type === "!=" ?
4612				value != check :
4613				type === "^=" ?
4614				value.indexOf(check) === 0 :
4615				type === "$=" ?
4616				value.substr(value.length - check.length) === check :
4617				type === "|=" ?
4618				value === check || value.substr(0, check.length + 1) === check + "-" :
4619				false;
4620		},
4621		POS: function(elem, match, i, array){
4622			var name = match[2], filter = Expr.setFilters[ name ];
4623
4624			if ( filter ) {
4625				return filter( elem, i, match, array );
4626			}
4627		}
4628	}
4629};
4630
4631var origPOS = Expr.match.POS;
4632
4633for ( var type in Expr.match ) {
4634	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
4635	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
4636}
4637
4638var makeArray = function(array, results) {
4639	array = Array.prototype.slice.call( array, 0 );
4640
4641	if ( results ) {
4642		results.push.apply( results, array );
4643		return results;
4644	}
4645
4646	return array;
4647};
4648
4649try {
4650	Array.prototype.slice.call( document.documentElement.childNodes, 0 );
4651
4652} catch(e){
4653	makeArray = function(array, results) {
4654		var ret = results || [];
4655
4656		if ( toString.call(array) === "[object Array]" ) {
4657			Array.prototype.push.apply( ret, array );
4658		} else {
4659			if ( typeof array.length === "number" ) {
4660				for ( var i = 0, l = array.length; i < l; i++ ) {
4661					ret.push( array[i] );
4662				}
4663			} else {
4664				for ( var i = 0; array[i]; i++ ) {
4665					ret.push( array[i] );
4666				}
4667			}
4668		}
4669
4670		return ret;
4671	};
4672}
4673
4674var sortOrder;
4675
4676if ( document.documentElement.compareDocumentPosition ) {
4677	sortOrder = function( a, b ) {
4678		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4679			if ( a == b ) {
4680				hasDuplicate = true;
4681			}
4682			return 0;
4683		}
4684
4685		var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
4686		if ( ret === 0 ) {
4687			hasDuplicate = true;
4688		}
4689		return ret;
4690	};
4691} else if ( "sourceIndex" in document.documentElement ) {
4692	sortOrder = function( a, b ) {
4693		if ( !a.sourceIndex || !b.sourceIndex ) {
4694			if ( a == b ) {
4695				hasDuplicate = true;
4696			}
4697			return 0;
4698		}
4699
4700		var ret = a.sourceIndex - b.sourceIndex;
4701		if ( ret === 0 ) {
4702			hasDuplicate = true;
4703		}
4704		return ret;
4705	};
4706} else if ( document.createRange ) {
4707	sortOrder = function( a, b ) {
4708		if ( !a.ownerDocument || !b.ownerDocument ) {
4709			if ( a == b ) {
4710				hasDuplicate = true;
4711			}
4712			return 0;
4713		}
4714
4715		var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
4716		aRange.setStart(a, 0);
4717		aRange.setEnd(a, 0);
4718		bRange.setStart(b, 0);
4719		bRange.setEnd(b, 0);
4720		var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
4721		if ( ret === 0 ) {
4722			hasDuplicate = true;
4723		}
4724		return ret;
4725	};
4726}
4727
4728(function(){
4729	var form = document.createElement("div"),
4730		id = "script" + (new Date).getTime();
4731	form.innerHTML = "<a name='" + id + "'/>";
4732
4733	var root = document.documentElement;
4734	root.insertBefore( form, root.firstChild );
4735
4736	if ( !!document.getElementById( id ) ) {
4737		Expr.find.ID = function(match, context, isXML){
4738			if ( typeof context.getElementById !== "undefined" && !isXML ) {
4739				var m = context.getElementById(match[1]);
4740				return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
4741			}
4742		};
4743
4744		Expr.filter.ID = function(elem, match){
4745			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4746			return elem.nodeType === 1 && node && node.nodeValue === match;
4747		};
4748	}
4749
4750	root.removeChild( form );
4751	root = form = null; // release memory in IE
4752})();
4753
4754(function(){
4755
4756	var div = document.createElement("div");
4757	div.appendChild( document.createComment("") );
4758
4759	if ( div.getElementsByTagName("*").length > 0 ) {
4760		Expr.find.TAG = function(match, context){
4761			var results = context.getElementsByTagName(match[1]);
4762
4763			if ( match[1] === "*" ) {
4764				var tmp = [];
4765
4766				for ( var i = 0; results[i]; i++ ) {
4767					if ( results[i].nodeType === 1 ) {
4768						tmp.push( results[i] );
4769					}
4770				}
4771
4772				results = tmp;
4773			}
4774
4775			return results;
4776		};
4777	}
4778
4779	div.innerHTML = "<a href='#'></a>";
4780	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4781			div.firstChild.getAttribute("href") !== "#" ) {
4782		Expr.attrHandle.href = function(elem){
4783			return elem.getAttribute("href", 2);
4784		};
4785	}
4786
4787	div = null; // release memory in IE
4788})();
4789
4790if ( document.querySelectorAll ) (function(){
4791	var oldSizzle = Sizzle, div = document.createElement("div");
4792	div.innerHTML = "<p class='TEST'></p>";
4793
4794	if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4795		return;
4796	}
4797
4798	Sizzle = function(query, context, extra, seed){
4799		context = context || document;
4800
4801		if ( !seed && context.nodeType === 9 && !isXML(context) ) {
4802			try {
4803				return makeArray( context.querySelectorAll(query), extra );
4804			} catch(e){}
4805		}
4806
4807		return oldSizzle(query, context, extra, seed);
4808	};
4809
4810	for ( var prop in oldSizzle ) {
4811		Sizzle[ prop ] = oldSizzle[ prop ];
4812	}
4813
4814	div = null; // release memory in IE
4815})();
4816
4817if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
4818	var div = document.createElement("div");
4819	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4820
4821	if ( div.getElementsByClassName("e").length === 0 )
4822		return;
4823
4824	div.lastChild.className = "e";
4825
4826	if ( div.getElementsByClassName("e").length === 1 )
4827		return;
4828
4829	Expr.order.splice(1, 0, "CLASS");
4830	Expr.find.CLASS = function(match, context, isXML) {
4831		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4832			return context.getElementsByClassName(match[1]);
4833		}
4834	};
4835
4836	div = null; // release memory in IE
4837})();
4838
4839function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4840	var sibDir = dir == "previousSibling" && !isXML;
4841	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4842		var elem = checkSet[i];
4843		if ( elem ) {
4844			if ( sibDir && elem.nodeType === 1 ){
4845				elem.sizcache = doneName;
4846				elem.sizset = i;
4847			}
4848			elem = elem[dir];
4849			var match = false;
4850
4851			while ( elem ) {
4852				if ( elem.sizcache === doneName ) {
4853					match = checkSet[elem.sizset];
4854					break;
4855				}
4856
4857				if ( elem.nodeType === 1 && !isXML ){
4858					elem.sizcache = doneName;
4859					elem.sizset = i;
4860				}
4861
4862				if ( elem.nodeName === cur ) {
4863					match = elem;
4864					break;
4865				}
4866
4867				elem = elem[dir];
4868			}
4869
4870			checkSet[i] = match;
4871		}
4872	}
4873}
4874
4875function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4876	var sibDir = dir == "previousSibling" && !isXML;
4877	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4878		var elem = checkSet[i];
4879		if ( elem ) {
4880			if ( sibDir && elem.nodeType === 1 ) {
4881				elem.sizcache = doneName;
4882				elem.sizset = i;
4883			}
4884			elem = elem[dir];
4885			var match = false;
4886
4887			while ( elem ) {
4888				if ( elem.sizcache === doneName ) {
4889					match = checkSet[elem.sizset];
4890					break;
4891				}
4892
4893				if ( elem.nodeType === 1 ) {
4894					if ( !isXML ) {
4895						elem.sizcache = doneName;
4896						elem.sizset = i;
4897					}
4898					if ( typeof cur !== "string" ) {
4899						if ( elem === cur ) {
4900							match = true;
4901							break;
4902						}
4903
4904					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4905						match = elem;
4906						break;
4907					}
4908				}
4909
4910				elem = elem[dir];
4911			}
4912
4913			checkSet[i] = match;
4914		}
4915	}
4916}
4917
4918var contains = document.compareDocumentPosition ?  function(a, b){
4919	return a.compareDocumentPosition(b) & 16;
4920} : function(a, b){
4921	return a !== b && (a.contains ? a.contains(b) : true);
4922};
4923
4924var isXML = function(elem){
4925	return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
4926		!!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
4927};
4928
4929var posProcess = function(selector, context){
4930	var tmpSet = [], later = "", match,
4931		root = context.nodeType ? [context] : context;
4932
4933	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4934		later += match[0];
4935		selector = selector.replace( Expr.match.PSEUDO, "" );
4936	}
4937
4938	selector = Expr.relative[selector] ? selector + "*" : selector;
4939
4940	for ( var i = 0, l = root.length; i < l; i++ ) {
4941		Sizzle( selector, root[i], tmpSet );
4942	}
4943
4944	return Sizzle.filter( later, tmpSet );
4945};
4946
4947
4948window.Sizzle = Sizzle;
4949
4950})();
4951
4952;(function(engine) {
4953  var extendElements = Prototype.Selector.extendElements;
4954
4955  function select(selector, scope) {
4956    return extendElements(engine(selector, scope || document));
4957  }
4958
4959  function match(element, selector) {
4960    return engine.matches(selector, [element]).length == 1;
4961  }
4962
4963  Prototype.Selector.engine = engine;
4964  Prototype.Selector.select = select;
4965  Prototype.Selector.match = match;
4966})(Sizzle);
4967
4968window.Sizzle = Prototype._original_property;
4969delete Prototype._original_property;
4970
4971var Form = {
4972  reset: function(form) {
4973    form = $(form);
4974    form.reset();
4975    return form;
4976  },
4977
4978  serializeElements: function(elements, options) {
4979    if (typeof options != 'object') options = { hash: !!options };
4980    else if (Object.isUndefined(options.hash)) options.hash = true;
4981    var key, value, submitted = false, submit = options.submit, accumulator, initial;
4982
4983    if (options.hash) {
4984      initial = {};
4985      accumulator = function(result, key, value) {
4986        if (key in result) {
4987          if (!Object.isArray(result[key])) result[key] = [result[key]];
4988          result[key].push(value);
4989        } else result[key] = value;
4990        return result;
4991      };
4992    } else {
4993      initial = '';
4994      accumulator = function(result, key, value) {
4995        return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value);
4996      }
4997    }
4998
4999    return elements.inject(initial, function(result, element) {
5000      if (!element.disabled && element.name) {
5001        key = element.name; value = $(element).getValue();
5002        if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
5003            submit !== false && (!submit || key == submit) && (submitted = true)))) {
5004          result = accumulator(result, key, value);
5005        }
5006      }
5007      return result;
5008    });
5009  }
5010};
5011
5012Form.Methods = {
5013  serialize: function(form, options) {
5014    return Form.serializeElements(Form.getElements(form), options);
5015  },
5016
5017  getElements: function(form) {
5018    var elements = $(form).getElementsByTagName('*'),
5019        element,
5020        arr = [ ],
5021        serializers = Form.Element.Serializers;
5022    for (var i = 0; element = elements[i]; i++) {
5023      arr.push(element);
5024    }
5025    return arr.inject([], function(elements, child) {
5026      if (serializers[child.tagName.toLowerCase()])
5027        elements.push(Element.extend(child));
5028      return elements;
5029    })
5030  },
5031
5032  getInputs: function(form, typeName, name) {
5033    form = $(form);
5034    var inputs = form.getElementsByTagName('input');
5035
5036    if (!typeName && !name) return $A(inputs).map(Element.extend);
5037
5038    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
5039      var input = inputs[i];
5040      if ((typeName && input.type != typeName) || (name && input.name != name))
5041        continue;
5042      matchingInputs.push(Element.extend(input));
5043    }
5044
5045    return matchingInputs;
5046  },
5047
5048  disable: function(form) {
5049    form = $(form);
5050    Form.getElements(form).invoke('disable');
5051    return form;
5052  },
5053
5054  enable: function(form) {
5055    form = $(form);
5056    Form.getElements(form).invoke('enable');
5057    return form;
5058  },
5059
5060  findFirstElement: function(form) {
5061    var elements = $(form).getElements().findAll(function(element) {
5062      return 'hidden' != element.type && !element.disabled;
5063    });
5064    var firstByIndex = elements.findAll(function(element) {
5065      return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
5066    }).sortBy(function(element) { return element.tabIndex }).first();
5067
5068    return firstByIndex ? firstByIndex : elements.find(function(element) {
5069      return /^(?:input|select|textarea)$/i.test(element.tagName);
5070    });
5071  },
5072
5073  focusFirstElement: function(form) {
5074    form = $(form);
5075    var element = form.findFirstElement();
5076    if (element) element.activate();
5077    return form;
5078  },
5079
5080  request: function(form, options) {
5081    form = $(form), options = Object.clone(options || { });
5082
5083    var params = options.parameters, action = form.readAttribute('action') || '';
5084    if (action.blank()) action = window.location.href;
5085    options.parameters = form.serialize(true);
5086
5087    if (params) {
5088      if (Object.isString(params)) params = params.toQueryParams();
5089      Object.extend(options.parameters, params);
5090    }
5091
5092    if (form.hasAttribute('method') && !options.method)
5093      options.method = form.method;
5094
5095    return new Ajax.Request(action, options);
5096  }
5097};
5098
5099/*--------------------------------------------------------------------------*/
5100
5101
5102Form.Element = {
5103  focus: function(element) {
5104    $(element).focus();
5105    return element;
5106  },
5107
5108  select: function(element) {
5109    $(element).select();
5110    return element;
5111  }
5112};
5113
5114Form.Element.Methods = {
5115
5116  serialize: function(element) {
5117    element = $(element);
5118    if (!element.disabled && element.name) {
5119      var value = element.getValue();
5120      if (value != undefined) {
5121        var pair = { };
5122        pair[element.name] = value;
5123        return Object.toQueryString(pair);
5124      }
5125    }
5126    return '';
5127  },
5128
5129  getValue: function(element) {
5130    element = $(element);
5131    var method = element.tagName.toLowerCase();
5132    return Form.Element.Serializers[method](element);
5133  },
5134
5135  setValue: function(element, value) {
5136    element = $(element);
5137    var method = element.tagName.toLowerCase();
5138    Form.Element.Serializers[method](element, value);
5139    return element;
5140  },
5141
5142  clear: function(element) {
5143    $(element).value = '';
5144    return element;
5145  },
5146
5147  present: function(element) {
5148    return $(element).value != '';
5149  },
5150
5151  activate: function(element) {
5152    element = $(element);
5153    try {
5154      element.focus();
5155      if (element.select && (element.tagName.toLowerCase() != 'input' ||
5156          !(/^(?:button|reset|submit)$/i.test(element.type))))
5157        element.select();
5158    } catch (e) { }
5159    return element;
5160  },
5161
5162  disable: function(element) {
5163    element = $(element);
5164    element.disabled = true;
5165    return element;
5166  },
5167
5168  enable: function(element) {
5169    element = $(element);
5170    element.disabled = false;
5171    return element;
5172  }
5173};
5174
5175/*--------------------------------------------------------------------------*/
5176
5177var Field = Form.Element;
5178
5179var $F = Form.Element.Methods.getValue;
5180
5181/*--------------------------------------------------------------------------*/
5182
5183Form.Element.Serializers = (function() {
5184  function input(element, value) {
5185    switch (element.type.toLowerCase()) {
5186      case 'checkbox':
5187      case 'radio':
5188        return inputSelector(element, value);
5189      default:
5190        return valueSelector(element, value);
5191    }
5192  }
5193
5194  function inputSelector(element, value) {
5195    if (Object.isUndefined(value))
5196      return element.checked ? element.value : null;
5197    else element.checked = !!value;
5198  }
5199
5200  function valueSelector(element, value) {
5201    if (Object.isUndefined(value)) return element.value;
5202    else element.value = value;
5203  }
5204
5205  function select(element, value) {
5206    if (Object.isUndefined(value))
5207      return (element.type === 'select-one' ? selectOne : selectMany)(element);
5208
5209    var opt, currentValue, single = !Object.isArray(value);
5210    for (var i = 0, length = element.length; i < length; i++) {
5211      opt = element.options[i];
5212      currentValue = this.optionValue(opt);
5213      if (single) {
5214        if (currentValue == value) {
5215          opt.selected = true;
5216          return;
5217        }
5218      }
5219      else opt.selected = value.include(currentValue);
5220    }
5221  }
5222
5223  function selectOne(element) {
5224    var index = element.selectedIndex;
5225    return index >= 0 ? optionValue(element.options[index]) : null;
5226  }
5227
5228  function selectMany(element) {
5229    var values, length = element.length;
5230    if (!length) return null;
5231
5232    for (var i = 0, values = []; i < length; i++) {
5233      var opt = element.options[i];
5234      if (opt.selected) values.push(optionValue(opt));
5235    }
5236    return values;
5237  }
5238
5239  function optionValue(opt) {
5240    return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
5241  }
5242
5243  return {
5244    input:         input,
5245    inputSelector: inputSelector,
5246    textarea:      valueSelector,
5247    select:        select,
5248    selectOne:     selectOne,
5249    selectMany:    selectMany,
5250    optionValue:   optionValue,
5251    button:        valueSelector
5252  };
5253})();
5254
5255/*--------------------------------------------------------------------------*/
5256
5257
5258Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
5259  initialize: function($super, element, frequency, callback) {
5260    $super(callback, frequency);
5261    this.element   = $(element);
5262    this.lastValue = this.getValue();
5263  },
5264
5265  execute: function() {
5266    var value = this.getValue();
5267    if (Object.isString(this.lastValue) && Object.isString(value) ?
5268        this.lastValue != value : String(this.lastValue) != String(value)) {
5269      this.callback(this.element, value);
5270      this.lastValue = value;
5271    }
5272  }
5273});
5274
5275Form.Element.Observer = Class.create(Abstract.TimedObserver, {
5276  getValue: function() {
5277    return Form.Element.getValue(this.element);
5278  }
5279});
5280
5281Form.Observer = Class.create(Abstract.TimedObserver, {
5282  getValue: function() {
5283    return Form.serialize(this.element);
5284  }
5285});
5286
5287/*--------------------------------------------------------------------------*/
5288
5289Abstract.EventObserver = Class.create({
5290  initialize: function(element, callback) {
5291    this.element  = $(element);
5292    this.callback = callback;
5293
5294    this.lastValue = this.getValue();
5295    if (this.element.tagName.toLowerCase() == 'form')
5296      this.registerFormCallbacks();
5297    else
5298      this.registerCallback(this.element);
5299  },
5300
5301  onElementEvent: function() {
5302    var value = this.getValue();
5303    if (this.lastValue != value) {
5304      this.callback(this.element, value);
5305      this.lastValue = value;
5306    }
5307  },
5308
5309  registerFormCallbacks: function() {
5310    Form.getElements(this.element).each(this.registerCallback, this);
5311  },
5312
5313  registerCallback: function(element) {
5314    if (element.type) {
5315      switch (element.type.toLowerCase()) {
5316        case 'checkbox':
5317        case 'radio':
5318          Event.observe(element, 'click', this.onElementEvent.bind(this));
5319          break;
5320        default:
5321          Event.observe(element, 'change', this.onElementEvent.bind(this));
5322          break;
5323      }
5324    }
5325  }
5326});
5327
5328Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
5329  getValue: function() {
5330    return Form.Element.getValue(this.element);
5331  }
5332});
5333
5334Form.EventObserver = Class.create(Abstract.EventObserver, {
5335  getValue: function() {
5336    return Form.serialize(this.element);
5337  }
5338});
5339(function() {
5340
5341  var Event = {
5342    KEY_BACKSPACE: 8,
5343    KEY_TAB:       9,
5344    KEY_RETURN:   13,
5345    KEY_ESC:      27,
5346    KEY_LEFT:     37,
5347    KEY_UP:       38,
5348    KEY_RIGHT:    39,
5349    KEY_DOWN:     40,
5350    KEY_DELETE:   46,
5351    KEY_HOME:     36,
5352    KEY_END:      35,
5353    KEY_PAGEUP:   33,
5354    KEY_PAGEDOWN: 34,
5355    KEY_INSERT:   45,
5356
5357    cache: {}
5358  };
5359
5360  var docEl = document.documentElement;
5361  var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
5362    && 'onmouseleave' in docEl;
5363
5364
5365
5366  var isIELegacyEvent = function(event) { return false; };
5367
5368  if (window.attachEvent) {
5369    if (window.addEventListener) {
5370      isIELegacyEvent = function(event) {
5371        return !(event instanceof window.Event);
5372      };
5373    } else {
5374      isIELegacyEvent = function(event) { return true; };
5375    }
5376  }
5377
5378  var _isButton;
5379
5380  function _isButtonForDOMEvents(event, code) {
5381    return event.which ? (event.which === code + 1) : (event.button === code);
5382  }
5383
5384  var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
5385  function _isButtonForLegacyEvents(event, code) {
5386    return event.button === legacyButtonMap[code];
5387  }
5388
5389  function _isButtonForWebKit(event, code) {
5390    switch (code) {
5391      case 0: return event.which == 1 && !event.metaKey;
5392      case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
5393      case 2: return event.which == 3;
5394      default: return false;
5395    }
5396  }
5397
5398  if (window.attachEvent) {
5399    if (!window.addEventListener) {
5400      _isButton = _isButtonForLegacyEvents;
5401    } else {
5402      _isButton = function(event, code) {
5403        return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) :
5404         _isButtonForDOMEvents(event, code);
5405      }
5406    }
5407  } else if (Prototype.Browser.WebKit) {
5408    _isButton = _isButtonForWebKit;
5409  } else {
5410    _isButton = _isButtonForDOMEvents;
5411  }
5412
5413  function isLeftClick(event)   { return _isButton(event, 0) }
5414
5415  function isMiddleClick(event) { return _isButton(event, 1) }
5416
5417  function isRightClick(event)  { return _isButton(event, 2) }
5418
5419  function element(event) {
5420    event = Event.extend(event);
5421
5422    var node = event.target, type = event.type,
5423     currentTarget = event.currentTarget;
5424
5425    if (currentTarget && currentTarget.tagName) {
5426      if (type === 'load' || type === 'error' ||
5427        (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
5428          && currentTarget.type === 'radio'))
5429            node = currentTarget;
5430    }
5431
5432    if (node.nodeType == Node.TEXT_NODE)
5433      node = node.parentNode;
5434
5435    return Element.extend(node);
5436  }
5437
5438  function findElement(event, expression) {
5439    var element = Event.element(event);
5440
5441    if (!expression) return element;
5442    while (element) {
5443      if (Object.isElement(element) && Prototype.Selector.match(element, expression)) {
5444        return Element.extend(element);
5445      }
5446      element = element.parentNode;
5447    }
5448  }
5449
5450  function pointer(event) {
5451    return { x: pointerX(event), y: pointerY(event) };
5452  }
5453
5454  function pointerX(event) {
5455    var docElement = document.documentElement,
5456     body = document.body || { scrollLeft: 0 };
5457
5458    return event.pageX || (event.clientX +
5459      (docElement.scrollLeft || body.scrollLeft) -
5460      (docElement.clientLeft || 0));
5461  }
5462
5463  function pointerY(event) {
5464    var docElement = document.documentElement,
5465     body = document.body || { scrollTop: 0 };
5466
5467    return  event.pageY || (event.clientY +
5468       (docElement.scrollTop || body.scrollTop) -
5469       (docElement.clientTop || 0));
5470  }
5471
5472
5473  function stop(event) {
5474    Event.extend(event);
5475    event.preventDefault();
5476    event.stopPropagation();
5477
5478    event.stopped = true;
5479  }
5480
5481
5482  Event.Methods = {
5483    isLeftClick:   isLeftClick,
5484    isMiddleClick: isMiddleClick,
5485    isRightClick:  isRightClick,
5486
5487    element:     element,
5488    findElement: findElement,
5489
5490    pointer:  pointer,
5491    pointerX: pointerX,
5492    pointerY: pointerY,
5493
5494    stop: stop
5495  };
5496
5497  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
5498    m[name] = Event.Methods[name].methodize();
5499    return m;
5500  });
5501
5502  if (window.attachEvent) {
5503    function _relatedTarget(event) {
5504      var element;
5505      switch (event.type) {
5506        case 'mouseover':
5507        case 'mouseenter':
5508          element = event.fromElement;
5509          break;
5510        case 'mouseout':
5511        case 'mouseleave':
5512          element = event.toElement;
5513          break;
5514        default:
5515          return null;
5516      }
5517      return Element.extend(element);
5518    }
5519
5520    var additionalMethods = {
5521      stopPropagation: function() { this.cancelBubble = true },
5522      preventDefault:  function() { this.returnValue = false },
5523      inspect: function() { return '[object Event]' }
5524    };
5525
5526    Event.extend = function(event, element) {
5527      if (!event) return false;
5528
5529      if (!isIELegacyEvent(event)) return event;
5530
5531      if (event._extendedByPrototype) return event;
5532      event._extendedByPrototype = Prototype.emptyFunction;
5533
5534      var pointer = Event.pointer(event);
5535
5536      Object.extend(event, {
5537        target: event.srcElement || element,
5538        relatedTarget: _relatedTarget(event),
5539        pageX:  pointer.x,
5540        pageY:  pointer.y
5541      });
5542
5543      Object.extend(event, methods);
5544      Object.extend(event, additionalMethods);
5545
5546      return event;
5547    };
5548  } else {
5549    Event.extend = Prototype.K;
5550  }
5551
5552  if (window.addEventListener) {
5553    Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
5554    Object.extend(Event.prototype, methods);
5555  }
5556
5557  function _createResponder(element, eventName, handler) {
5558    var registry = Element.retrieve(element, 'prototype_event_registry');
5559
5560    if (Object.isUndefined(registry)) {
5561      CACHE.push(element);
5562      registry = Element.retrieve(element, 'prototype_event_registry', $H());
5563    }
5564
5565    var respondersForEvent = registry.get(eventName);
5566    if (Object.isUndefined(respondersForEvent)) {
5567      respondersForEvent = [];
5568      registry.set(eventName, respondersForEvent);
5569    }
5570
5571    if (respondersForEvent.pluck('handler').include(handler)) return false;
5572
5573    var responder;
5574    if (eventName.include(":")) {
5575      responder = function(event) {
5576        if (Object.isUndefined(event.eventName))
5577          return false;
5578
5579        if (event.eventName !== eventName)
5580          return false;
5581
5582        Event.extend(event, element);
5583        handler.call(element, event);
5584      };
5585    } else {
5586      if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
5587       (eventName === "mouseenter" || eventName === "mouseleave")) {
5588        if (eventName === "mouseenter" || eventName === "mouseleave") {
5589          responder = function(event) {
5590            Event.extend(event, element);
5591
5592            var parent = event.relatedTarget;
5593            while (parent && parent !== element) {
5594              try { parent = parent.parentNode; }
5595              catch(e) { parent = element; }
5596            }
5597
5598            if (parent === element) return;
5599
5600            handler.call(element, event);
5601          };
5602        }
5603      } else {
5604        responder = function(event) {
5605          Event.extend(event, element);
5606          handler.call(element, event);
5607        };
5608      }
5609    }
5610
5611    responder.handler = handler;
5612    respondersForEvent.push(responder);
5613    return responder;
5614  }
5615
5616  function _destroyCache() {
5617    for (var i = 0, length = CACHE.length; i < length; i++) {
5618      Event.stopObserving(CACHE[i]);
5619      CACHE[i] = null;
5620    }
5621  }
5622
5623  var CACHE = [];
5624
5625  if (Prototype.Browser.IE)
5626    window.attachEvent('onunload', _destroyCache);
5627
5628  if (Prototype.Browser.WebKit)
5629    window.addEventListener('unload', Prototype.emptyFunction, false);
5630
5631
5632  var _getDOMEventName = Prototype.K,
5633      translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
5634
5635  if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
5636    _getDOMEventName = function(eventName) {
5637      return (translations[eventName] || eventName);
5638    };
5639  }
5640
5641  function observe(element, eventName, handler) {
5642    element = $(element);
5643
5644    var responder = _createResponder(element, eventName, handler);
5645
5646    if (!responder) return element;
5647
5648    if (eventName.include(':')) {
5649      if (element.addEventListener)
5650        element.addEventListener("dataavailable", responder, false);
5651      else {
5652        element.attachEvent("ondataavailable", responder);
5653        element.attachEvent("onlosecapture", responder);
5654      }
5655    } else {
5656      var actualEventName = _getDOMEventName(eventName);
5657
5658      if (element.addEventListener)
5659        element.addEventListener(actualEventName, responder, false);
5660      else
5661        element.attachEvent("on" + actualEventName, responder);
5662    }
5663
5664    return element;
5665  }
5666
5667  function stopObserving(element, eventName, handler) {
5668    element = $(element);
5669
5670    var registry = Element.retrieve(element, 'prototype_event_registry');
5671    if (!registry) return element;
5672
5673    if (!eventName) {
5674      registry.each( function(pair) {
5675        var eventName = pair.key;
5676        stopObserving(element, eventName);
5677      });
5678      return element;
5679    }
5680
5681    var responders = registry.get(eventName);
5682    if (!responders) return element;
5683
5684    if (!handler) {
5685      responders.each(function(r) {
5686        stopObserving(element, eventName, r.handler);
5687      });
5688      return element;
5689    }
5690
5691    var i = responders.length, responder;
5692    while (i--) {
5693      if (responders[i].handler === handler) {
5694        responder = responders[i];
5695        break;
5696      }
5697    }
5698    if (!responder) return element;
5699
5700    if (eventName.include(':')) {
5701      if (element.removeEventListener)
5702        element.removeEventListener("dataavailable", responder, false);
5703      else {
5704        element.detachEvent("ondataavailable", responder);
5705        element.detachEvent("onlosecapture", responder);
5706      }
5707    } else {
5708      var actualEventName = _getDOMEventName(eventName);
5709      if (element.removeEventListener)
5710        element.removeEventListener(actualEventName, responder, false);
5711      else
5712        element.detachEvent('on' + actualEventName, responder);
5713    }
5714
5715    registry.set(eventName, responders.without(responder));
5716
5717    return element;
5718  }
5719
5720  function fire(element, eventName, memo, bubble) {
5721    element = $(element);
5722
5723    if (Object.isUndefined(bubble))
5724      bubble = true;
5725
5726    if (element == document && document.createEvent && !element.dispatchEvent)
5727      element = document.documentElement;
5728
5729    var event;
5730    if (document.createEvent) {
5731      event = document.createEvent('HTMLEvents');
5732      event.initEvent('dataavailable', bubble, true);
5733    } else {
5734      event = document.createEventObject();
5735      event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
5736    }
5737
5738    event.eventName = eventName;
5739    event.memo = memo || { };
5740
5741    if (document.createEvent)
5742      element.dispatchEvent(event);
5743    else
5744      element.fireEvent(event.eventType, event);
5745
5746    return Event.extend(event);
5747  }
5748
5749  Event.Handler = Class.create({
5750    initialize: function(element, eventName, selector, callback) {
5751      this.element   = $(element);
5752      this.eventName = eventName;
5753      this.selector  = selector;
5754      this.callback  = callback;
5755      this.handler   = this.handleEvent.bind(this);
5756    },
5757
5758    start: function() {
5759      Event.observe(this.element, this.eventName, this.handler);
5760      return this;
5761    },
5762
5763    stop: function() {
5764      Event.stopObserving(this.element, this.eventName, this.handler);
5765      return this;
5766    },
5767
5768    handleEvent: function(event) {
5769      var element = Event.findElement(event, this.selector);
5770      if (element) this.callback.call(this.element, event, element);
5771    }
5772  });
5773
5774  function on(element, eventName, selector, callback) {
5775    element = $(element);
5776    if (Object.isFunction(selector) && Object.isUndefined(callback)) {
5777      callback = selector, selector = null;
5778    }
5779
5780    return new Event.Handler(element, eventName, selector, callback).start();
5781  }
5782
5783  Object.extend(Event, Event.Methods);
5784
5785  Object.extend(Event, {
5786    fire:          fire,
5787    observe:       observe,
5788    stopObserving: stopObserving,
5789    on:            on
5790  });
5791
5792  Element.addMethods({
5793    fire:          fire,
5794
5795    observe:       observe,
5796
5797    stopObserving: stopObserving,
5798
5799    on:            on
5800  });
5801
5802  Object.extend(document, {
5803    fire:          fire.methodize(),
5804
5805    observe:       observe.methodize(),
5806
5807    stopObserving: stopObserving.methodize(),
5808
5809    on:            on.methodize(),
5810
5811    loaded:        false
5812  });
5813
5814  if (window.Event) Object.extend(window.Event, Event);
5815  else window.Event = Event;
5816})();
5817
5818(function() {
5819  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
5820     Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
5821
5822  var timer;
5823
5824  function fireContentLoadedEvent() {
5825    if (document.loaded) return;
5826    if (timer) window.clearTimeout(timer);
5827    document.loaded = true;
5828    document.fire('dom:loaded');
5829  }
5830
5831  function checkReadyState() {
5832    if (document.readyState === 'complete') {
5833      document.stopObserving('readystatechange', checkReadyState);
5834      fireContentLoadedEvent();
5835    }
5836  }
5837
5838  function pollDoScroll() {
5839    try { document.documentElement.doScroll('left'); }
5840    catch(e) {
5841      timer = pollDoScroll.defer();
5842      return;
5843    }
5844    fireContentLoadedEvent();
5845  }
5846
5847  if (document.addEventListener) {
5848    document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
5849  } else {
5850    document.observe('readystatechange', checkReadyState);
5851    if (window == top)
5852      timer = pollDoScroll.defer();
5853  }
5854
5855  Event.observe(window, 'load', fireContentLoadedEvent);
5856})();
5857
5858Element.addMethods();
5859
5860/*------------------------------- DEPRECATED -------------------------------*/
5861
5862Hash.toQueryString = Object.toQueryString;
5863
5864var Toggle = { display: Element.toggle };
5865
5866Element.Methods.childOf = Element.Methods.descendantOf;
5867
5868var Insertion = {
5869  Before: function(element, content) {
5870    return Element.insert(element, {before:content});
5871  },
5872
5873  Top: function(element, content) {
5874    return Element.insert(element, {top:content});
5875  },
5876
5877  Bottom: function(element, content) {
5878    return Element.insert(element, {bottom:content});
5879  },
5880
5881  After: function(element, content) {
5882    return Element.insert(element, {after:content});
5883  }
5884};
5885
5886var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
5887
5888var Position = {
5889  includeScrollOffsets: false,
5890
5891  prepare: function() {
5892    this.deltaX =  window.pageXOffset
5893                || document.documentElement.scrollLeft
5894                || document.body.scrollLeft
5895                || 0;
5896    this.deltaY =  window.pageYOffset
5897                || document.documentElement.scrollTop
5898                || document.body.scrollTop
5899                || 0;
5900  },
5901
5902  within: function(element, x, y) {
5903    if (this.includeScrollOffsets)
5904      return this.withinIncludingScrolloffsets(element, x, y);
5905    this.xcomp = x;
5906    this.ycomp = y;
5907    this.offset = Element.cumulativeOffset(element);
5908
5909    return (y >= this.offset[1] &&
5910            y <  this.offset[1] + element.offsetHeight &&
5911            x >= this.offset[0] &&
5912            x <  this.offset[0] + element.offsetWidth);
5913  },
5914
5915  withinIncludingScrolloffsets: function(element, x, y) {
5916    var offsetcache = Element.cumulativeScrollOffset(element);
5917
5918    this.xcomp = x + offsetcache[0] - this.deltaX;
5919    this.ycomp = y + offsetcache[1] - this.deltaY;
5920    this.offset = Element.cumulativeOffset(element);
5921
5922    return (this.ycomp >= this.offset[1] &&
5923            this.ycomp <  this.offset[1] + element.offsetHeight &&
5924            this.xcomp >= this.offset[0] &&
5925            this.xcomp <  this.offset[0] + element.offsetWidth);
5926  },
5927
5928  overlap: function(mode, element) {
5929    if (!mode) return 0;
5930    if (mode == 'vertical')
5931      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
5932        element.offsetHeight;
5933    if (mode == 'horizontal')
5934      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
5935        element.offsetWidth;
5936  },
5937
5938
5939  cumulativeOffset: Element.Methods.cumulativeOffset,
5940
5941  positionedOffset: Element.Methods.positionedOffset,
5942
5943  absolutize: function(element) {
5944    Position.prepare();
5945    return Element.absolutize(element);
5946  },
5947
5948  relativize: function(element) {
5949    Position.prepare();
5950    return Element.relativize(element);
5951  },
5952
5953  realOffset: Element.Methods.cumulativeScrollOffset,
5954
5955  offsetParent: Element.Methods.getOffsetParent,
5956
5957  page: Element.Methods.viewportOffset,
5958
5959  clone: function(source, target, options) {
5960    options = options || { };
5961    return Element.clonePosition(target, source, options);
5962  }
5963};
5964
5965/*--------------------------------------------------------------------------*/
5966
5967if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
5968  function iter(name) {
5969    return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
5970  }
5971
5972  instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
5973  function(element, className) {
5974    className = className.toString().strip();
5975    var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
5976    return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
5977  } : function(element, className) {
5978    className = className.toString().strip();
5979    var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
5980    if (!classNames && !className) return elements;
5981
5982    var nodes = $(element).getElementsByTagName('*');
5983    className = ' ' + className + ' ';
5984
5985    for (var i = 0, child, cn; child = nodes[i]; i++) {
5986      if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
5987          (classNames && classNames.all(function(name) {
5988            return !name.toString().blank() && cn.include(' ' + name + ' ');
5989          }))))
5990        elements.push(Element.extend(child));
5991    }
5992    return elements;
5993  };
5994
5995  return function(className, parentElement) {
5996    return $(parentElement || document.body).getElementsByClassName(className);
5997  };
5998}(Element.Methods);
5999
6000/*--------------------------------------------------------------------------*/
6001
6002Element.ClassNames = Class.create();
6003Element.ClassNames.prototype = {
6004  initialize: function(element) {
6005    this.element = $(element);
6006  },
6007
6008  _each: function(iterator) {
6009    this.element.className.split(/\s+/).select(function(name) {
6010      return name.length > 0;
6011    })._each(iterator);
6012  },
6013
6014  set: function(className) {
6015    this.element.className = className;
6016  },
6017
6018  add: function(classNameToAdd) {
6019    if (this.include(classNameToAdd)) return;
6020    this.set($A(this).concat(classNameToAdd).join(' '));
6021  },
6022
6023  remove: function(classNameToRemove) {
6024    if (!this.include(classNameToRemove)) return;
6025    this.set($A(this).without(classNameToRemove).join(' '));
6026  },
6027
6028  toString: function() {
6029    return $A(this).join(' ');
6030  }
6031};
6032
6033Object.extend(Element.ClassNames.prototype, Enumerable);
6034
6035/*--------------------------------------------------------------------------*/
6036
6037(function() {
6038  window.Selector = Class.create({
6039    initialize: function(expression) {
6040      this.expression = expression.strip();
6041    },
6042
6043    findElements: function(rootElement) {
6044      return Prototype.Selector.select(this.expression, rootElement);
6045    },
6046
6047    match: function(element) {
6048      return Prototype.Selector.match(element, this.expression);
6049    },
6050
6051    toString: function() {
6052      return this.expression;
6053    },
6054
6055    inspect: function() {
6056      return "#<Selector: " + this.expression + ">";
6057    }
6058  });
6059
6060  Object.extend(Selector, {
6061    matchElements: function(elements, expression) {
6062      var match = Prototype.Selector.match,
6063          results = [];
6064
6065      for (var i = 0, length = elements.length; i < length; i++) {
6066        var element = elements[i];
6067        if (match(element, expression)) {
6068          results.push(Element.extend(element));
6069        }
6070      }
6071      return results;
6072    },
6073
6074    findElement: function(elements, expression, index) {
6075      index = index || 0;
6076      var matchIndex = 0, element;
6077      for (var i = 0, length = elements.length; i < length; i++) {
6078        element = elements[i];
6079        if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
6080          return Element.extend(element);
6081        }
6082      }
6083    },
6084
6085    findChildElements: function(element, expressions) {
6086      var selector = expressions.toArray().join(', ');
6087      return Prototype.Selector.select(selector, element || document);
6088    }
6089  });
6090})();
6091
6092// Credit Card Validation Javascript
6093// copyright 12th May 2003, by Stephen Chapman, Felgall Pty Ltd
6094
6095// You have permission to copy and use this javascript provided that
6096// the content of the script is not changed in any way.
6097
6098function validateCreditCard(s) {
6099    // remove non-numerics
6100    var v = "0123456789";
6101    var w = "";
6102    for (i=0; i < s.length; i++) {
6103        x = s.charAt(i);
6104        if (v.indexOf(x,0) != -1)
6105        w += x;
6106    }
6107    // validate number
6108    j = w.length / 2;
6109    k = Math.floor(j);
6110    m = Math.ceil(j) - k;
6111    c = 0;
6112    for (i=0; i<k; i++) {
6113        a = w.charAt(i*2+m) * 2;
6114        c += a > 9 ? Math.floor(a/10 + a%10) : a;
6115    }
6116    for (i=0; i<k+m; i++) c += w.charAt(i*2+1-m) * 1;
6117    return (c%10 == 0);
6118}
6119
6120
6121/*
6122* Really easy field validation with Prototype
6123* http://tetlaw.id.au/view/javascript/really-easy-field-validation
6124* Andrew Tetlaw
6125* Version 1.5.4.1 (2007-01-05)
6126*
6127* Copyright (c) 2007 Andrew Tetlaw
6128* Permission is hereby granted, free of charge, to any person
6129* obtaining a copy of this software and associated documentation
6130* files (the "Software"), to deal in the Software without
6131* restriction, including without limitation the rights to use, copy,
6132* modify, merge, publish, distribute, sublicense, and/or sell copies
6133* of the Software, and to permit persons to whom the Software is
6134* furnished to do so, subject to the following conditions:
6135*
6136* The above copyright notice and this permission notice shall be
6137* included in all copies or substantial portions of the Software.
6138*
6139* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
6140* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
6141* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
6142* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
6143* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
6144* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
6145* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
6146* SOFTWARE.
6147*
6148*/
6149var Validator = Class.create();
6150
6151Validator.prototype = {
6152    initialize : function(className, error, test, options) {
6153        if(typeof test == 'function'){
6154            this.options = $H(options);
6155            this._test = test;
6156        } else {
6157            this.options = $H(test);
6158            this._test = function(){return true};
6159        }
6160        this.error = error || 'Validation failed.';
6161        this.className = className;
6162    },
6163    test : function(v, elm) {
6164        return (this._test(v,elm) && this.options.all(function(p){
6165            return Validator.methods[p.key] ? Validator.methods[p.key](v,elm,p.value) : true;
6166        }));
6167    }
6168}
6169Validator.methods = {
6170    pattern : function(v,elm,opt) {return Validation.get('IsEmpty').test(v) || opt.test(v)},
6171    minLength : function(v,elm,opt) {return v.length >= opt},
6172    maxLength : function(v,elm,opt) {return v.length <= opt},
6173    min : function(v,elm,opt) {return v >= parseFloat(opt)},
6174    max : function(v,elm,opt) {return v <= parseFloat(opt)},
6175    notOneOf : function(v,elm,opt) {return $A(opt).all(function(value) {
6176        return v != value;
6177    })},
6178    oneOf : function(v,elm,opt) {return $A(opt).any(function(value) {
6179        return v == value;
6180    })},
6181    is : function(v,elm,opt) {return v == opt},
6182    isNot : function(v,elm,opt) {return v != opt},
6183    equalToField : function(v,elm,opt) {return v == $F(opt)},
6184    notEqualToField : function(v,elm,opt) {return v != $F(opt)},
6185    include : function(v,elm,opt) {return $A(opt).all(function(value) {
6186        return Validation.get(value).test(v,elm);
6187    })}
6188}
6189
6190var Validation = Class.create();
6191Validation.defaultOptions = {
6192    onSubmit : true,
6193    stopOnFirst : false,
6194    immediate : false,
6195    focusOnError : true,
6196    useTitles : false,
6197    addClassNameToContainer: false,
6198    containerClassName: '.input-box',
6199    onFormValidate : function(result, form) {},
6200    onElementValidate : function(result, elm) {}
6201};
6202
6203Validation.prototype = {
6204    initialize : function(form, options){
6205        this.form = $(form);
6206        if (!this.form) {
6207            return;
6208        }
6209        this.options = Object.extend({
6210            onSubmit : Validation.defaultOptions.onSubmit,
6211            stopOnFirst : Validation.defaultOptions.stopOnFirst,
6212            immediate : Validation.defaultOptions.immediate,
6213            focusOnError : Validation.defaultOptions.focusOnError,
6214            useTitles : Validation.defaultOptions.useTitles,
6215            onFormValidate : Validation.defaultOptions.onFormValidate,
6216            onElementValidate : Validation.defaultOptions.onElementValidate
6217        }, options || {});
6218        if(this.options.onSubmit) Event.observe(this.form,'submit',this.onSubmit.bind(this),false);
6219        if(this.options.immediate) {
6220            Form.getElements(this.form).each(function(input) { // Thanks Mike!
6221                if (input.tagName.toLowerCase() == 'select') {
6222                    Event.observe(input, 'blur', this.onChange.bindAsEventListener(this));
6223                }
6224                if (input.type.toLowerCase() == 'radio' || input.type.toLowerCase() == 'checkbox') {
6225                    Event.observe(input, 'click', this.onChange.bindAsEventListener(this));
6226                } else {
6227                    Event.observe(input, 'change', this.onChange.bindAsEventListener(this));
6228                }
6229            }, this);
6230        }
6231    },
6232    onChange : function (ev) {
6233        Validation.isOnChange = true;
6234        Validation.validate(Event.element(ev),{
6235                useTitle : this.options.useTitles,
6236                onElementValidate : this.options.onElementValidate
6237        });
6238        Validation.isOnChange = false;
6239    },
6240    onSubmit :  function(ev){
6241        if(!this.validate()) Event.stop(ev);
6242    },
6243    validate : function() {
6244        var result = false;
6245        var useTitles = this.options.useTitles;
6246        var callback = this.options.onElementValidate;
6247        try {
6248            if(this.options.stopOnFirst) {
6249                result = Form.getElements(this.form).all(function(elm) {
6250                    if (elm.hasClassName('local-validation') && !this.isElementInForm(elm, this.form)) {
6251                        return true;
6252                    }
6253                    return Validation.validate(elm,{useTitle : useTitles, onElementValidate : callback});
6254                }, this);
6255            } else {
6256                result = Form.getElements(this.form).collect(function(elm) {
6257                    if (elm.hasClassName('local-validation') && !this.isElementInForm(elm, this.form)) {
6258                        return true;
6259                    }
6260                    return Validation.validate(elm,{useTitle : useTitles, onElementValidate : callback});
6261                }, this).all();
6262            }
6263        } catch (e) {
6264        }
6265        if(!result && this.options.focusOnError) {
6266            try{
6267                Form.getElements(this.form).findAll(function(elm){return $(elm).hasClassName('validation-failed')}).first().focus()
6268            }
6269            catch(e){
6270            }
6271        }
6272        this.options.onFormValidate(result, this.form);
6273        return result;
6274    },
6275    reset : function() {
6276        Form.getElements(this.form).each(Validation.reset);
6277    },
6278    isElementInForm : function(elm, form) {
6279        var domForm = elm.up('form');
6280        if (domForm == form) {
6281            return true;
6282        }
6283        return false;
6284    }
6285}
6286
6287Object.extend(Validation, {
6288    validate : function(elm, options){
6289        options = Object.extend({
6290            useTitle : false,
6291            onElementValidate : function(result, elm) {}
6292        }, options || {});
6293        elm = $(elm);
6294
6295        var cn = $w(elm.className);
6296        return result = cn.all(function(value) {
6297            var test = Validation.test(value,elm,options.useTitle);
6298            options.onElementValidate(test, elm);
6299            return test;
6300        });
6301    },
6302    insertAdvice : function(elm, advice){
6303        var container = $(elm).up('.field-row');
6304        if(container){
6305            Element.insert(container, {after: advice});
6306        } else if (elm.up('td.value')) {
6307            elm.up('td.value').insert({bottom: advice});
6308        } else if (elm.advaiceContainer && $(elm.advaiceContainer)) {
6309            $(elm.advaiceContainer).update(advice);
6310        }
6311        else {
6312            switch (elm.type.toLowerCase()) {
6313                case 'checkbox':
6314                case 'radio':
6315                    var p = elm.parentNode;
6316                    if(p) {
6317                        Element.insert(p, {'bottom': advice});
6318                    } else {
6319                        Element.insert(elm, {'after': advice});
6320                    }
6321                    break;
6322                default:
6323                    Element.insert(elm, {'after': advice});
6324            }
6325        }
6326    },
6327    showAdvice : function(elm, advice, adviceName){
6328        if(!elm.advices){
6329            elm.advices = new Hash();
6330        }
6331        else{
6332            elm.advices.each(function(pair){
6333                if (!advice || pair.value.id != advice.id) {
6334                    // hide non-current advice after delay
6335                    this.hideAdvice(elm, pair.value);
6336                }
6337            }.bind(this));
6338        }
6339        elm.advices.set(adviceName, advice);
6340        if(typeof Effect == 'undefined') {
6341            advice.style.display = 'block';
6342        } else {
6343            if(!advice._adviceAbsolutize) {
6344                new Effect.Appear(advice, {duration : 1 });
6345            } else {
6346                Position.absolutize(advice);
6347                advice.show();
6348                advice.setStyle({
6349                    'top':advice._adviceTop,
6350                    'left': advice._adviceLeft,
6351                    'width': advice._adviceWidth,
6352                    'z-index': 1000
6353                });
6354                advice.addClassName('advice-absolute');
6355            }
6356        }
6357    },
6358    hideAdvice : function(elm, advice){
6359        if (advice != null) {
6360            new Effect.Fade(advice, {duration : 1, afterFinishInternal : function() {advice.hide();}});
6361        }
6362    },
6363    updateCallback : function(elm, status) {
6364        if (typeof elm.callbackFunction != 'undefined') {
6365            eval(elm.callbackFunction+'(\''+elm.id+'\',\''+status+'\')');
6366        }
6367    },
6368    ajaxError : function(elm, errorMsg) {
6369        var name = 'validate-ajax';
6370        var advice = Validation.getAdvice(name, elm);
6371        if (advice == null) {
6372            advice = this.createAdvice(name, elm, false, errorMsg);
6373        }
6374        this.showAdvice(elm, advice, 'validate-ajax');
6375        this.updateCallback(elm, 'failed');
6376
6377        elm.addClassName('validation-failed');
6378        elm.addClassName('validate-ajax');
6379        if (Validation.defaultOptions.addClassNameToContainer && Validation.defaultOptions.containerClassName != '') {
6380            var container = elm.up(Validation.defaultOptions.containerClassName);
6381            if (container && this.allowContainerClassName(elm)) {
6382                container.removeClassName('validation-passed');
6383                container.addClassName('validation-error');
6384            }
6385        }
6386    },
6387    allowContainerClassName: function (elm) {
6388        if (elm.type == 'radio' || elm.type == 'checkbox') {
6389            return elm.hasClassName('change-container-classname');
6390        }
6391
6392        return true;
6393    },
6394    test : function(name, elm, useTitle) {
6395        var v = Validation.get(name);
6396        var prop = '__advice'+name.camelize();
6397        try {
6398        if(Validation.isVisible(elm) && !v.test($F(elm), elm)) {
6399            //if(!elm[prop]) {
6400                var advice = Validation.getAdvice(name, elm);
6401                if (advice == null) {
6402                    advice = this.createAdvice(name, elm, useTitle);
6403                }
6404                this.showAdvice(elm, advice, name);
6405                this.updateCallback(elm, 'failed');
6406            //}
6407            elm[prop] = 1;
6408            if (!elm.advaiceContainer) {
6409                elm.removeClassName('validation-passed');
6410                elm.addClassName('validation-failed');
6411            }
6412
6413           if (Validation.defaultOptions.addClassNameToContainer && Validation.defaultOptions.containerClassName != '') {
6414                var container = elm.up(Validation.defaultOptions.containerClassName);
6415                if (container && this.allowContainerClassName(elm)) {
6416                    container.removeClassName('validation-passed');
6417                    container.addClassName('validation-error');
6418                }
6419            }
6420            return false;
6421        } else {
6422            var advice = Validation.getAdvice(name, elm);
6423            this.hideAdvice(elm, advice);
6424            this.updateCallback(elm, 'passed');
6425            elm[prop] = '';
6426            elm.removeClassName('validation-failed');
6427            elm.addClassName('validation-passed');
6428            if (Validation.defaultOptions.addClassNameToContainer && Validation.defaultOptions.containerClassName != '') {
6429                var container = elm.up(Validation.defaultOptions.containerClassName);
6430                if (container && !container.down('.validation-failed') && this.allowContainerClassName(elm)) {
6431                    if (!Validation.get('IsEmpty').test(elm.value) || !this.isVisible(elm)) {
6432                        container.addClassName('validation-passed');
6433                    } else {
6434                        container.removeClassName('validation-passed');
6435                    }
6436                    container.removeClassName('validation-error');
6437                }
6438            }
6439            return true;
6440        }
6441        } catch(e) {
6442            throw(e)
6443        }
6444    },
6445    isVisible : function(elm) {
6446        while(elm.tagName != 'BODY') {
6447            if(!$(elm).visible()) return false;
6448            elm = elm.parentNode;
6449        }
6450        return true;
6451    },
6452    getAdvice : function(name, elm) {
6453        return $('advice-' + name + '-' + Validation.getElmID(elm)) || $('advice-' + Validation.getElmID(elm));
6454    },
6455    createAdvice : function(name, elm, useTitle, customError) {
6456        var v = Validation.get(name);
6457        var errorMsg = useTitle ? ((elm && elm.title) ? elm.title : v.error) : v.error;
6458        if (customError) {
6459            errorMsg = customError;
6460        }
6461        try {
6462            if (Translator){
6463                errorMsg = Translator.translate(errorMsg);
6464            }
6465        }
6466        catch(e){}
6467
6468        advice = '<div class="validation-advice" id="advice-' + name + '-' + Validation.getElmID(elm) +'" style="display:none">' + errorMsg + '</div>'
6469
6470
6471        Validation.insertAdvice(elm, advice);
6472        advice = Validation.getAdvice(name, elm);
6473        if($(elm).hasClassName('absolute-advice')) {
6474            var dimensions = $(elm).getDimensions();
6475            var originalPosition = Position.cumulativeOffset(elm);
6476
6477            advice._adviceTop = (originalPosition[1] + dimensions.height) + 'px';
6478            advice._adviceLeft = (originalPosition[0])  + 'px';
6479            advice._adviceWidth = (dimensions.width)  + 'px';
6480            advice._adviceAbsolutize = true;
6481        }
6482        return advice;
6483    },
6484    getElmID : function(elm) {
6485        return elm.id ? elm.id : elm.name;
6486    },
6487    reset : function(elm) {
6488        elm = $(elm);
6489        var cn = $w(elm.className);
6490        cn.each(function(value) {
6491            var prop = '__advice'+value.camelize();
6492            if(elm[prop]) {
6493                var advice = Validation.getAdvice(value, elm);
6494                if (advice) {
6495                    advice.hide();
6496                }
6497                elm[prop] = '';
6498            }
6499            elm.removeClassName('validation-failed');
6500            elm.removeClassName('validation-passed');
6501            if (Validation.defaultOptions.addClassNameToContainer && Validation.defaultOptions.containerClassName != '') {
6502                var container = elm.up(Validation.defaultOptions.containerClassName);
6503                if (container) {
6504                    container.removeClassName('validation-passed');
6505                    container.removeClassName('validation-error');
6506                }
6507            }
6508        });
6509    },
6510    add : function(className, error, test, options) {
6511        var nv = {};
6512        nv[className] = new Validator(className, error, test, options);
6513        Object.extend(Validation.methods, nv);
6514    },
6515    addAllThese : function(validators) {
6516        var nv = {};
6517        $A(validators).each(function(value) {
6518                nv[value[0]] = new Validator(value[0], value[1], value[2], (value.length > 3 ? value[3] : {}));
6519            });
6520        Object.extend(Validation.methods, nv);
6521    },
6522    get : function(name) {
6523        return  Validation.methods[name] ? Validation.methods[name] : Validation.methods['_LikeNoIDIEverSaw_'];
6524    },
6525    methods : {
6526        '_LikeNoIDIEverSaw_' : new Validator('_LikeNoIDIEverSaw_','',{})
6527    }
6528});
6529
6530Validation.add('IsEmpty', '', function(v) {
6531    return  (v == '' || (v == null) || (v.length == 0) || /^\s+$/.test(v));
6532});
6533
6534Validation.addAllThese([
6535    ['validate-no-html-tags', 'HTML tags are not allowed', function(v) {
6536				return !/<(\/)?\w+/.test(v);
6537			}],
6538	['validate-select', 'Please select an option.', function(v) {
6539                return ((v != "none") && (v != null) && (v.length != 0));
6540            }],
6541    ['required-entry', 'This is a required field.', function(v) {
6542                return !Validation.get('IsEmpty').test(v);
6543            }],
6544    ['validate-number', 'Please enter a valid number in this field.', function(v) {
6545                return Validation.get('IsEmpty').test(v)
6546                    || (!isNaN(parseNumber(v)) && /^\s*-?\d*(\.\d*)?\s*$/.test(v));
6547            }],
6548    ['validate-number-range', 'The value is not within the specified range.', function(v, elm) {
6549                if (Validation.get('IsEmpty').test(v)) {
6550                    return true;
6551                }
6552
6553                var numValue = parseNumber(v);
6554                if (isNaN(numValue)) {
6555                    return false;
6556                }
6557
6558                var reRange = /^number-range-(-?[\d.,]+)?-(-?[\d.,]+)?$/,
6559                    result = true;
6560
6561                $w(elm.className).each(function(name) {
6562                    var m = reRange.exec(name);
6563                    if (m) {
6564                        result = result
6565                            && (m[1] == null || m[1] == '' || numValue >= parseNumber(m[1]))
6566                            && (m[2] == null || m[2] == '' || numValue <= parseNumber(m[2]));
6567                    }
6568                });
6569
6570                return result;
6571            }],
6572    ['validate-digits', 'Please use numbers only in this field. Please avoid spaces or other characters such as dots or commas.', function(v) {
6573                return Validation.get('IsEmpty').test(v) ||  !/[^\d]/.test(v);
6574            }],
6575    ['validate-digits-range', 'The value is not within the specified range.', function(v, elm) {
6576                if (Validation.get('IsEmpty').test(v)) {
6577                    return true;
6578                }
6579
6580                var numValue = parseNumber(v);
6581                if (isNaN(numValue)) {
6582                    return false;
6583                }
6584
6585                var reRange = /^digits-range-(-?\d+)?-(-?\d+)?$/,
6586                    result = true;
6587
6588                $w(elm.className).each(function(name) {
6589                    var m = reRange.exec(name);
6590                    if (m) {
6591                        result = result
6592                            && (m[1] == null || m[1] == '' || numValue >= parseNumber(m[1]))
6593                            && (m[2] == null || m[2] == '' || numValue <= parseNumber(m[2]));
6594                    }
6595                });
6596
6597                return result;
6598            }],
6599    ['validate-alpha', 'Please use letters only (a-z or A-Z) in this field.', function (v) {
6600                return Validation.get('IsEmpty').test(v) ||  /^[a-zA-Z]+$/.test(v)
6601            }],
6602    ['validate-code', 'Please use only letters (a-z), numbers (0-9) or underscore(_) in this field, first character should be a letter.', function (v) {
6603                return Validation.get('IsEmpty').test(v) ||  /^[a-z]+[a-z0-9_]+$/.test(v)
6604            }],
6605    ['validate-alphanum', 'Please use only letters (a-z or A-Z) or numbers (0-9) only in this field. No spaces or other characters are allowed.', function(v) {
6606                return Validation.get('IsEmpty').test(v) || /^[a-zA-Z0-9]+$/.test(v)
6607            }],
6608    ['validate-alphanum-with-spaces', 'Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.', function(v) {
6609                    return Validation.get('IsEmpty').test(v) || /^[a-zA-Z0-9 ]+$/.test(v)
6610            }],
6611    ['validate-street', 'Please use only letters (a-z or A-Z) or numbers (0-9) or spaces and # only in this field.', function(v) {
6612                return Validation.get('IsEmpty').test(v) ||  /^[ \w]{3,}([A-Za-z]\.)?([ \w]*\#\d+)?(\r\n| )[ \w]{3,}/.test(v)
6613            }],
6614    ['validate-phoneStrict', 'Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.', function(v) {
6615                return Validation.get('IsEmpty').test(v) || /^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(v);
6616            }],
6617    ['validate-phoneLax', 'Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.', function(v) {
6618                return Validation.get('IsEmpty').test(v) || /^((\d[-. ]?)?((\(\d{3}\))|\d{3}))?[-. ]?\d{3}[-. ]?\d{4}$/.test(v);
6619            }],
6620    ['validate-fax', 'Please enter a valid fax number. For example (123) 456-7890 or 123-456-7890.', function(v) {
6621                return Validation.get('IsEmpty').test(v) || /^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(v);
6622            }],
6623    ['validate-date', 'Please enter a valid date.', function(v) {
6624                var test = new Date(v);
6625                return Validation.get('IsEmpty').test(v) || !isNaN(test);
6626            }],
6627    ['validate-date-range', 'The From Date value should be less than or equal to the To Date value.', function(v, elm) {
6628            var m = /\bdate-range-(\w+)-(\w+)\b/.exec(elm.className);
6629            if (!m || m[2] == 'to' || Validation.get('IsEmpty').test(v)) {
6630                return true;
6631            }
6632
6633            var currentYear = new Date().getFullYear() + '';
6634            var normalizedTime = function(v) {
6635                v = v.split(/[.\/]/);
6636                if (v[2] && v[2].length < 4) {
6637                    v[2] = currentYear.substr(0, v[2].length) + v[2];
6638                }
6639                return new Date(v.join('/')).getTime();
6640            };
6641
6642            var dependentElements = Element.select(elm.form, '.validate-date-range.date-range-' + m[1] + '-to');
6643            return !dependentElements.length || Validation.get('IsEmpty').test(dependentElements[0].value)
6644                || normalizedTime(v) <= normalizedTime(dependentElements[0].value);
6645        }],
6646    ['validate-email', 'Please enter a valid email address. For example [email protected].', function (v) {
6647                //return Validation.get('IsEmpty').test(v) || /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(v)
6648                //return Validation.get('IsEmpty').test(v) || /^[\!\#$%\*/?|\^\{\}`~&\'\+\-=_a-z0-9][\!\#$%\*/?|\^\{\}`~&\'\+\-=_a-z0-9\.]{1,30}[\!\#$%\*/?|\^\{\}`~&\'\+\-=_a-z0-9]@([a-z0-9_-]{1,30}\.){1,5}[a-z]{2,4}$/i.test(v)
6649                return Validation.get('IsEmpty').test(v) || /^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i.test(v)
6650            }],
6651    ['validate-emailSender', 'Please use only visible characters and spaces.', function (v) {
6652                return Validation.get('IsEmpty').test(v) ||  /^[\S ]+$/.test(v)
6653                    }],
6654    ['validate-password', 'Please enter more characters or clean leading or trailing space
6654s.', function(v, elm) {
6655                var pass=v.strip(); /*strip leading and trailing spaces*/
6656                var reMin = new RegExp(/^min-pass-length-[0-9]+$/);
6657                var minLength = 7;
6658                $w(elm.className).each(function(name, index) {
6659                    if (name.match(reMin)) {
6660                        minLength = name.split('-')[3];
6661                    }
6662                });
6663                return (!(v.length > 0 && v.length < minLength) && v.length == pass.length);
6664            }],
6665    ['validate-admin-password', 'Please enter more characters. Password should contain both numeric and alphabetic characters.', function(v, elm) {
6666                var pass=v.strip();
6667                if (0 == pass.length) {
6668                    return true;
6669                }
6670                if (!(/[a-z]/i.test(v)) || !(/[0-9]/.test(v))) {
6671                    return false;
6672                }
6673                var reMin = new RegExp(/^min-admin-pass-length-[0-9]+$/);
6674                var minLength = 7;
6675                $w(elm.className).each(function(name, index) {
6676                    if (name.match(reMin)) {
6677                        minLength = name.split('-')[4];
6678                    }
6679                });
6680                return !(pass.length < minLength);
6681            }],
6682    ['validate-cpassword', 'Please make sure your passwords match.', function(v) {
6683                var conf = $('confirmation') ? $('confirmation') : $$('.validate-cpassword')[0];
6684                var pass = false;
6685                if ($('password')) {
6686                    pass = $('password');
6687                }
6688                var passwordElements = $$('.validate-password');
6689                for (var i = 0; i < passwordElements.size(); i++) {
6690                    var passwordElement = passwordElements[i];
6691                    if (passwordElement.up('form').id == conf.up('form').id) {
6692                        pass = passwordElement;
6693                    }
6694                }
6695                if ($$('.validate-admin-password').size()) {
6696                    pass = $$('.validate-admin-password')[0];
6697                }
6698                return (pass.value == conf.value);
6699            }],
6700    ['validate-both-passwords', 'Please make sure your passwords match.', function(v, input) {
6701                var dependentInput = $(input.form[input.name == 'password' ? 'confirmation' : 'password']),
6702                    isEqualValues  = input.value == dependentInput.value;
6703
6704                if (isEqualValues && dependentInput.hasClassName('validation-failed')) {
6705                    Validation.test(this.className, dependentInput);
6706                }
6707
6708                return dependentInput.value == '' || isEqualValues;
6709            }],
6710    ['validate-url', 'Please enter a valid URL. Protocol is required (http://, https:// or ftp://)', function (v) {
6711                v = (v || '').replace(/^\s+/, '').replace(/\s+$/, '');
6712                return Validation.get('IsEmpty').test(v) || /^(http|https|ftp):\/\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\d+))?(\/[A-Z0-9~](([A-Z0-9_~-]|\.)*[A-Z0-9~]|))*\/?(.*)?$/i.test(v)
6713            }],
6714    ['validate-clean-url', 'Please enter a valid URL. For example http://www.example.com or www.example.com', function (v) {
6715                return Validation.get('IsEmpty').test(v) || /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i.test(v) || /^(www)((\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i.test(v)
6716            }],
6717    ['validate-identifier', 'Please enter a valid URL Key. For example "example-page", "example-page.html" or "anotherlevel/example-page".', function (v) {
6718                return Validation.get('IsEmpty').test(v) || /^[a-z0-9][a-z0-9_\/-]+(\.[a-z0-9_-]+)?$/.test(v)
6719            }],
6720    ['validate-xml-identifier', 'Please enter a valid XML-identifier. For example something_1, block5, id-4.', function (v) {
6721                return Validation.get('IsEmpty').test(v) || /^[A-Z][A-Z0-9_\/-]*$/i.test(v)
6722            }],
6723    ['validate-ssn', 'Please enter a valid social security number. For example 123-45-6789.', function(v) {
6724            return Validation.get('IsEmpty').test(v) || /^\d{3}-?\d{2}-?\d{4}$/.test(v);
6725            }],
6726    ['validate-zip', 'Please enter a valid zip code. For example 90602 or 90602-1234.', function(v) {
6727            return Validation.get('IsEmpty').test(v) || /(^\d{5}$)|(^\d{5}-\d{4}$)/.test(v);
6728            }],
6729    ['validate-zip-international', 'Please enter a valid zip code.', function(v) {
6730            //return Validation.get('IsEmpty').test(v) || /(^[A-z0-9]{2,10}([\s]{0,1}|[\-]{0,1})[A-z0-9]{2,10}$)/.test(v);
6731            return true;
6732            }],
6733    ['validate-date-au', 'Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.', function(v) {
6734                if(Validation.get('IsEmpty').test(v)) return true;
6735                var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;
6736                if(!regex.test(v)) return false;
6737                var d = new Date(v.replace(regex, '$2/$1/$3'));
6738                return ( parseInt(RegExp.$2, 10) == (1+d.getMonth()) ) &&
6739                            (parseInt(RegExp.$1, 10) == d.getDate()) &&
6740                            (parseInt(RegExp.$3, 10) == d.getFullYear() );
6741            }],
6742    ['validate-currency-dollar', 'Please enter a valid $ amount. For example $100.00.', function(v) {
6743                // [$]1[##][,###]+[.##]
6744                // [$]1###+[.##]
6745                // [$]0.##
6746                // [$].##
6747                return Validation.get('IsEmpty').test(v) ||  /^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/.test(v)
6748            }],
6749    ['validate-one-required', 'Please select one of the above options.', function (v,elm) {
6750                var p = elm.parentNode;
6751                var options = p.getElementsByTagName('INPUT');
6752                return $A(options).any(function(elm) {
6753                    return $F(elm);
6754                });
6755            }],
6756    ['validate-one-required-by-name', 'Please select one of the options.', function (v,elm) {
6757                var inputs = $$('input[name="' + elm.name.replace(/([\\"])/g, '\\$1') + '"]');
6758
6759                var error = 1;
6760                for(var i=0;i<inputs.length;i++) {
6761                    if((inputs[i].type == 'checkbox' || inputs[i].type == 'radio') && inputs[i].checked == true) {
6762                        error = 0;
6763                    }
6764
6765                    if(Validation.isOnChange && (inputs[i].type == 'checkbox' || inputs[i].type == 'radio')) {
6766                        Validation.reset(inputs[i]);
6767                    }
6768                }
6769
6770                if( error == 0 ) {
6771                    return true;
6772                } else {
6773                    return false;
6774                }
6775            }],
6776    ['validate-not-negative-number', 'Please enter a number 0 or greater in this field.', function(v) {
6777                if (Validation.get('IsEmpty').test(v)) {
6778                    return true;
6779                }
6780                v = parseNumber(v);
6781                return !isNaN(v) && v >= 0;
6782            }],
6783    ['validate-zero-or-greater', 'Please enter a number 0 or greater in this field.', function(v) {
6784            return Validation.get('validate-not-negative-number').test(v);
6785        }],
6786    ['validate-greater-than-zero', 'Please enter a number greater than 0 in this field.', function(v) {
6787            if (Validation.get('IsEmpty').test(v)) {
6788                return true;
6789            }
6790            v = parseNumber(v);
6791            return !isNaN(v) && v > 0;
6792        }],
6793    ['validate-state', 'Please select State/Province.', function(v) {
6794                return (v!=0 || v == '');
6795            }],
6796    ['validate-new-password', 'Please enter more characters or clean leading or trailing spaces.', function(v, elm) {
6797                if (!Validation.get('validate-password').test(v, elm)) return false;
6798                if (Validation.get('IsEmpty').test(v) && v != '') return false;
6799                return true;
6800            }],
6801    ['validate-cc-number', 'Please enter a valid credit card number.', function(v, elm) {
6802                // remove non-numerics
6803                var ccTypeContainer = $(elm.id.substr(0,elm.id.indexOf('_cc_number')) + '_cc_type');
6804                if (ccTypeContainer && typeof Validation.creditCartTypes.get(ccTypeContainer.value) != 'undefined'
6805                        && Validation.creditCartTypes.get(ccTypeContainer.value)[2] == false) {
6806                    if (!Validation.get('IsEmpty').test(v) && Validation.get('validate-digits').test(v)) {
6807                        return true;
6808                    } else {
6809                        return false;
6810                    }
6811                }
6812                return validateCreditCard(v);
6813            }],
6814    ['validate-cc-type', 'Credit card number does not match credit card type.', function(v, elm) {
6815                // remove credit card number delimiters such as "-" and space
6816                elm.value = removeDelimiters(elm.value);
6817                v         = removeDelimiters(v);
6818
6819                var ccTypeContainer = $(elm.id.substr(0,elm.id.indexOf('_cc_number')) + '_cc_type');
6820                if (!ccTypeContainer) {
6821                    return true;
6822                }
6823                var ccType = ccTypeContainer.value;
6824
6825                if (typeof Validation.creditCartTypes.get(ccType) == 'undefined') {
6826                    return false;
6827                }
6828
6829                // Other card type or switch or solo card
6830                if (Validation.creditCartTypes.get(ccType)[0]==false) {
6831                    return true;
6832                }
6833
6834                var validationFailure = false;
6835                Validation.creditCartTypes.each(function (pair) {
6836                    if (pair.key == ccType) {
6837                        if (pair.value[0] && !v.match(pair.value[0])) {
6838                            validationFailure = true;
6839                        }
6840                        throw $break;
6841                    }
6842                });
6843
6844                if (validationFailure) {
6845                    return false;
6846                }
6847
6848                if (ccTypeContainer.hasClassName('validation-failed') && Validation.isOnChange) {
6849                    Validation.validate(ccTypeContainer);
6850                }
6851
6852                return true;
6853            }],
6854     ['validate-cc-type-select', 'Card type does not match credit card number.', function(v, elm) {
6855                var ccNumberContainer = $(elm.id.substr(0,elm.id.indexOf('_cc_type')) + '_cc_number');
6856                if (Validation.isOnChange && Validation.get('IsEmpty').test(ccNumberContainer.value)) {
6857                    return true;
6858                }
6859                if (Validation.get('validate-cc-type').test(ccNumberContainer.value, ccNumberContainer)) {
6860                    Validation.validate(ccNumberContainer);
6861                }
6862                return Validation.get('validate-cc-type').test(ccNumberContainer.value, ccNumberContainer);
6863            }],
6864     ['validate-cc-exp', 'Incorrect credit card expiration date.', function(v, elm) {
6865                var ccExpMonth   = v;
6866                var ccExpYear    = $(elm.id.substr(0,elm.id.indexOf('_expiration')) + '_expiration_yr').value;
6867                var currentTime  = new Date();
6868                var currentMonth = currentTime.getMonth() + 1;
6869                var currentYear  = currentTime.getFullYear();
6870                if (ccExpMonth < currentMonth && ccExpYear == currentYear) {
6871                    return false;
6872                }
6873                return true;
6874            }],
6875     ['validate-cc-cvn', 'Please enter a valid credit card verification number.', function(v, elm) {
6876                var ccTypeContainer = $(elm.id.substr(0,elm.id.indexOf('_cc_cid')) + '_cc_type');
6877                if (!ccTypeContainer) {
6878                    return true;
6879                }
6880                var ccType = ccTypeContainer.value;
6881
6882                if (typeof Validation.creditCartTypes.get(ccType) == 'undefined') {
6883                    return false;
6884                }
6885
6886                var re = Validation.creditCartTypes.get(ccType)[1];
6887
6888                if (v.match(re)) {
6889                    return true;
6890                }
6891
6892                return false;
6893            }],
6894     ['validate-ajax', '', function(v, elm) { return true; }],
6895     ['validate-data', 'Please use only letters (a-z or A-Z), numbers (0-9) or underscore(_) in this field, first character should be a letter.', function (v) {
6896                if(v != '' && v) {
6897                    return /^[A-Za-z]+[A-Za-z0-9_]+$/.test(v);
6898                }
6899                return true;
6900            }],
6901     ['validate-css-length', 'Please input a valid CSS-length. For example 100px or 77pt or 20em or .5ex or 50%.', function (v) {
6902                if (v != '' && v) {
6903                    return /^[0-9\.]+(px|pt|em|ex|%)?$/.test(v) && (!(/\..*\./.test(v))) && !(/\.$/.test(v));
6904                }
6905                return true;
6906            }],
6907     ['validate-length', 'Text length does not satisfy specified text range.', function (v, elm) {
6908                var reMax = new RegExp(/^maximum-length-[0-9]+$/);
6909                var reMin = new RegExp(/^minimum-length-[0-9]+$/);
6910                var result = true;
6911                $w(elm.className).each(function(name, index) {
6912                    if (name.match(reMax) && result) {
6913                       var length = name.split('-')[2];
6914                       result = (v.length <= length);
6915                    }
6916                    if (name.match(reMin) && result && !Validation.get('IsEmpty').test(v)) {
6917                        var length = name.split('-')[2];
6918                        result = (v.length >= length);
6919                    }
6920                });
6921                return result;
6922            }],
6923     ['validate-percents', 'Please enter a number lower than 100.', {max:100}],
6924     ['required-file', 'Please select a file', function(v, elm) {
6925         var result = !Validation.get('IsEmpty').test(v);
6926         if (result === false) {
6927             ovId = elm.id + '_value';
6928             if ($(ovId)) {
6929                 result = !Validation.get('IsEmpty').test($(ovId).value);
6930             }
6931         }
6932         return result;
6933     }],
6934     ['validate-cc-ukss', 'Please enter issue number or start date for switch/solo card type.', function(v,elm) {
6935         var endposition;
6936
6937         if (elm.id.match(/(.)+_cc_issue$/)) {
6938             endposition = elm.id.indexOf('_cc_issue');
6939         } else if (elm.id.match(/(.)+_start_month$/)) {
6940             endposition = elm.id.indexOf('_start_month');
6941         } else {
6942             endposition = elm.id.indexOf('_start_year');
6943         }
6944
6945         var prefix = elm.id.substr(0,endposition);
6946
6947         var ccTypeContainer = $(prefix + '_cc_type');
6948
6949         if (!ccTypeContainer) {
6950               return true;
6951         }
6952         var ccType = ccTypeContainer.value;
6953
6954         if(['SS','SM','SO'].indexOf(ccType) == -1){
6955             return true;
6956         }
6957
6958         $(prefix + '_cc_issue').advaiceContainer
6959           = $(prefix + '_start_month').advaiceContainer
6960           = $(prefix + '_start_year').advaiceContainer
6961           = $(prefix + '_cc_type_ss_div').down('ul li.adv-container');
6962
6963         var ccIssue   =  $(prefix + '_cc_issue').value;
6964         var ccSMonth  =  $(prefix + '_start_month').value;
6965         var ccSYear   =  $(prefix + '_start_year').value;
6966
6967         var ccStartDatePresent = (ccSMonth && ccSYear) ? true : false;
6968
6969         if (!ccStartDatePresent && !ccIssue){
6970             return false;
6971         }
6972         return true;
6973     }]
6974]);
6975
6976function removeDelimiters (v) {
6977    v = v.replace(/\s/g, '');
6978    v = v.replace(/\-/g, '');
6979    return v;
6980}
6981
6982function parseNumber(v)
6983{
6984    if (typeof v != 'string') {
6985        return parseFloat(v);
6986    }
6987
6988    var isDot  = v.indexOf('.');
6989    var isComa = v.indexOf(',');
6990
6991    if (isDot != -1 && isComa != -1) {
6992        if (isComa > isDot) {
6993            v = v.replace('.', '').replace(',', '.');
6994        }
6995        else {
6996            v = v.replace(',', '');
6997        }
6998    }
6999    else if (isComa != -1) {
7000        v = v.replace(',', '.');
7001    }
7002
7003    return parseFloat(v);
7004}
7005
7006/**
7007 * Hash with credit card types which can be simply extended in payment modules
7008 * 0 - regexp for card number
7009 * 1 - regexp for cvn
7010 * 2 - check or not credit card number trough Luhn algorithm by
7011 *     function validateCreditCard which you can find above in this file
7012 */
7013Validation.creditCartTypes = $H({
7014//    'SS': [new RegExp('^((6759[0-9]{12})|(5018|5020|5038|6304|6759|6761|6763[0-9]{12,19})|(49[013][1356][0-9]{12})|(6333[0-9]{12})|(6334[0-4]\d{11})|(633110[0-9]{10})|(564182[0-9]{10}))([0-9]{2,3})?$'), new RegExp('^([0-9]{3}|[0-9]{4})?$'), true],
7015    'SO': [new RegExp('^(6334[5-9]([0-9]{11}|[0-9]{13,14}))|(6767([0-9]{12}|[0-9]{14,15}))$'), new RegExp('^([0-9]{3}|[0-9]{4})?$'), true],
7016    'VI': [new RegExp('^4[0-9]{12}([0-9]{3})?$'), new RegExp('^[0-9]{3}$'), true],
7017    'MC': [new RegExp('^5[1-5][0-9]{14}$'), new RegExp('^[0-9]{3}$'), true],
7018    'AE': [new RegExp('^3[47][0-9]{13}$'), new RegExp('^[0-9]{4}$'), true],
7019    'DI': [new RegExp('^(30[0-5][0-9]{13}|3095[0-9]{12}|35(2[8-9][0-9]{12}|[3-8][0-9]{13})|36[0-9]{12}|3[8-9][0-9]{14}|6011(0[0-9]{11}|[2-4][0-9]{11}|74[0-9]{10}|7[7-9][0-9]{10}|8[6-9][0-9]{10}|9[0-9]{11})|62(2(12[6-9][0-9]{10}|1[3-9][0-9]{11}|[2-8][0-9]{12}|9[0-1][0-9]{11}|92[0-5][0-9]{10})|[4-6][0-9]{13}|8[2-8][0-9]{12})|6(4[4-9][0-9]{13}|5[0-9]{14}))$'), new RegExp('^[0-9]{3}$'), true],
7020    'JCB': [new RegExp('^(30[0-5][0-9]{13}|3095[0-9]{12}|35(2[8-9][0-9]{12}|[3-8][0-9]{13})|36[0-9]{12}|3[8-9][0-9]{14}|6011(0[0-9]{11}|[2-4][0-9]{11}|74[0-9]{10}|7[7-9][0-9]{10}|8[6-9][0-9]{10}|9[0-9]{11})|62(2(12[6-9][0-9]{10}|1[3-9][0-9]{11}|[2-8][0-9]{12}|9[0-1][0-9]{11}|92[0-5][0-9]{10})|[4-6][0-9]{13}|8[2-8][0-9]{12})|6(4[4-9][0-9]{13}|5[0-9]{14}))$'), new RegExp('^[0-9]{3,4}$'), true],
7021    'DICL': [new RegExp('^(30[0-5][0-9]{13}|3095[0-9]{12}|35(2[8-9][0-9]{12}|[3-8][0-9]{13})|36[0-9]{12}|3[8-9][0-9]{14}|6011(0[0-9]{11}|[2-4][0-9]{11}|74[0-9]{10}|7[7-9][0-9]{10}|8[6-9][0-9]{10}|9[0-9]{11})|62(2(12[6-9][0-9]{10}|1[3-9][0-9]{11}|[2-8][0-9]{12}|9[0-1][0-9]{11}|92[0-5][0-9]{10})|[4-6][0-9]{13}|8[2-8][0-9]{12})|6(4[4-9][0-9]{13}|5[0-9]{14}))$'), new RegExp('^[0-9]{3}$'), true],
7022    'SM': [new RegExp('(^(5[0678])[0-9]{11,18}$)|(^(6[^05])[0-9]{11,18}$)|(^(601)[^1][0-9]{9,16}$)|(^(6011)[0-9]{9,11}$)|(^(6011)[0-9]{13,16}$)|(^(65)[0-9]{11,13}$)|(^(65)[0-9]{15,18}$)|(^(49030)[2-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49033)[5-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49110)[1-2]([0-9]{10}$|[0-9]{12,13}$))|(^(49117)[4-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49118)[0-2]([0-9]{10}$|[0-9]{12,13}$))|(^(4936)([0-9]{12}$|[0-9]{14,15}$))'), new RegExp('^([0-9]{3}|[0-9]{4})?$'), true],
7023    'OT': [false, new RegExp('^([0-9]{3}|[0-9]{4})?$'), false]
7024});
7025
7026// script.aculo.us builder.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
7027
7028// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
7029//
7030// script.aculo.us is freely distributable under the terms of an MIT-style license.
7031// For details, see the script.aculo.us web site: http://script.aculo.us/
7032
7033var Builder = {
7034  NODEMAP: {
7035    AREA: 'map',
7036    CAPTION: 'table',
7037    COL: 'table',
7038    COLGROUP: 'table',
7039    LEGEND: 'fieldset',
7040    OPTGROUP: 'select',
7041    OPTION: 'select',
7042    PARAM: 'object',
7043    TBODY: 'table',
7044    TD: 'table',
7045    TFOOT: 'table',
7046    TH: 'table',
7047    THEAD: 'table',
7048    TR: 'table'
7049  },
7050  // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
7051  //       due to a Firefox bug
7052  node: function(elementName) {
7053    elementName = elementName.toUpperCase();
7054
7055    // try innerHTML approach
7056    var parentTag = this.NODEMAP[elementName] || 'div';
7057    var parentElement = document.createElement(parentTag);
7058    try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
7059      parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
7060    } catch(e) {}
7061    var element = parentElement.firstChild || null;
7062
7063    // see if browser added wrapping tags
7064    if(element && (element.tagName.toUpperCase() != elementName))
7065      element = element.getElementsByTagName(elementName)[0];
7066
7067    // fallback to createElement approach
7068    if(!element) element = document.createElement(elementName);
7069
7070    // abort if nothing could be created
7071    if(!element) return;
7072
7073    // attributes (or text)
7074    if(arguments[1])
7075      if(this._isStringOrNumber(arguments[1]) ||
7076        (arguments[1] instanceof Array) ||
7077        arguments[1].tagName) {
7078          this._children(element, arguments[1]);
7079        } else {
7080          var attrs = this._attributes(arguments[1]);
7081          if(attrs.length) {
7082            try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
7083              parentElement.innerHTML = "<" +elementName + " " +
7084                attrs + "></" + elementName + ">";
7085            } catch(e) {}
7086            element = parentElement.firstChild || null;
7087            // workaround firefox 1.0.X bug
7088            if(!element) {
7089              element = document.createElement(elementName);
7090              for(attr in arguments[1])
7091                element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
7092            }
7093            if(element.tagName.toUpperCase() != elementName)
7094              element = parentElement.getElementsByTagName(elementName)[0];
7095          }
7096        }
7097
7098    // text, or array of children
7099    if(arguments[2])
7100      this._children(element, arguments[2]);
7101
7102     return $(element);
7103  },
7104  _text: function(text) {
7105     return document.createTextNode(text);
7106  },
7107
7108  ATTR_MAP: {
7109    'className': 'class',
7110    'htmlFor': 'for'
7111  },
7112
7113  _attributes: function(attributes) {
7114    var attrs = [];
7115    for(attribute in attributes)
7116      attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
7117          '="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'&quot;') + '"');
7118    return attrs.join(" ");
7119  },
7120  _children: function(element, children) {
7121    if(children.tagName) {
7122      element.appendChild(children);
7123      return;
7124    }
7125    if(typeof children=='object') { // array can hold nodes and text
7126      children.flatten().each( function(e) {
7127        if(typeof e=='object')
7128          element.appendChild(e);
7129        else
7130          if(Builder._isStringOrNumber(e))
7131            element.appendChild(Builder._text(e));
7132      });
7133    } else
7134      if(Builder._isStringOrNumber(children))
7135        element.appendChild(Builder._text(children));
7136  },
7137  _isStringOrNumber: function(param) {
7138    return(typeof param=='string' || typeof param=='number');
7139  },
7140  build: function(html) {
7141    var element = this.node('div');
7142    $(element).update(html.strip());
7143    return element.down();
7144  },
7145  dump: function(scope) {
7146    if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope
7147
7148    var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
7149      "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
7150      "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+
7151      "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+
7152      "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
7153      "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
7154
7155    tags.each( function(tag){
7156      scope[tag] = function() {
7157        return Builder.node.apply(Builder, [tag].concat($A(arguments)));
7158      };
7159    });
7160  }
7161};
7162// script.aculo.us effects.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
7163
7164// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
7165// Contributors:
7166//  Justin Palmer (http://encytemedia.com/)
7167//  Mark Pilgrim (http://diveintomark.org/)
7168//  Martin Bialasinki
7169//
7170// script.aculo.us is freely distributable under the terms of an MIT-style license.
7171// For details, see the script.aculo.us web site: http://script.aculo.us/
7172
7173// converts rgb() and #xxx to #xxxxxx format,
7174// returns self (or first argument) if not convertable
7175String.prototype.parseColor = function() {
7176  var color = '#';
7177  if (this.slice(0,4) == 'rgb(') {
7178    var cols = this.slice(4,this.length-1).split(',');
7179    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
7180  } else {
7181    if (this.slice(0,1) == '#') {
7182      if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
7183      if (this.length==7) color = this.toLowerCase();
7184    }
7185  }
7186  return (color.length==7 ? color : (arguments[0] || this));
7187};
7188
7189/*--------------------------------------------------------------------------*/
7190
7191Element.collectTextNodes = function(element) {
7192  return $A($(element).childNodes).collect( function(node) {
7193    return (node.nodeType==3 ? node.nodeValue :
7194      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
7195  }).flatten().join('');
7196};
7197
7198Element.collectTextNodesIgnoreClass = function(element, className) {
7199  return $A($(element).childNodes).collect( function(node) {
7200    return (node.nodeType==3 ? node.nodeValue :
7201      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
7202        Element.collectTextNodesIgnoreClass(node, className) : ''));
7203  }).flatten().join('');
7204};
7205
7206Element.setContentZoom = function(element, percent) {
7207  element = $(element);
7208  element.setStyle({fontSize: (percent/100) + 'em'});
7209  if (Prototype.Browser.WebKit) window.scrollBy(0,0);
7210  return element;
7211};
7212
7213Element.getInlineOpacity = function(element){
7214  return $(element).style.opacity || '';
7215};
7216
7217Element.forceRerendering = function(element) {
7218  try {
7219    element = $(element);
7220    var n = document.createTextNode(' ');
7221    element.appendChild(n);
7222    element.removeChild(n);
7223  } catch(e) { }
7224};
7225
7226/*--------------------------------------------------------------------------*/
7227
7228var Effect = {
7229  _elementDoesNotExistError: {
7230    name: 'ElementDoesNotExistError',
7231    message: 'The specified DOM element does not exist, but is required for this effect to operate'
7232  },
7233  Transitions: {
7234    linear: Prototype.K,
7235    sinoidal: function(pos) {
7236      return (-Math.cos(pos*Math.PI)/2) + .5;
7237    },
7238    reverse: function(pos) {
7239      return 1-pos;
7240    },
7241    flicker: function(pos) {
7242      var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
7243      return pos > 1 ? 1 : pos;
7244    },
7245    wobble: function(pos) {
7246      return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
7247    },
7248    pulse: function(pos, pulses) {
7249      return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
7250    },
7251    spring: function(pos) {
7252      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
7253    },
7254    none: function(pos) {
7255      return 0;
7256    },
7257    full: function(pos) {
7258      return 1;
7259    }
7260  },
7261  DefaultOptions: {
7262    duration:   1.0,   // seconds
7263    fps:        100,   // 100= assume 66fps max.
7264    sync:       false, // true for combining
7265    from:       0.0,
7266    to:         1.0,
7267    delay:      0.0,
7268    queue:      'parallel'
7269  },
7270  tagifyText: function(element) {
7271    var tagifyStyle = 'position:relative';
7272    if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
7273
7274    element = $(element);
7275    $A(element.childNodes).each( function(child) {
7276      if (child.nodeType==3) {
7277        child.nodeValue.toArray().each( function(character) {
7278          element.insertBefore(
7279            new Element('span', {style: tagifyStyle}).update(
7280              character == ' ' ? String.fromCharCode(160) : character),
7281              child);
7282        });
7283        Element.remove(child);
7284      }
7285    });
7286  },
7287  multiple: function(element, effect) {
7288    var elements;
7289    if (((typeof element == 'object') ||
7290        Object.isFunction(element)) &&
7291       (element.length))
7292      elements = element;
7293    else
7294      elements = $(element).childNodes;
7295
7296    var options = Object.extend({
7297      speed: 0.1,
7298      delay: 0.0
7299    }, arguments[2] || { });
7300    var masterDelay = options.delay;
7301
7302    $A(elements).each( function(element, index) {
7303      new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
7304    });
7305  },
7306  PAIRS: {
7307    'slide':  ['SlideDown','SlideUp'],
7308    'blind':  ['BlindDown','BlindUp'],
7309    'appear': ['Appear','Fade']
7310  },
7311  toggle: function(element, effect) {
7312    element = $(element);
7313    effect = (effect || 'appear').toLowerCase();
7314    var options = Object.extend({
7315      queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
7316    }, arguments[2] || { });
7317    Effect[element.visible() ?
7318      Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
7319  }
7320};
7321
7322Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
7323
7324/* ------------- core effects ------------- */
7325
7326Effect.ScopedQueue = Class.create(Enumerable, {
7327  initialize: function() {
7328    this.effects  = [];
7329    this.interval = null;
7330  },
7331  _each: function(iterator) {
7332    this.effects._each(iterator);
7333  },
7334  add: function(effect) {
7335    var timestamp = new Date().getTime();
7336
7337    var position = Object.isString(effect.options.queue) ?
7338      effect.options.queue : effect.options.queue.position;
7339
7340    switch(position) {
7341      case 'front':
7342        // move unstarted effects after this effect
7343        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
7344            e.startOn  += effect.finishOn;
7345            e.finishOn += effect.finishOn;
7346          });
7347        break;
7348      case 'with-last':
7349        timestamp = this.effects.pluck('startOn').max() || timestamp;
7350        break;
7351      case 'end':
7352        // start effect after last queued effect has finished
7353        timestamp = this.effects.pluck('finishOn').max() || timestamp;
7354        break;
7355    }
7356
7357    effect.startOn  += timestamp;
7358    effect.finishOn += timestamp;
7359
7360    if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
7361      this.effects.push(effect);
7362
7363    if (!this.interval)
7364      this.interval = setInterval(this.loop.bind(this), 15);
7365  },
7366  remove: function(effect) {
7367    this.effects = this.effects.reject(function(e) { return e==effect });
7368    if (this.effects.length == 0) {
7369      clearInterval(this.interval);
7370      this.interval = null;
7371    }
7372  },
7373  loop: function() {
7374    var timePos = new Date().getTime();
7375    for(var i=0, len=this.effects.length;i<len;i++)
7376      this.effects[i] && this.effects[i].loop(timePos);
7377  }
7378});
7379
7380Effect.Queues = {
7381  instances: $H(),
7382  get: function(queueName) {
7383    if (!Object.isString(queueName)) return queueName;
7384
7385    return this.instances.get(queueName) ||
7386      this.instances.set(queueName, new Effect.ScopedQueue());
7387  }
7388};
7389Effect.Queue = Effect.Queues.get('global');
7390
7391Effect.Base = Class.create({
7392  position: null,
7393  start: function(options) {
7394    function codeForEvent(options,eventName){
7395      return (
7396        (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
7397        (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
7398      );
7399    }
7400    if (options && options.transition === false) options.transition = Effect.Transitions.linear;
7401    this.options      = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
7402    this.currentFrame = 0;
7403    this.state        = 'idle';
7404    this.startOn      = this.options.delay*1000;
7405    this.finishOn     = this.startOn+(this.options.duration*1000);
7406    this.fromToDelta  = this.options.to-this.options.from;
7407    this.totalTime    = this.finishOn-this.startOn;
7408    this.totalFrames  = this.options.fps*this.options.duration;
7409
7410    this.render = (function() {
7411      function dispatch(effect, eventName) {
7412        if (effect.options[eventName + 'Internal'])
7413          effect.options[eventName + 'Internal'](effect);
7414        if (effect.options[eventName])
7415          effect.options[eventName](effect);
7416      }
7417
7418      return function(pos) {
7419        if (this.state === "idle") {
7420          this.state = "running";
7421          dispatch(this, 'beforeSetup');
7422          if (this.setup) this.setup();
7423          dispatch(this, 'afterSetup');
7424        }
7425        if (this.state === "running") {
7426          pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
7427          this.position = pos;
7428          dispatch(this, 'beforeUpdate');
7429          if (this.update) this.update(pos);
7430          dispatch(this, 'afterUpdate');
7431        }
7432      };
7433    })();
7434
7435    this.event('beforeStart');
7436    if (!this.options.sync)
7437      Effect.Queues.get(Object.isString(this.options.queue) ?
7438        'global' : this.options.queue.scope).add(this);
7439  },
7440  loop: function(timePos) {
7441    if (timePos >= this.startOn) {
7442      if (timePos >= this.finishOn) {
7443        this.render(1.0);
7444        this.cancel();
7445        this.event('beforeFinish');
7446        if (this.finish) this.finish();
7447        this.event('afterFinish');
7448        return;
7449      }
7450      var pos   = (timePos - this.startOn) / this.totalTime,
7451          frame = (pos * this.totalFrames).round();
7452      if (frame > this.currentFrame) {
7453        this.render(pos);
7454        this.currentFrame = frame;
7455      }
7456    }
7457  },
7458  cancel: function() {
7459    if (!this.options.sync)
7460      Effect.Queues.get(Object.isString(this.options.queue) ?
7461        'global' : this.options.queue.scope).remove(this);
7462    this.state = 'finished';
7463  },
7464  event: function(eventName) {
7465    if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
7466    if (this.options[eventName]) this.options[eventName](this);
7467  },
7468  inspect: function() {
7469    var data = $H();
7470    for(property in this)
7471      if (!Object.isFunction(this[property])) data.set(property, this[property]);
7472    return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
7473  }
7474});
7475
7476Effect.Parallel = Class.create(Effect.Base, {
7477  initialize: function(effects) {
7478    this.effects = effects || [];
7479    this.start(arguments[1]);
7480  },
7481  update: function(position) {
7482    this.effects.invoke('render', position);
7483  },
7484  finish: function(position) {
7485    this.effects.each( function(effect) {
7486      effect.render(1.0);
7487      effect.cancel();
7488      effect.event('beforeFinish');
7489      if (effect.finish) effect.finish(position);
7490      effect.event('afterFinish');
7491    });
7492  }
7493});
7494
7495Effect.Tween = Class.create(Effect.Base, {
7496  initialize: function(object, from, to) {
7497    object = Object.isString(object) ? $(object) : object;
7498    var args = $A(arguments), method = args.last(),
7499      options = args.length == 5 ? args[3] : null;
7500    this.method = Object.isFunction(method) ? method.bind(object) :
7501      Object.isFunction(object[method]) ? object[method].bind(object) :
7502      function(value) { object[method] = value };
7503    this.start(Object.extend({ from: from, to: to }, options || { }));
7504  },
7505  update: function(position) {
7506    this.method(position);
7507  }
7508});
7509
7510Effect.Event = Class.create(Effect.Base, {
7511  initialize: function() {
7512    this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
7513  },
7514  update: Prototype.emptyFunction
7515});
7516
7517Effect.Opacity = Class.create(Effect.Base, {
7518  initialize: function(element) {
7519    this.element = $(element);
7520    if (!this.element) throw(Effect._elementDoesNotExistError);
7521    // make this work on IE on elements without 'layout'
7522    if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
7523      this.element.setStyle({zoom: 1});
7524    var options = Object.extend({
7525      from: this.element.getOpacity() || 0.0,
7526      to:   1.0
7527    }, arguments[1] || { });
7528    this.start(options);
7529  },
7530  update: function(position) {
7531    this.element.setOpacity(position);
7532  }
7533});
7534
7535Effect.Move = Class.create(Effect.Base, {
7536  initialize: function(element) {
7537    this.element = $(element);
7538    if (!this.element) throw(Effect._elementDoesNotExistError);
7539    var options = Object.extend({
7540      x:    0,
7541      y:    0,
7542      mode: 'relative'
7543    }, arguments[1] || { });
7544    this.start(options);
7545  },
7546  setup: function() {
7547    this.element.makePositioned();
7548    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
7549    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
7550    if (this.options.mode == 'absolute') {
7551      this.options.x = this.options.x - this.originalLeft;
7552      this.options.y = this.options.y - this.originalTop;
7553    }
7554  },
7555  update: function(position) {
7556    this.element.setStyle({
7557      left: (this.options.x  * position + this.originalLeft).round() + 'px',
7558      top:  (this.options.y  * position + this.originalTop).round()  + 'px'
7559    });
7560  }
7561});
7562
7563// for backwards compatibility
7564Effect.MoveBy = function(element, toTop, toLeft) {
7565  return new Effect.Move(element,
7566    Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
7567};
7568
7569Effect.Scale = Class.create(Effect.Base, {
7570  initialize: function(element, percent) {
7571    this.element = $(element);
7572    if (!this.element) throw(Effect._elementDoesNotExistError);
7573    var options = Object.extend({
7574      scaleX: true,
7575      scaleY: true,
7576      scaleContent: true,
7577      scaleFromCenter: false,
7578      scaleMode: 'box',        // 'box' or 'contents' or { } with provided values
7579      scaleFrom: 100.0,
7580      scaleTo:   percent
7581    }, arguments[2] || { });
7582    this.start(options);
7583  },
7584  setup: function() {
7585    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
7586    this.elementPositioning = this.element.getStyle('position');
7587
7588    this.originalStyle = { };
7589    ['top','left','width','height','fontSize'].each( function(k) {
7590      this.originalStyle[k] = this.element.style[k];
7591    }.bind(this));
7592
7593    this.originalTop  = this.element.offsetTop;
7594    this.originalLeft = this.element.offsetLeft;
7595
7596    var fontSize = this.element.getStyle('font-size') || '100%';
7597    ['em','px','%','pt'].each( function(fontSizeType) {
7598      if (fontSize.indexOf(fontSizeType)>0) {
7599        this.fontSize     = parseFloat(fontSize);
7600        this.fontSizeType = fontSizeType;
7601      }
7602    }.bind(this));
7603
7604    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
7605
7606    this.dims = null;
7607    if (this.options.scaleMode=='box')
7608      this.dims = [this.element.offsetHeight, this.element.offsetWidth];
7609    if (/^content/.test(this.options.scaleMode))
7610      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
7611    if (!this.dims)
7612      this.dims = [this.options.scaleMode.originalHeight,
7613                   this.options.scaleMode.originalWidth];
7614  },
7615  update: function(position) {
7616    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
7617    if (this.options.scaleContent && this.fontSize)
7618      this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
7619    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
7620  },
7621  finish: function(position) {
7622    if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
7623  },
7624  setDimensions: function(height, width) {
7625    var d = { };
7626    if (this.options.scaleX) d.width = width.round() + 'px';
7627    if (this.options.scaleY) d.height = height.round() + 'px';
7628    if (this.options.scaleFromCenter) {
7629      var topd  = (height - this.dims[0])/2;
7630      var leftd = (width  - this.dims[1])/2;
7631      if (this.elementPositioning == 'absolute') {
7632        if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
7633        if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
7634      } else {
7635        if (this.options.scaleY) d.top = -topd + 'px';
7636        if (this.options.scaleX) d.left = -leftd + 'px';
7637      }
7638    }
7639    this.element.setStyle(d);
7640  }
7641});
7642
7643Effect.Highlight = Class.create(Effect.Base, {
7644  initialize: function(element) {
7645    this.element = $(element);
7646    if (!this.element) throw(Effect._elementDoesNotExistError);
7647    var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
7648    this.start(options);
7649  },
7650  setup: function() {
7651    // Prevent executing on elements not in the layout flow
7652    if (this.element.getStyle('display')=='none') { this.cancel(); return; }
7653    // Disable background image during the effect
7654    this.oldStyle = { };
7655    if (!this.options.keepBackgroundImage) {
7656      this.oldStyle.backgroundImage = this.element.getStyle('background-image');
7657      this.element.setStyle({backgroundImage: 'none'});
7658    }
7659    if (!this.options.endcolor)
7660      this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
7661    if (!this.options.restorecolor)
7662      this.options.restorecolor = this.element.getStyle('background-color');
7663    // init color calculations
7664    this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
7665    this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
7666  },
7667  update: function(position) {
7668    this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
7669      return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
7670  },
7671  finish: function() {
7672    this.element.setStyle(Object.extend(this.oldStyle, {
7673      backgroundColor: this.options.restorecolor
7674    }));
7675  }
7676});
7677
7678Effect.ScrollTo = function(element) {
7679  var options = arguments[1] || { },
7680  scrollOffsets = document.viewport.getScrollOffsets(),
7681  elementOffsets = $(element).cumulativeOffset();
7682
7683  if (options.offset) elementOffsets[1] += options.offset;
7684
7685  return new Effect.Tween(null,
7686    scrollOffsets.top,
7687    elementOffsets[1],
7688    options,
7689    function(p){ scrollTo(scrollOffsets.left, p.round()); }
7690  );
7691};
7692
7693/* ------------- combination effects ------------- */
7694
7695Effect.Fade = function(element) {
7696  element = $(element);
7697  var oldOpacity = element.getInlineOpacity();
7698  var options = Object.extend({
7699    from: element.getOpacity() || 1.0,
7700    to:   0.0,
7701    afterFinishInternal: function(effect) {
7702      if (effect.options.to!=0) return;
7703      effect.element.hide().setStyle({opacity: oldOpacity});
7704    }
7705  }, arguments[1] || { });
7706  return new Effect.Opacity(element,options);
7707};
7708
7709Effect.Appear = function(element) {
7710  element = $(element);
7711  var options = Object.extend({
7712  from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
7713  to:   1.0,
7714  // force Safari to render floated elements properly
7715  afterFinishInternal: function(effect) {
7716    effect.element.forceRerendering();
7717  },
7718  beforeSetup: function(effect) {
7719    effect.element.setOpacity(effect.options.from).show();
7720  }}, arguments[1] || { });
7721  return new Effect.Opacity(element,options);
7722};
7723
7724Effect.Puff = function(element) {
7725  element = $(element);
7726  var oldStyle = {
7727    opacity: element.getInlineOpacity(),
7728    position: element.getStyle('position'),
7729    top:  element.style.top,
7730    left: element.style.left,
7731    width: element.style.width,
7732    height: element.style.height
7733  };
7734  return new Effect.Parallel(
7735   [ new Effect.Scale(element, 200,
7736      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
7737     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
7738     Object.extend({ duration: 1.0,
7739      beforeSetupInternal: function(effect) {
7740        Position.absolutize(effect.effects[0].element);
7741      },
7742      afterFinishInternal: function(effect) {
7743         effect.effects[0].element.hide().setStyle(oldStyle); }
7744     }, arguments[1] || { })
7745   );
7746};
7747
7748Effect.BlindUp = function(element) {
7749  element = $(element);
7750  element.makeClipping();
7751  return new Effect.Scale(element, 0,
7752    Object.extend({ scaleContent: false,
7753      scaleX: false,
7754      restoreAfterFinish: true,
7755      afterFinishInternal: function(effect) {
7756        effect.element.hide().undoClipping();
7757      }
7758    }, arguments[1] || { })
7759  );
7760};
7761
7762Effect.BlindDown = function(element) {
7763  element = $(element);
7764  var elementDimensions = element.getDimensions();
7765  return new Effect.Scale(element, 100, Object.extend({
7766    scaleContent: false,
7767    scaleX: false,
7768    scaleFrom: 0,
7769    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
7770    restoreAfterFinish: true,
7771    afterSetup: function(effect) {
7772      effect.element.makeClipping().setStyle({height: '0px'}).show();
7773    },
7774    afterFinishInternal: function(effect) {
7775      effect.element.undoClipping();
7776    }
7777  }, arguments[1] || { }));
7778};
7779
7780Effect.SwitchOff = function(element) {
7781  element = $(element);
7782  var oldOpacity = element.getInlineOpacity();
7783  return new Effect.Appear(element, Object.extend({
7784    duration: 0.4,
7785    from: 0,
7786    transition: Effect.Transitions.flicker,
7787    afterFinishInternal: function(effect) {
7788      new Effect.Scale(effect.element, 1, {
7789        duration: 0.3, scaleFromCenter: true,
7790        scaleX: false, scaleContent: false, restoreAfterFinish: true,
7791        beforeSetup: function(effect) {
7792          effect.element.makePositioned().makeClipping();
7793        },
7794        afterFinishInternal: function(effect) {
7795          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
7796        }
7797      });
7798    }
7799  }, arguments[1] || { }));
7800};
7801
7802Effect.DropOut = function(element) {
7803  element = $(element);
7804  var oldStyle = {
7805    top: element.getStyle('top'),
7806    left: element.getStyle('left'),
7807    opacity: element.getInlineOpacity() };
7808  return new Effect.Parallel(
7809    [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
7810      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
7811    Object.extend(
7812      { duration: 0.5,
7813        beforeSetup: function(effect) {
7814          effect.effects[0].element.makePositioned();
7815        },
7816        afterFinishInternal: function(effect) {
7817          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
7818        }
7819      }, arguments[1] || { }));
7820};
7821
7822Effect.Shake = function(element) {
7823  element = $(element);
7824  var options = Object.extend({
7825    distance: 20,
7826    duration: 0.5
7827  }, arguments[1] || {});
7828  var distance = parseFloat(options.distance);
7829  var split = parseFloat(options.duration) / 10.0;
7830  var oldStyle = {
7831    top: element.getStyle('top'),
7832    left: element.getStyle('left') };
7833    return new Effect.Move(element,
7834      { x:  distance, y: 0, duration: split, afterFinishInternal: function(effect) {
7835    new Effect.Move(effect.element,
7836      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
7837    new Effect.Move(effect.element,
7838      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
7839    new Effect.Move(effect.element,
7840      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
7841    new Effect.Move(effect.element,
7842      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
7843    new Effect.Move(effect.element,
7844      { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
7845        effect.element.undoPositioned().setStyle(oldStyle);
7846  }}); }}); }}); }}); }}); }});
7847};
7848
7849Effect.SlideDown = function(element) {
7850  element = $(element).cleanWhitespace();
7851  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
7852  var oldInnerBottom = element.down().getStyle('bottom');
7853  var elementDimensions = element.getDimensions();
7854  return new Effect.Scale(element, 100, Object.extend({
7855    scaleContent: false,
7856    scaleX: false,
7857    scaleFrom: window.opera ? 0 : 1,
7858    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
7859    restoreAfterFinish: true,
7860    afterSetup: function(effect) {
7861      effect.element.makePositioned();
7862      effect.element.down().makePositioned();
7863      if (window.opera) effect.element.setStyle({top: ''});
7864      effect.element.makeClipping().setStyle({height: '0px'}).show();
7865    },
7866    afterUpdateInternal: function(effect) {
7867      effect.element.down().setStyle({bottom:
7868        (effect.dims[0] - effect.element.clientHeight) + 'px' });
7869    },
7870    afterFinishInternal: function(effect) {
7871      effect.element.undoClipping().undoPositioned();
7872      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
7873    }, arguments[1] || { })
7874  );
7875};
7876
7877Effect.SlideUp = function(element) {
7878  element = $(element).cleanWhitespace();
7879  var oldInnerBottom = element.down().getStyle('bottom');
7880  var elementDimensions = element.getDimensions();
7881  return new Effect.Scale(element, window.opera ? 0 : 1,
7882   Object.extend({ scaleContent: false,
7883    scaleX: false,
7884    scaleMode: 'box',
7885    scaleFrom: 100,
7886    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
7887    restoreAfterFinish: true,
7888    afterSetup: function(effect) {
7889      effect.element.makePositioned();
7890      effect.element.down().makePositioned();
7891      if (window.opera) effect.element.setStyle({top: ''});
7892      effect.element.makeClipping().show();
7893    },
7894    afterUpdateInternal: function(effect) {
7895      effect.element.down().setStyle({bottom:
7896        (effect.dims[0] - effect.element.clientHeight) + 'px' });
7897    },
7898    afterFinishInternal: function(effect) {
7899      effect.element.hide().undoClipping().undoPositioned();
7900      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
7901    }
7902   }, arguments[1] || { })
7903  );
7904};
7905
7906// Bug in opera makes the TD containing this element expand for a instance after finish
7907Effect.Squish = function(element) {
7908  return new Effect.Scale(element, window.opera ? 1 : 0, {
7909    restoreAfterFinish: true,
7910    beforeSetup: function(effect) {
7911      effect.element.makeClipping();
7912    },
7913    afterFinishInternal: function(effect) {
7914      effect.element.hide().undoClipping();
7915    }
7916  });
7917};
7918
7919Effect.Grow = function(element) {
7920  element = $(element);
7921  var options = Object.extend({
7922    direction: 'center',
7923    moveTransition: Effect.Transitions.sinoidal,
7924    scaleTransition: Effect.Transitions.sinoidal,
7925    opacityTransition: Effect.Transitions.full
7926  }, arguments[1] || { });
7927  var oldStyle = {
7928    top: element.style.top,
7929    left: element.style.left,
7930    height: element.style.height,
7931    width: element.style.width,
7932    opacity: element.getInlineOpacity() };
7933
7934  var dims = element.getDimensions();
7935  var initialMoveX, initialMoveY;
7936  var moveX, moveY;
7937
7938  switch (options.direction) {
7939    case 'top-left':
7940      initialMoveX = initialMoveY = moveX = moveY = 0;
7941      break;
7942    case 'top-right':
7943      initialMoveX = dims.width;
7944      initialMoveY = moveY = 0;
7945      moveX = -dims.width;
7946      break;
7947    case 'bottom-left':
7948      initialMoveX = moveX = 0;
7949      initialMoveY = dims.height;
7950      moveY = -dims.height;
7951      break;
7952    case 'bottom-right':
7953      initialMoveX = dims.width;
7954      initialMoveY = dims.height;
7955      moveX = -dims.width;
7956      moveY = -dims.height;
7957      break;
7958    case 'center':
7959      initialMoveX = dims.width / 2;
7960      initialMoveY = dims.height / 2;
7961      moveX = -dims.width / 2;
7962      moveY = -dims.height / 2;
7963      break;
7964  }
7965
7966  return new Effect.Move(element, {
7967    x: initialMoveX,
7968    y: initialMoveY,
7969    duration: 0.01,
7970    beforeSetup: function(effect) {
7971      effect.element.hide().makeClipping().makePositioned();
7972    },
7973    afterFinishInternal: function(effect) {
7974      new Effect.Parallel(
7975        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
7976          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
7977          new Effect.Scale(effect.element, 100, {
7978            scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
7979            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
7980        ], Object.extend({
7981             beforeSetup: function(effect) {
7982               effect.effects[0].element.setStyle({height: '0px'}).show();
7983             },
7984             afterFinishInternal: function(effect) {
7985               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
7986             }
7987           }, options)
7988      );
7989    }
7990  });
7991};
7992
7993Effect.Shrink = function(element) {
7994  element = $(element);
7995  var options = Object.extend({
7996    direction: 'center',
7997    moveTransition: Effect.Transitions.sinoidal,
7998    scaleTransition: Effect.Transitions.sinoidal,
7999    opacityTransition: Effect.Transitions.none
8000  }, arguments[1] || { });
8001  var oldStyle = {
8002    top: element.style.top,
8003    left: element.style.left,
8004    height: element.style.height,
8005    width: element.style.width,
8006    opacity: element.getInlineOpacity() };
8007
8008  var dims = element.getDimensions();
8009  var moveX, moveY;
8010
8011  switch (options.direction) {
8012    case 'top-left':
8013      moveX = moveY = 0;
8014      break;
8015    case 'top-right':
8016      moveX = dims.width;
8017      moveY = 0;
8018      break;
8019    case 'bottom-left':
8020      moveX = 0;
8021      moveY = dims.height;
8022      break;
8023    case 'bottom-right':
8024      moveX = dims.width;
8025      moveY = dims.height;
8026      break;
8027    case 'center':
8028      moveX = dims.width / 2;
8029      moveY = dims.height / 2;
8030      break;
8031  }
8032
8033  return new Effect.Parallel(
8034    [ new Effect.Opacity(elemen
8034t, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
8035      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
8036      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
8037    ], Object.extend({
8038         beforeStartInternal: function(effect) {
8039           effect.effects[0].element.makePositioned().makeClipping();
8040         },
8041         afterFinishInternal: function(effect) {
8042           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
8043       }, options)
8044  );
8045};
8046
8047Effect.Pulsate = function(element) {
8048  element = $(element);
8049  var options    = arguments[1] || { },
8050    oldOpacity = element.getInlineOpacity(),
8051    transition = options.transition || Effect.Transitions.linear,
8052    reverser   = function(pos){
8053      return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
8054    };
8055
8056  return new Effect.Opacity(element,
8057    Object.extend(Object.extend({  duration: 2.0, from: 0,
8058      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
8059    }, options), {transition: reverser}));
8060};
8061
8062Effect.Fold = function(element) {
8063  element = $(element);
8064  var oldStyle = {
8065    top: element.style.top,
8066    left: element.style.left,
8067    width: element.style.width,
8068    height: element.style.height };
8069  element.makeClipping();
8070  return new Effect.Scale(element, 5, Object.extend({
8071    scaleContent: false,
8072    scaleX: false,
8073    afterFinishInternal: function(effect) {
8074    new Effect.Scale(element, 1, {
8075      scaleContent: false,
8076      scaleY: false,
8077      afterFinishInternal: function(effect) {
8078        effect.element.hide().undoClipping().setStyle(oldStyle);
8079      } });
8080  }}, arguments[1] || { }));
8081};
8082
8083Effect.Morph = Class.create(Effect.Base, {
8084  initialize: function(element) {
8085    this.element = $(element);
8086    if (!this.element) throw(Effect._elementDoesNotExistError);
8087    var options = Object.extend({
8088      style: { }
8089    }, arguments[1] || { });
8090
8091    if (!Object.isString(options.style)) this.style = $H(options.style);
8092    else {
8093      if (options.style.include(':'))
8094        this.style = options.style.parseStyle();
8095      else {
8096        this.element.addClassName(options.style);
8097        this.style = $H(this.element.getStyles());
8098        this.element.removeClassName(options.style);
8099        var css = this.element.getStyles();
8100        this.style = this.style.reject(function(style) {
8101          return style.value == css[style.key];
8102        });
8103        options.afterFinishInternal = function(effect) {
8104          effect.element.addClassName(effect.options.style);
8105          effect.transforms.each(function(transform) {
8106            effect.element.style[transform.style] = '';
8107          });
8108        };
8109      }
8110    }
8111    this.start(options);
8112  },
8113
8114  setup: function(){
8115    function parseColor(color){
8116      if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
8117      color = color.parseColor();
8118      return $R(0,2).map(function(i){
8119        return parseInt( color.slice(i*2+1,i*2+3), 16 );
8120      });
8121    }
8122    this.transforms = this.style.map(function(pair){
8123      var property = pair[0], value = pair[1], unit = null;
8124
8125      if (value.parseColor('#zzzzzz') != '#zzzzzz') {
8126        value = value.parseColor();
8127        unit  = 'color';
8128      } else if (property == 'opacity') {
8129        value = parseFloat(value);
8130        if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
8131          this.element.setStyle({zoom: 1});
8132      } else if (Element.CSS_LENGTH.test(value)) {
8133          var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
8134          value = parseFloat(components[1]);
8135          unit = (components.length == 3) ? components[2] : null;
8136      }
8137
8138      var originalValue = this.element.getStyle(property);
8139      return {
8140        style: property.camelize(),
8141        originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
8142        targetValue: unit=='color' ? parseColor(value) : value,
8143        unit: unit
8144      };
8145    }.bind(this)).reject(function(transform){
8146      return (
8147        (transform.originalValue == transform.targetValue) ||
8148        (
8149          transform.unit != 'color' &&
8150          (isNaN(transform.originalValue) || isNaN(transform.targetValue))
8151        )
8152      );
8153    });
8154  },
8155  update: function(position) {
8156    var style = { }, transform, i = this.transforms.length;
8157    while(i--)
8158      style[(transform = this.transforms[i]).style] =
8159        transform.unit=='color' ? '#'+
8160          (Math.round(transform.originalValue[0]+
8161            (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
8162          (Math.round(transform.originalValue[1]+
8163            (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
8164          (Math.round(transform.originalValue[2]+
8165            (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
8166        (transform.originalValue +
8167          (transform.targetValue - transform.originalValue) * position).toFixed(3) +
8168            (transform.unit === null ? '' : transform.unit);
8169    this.element.setStyle(style, true);
8170  }
8171});
8172
8173Effect.Transform = Class.create({
8174  initialize: function(tracks){
8175    this.tracks  = [];
8176    this.options = arguments[1] || { };
8177    this.addTracks(tracks);
8178  },
8179  addTracks: function(tracks){
8180    tracks.each(function(track){
8181      track = $H(track);
8182      var data = track.values().first();
8183      this.tracks.push($H({
8184        ids:     track.keys().first(),
8185        effect:  Effect.Morph,
8186        options: { style: data }
8187      }));
8188    }.bind(this));
8189    return this;
8190  },
8191  play: function(){
8192    return new Effect.Parallel(
8193      this.tracks.map(function(track){
8194        var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
8195        var elements = [$(ids) || $$(ids)].flatten();
8196        return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
8197      }).flatten(),
8198      this.options
8199    );
8200  }
8201});
8202
8203Element.CSS_PROPERTIES = $w(
8204  'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
8205  'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
8206  'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
8207  'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
8208  'fontSize fontWeight height left letterSpacing lineHeight ' +
8209  'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
8210  'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
8211  'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
8212  'right textIndent top width wordSpacing zIndex');
8213
8214Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
8215
8216String.__parseStyleElement = document.createElement('div');
8217String.prototype.parseStyle = function(){
8218  var style, styleRules = $H();
8219  if (Prototype.Browser.WebKit)
8220    style = new Element('div',{style:this}).style;
8221  else {
8222    String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
8223    style = String.__parseStyleElement.childNodes[0].style;
8224  }
8225
8226  Element.CSS_PROPERTIES.each(function(property){
8227    if (style[property]) styleRules.set(property, style[property]);
8228  });
8229
8230  if (Prototype.Browser.IE && this.include('opacity'))
8231    styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
8232
8233  return styleRules;
8234};
8235
8236if (document.defaultView && document.defaultView.getComputedStyle) {
8237  Element.getStyles = function(element) {
8238    var css = document.defaultView.getComputedStyle($(element), null);
8239    return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
8240      styles[property] = css[property];
8241      return styles;
8242    });
8243  };
8244} else {
8245  Element.getStyles = function(element) {
8246    element = $(element);
8247    var css = element.currentStyle, styles;
8248    styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
8249      results[property] = css[property];
8250      return results;
8251    });
8252    if (!styles.opacity) styles.opacity = element.getOpacity();
8253    return styles;
8254  };
8255}
8256
8257Effect.Methods = {
8258  morph: function(element, style) {
8259    element = $(element);
8260    new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
8261    return element;
8262  },
8263  visualEffect: function(element, effect, options) {
8264    element = $(element);
8265    var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
8266    new Effect[klass](element, options);
8267    return element;
8268  },
8269  highlight: function(element, options) {
8270    element = $(element);
8271    new Effect.Highlight(element, options);
8272    return element;
8273  }
8274};
8275
8276$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
8277  'pulsate shake puff squish switchOff dropOut').each(
8278  function(effect) {
8279    Effect.Methods[effect] = function(element, options){
8280      element = $(element);
8281      Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
8282      return element;
8283    };
8284  }
8285);
8286
8287$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
8288  function(f) { Effect.Methods[f] = Element[f]; }
8289);
8290
8291Element.addMethods(Effect.Methods);
8292// script.aculo.us dragdrop.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
8293
8294// Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
8295//
8296// script.aculo.us is freely distributable under the terms of an MIT-style license.
8297// For details, see the script.aculo.us web site: http://script.aculo.us/
8298
8299if(Object.isUndefined(Effect))
8300  throw("dragdrop.js requires including script.aculo.us' effects.js library");
8301
8302var Droppables = {
8303  drops: [],
8304
8305  remove: function(element) {
8306    this.drops = this.drops.reject(function(d) { return d.element==$(element) });
8307  },
8308
8309  add: function(element) {
8310    element = $(element);
8311    var options = Object.extend({
8312      greedy:     true,
8313      hoverclass: null,
8314      tree:       false
8315    }, arguments[1] || { });
8316
8317    // cache containers
8318    if(options.containment) {
8319      options._containers = [];
8320      var containment = options.containment;
8321      if(Object.isArray(containment)) {
8322        containment.each( function(c) { options._containers.push($(c)) });
8323      } else {
8324        options._containers.push($(containment));
8325      }
8326    }
8327
8328    if(options.accept) options.accept = [options.accept].flatten();
8329
8330    Element.makePositioned(element); // fix IE
8331    options.element = element;
8332
8333    this.drops.push(options);
8334  },
8335
8336  findDeepestChild: function(drops) {
8337    deepest = drops[0];
8338
8339    for (i = 1; i < drops.length; ++i)
8340      if (Element.isParent(drops[i].element, deepest.element))
8341        deepest = drops[i];
8342
8343    return deepest;
8344  },
8345
8346  isContained: function(element, drop) {
8347    var containmentNode;
8348    if(drop.tree) {
8349      containmentNode = element.treeNode;
8350    } else {
8351      containmentNode = element.parentNode;
8352    }
8353    return drop._containers.detect(function(c) { return containmentNode == c });
8354  },
8355
8356  isAffected: function(point, element, drop) {
8357    return (
8358      (drop.element!=element) &&
8359      ((!drop._containers) ||
8360        this.isContained(element, drop)) &&
8361      ((!drop.accept) ||
8362        (Element.classNames(element).detect(
8363          function(v) { return drop.accept.include(v) } ) )) &&
8364      Position.within(drop.element, point[0], point[1]) );
8365  },
8366
8367  deactivate: function(drop) {
8368    if(drop.hoverclass)
8369      Element.removeClassName(drop.element, drop.hoverclass);
8370    this.last_active = null;
8371  },
8372
8373  activate: function(drop) {
8374    if(drop.hoverclass)
8375      Element.addClassName(drop.element, drop.hoverclass);
8376    this.last_active = drop;
8377  },
8378
8379  show: function(point, element) {
8380    if(!this.drops.length) return;
8381    var drop, affected = [];
8382
8383    this.drops.each( function(drop) {
8384      if(Droppables.isAffected(point, element, drop))
8385        affected.push(drop);
8386    });
8387
8388    if(affected.length>0)
8389      drop = Droppables.findDeepestChild(affected);
8390
8391    if(this.last_active && this.last_active != drop) this.deactivate(this.last_active);
8392    if (drop) {
8393      Position.within(drop.element, point[0], point[1]);
8394      if(drop.onHover)
8395        drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
8396
8397      if (drop != this.last_active) Droppables.activate(drop);
8398    }
8399  },
8400
8401  fire: function(event, element) {
8402    if(!this.last_active) return;
8403    Position.prepare();
8404
8405    if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
8406      if (this.last_active.onDrop) {
8407        this.last_active.onDrop(element, this.last_active.element, event);
8408        return true;
8409      }
8410  },
8411
8412  reset: function() {
8413    if(this.last_active)
8414      this.deactivate(this.last_active);
8415  }
8416};
8417
8418var Draggables = {
8419  drags: [],
8420  observers: [],
8421
8422  register: function(draggable) {
8423    if(this.drags.length == 0) {
8424      this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
8425      this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
8426      this.eventKeypress  = this.keyPress.bindAsEventListener(this);
8427
8428      Event.observe(document, "mouseup", this.eventMouseUp);
8429      Event.observe(document, "mousemove", this.eventMouseMove);
8430      Event.observe(document, "keypress", this.eventKeypress);
8431    }
8432    this.drags.push(draggable);
8433  },
8434
8435  unregister: function(draggable) {
8436    this.drags = this.drags.reject(function(d) { return d==draggable });
8437    if(this.drags.length == 0) {
8438      Event.stopObserving(document, "mouseup", this.eventMouseUp);
8439      Event.stopObserving(document, "mousemove", this.eventMouseMove);
8440      Event.stopObserving(document, "keypress", this.eventKeypress);
8441    }
8442  },
8443
8444  activate: function(draggable) {
8445    if(draggable.options.delay) {
8446      this._timeout = setTimeout(function() {
8447        Draggables._timeout = null;
8448        window.focus();
8449        Draggables.activeDraggable = draggable;
8450      }.bind(this), draggable.options.delay);
8451    } else {
8452      window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
8453      this.activeDraggable = draggable;
8454    }
8455  },
8456
8457  deactivate: function() {
8458    this.activeDraggable = null;
8459  },
8460
8461  updateDrag: function(event) {
8462    if(!this.activeDraggable) return;
8463    var pointer = [Event.pointerX(event), Event.pointerY(event)];
8464    // Mozilla-based browsers fire successive mousemove events with
8465    // the same coordinates, prevent needless redrawing (moz bug?)
8466    if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
8467    this._lastPointer = pointer;
8468
8469    this.activeDraggable.updateDrag(event, pointer);
8470  },
8471
8472  endDrag: function(event) {
8473    if(this._timeout) {
8474      clearTimeout(this._timeout);
8475      this._timeout = null;
8476    }
8477    if(!this.activeDraggable) return;
8478    this._lastPointer = null;
8479    this.activeDraggable.endDrag(event);
8480    this.activeDraggable = null;
8481  },
8482
8483  keyPress: function(event) {
8484    if(this.activeDraggable)
8485      this.activeDraggable.keyPress(event);
8486  },
8487
8488  addObserver: function(observer) {
8489    this.observers.push(observer);
8490    this._cacheObserverCallbacks();
8491  },
8492
8493  removeObserver: function(element) {  // element instead of observer fixes mem leaks
8494    this.observers = this.observers.reject( function(o) { return o.element==element });
8495    this._cacheObserverCallbacks();
8496  },
8497
8498  notify: function(eventName, draggable, event) {  // 'onStart', 'onEnd', 'onDrag'
8499    if(this[eventName+'Count'] > 0)
8500      this.observers.each( function(o) {
8501        if(o[eventName]) o[eventName](eventName, draggable, event);
8502      });
8503    if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
8504  },
8505
8506  _cacheObserverCallbacks: function() {
8507    ['onStart','onEnd','onDrag'].each( function(eventName) {
8508      Draggables[eventName+'Count'] = Draggables.observers.select(
8509        function(o) { return o[eventName]; }
8510      ).length;
8511    });
8512  }
8513};
8514
8515/*--------------------------------------------------------------------------*/
8516
8517var Draggable = Class.create({
8518  initialize: function(element) {
8519    var defaults = {
8520      handle: false,
8521      reverteffect: function(element, top_offset, left_offset) {
8522        var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
8523        new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
8524          queue: {scope:'_draggable', position:'end'}
8525        });
8526      },
8527      endeffect: function(element) {
8528        var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
8529        new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
8530          queue: {scope:'_draggable', position:'end'},
8531          afterFinish: function(){
8532            Draggable._dragging[element] = false
8533          }
8534        });
8535      },
8536      zindex: 1000,
8537      revert: false,
8538      quiet: false,
8539      scroll: false,
8540      scrollSensitivity: 20,
8541      scrollSpeed: 15,
8542      snap: false,  // false, or xy or [x,y] or function(x,y){ return [x,y] }
8543      delay: 0
8544    };
8545
8546    if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
8547      Object.extend(defaults, {
8548        starteffect: function(element) {
8549          element._opacity = Element.getOpacity(element);
8550          Draggable._dragging[element] = true;
8551          new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
8552        }
8553      });
8554
8555    var options = Object.extend(defaults, arguments[1] || { });
8556
8557    this.element = $(element);
8558
8559    if(options.handle && Object.isString(options.handle))
8560      this.handle = this.element.down('.'+options.handle, 0);
8561
8562    if(!this.handle) this.handle = $(options.handle);
8563    if(!this.handle) this.handle = this.element;
8564
8565    if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
8566      options.scroll = $(options.scroll);
8567      this._isScrollChild = Element.childOf(this.element, options.scroll);
8568    }
8569
8570    Element.makePositioned(this.element); // fix IE
8571
8572    this.options  = options;
8573    this.dragging = false;
8574
8575    this.eventMouseDown = this.initDrag.bindAsEventListener(this);
8576    Event.observe(this.handle, "mousedown", this.eventMouseDown);
8577
8578    Draggables.register(this);
8579  },
8580
8581  destroy: function() {
8582    Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
8583    Draggables.unregister(this);
8584  },
8585
8586  currentDelta: function() {
8587    return([
8588      parseInt(Element.getStyle(this.element,'left') || '0'),
8589      parseInt(Element.getStyle(this.element,'top') || '0')]);
8590  },
8591
8592  initDrag: function(event) {
8593    if(!Object.isUndefined(Draggable._dragging[this.element]) &&
8594      Draggable._dragging[this.element]) return;
8595    if(Event.isLeftClick(event)) {
8596      // abort on form elements, fixes a Firefox issue
8597      var src = Event.element(event);
8598      if((tag_name = src.tagName.toUpperCase()) && (
8599        tag_name=='INPUT' ||
8600        tag_name=='SELECT' ||
8601        tag_name=='OPTION' ||
8602        tag_name=='BUTTON' ||
8603        tag_name=='TEXTAREA')) return;
8604
8605      var pointer = [Event.pointerX(event), Event.pointerY(event)];
8606      var pos     = this.element.cumulativeOffset();
8607      this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
8608
8609      Draggables.activate(this);
8610      Event.stop(event);
8611    }
8612  },
8613
8614  startDrag: function(event) {
8615    this.dragging = true;
8616    if(!this.delta)
8617      this.delta = this.currentDelta();
8618
8619    if(this.options.zindex) {
8620      this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
8621      this.element.style.zIndex = this.options.zindex;
8622    }
8623
8624    if(this.options.ghosting) {
8625      this._clone = this.element.cloneNode(true);
8626      this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
8627      if (!this._originallyAbsolute)
8628        Position.absolutize(this.element);
8629      this.element.parentNode.insertBefore(this._clone, this.element);
8630    }
8631
8632    if(this.options.scroll) {
8633      if (this.options.scroll == window) {
8634        var where = this._getWindowScroll(this.options.scroll);
8635        this.originalScrollLeft = where.left;
8636        this.originalScrollTop = where.top;
8637      } else {
8638        this.originalScrollLeft = this.options.scroll.scrollLeft;
8639        this.originalScrollTop = this.options.scroll.scrollTop;
8640      }
8641    }
8642
8643    Draggables.notify('onStart', this, event);
8644
8645    if(this.options.starteffect) this.options.starteffect(this.element);
8646  },
8647
8648  updateDrag: function(event, pointer) {
8649    if(!this.dragging) this.startDrag(event);
8650
8651    if(!this.options.quiet){
8652      Position.prepare();
8653      Droppables.show(pointer, this.element);
8654    }
8655
8656    Draggables.notify('onDrag', this, event);
8657
8658    this.draw(pointer);
8659    if(this.options.change) this.options.change(this);
8660
8661    if(this.options.scroll) {
8662      this.stopScrolling();
8663
8664      var p;
8665      if (this.options.scroll == window) {
8666        with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
8667      } else {
8668        p = Position.page(this.options.scroll).toArray();
8669        p[0] += this.options.scroll.scrollLeft + Position.deltaX;
8670        p[1] += this.options.scroll.scrollTop + Position.deltaY;
8671        p.push(p[0]+this.options.scroll.offsetWidth);
8672        p.push(p[1]+this.options.scroll.offsetHeight);
8673      }
8674      var speed = [0,0];
8675      if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
8676      if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
8677      if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
8678      if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
8679      this.startScrolling(speed);
8680    }
8681
8682    // fix AppleWebKit rendering
8683    if(Prototype.Browser.WebKit) window.scrollBy(0,0);
8684
8685    Event.stop(event);
8686  },
8687
8688  finishDrag: function(event, success) {
8689    this.dragging = false;
8690
8691    if(this.options.quiet){
8692      Position.prepare();
8693      var pointer = [Event.pointerX(event), Event.pointerY(event)];
8694      Droppables.show(pointer, this.element);
8695    }
8696
8697    if(this.options.ghosting) {
8698      if (!this._originallyAbsolute)
8699        Position.relativize(this.element);
8700      delete this._originallyAbsolute;
8701      Element.remove(this._clone);
8702      this._clone = null;
8703    }
8704
8705    var dropped = false;
8706    if(success) {
8707      dropped = Droppables.fire(event, this.element);
8708      if (!dropped) dropped = false;
8709    }
8710    if(dropped && this.options.onDropped) this.options.onDropped(this.element);
8711    Draggables.notify('onEnd', this, event);
8712
8713    var revert = this.options.revert;
8714    if(revert && Object.isFunction(revert)) revert = revert(this.element);
8715
8716    var d = this.currentDelta();
8717    if(revert && this.options.reverteffect) {
8718      if (dropped == 0 || revert != 'failure')
8719        this.options.reverteffect(this.element,
8720          d[1]-this.delta[1], d[0]-this.delta[0]);
8721    } else {
8722      this.delta = d;
8723    }
8724
8725    if(this.options.zindex)
8726      this.element.style.zIndex = this.originalZ;
8727
8728    if(this.options.endeffect)
8729      this.options.endeffect(this.element);
8730
8731    Draggables.deactivate(this);
8732    Droppables.reset();
8733  },
8734
8735  keyPress: function(event) {
8736    if(event.keyCode!=Event.KEY_ESC) return;
8737    this.finishDrag(event, false);
8738    Event.stop(event);
8739  },
8740
8741  endDrag: function(event) {
8742    if(!this.dragging) return;
8743    this.stopScrolling();
8744    this.finishDrag(event, true);
8745    Event.stop(event);
8746  },
8747
8748  draw: function(point) {
8749    var pos = this.element.cumulativeOffset();
8750    if(this.options.ghosting) {
8751      var r   = Position.realOffset(this.element);
8752      pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
8753    }
8754
8755    var d = this.currentDelta();
8756    pos[0] -= d[0]; pos[1] -= d[1];
8757
8758    if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
8759      pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
8760      pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
8761    }
8762
8763    var p = [0,1].map(function(i){
8764      return (point[i]-pos[i]-this.offset[i])
8765    }.bind(this));
8766
8767    if(this.options.snap) {
8768      if(Object.isFunction(this.options.snap)) {
8769        p = this.options.snap(p[0],p[1],this);
8770      } else {
8771      if(Object.isArray(this.options.snap)) {
8772        p = p.map( function(v, i) {
8773          return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
8774      } else {
8775        p = p.map( function(v) {
8776          return (v/this.options.snap).round()*this.options.snap }.bind(this));
8777      }
8778    }}
8779
8780    var style = this.element.style;
8781    if((!this.options.constraint) || (this.options.constraint=='horizontal'))
8782      style.left = p[0] + "px";
8783    if((!this.options.constraint) || (this.options.constraint=='vertical'))
8784      style.top  = p[1] + "px";
8785
8786    if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
8787  },
8788
8789  stopScrolling: function() {
8790    if(this.scrollInterval) {
8791      clearInterval(this.scrollInterval);
8792      this.scrollInterval = null;
8793      Draggables._lastScrollPointer = null;
8794    }
8795  },
8796
8797  startScrolling: function(speed) {
8798    if(!(speed[0] || speed[1])) return;
8799    this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
8800    this.lastScrolled = new Date();
8801    this.scrollInterval = setInterval(this.scroll.bind(this), 10);
8802  },
8803
8804  scroll: function() {
8805    var current = new Date();
8806    var delta = current - this.lastScrolled;
8807    this.lastScrolled = current;
8808    if(this.options.scroll == window) {
8809      with (this._getWindowScroll(this.options.scroll)) {
8810        if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
8811          var d = delta / 1000;
8812          this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
8813        }
8814      }
8815    } else {
8816      this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
8817      this.options.scroll.scrollTop  += this.scrollSpeed[1] * delta / 1000;
8818    }
8819
8820    Position.prepare();
8821    Droppables.show(Draggables._lastPointer, this.element);
8822    Draggables.notify('onDrag', this);
8823    if (this._isScrollChild) {
8824      Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
8825      Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
8826      Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
8827      if (Draggables._lastScrollPointer[0] < 0)
8828        Draggables._lastScrollPointer[0] = 0;
8829      if (Draggables._lastScrollPointer[1] < 0)
8830        Draggables._lastScrollPointer[1] = 0;
8831      this.draw(Draggables._lastScrollPointer);
8832    }
8833
8834    if(this.options.change) this.options.change(this);
8835  },
8836
8837  _getWindowScroll: function(w) {
8838    var T, L, W, H;
8839    with (w.document) {
8840      if (w.document.documentElement && documentElement.scrollTop) {
8841        T = documentElement.scrollTop;
8842        L = documentElement.scrollLeft;
8843      } else if (w.document.body) {
8844        T = body.scrollTop;
8845        L = body.scrollLeft;
8846      }
8847      if (w.innerWidth) {
8848        W = w.innerWidth;
8849        H = w.innerHeight;
8850      } else if (w.document.documentElement && documentElement.clientWidth) {
8851        W = documentElement.clientWidth;
8852        H = documentElement.clientHeight;
8853      } else {
8854        W = body.offsetWidth;
8855        H = body.offsetHeight;
8856      }
8857    }
8858    return { top: T, left: L, width: W, height: H };
8859  }
8860});
8861
8862Draggable._dragging = { };
8863
8864/*--------------------------------------------------------------------------*/
8865
8866var SortableObserver = Class.create({
8867  initialize: function(element, observer) {
8868    this.element   = $(element);
8869    this.observer  = observer;
8870    this.lastValue = Sortable.serialize(this.element);
8871  },
8872
8873  onStart: function() {
8874    this.lastValue = Sortable.serialize(this.element);
8875  },
8876
8877  onEnd: function() {
8878    Sortable.unmark();
8879    if(this.lastValue != Sortable.serialize(this.element))
8880      this.observer(this.element)
8881  }
8882});
8883
8884var Sortable = {
8885  SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
8886
8887  sortables: { },
8888
8889  _findRootElement: function(element) {
8890    while (element.tagName.toUpperCase() != "BODY") {
8891      if(element.id && Sortable.sortables[element.id]) return element;
8892      element = element.parentNode;
8893    }
8894  },
8895
8896  options: function(element) {
8897    element = Sortable._findRootElement($(element));
8898    if(!element) return;
8899    return Sortable.sortables[element.id];
8900  },
8901
8902  destroy: function(element){
8903    element = $(element);
8904    var s = Sortable.sortables[element.id];
8905
8906    if(s) {
8907      Draggables.removeObserver(s.element);
8908      s.droppables.each(function(d){ Droppables.remove(d) });
8909      s.draggables.invoke('destroy');
8910
8911      delete Sortable.sortables[s.element.id];
8912    }
8913  },
8914
8915  create: function(element) {
8916    element = $(element);
8917    var options = Object.extend({
8918      element:     element,
8919      tag:         'li',       // assumes li children, override with tag: 'tagname'
8920      dropOnEmpty: false,
8921      tree:        false,
8922      treeTag:     'ul',
8923      overlap:     'vertical', // one of 'vertical', 'horizontal'
8924      constraint:  'vertical', // one of 'vertical', 'horizontal', false
8925      containment: element,    // also takes array of elements (or id's); or false
8926      handle:      false,      // or a CSS class
8927      only:        false,
8928      delay:       0,
8929      hoverclass:  null,
8930      ghosting:    false,
8931      quiet:       false,
8932      scroll:      false,
8933      scrollSensitivity: 20,
8934      scrollSpeed: 15,
8935      format:      this.SERIALIZE_RULE,
8936
8937      // these take arrays of elements or ids and can be
8938      // used for better initialization performance
8939      elements:    false,
8940      handles:     false,
8941
8942      onChange:    Prototype.emptyFunction,
8943      onUpdate:    Prototype.emptyFunction
8944    }, arguments[1] || { });
8945
8946    // clear any old sortable with same element
8947    this.destroy(element);
8948
8949    // build options for the draggables
8950    var options_for_draggable = {
8951      revert:      true,
8952      quiet:       options.quiet,
8953      scroll:      options.scroll,
8954      scrollSpeed: options.scrollSpeed,
8955      scrollSensitivity: options.scrollSensitivity,
8956      delay:       options.delay,
8957      ghosting:    options.ghosting,
8958      constraint:  options.constraint,
8959      handle:      options.handle };
8960
8961    if(options.starteffect)
8962      options_for_draggable.starteffect = options.starteffect;
8963
8964    if(options.reverteffect)
8965      options_for_draggable.reverteffect = options.reverteffect;
8966    else
8967      if(options.ghosting) options_for_draggable.reverteffect = function(element) {
8968        element.style.top  = 0;
8969        element.style.left = 0;
8970      };
8971
8972    if(options.endeffect)
8973      options_for_draggable.endeffect = options.endeffect;
8974
8975    if(options.zindex)
8976      options_for_draggable.zindex = options.zindex;
8977
8978    // build options for the droppables
8979    var options_for_droppable = {
8980      overlap:     options.overlap,
8981      containment: options.containment,
8982      tree:        options.tree,
8983      hoverclass:  options.hoverclass,
8984      onHover:     Sortable.onHover
8985    };
8986
8987    var options_for_tree = {
8988      onHover:      Sortable.onEmptyHover,
8989      overlap:      options.overlap,
8990      containment:  options.containment,
8991      hoverclass:   options.hoverclass
8992    };
8993
8994    // fix for gecko engine
8995    Element.cleanWhitespace(element);
8996
8997    options.draggables = [];
8998    options.droppables = [];
8999
9000    // drop on empty handling
9001    if(options.dropOnEmpty || options.tree) {
9002      Droppables.add(element, options_for_tree);
9003      options.droppables.push(element);
9004    }
9005
9006    (options.elements || this.findElements(element, options) || []).each( function(e,i) {
9007      var handle = options.handles ? $(options.handles[i]) :
9008        (options.handle ? $(e).select('.' + options.handle)[0] : e);
9009      options.draggables.push(
9010        new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
9011      Droppables.add(e, options_for_droppable);
9012      if(options.tree) e.treeNode = element;
9013      options.droppables.push(e);
9014    });
9015
9016    if(options.tree) {
9017      (Sortable.findTreeElements(element, options) || []).each( function(e) {
9018        Droppables.add(e, options_for_tree);
9019        e.treeNode = element;
9020        options.droppables.push(e);
9021      });
9022    }
9023
9024    // keep reference
9025    this.sortables[element.identify()] = options;
9026
9027    // for onupdate
9028    Draggables.addObserver(new SortableObserver(element, options.onUpdate));
9029
9030  },
9031
9032  // return all suitable-for-sortable elements in a guaranteed order
9033  findElements: function(element, options) {
9034    return Element.findChildren(
9035      element, options.only, options.tree ? true : false, options.tag);
9036  },
9037
9038  findTreeElements: function(element, options) {
9039    return Element.findChildren(
9040      element, options.only, options.tree ? true : false, options.treeTag);
9041  },
9042
9043  onHover: function(element, dropon, overlap) {
9044    if(Element.isParent(dropon, element)) return;
9045
9046    if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
9047      return;
9048    } else if(overlap>0.5) {
9049      Sortable.mark(dropon, 'before');
9050      if(dropon.previousSibling != element) {
9051        var oldParentNode = element.parentNode;
9052        element.style.visibility = "hidden"; // fix gecko rendering
9053        dropon.parentNode.insertBefore(element, dropon);
9054        if(dropon.parentNode!=oldParentNode)
9055          Sortable.options(oldParentNode).onChange(element);
9056        Sortable.options(dropon.parentNode).onChange(element);
9057      }
9058    } else {
9059      Sortable.mark(dropon, 'after');
9060      var nextElement = dropon.nextSibling || null;
9061      if(nextElement != element) {
9062        var oldParentNode = element.parentNode;
9063        element.style.visibility = "hidden"; // fix gecko rendering
9064        dropon.parentNode.insertBefore(element, nextElement);
9065        if(dropon.parentNode!=oldParentNode)
9066          Sortable.options(oldParentNode).onChange(element);
9067        Sortable.options(dropon.parentNode).onChange(element);
9068      }
9069    }
9070  },
9071
9072  onEmptyHover: function(element, dropon, overlap) {
9073    var oldParentNode = element.parentNode;
9074    var droponOptions = Sortable.options(dropon);
9075
9076    if(!Element.isParent(dropon, element)) {
9077      var index;
9078
9079      var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
9080      var child = null;
9081
9082      if(children) {
9083        var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
9084
9085        for (index = 0; index < children.length; index += 1) {
9086          if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
9087            offset -= Element.offsetSize (children[index], droponOptions.overlap);
9088          } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
9089            child = index + 1 < children.length ? children[index + 1] : null;
9090            break;
9091          } else {
9092            child = children[index];
9093            break;
9094          }
9095        }
9096      }
9097
9098      dropon.insertBefore(element, child);
9099
9100      Sortable.options(oldParentNode).onChange(element);
9101      droponOptions.onChange(element);
9102    }
9103  },
9104
9105  unmark: function() {
9106    if(Sortable._marker) Sortable._marker.hide();
9107  },
9108
9109  mark: function(dropon, position) {
9110    // mark on ghosting only
9111    var sortable = Sortable.options(dropon.parentNode);
9112    if(sortable && !sortable.ghosting) return;
9113
9114    if(!Sortable._marker) {
9115      Sortable._marker =
9116        ($('dropmarker') || Element.extend(document.createElement('DIV'))).
9117          hide().addClassName('dropmarker').setStyle({position:'absolute'});
9118      document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
9119    }
9120    var offsets = dropon.cumulativeOffset();
9121    Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
9122
9123    if(position=='after')
9124      if(sortable.overlap == 'horizontal')
9125        Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
9126      else
9127        Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
9128
9129    Sortable._marker.show();
9130  },
9131
9132  _tree: function(element, options, parent) {
9133    var children = Sortable.findElements(element, options) || [];
9134
9135    for (var i = 0; i < children.length; ++i) {
9136      var match = children[i].id.match(options.format);
9137
9138      if (!match) continue;
9139
9140      var child = {
9141        id: encodeURIComponent(match ? match[1] : null),
9142        element: element,
9143        parent: parent,
9144        children: [],
9145        position: parent.children.length,
9146        container: $(children[i]).down(options.treeTag)
9147      };
9148
9149      /* Get the element containing the children and recurse over it */
9150      if (child.container)
9151        this._tree(child.container, options, child);
9152
9153      parent.children.push (child);
9154    }
9155
9156    return parent;
9157  },
9158
9159  tree: function(element) {
9160    element = $(element);
9161    var sortableOptions = this.options(element);
9162    var options = Object.extend({
9163      tag: sortableOptions.tag,
9164      treeTag: sortableOptions.treeTag,
9165      only: sortableOptions.only,
9166      name: element.id,
9167      format: sortableOptions.format
9168    }, arguments[1] || { });
9169
9170    var root = {
9171      id: null,
9172      parent: null,
9173      children: [],
9174      container: element,
9175      position: 0
9176    };
9177
9178    return Sortable._tree(element, options, root);
9179  },
9180
9181  /* Construct a [i] index for a particular node */
9182  _constructIndex: function(node) {
9183    var index = '';
9184    do {
9185      if (node.id) index = '[' + node.position + ']' + index;
9186    } while ((node = node.parent) != null);
9187    return index;
9188  },
9189
9190  sequence: function(element) {
9191    element = $(element);
9192    var options = Object.extend(this.options(element), arguments[1] || { });
9193
9194    return $(this.findElements(element, options) || []).map( function(item) {
9195      return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
9196    });
9197  },
9198
9199  setSequence: function(element, new_sequence) {
9200    element = $(element);
9201    var options = Object.extend(this.options(element), arguments[2] || { });
9202
9203    var nodeMap = { };
9204    this.findElements(element, options).each( function(n) {
9205        if (n.id.match(options.format))
9206            nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
9207        n.parentNode.removeChild(n);
9208    });
9209
9210    new_sequence.each(function(ident) {
9211      var n = nodeMap[ident];
9212      if (n) {
9213        n[1].appendChild(n[0]);
9214        delete nodeMap[ident];
9215      }
9216    });
9217  },
9218
9219  serialize: function(element) {
9220    element = $(element);
9221    var options = Object.extend(Sortable.options(element), arguments[1] || { });
9222    var name = encodeURIComponent(
9223      (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
9224
9225    if (options.tree) {
9226      return Sortable.tree(element, arguments[1]).children.map( function (item) {
9227        return [name + Sortable._constructIndex(item) + "[id]=" +
9228                encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
9229      }).flatten().join('&');
9230    } else {
9231      return Sortable.sequence(element, arguments[1]).map( function(item) {
9232        return name + "[]=" + encodeURIComponent(item);
9233      }).join('&');
9234    }
9235  }
9236};
9237
9238// Returns true if child is contained within element
9239Element.isParent = function(child, element) {
9240  if (!child.parentNode || child == element) return false;
9241  if (child.parentNode == element) return true;
9242  return Element.isParent(child.parentNode, element);
9243};
9244
9245Element.findChildren = function(element, only, recursive, tagName) {
9246  if(!element.hasChildNodes()) return null;
9247  tagName = tagName.toUpperCase();
9248  if(only) only = [only].flatten();
9249  var elements = [];
9250  $A(element.childNodes).each( function(e) {
9251    if(e.tagName && e.tagName.toUpperCase()==tagName &&
9252      (!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
9253        elements.push(e);
9254    if(recursive) {
9255      var grandchildren = Element.findChildren(e, only, recursive, tagName);
9256      if(grandchildren) elements.push(grandchildren);
9257    }
9258  });
9259
9260  return (elements.length>0 ? elements.flatten() : []);
9261};
9262
9263Element.offsetSize = function (element, type) {
9264  return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
9265};
9266// script.aculo.us controls.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
9267
9268// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
9269//           (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
9270//           (c) 2005-2008 Jon Tirsen (http://www.tirsen.com)
9271// Contributors:
9272//  Richard Livsey
9273//  Rahul Bhargava
9274//  Rob Wills
9275//
9276// script.aculo.us is freely distributable under the terms of an MIT-style license.
9277// For details, see the script.aculo.us web site: http://script.aculo.us/
9278
9279// Autocompleter.Base handles all the autocompletion functionality
9280// that's independent of the data source for autocompletion. This
9281// includes drawing the autocompletion menu, observing keyboard
9282// and mouse events, and similar.
9283//
9284// Specific autocompleters need to provide, at the very least,
9285// a getUpdatedChoices function that will be invoked every time
9286// the text inside the monitored textbox changes. This method
9287// should get the text for which to provide autocompletion by
9288// invoking this.getToken(), NOT by directly accessing
9289// this.element.value. This is to allow incremental tokenized
9290// autocompletion. Specific auto-completion logic (AJAX, etc)
9291// belongs in getUpdatedChoices.
9292//
9293// Tokenized incremental autocompletion is enabled automatically
9294// when an autocompleter is instantiated with the 'tokens' option
9295// in the options parameter, e.g.:
9296// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
9297// will incrementally autocomplete with a comma as the token.
9298// Additionally, ',' in the above example can be replaced with
9299// a token array, e.g. { tokens: [',', '\n'] } which
9300// enables autocompletion on multiple tokens. This is most
9301// useful when one of the tokens is \n (a newline), as it
9302// allows smart autocompletion after linebreaks.
9303
9304if(typeof Effect == 'undefined')
9305  throw("controls.js requires including script.aculo.us' effects.js library");
9306
9307var Autocompleter = { };
9308Autocompleter.Base = Class.create({
9309  baseInitialize: function(element, update, options) {
9310    element          = $(element);
9311    this.element     = element;
9312    this.update      = $(update);
9313    this.hasFocus    = false;
9314    this.changed     = false;
9315    this.active      = false;
9316    this.index       = 0;
9317    this.entryCount  = 0;
9318    this.oldElementValue = this.element.value;
9319
9320    if(this.setOptions)
9321      this.setOptions(options);
9322    else
9323      this.options = options || { };
9324
9325    this.options.paramName    = this.options.paramName || this.element.name;
9326    this.options.tokens       = this.options.tokens || [];
9327    this.options.frequency    = this.options.frequency || 0.4;
9328    this.options.minChars     = this.options.minChars || 1;
9329    this.options.onShow       = this.options.onShow ||
9330      function(element, update){
9331        if(!update.style.position || update.style.position=='absolute') {
9332          update.style.position = 'absolute';
9333          Position.clone(element, update, {
9334            setHeight: false,
9335            offsetTop: element.offsetHeight
9336          });
9337        }
9338        Effect.Appear(update,{duration:0.15});
9339      };
9340    this.options.onHide = this.options.onHide ||
9341      function(element, update){ new Effect.Fade(update,{duration:0.15}) };
9342
9343    if(typeof(this.options.tokens) == 'string')
9344      this.options.tokens = new Array(this.options.tokens);
9345    // Force carriage returns as token delimiters anyway
9346    if (!this.options.tokens.include('\n'))
9347      this.options.tokens.push('\n');
9348
9349    this.observer = null;
9350
9351    this.element.setAttribute('autocomplete','off');
9352
9353    Element.hide(this.update);
9354
9355    Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
9356    Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
9357  },
9358
9359  show: function() {
9360    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
9361    if(!this.iefix &&
9362      (Prototype.Browser.IE) &&
9363      (Element.getStyle(this.update, 'position')=='absolute')) {
9364      new Insertion.After(this.update,
9365       '<iframe id="' + this.update.id + '_iefix" '+
9366       'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
9367       'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
9368      this.iefix = $(this.update.id+'_iefix');
9369    }
9370    if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
9371  },
9372
9373  fixIEOverlapping: function() {
9374    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
9375    this.iefix.style.zIndex = 1;
9376    this.update.style.zIndex = 2;
9377    Element.show(this.iefix);
9378  },
9379
9380  hide: function() {
9381    this.stopIndicator();
9382    if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
9383    if(this.iefix) Element.hide(this.iefix);
9384  },
9385
9386  startIndicator: function() {
9387    if(this.options.indicator) Element.show(this.options.indicator);
9388  },
9389
9390  stopIndicator: function() {
9391    if(this.options.indicator) Element.hide(this.options.indicator);
9392  },
9393
9394  onKeyPress: function(event) {
9395    if(this.active)
9396      switch(event.keyCode) {
9397       case Event.KEY_TAB:
9398       case Event.KEY_RETURN:
9399         this.selectEntry();
9400         Event.stop(event);
9401       case Event.KEY_ESC:
9402         this.hide();
9403         this.active = false;
9404         Event.stop(event);
9405         return;
9406       case Event.KEY_LEFT:
9407       case Event.KEY_RIGHT:
9408         return;
9409       case Event.KEY_UP:
9410         this.markPrevious();
9411         this.render();
9412         Event.stop(event);
9413         return;
9414       case Event.KEY_DOWN:
9415         this.markNext();
9416         this.render();
9417         Event.stop(event);
9418         return;
9419      }
9420     else
9421       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
9422         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
9423
9424    this.changed = true;
9425    this.hasFocus = true;
9426
9427    if(this.observer) clearTimeout(this.observer);
9428      this.observer =
9429        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
9430  },
9431
9432  activate: function() {
9433    this.changed = false;
9434    this.hasFocus = true;
9435    this.getUpdatedChoices();
9436  },
9437
9438  onHover: function(event) {
9439    var element = Event.findElement(event, 'LI');
9440    if(this.index != element.autocompleteIndex)
9441    {
9442        this.index = element.autocompleteIndex;
9443        this.render();
9444    }
9445    Event.stop(event);
9446  },
9447
9448  onClick: function(event) {
9449    var element = Event.findElement(event, 'LI');
9450    this.index = element.autocompleteIndex;
9451    this.selectEntry();
9452    this.hide();
9453  },
9454
9455  onBlur: function(event) {
9456    // needed to make click events working
9457    setTimeout(this.hide.bind(this), 250);
9458    this.hasFocus = false;
9459    this.active = false;
9460  },
9461
9462  render: function() {
9463    if(this.entryCount > 0) {
9464      for (var i = 0; i < this.entryCount; i++)
9465        this.index==i ?
9466          Element.addClassName(this.getEntry(i),"selected") :
9467          Element.removeClassName(this.getEntry(i),"selected");
9468      if(this.hasFocus) {
9469        this.show();
9470        this.active = true;
9471      }
9472    } else {
9473      this.active = false;
9474      this.hide();
9475    }
9476  },
9477
9478  markPrevious: function() {
9479    if(this.index > 0) this.index--;
9480      else this.index = this.entryCount-1;
9481    //this.getEntry(this.index).scrollIntoView(true); useless
9482  },
9483
9484  markNext: function() {
9485    if(this.index < this.entryCount-1) this.index++;
9486      else this.index = 0;
9487    this.getEntry(this.index).scrollIntoView(false);
9488  },
9489
9490  getEntry: function(index) {
9491    return this.update.firstChild.childNodes[index];
9492  },
9493
9494  getCurrentEntry: function() {
9495    return this.getEntry(this.index);
9496  },
9497
9498  selectEntry: function() {
9499    this.active = false;
9500    this.updateElement(this.getCurrentEntry());
9501  },
9502
9503  updateElement: function(selectedElement) {
9504    if (this.options.updateElement) {
9505      this.options.updateElement(selectedElement);
9506      return;
9507    }
9508    var value = '';
9509    if (this.options.select) {
9510      var nodes = $(selectedElement).select('.' + this.options.select) || [];
9511      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
9512    } else
9513      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
9514
9515    var bounds = this.getTokenBounds();
9516    if (bounds[0] != -1) {
9517      var newValue = this.element.value.substr(0, bounds[0]);
9518      var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
9519      if (whitespace)
9520        newValue += whitespace[0];
9521      this.element.value = newValue + value + this.element.value.substr(bounds[1]);
9522    } else {
9523      this.element.value = value;
9524    }
9525    this.oldElementValue = this.element.value;
9526    this.element.focus();
9527
9528    if (this.options.afterUpdateElement)
9529      this.options.afterUpdateElement(this.element, selectedElement);
9530  },
9531
9532  updateChoices: function(choices) {
9533    if(!this.changed && this.hasFocus) {
9534      this.update.innerHTML = choices;
9535      Element.cleanWhitespace(this.update);
9536      Element.cleanWhitespace(this.update.down());
9537
9538      if(this.update.firstChild && this.update.down().childNodes) {
9539        this.entryCount =
9540          this.update.down().childNodes.length;
9541        for (var i = 0; i < this.entryCount; i++) {
9542          var entry = this.getEntry(i);
9543          entry.autocompleteIndex = i;
9544          this.addObservers(entry);
9545        }
9546      } else {
9547        this.entryCount = 0;
9548      }
9549
9550      this.stopIndicator();
9551      this.index = 0;
9552
9553      if(this.entryCount==1 && this.options.autoSelect) {
9554        this.selectEntry();
9555        this.hide();
9556      } else {
9557        this.render();
9558      }
9559    }
9560  },
9561
9562  addObservers: function(element) {
9563    Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
9564    Event.observe(element, "click", this.onClick.bindAsEventListener(this));
9565  },
9566
9567  onObserverEvent: function() {
9568    this.changed = false;
9569    this.tokenBounds = null;
9570    if(this.getToken().length>=this.options.minChars) {
9571      this.getUpdatedChoices();
9572    } else {
9573      this.active = false;
9574      this.hide();
9575    }
9576    this.oldElementValue = this.element.value;
9577  },
9578
9579  getToken: function() {
9580    var bounds = this.getTokenBounds();
9581    return this.element.value.substring(bounds[0], bounds[1]).strip();
9582  },
9583
9584  getTokenBounds: function() {
9585    if (null != this.tokenBounds) return this.tokenBounds;
9586    var value = this.element.value;
9587    if (value.strip().empty()) return [-1, 0];
9588    var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
9589    var offset = (diff == this.oldElementValue.length ? 1 : 0);
9590    var prevTokenPos = -1, nextTokenPos = value.length;
9591    var tp;
9592    for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
9593      tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
9594      if (tp > prevTokenPos) prevTokenPos = tp;
9595      tp = value.indexOf(this.options.tokens[index], diff + offset);
9596      if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
9597    }
9598    return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
9599  }
9600});
9601
9602Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
9603  var boundary = Math.min(newS.length, oldS.length);
9604  for (var index = 0; index < boundary; ++index)
9605    if (newS[index] != oldS[index])
9606      return index;
9607  return boundary;
9608};
9609
9610Ajax.Autocompleter = Class.create(Autocompleter.Base, {
9611  initialize: function(element, update, url, options) {
9612    this.baseInitialize(element, update, options);
9613    this.options.asynchronous  = true;
9614    this.options.onComplete    = this.onComplete.bind(this);
9615    this.options.defaultParams = this.options.parameters || null;
9616    this.url                   = url;
9617  },
9618
9619  getUpdatedChoices: function() {
9620    this.startIndicator();
9621
9622    var entry = encodeURIComponent(this.options.paramName) + '=' +
9623      encodeURIComponent(this.getToken());
9624
9625    this.options.parameters = this.options.callback ?
9626      this.options.callback(this.element, entry) : entry;
9627
9628    if(this.options.defaultParams)
9629      this.options.parameters += '&' + this.options.defaultParams;
9630
9631    new Ajax.Request(this.url, this.options);
9632  },
9633
9634  onComplete: function(request) {
9635    this.updateChoices(request.responseText);
9636  }
9637});
9638
9639// The local array autocompleter. Used when you'd prefer to
9640// inject an array of autocompletion options into the page, rather
9641// than sending out Ajax queries, which can be quite slow sometimes.
9642//
9643// The constructor takes four parameters. The first two are, as usual,
9644// the id of the monitored textbox, and id of the autocompletion menu.
9645// The third is the array you want to autocomplete from, and the fourth
9646// is the options block.
9647//
9648// Extra local autocompletion options:
9649// - choices - How many autocompletion choices to offer
9650//
9651// - partialSearch - If false, the autocompleter will match entered
9652//                    text only at the beginning of strings in the
9653//                    autocomplete array. Defaults to true, which will
9654//                    match text at the beginning of any *word* in the
9655//                    strings in the autocomplete array. If you want to
9656//                    search anywhere in the string, additionally set
9657//                    the option fullSearch to true (default: off).
9658//
9659// - fullSsearch - Search anywhere in autocomplete array strings.
9660//
9661// - partialChars - How many characters to enter before triggering
9662//                   a partial match (unlike minChars, which defines
9663//                   how many characters are required to do any match
9664//                   at all). Defaults to 2.
9665//
9666// - ignoreCase - Whether to ignore case when autocompleting.
9667//                 Defaults to true.
9668//
9669// It's possible to pass in a custom function as the 'selector'
9670// option, if you prefer to write your own autocompletion logic.
9671// In that case, the other options above will not apply unless
9672// you support them.
9673
9674Autocompleter.Local = Class.create(Autocompleter.Base, {
9675  initialize: function(element, update, array, options) {
9676    this.baseInitialize(element, update, options);
9677    this.options.array = array;
9678  },
9679
9680  getUpdatedChoices: function() {
9681    this.updateChoices(this.options.selector(this));
9682  },
9683
9684  setOptions: function(options) {
9685    this.options = Object.extend({
9686      choices: 10,
9687      partialSearch: true,
9688      partialChars: 2,
9689      ignoreCase: true,
9690      fullSearch: false,
9691      selector: function(instance) {
9692        var ret       = []; // Beginning matches
9693        var partial   = []; // Inside matches
9694        var entry     = instance.getToken();
9695        var count     = 0;
9696
9697        for (var i = 0; i < instance.options.array.length &&
9698          ret.length < instance.options.choices ; i++) {
9699
9700          var elem = instance.options.array[i];
9701          var foundPos = instance.options.ignoreCase ?
9702            elem.toLowerCase().indexOf(entry.toLowerCase()) :
9703            elem.indexOf(entry);
9704
9705          while (foundPos != -1) {
9706            if (foundPos == 0 && elem.length != entry.length) {
9707              ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
9708                elem.substr(entry.length) + "</li>");
9709              break;
9710            } else if (entry.length >= instance.options.partialChars &&
9711              instance.options.partialSearch && foundPos != -1) {
9712              if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
9713                partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
9714                  elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
9715                  foundPos + entry.length) + "</li>");
9716                break;
9717              }
9718            }
9719
9720            foundPos = instance.options.ignoreCase ?
9721              elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
9722              elem.indexOf(entry, foundPos + 1);
9723
9724          }
9725        }
9726        if (partial.length)
9727          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
9728        return "<ul>" + ret.join('') + "</ul>";
9729      }
9730    }, options || { });
9731  }
9732});
9733
9734// AJAX in-place editor and collection editor
9735// Full rewrite by Christophe Porteneuve <[email protected]> (April 2007).
9736
9737// Use this if you notice weird scrolling problems on some browsers,
9738// the DOM might be a bit confused when this gets called so do this
9739// waits 1 ms (with setTimeout) until it does the activation
9740Field.scrollFreeActivate = function(field) {
9741  setTimeout(function() {
9742    Field.activate(field);
9743  }, 1);
9744};
9745
9746Ajax.InPlaceEditor = Class.create({
9747  initialize: function(element, url, options) {
9748    this.url = url;
9749    this.element = element = $(element);
9750    this.prepareOptions();
9751    this._controls = { };
9752    arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
9753    Object.extend(this.options, options || { });
9754    if (!this.options.formId && this.element.id) {
9755      this.options.formId = this.element.id + '-inplaceeditor';
9756      if ($(this.options.formId))
9757        this.options.formId = '';
9758    }
9759    if (this.options.externalControl)
9760      this.options.externalControl = $(this.options.externalControl);
9761    if (!this.options.externalControl)
9762      this.options.externalControlOnly = false;
9763    this._originalBackground = this.element.getStyle('background-color') || 'transparent';
9764    this.element.title = this.options.clickToEditText;
9765    this._boundCancelHandler = this.handleFormCancellation.bind(this);
9766    this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
9767    this._boundFailureHandler = this.handleAJAXFailure.bind(this);
9768    this._boundSubmitHandler = this.handleFormSubmission.bind(this);
9769    this._boundWrapperHandler = this.wrapUp.bind(this);
9770    this.registerListeners();
9771  },
9772  checkForEscapeOrReturn: function(e) {
9773    if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
9774    if (Event.KEY_ESC == e.keyCode)
9775      this.handleFormCancellation(e);
9776    else if (Event.KEY_RETURN == e.keyCode)
9777      this.handleFormSubmission(e);
9778  },
9779  createControl: function(mode, handler, extraClasses) {
9780    var control = this.options[mode + 'Control'];
9781    var text = this.options[mode + 'Text'];
9782    if ('button' == control) {
9783      var btn = document.createElement('input');
9784      btn.type = 'submit';
9785      btn.value = text;
9786      btn.className = 'editor_' + mode + '_button';
9787      if ('cancel' == mode)
9788        btn.onclick = this._boundCancelHandler;
9789      this._form.appendChild(btn);
9790      this._controls[mode] = btn;
9791    } else if ('link' == control) {
9792      var link = document.createElement('a');
9793      link.href = '#';
9794      link.appendChild(document.createTextNode(text));
9795      link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
9796      link.className = 'editor_' + mode + '_link';
9797      if (extraClasses)
9798        link.className += ' ' + extraClasses;
9799      this._form.appendChild(link);
9800      this._controls[mode] = link;
9801    }
9802  },
9803  createEditField: function() {
9804    var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
9805    var fld;
9806    if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
9807      fld = document.createElement('input');
9808      fld.type = 'text';
9809      var size = this.options.size || this.options.cols || 0;
9810      if (0 < size) fld.size = size;
9811    } else {
9812      fld = document.createElement('textarea');
9813      fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
9814      fld.cols = this.options.cols || 40;
9815    }
9816    fld.name = this.options.paramName;
9817    fld.value = text; // No HTML breaks conversion anymore
9818    fld.className = 'editor_field';
9819    if (this.options.submitOnBlur)
9820      fld.onblur = this._boundSubmitHandler;
9821    this._controls.editor = fld;
9822    if (this.options.loadTextURL)
9823      this.loadExternalText();
9824    this._form.appendChild(this._controls.editor);
9825  },
9826  createForm: function() {
9827    var ipe = this;
9828    function addText(mode, condition) {
9829      var text = ipe.options['text' + mode + 'Controls'];
9830      if (!text || condition === false) return;
9831      ipe._form.appendChild(document.createTextNode(text));
9832    };
9833    this._form = $(document.createElement('form'));
9834    this._form.id = this.options.formId;
9835    this._form.addClassName(this.options.formClassName);
9836    this._form.onsubmit = this._boundSubmitHandler;
9837    this.createEditField();
9838    if ('textarea' == this._controls.editor.tagName.toLowerCase())
9839      this._form.appendChild(document.createElement('br'));
9840    if (this.options.onFormCustomization)
9841      this.options.onFormCustomization(this, this._form);
9842    addText('Before', this.options.okControl || this.options.cancelControl);
9843    this.createControl('ok', this._boundSubmitHandler);
9844    addText('Between', this.options.okControl && this.options.cancelControl);
9845    this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
9846    addText('After', this.options.okControl || this.options.cancelControl);
9847  },
9848  destroy: function() {
9849    if (this._oldInnerHTML)
9850      this.element.innerHTML = this._oldInnerHTML;
9851    this.leaveEditMode();
9852    this.unregisterListeners();
9853  },
9854  enterEditMode: function(e) {
9855    if (this._saving || this._editing) return;
9856    this._editing = true;
9857    this.triggerCallback('onEnterEditMode');
9858    if (this.options.externalControl)
9859      this.options.externalControl.hide();
9860    this.element.hide();
9861    this.createForm();
9862    this.element.parentNode.insertBefore(this._form, this.element);
9863    if (!this.options.loadTextURL)
9864      this.postProcessEditField();
9865    if (e) Event.stop(e);
9866  },
9867  enterHover: function(e) {
9868    if (this.options.hoverClassName)
9869      this.element.addClassName(this.options.hoverClassName);
9870    if (this._saving) return;
9871    this.triggerCallback('onEnterHover');
9872  },
9873  getText: function() {
9874    return this.element.innerHTML.unescapeHTML();
9875  },
9876  handleAJAXFailure: function(transport) {
9877    this.triggerCallback('onFailure', transport);
9878    if (this._oldInnerHTML) {
9879      this.element.innerHTML = this._oldInnerHTML;
9880      this._oldInnerHTML = null;
9881    }
9882  },
9883  handleFormCancellation: function(e) {
9884    this.wrapUp();
9885    if (e) Event.stop(e);
9886  },
9887  handleFormSubmission: function(e) {
9888    var form = this._form;
9889    var value = $F(this._controls.editor);
9890    this.prepareSubmission();
9891    var params = this.options.callback(form, value) || '';
9892    if (Object.isString(params))
9893      params = params.toQueryParams();
9894    params.editorId = this.element.id;
9895    if (this.options.htmlResponse) {
9896      var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
9897      Object.extend(options, {
9898        parameters: params,
9899        onComplete: this._boundWrapperHandler,
9900        onFailure: this._boundFailureHandler
9901      });
9902      new Ajax.Updater({ success: this.element }, this.url, options);
9903    } else {
9904      var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
9905      Object.extend(options, {
9906        parameters: params,
9907        onComplete: this._boundWrapperHandler,
9908        onFailure: this._boundFailureHandler
9909      });
9910      new Ajax.Request(this.url, options);
9911    }
9912    if (e) Event.stop(e);
9913  },
9914  leaveEditMode: function() {
9915    this.element.removeClassName(this.options.savingClassName);
9916    this.removeForm();
9917    this.leaveHover();
9918    this.element.style.backgroundColor = this._originalBackground;
9919    this.element.show();
9920    if (this.options.externalControl)
9921      this.options.externalControl.show();
9922    this._saving = false;
9923    this._editing = false;
9924    this._oldInnerHTML = null;
9925    this.triggerCallback('onLeaveEditMode');
9926  },
9927  leaveHover: function(e) {
9928    if (this.options.hoverClassName)
9929      this.element.removeClassName(this.options.hoverClassName);
9930    if (this._saving) return;
9931    this.triggerCallback('onLeaveHover');
9932  },
9933  loadExternalText: function() {
9934    this._form.addClassName(this.options.loadingClassName);
9935    this._controls.editor.disabled = true;
9936    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
9937    Object.extend(options, {
9938      parameters: 'editorId=' + encodeURIComponent(this.element.id),
9939      onComplete: Prototype.emptyFunction,
9940      onSuccess: function(transport) {
9941        this._form.removeClassName(this.options.loadingClassName);
9942        var text = transport.responseText;
9943        if (this.options.stripLoadedTextTags)
9944          text = text.stripTags();
9945        this._controls.editor.value = text;
9946        this._controls.editor.disabled = false;
9947        this.postProcessEditField();
9948      }.bind(this),
9949      onFailure: this._boundFailureHandler
9950    });
9951    new Ajax.Request(this.options.loadTextURL, options);
9952  },
9953  postProcessEditField: function() {
9954    var fpc = this.options.fieldPostCreation;
9955    if (fpc)
9956      $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
9957  },
9958  prepareOptions: function() {
9959    this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
9960    Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
9961    [this._extraDefaultOptions].flatten().compact().each(function(defs) {
9962      Object.extend(this.options, defs);
9963    }.bind(this));
9964  },
9965  prepareSubmission: function() {
9966    this._saving = true;
9967    this.removeForm();
9968    this.leaveHover();
9969    this.showSaving();
9970  },
9971  registerListeners: function() {
9972    this._listeners = { };
9973    var listener;
9974    $H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
9975      listener = this[pair.value].bind(this);
9976      this._listeners[pair.key] = listener;
9977      if (!this.options.externalControlOnly)
9978        this.element.observe(pair.key, listener);
9979      if (this.options.externalControl)
9980        this.options.externalControl.observe(pair.key, listener);
9981    }.bind(this));
9982  },
9983  removeForm: function() {
9984    if (!this._form) return;
9985    this._form.remove();
9986    this._form = null;
9987    this._controls = { };
9988  },
9989  showSaving: function() {
9990    this._oldInnerHTML = this.element.innerHTML;
9991    this.element.innerHTML = this.options.savingText;
9992    this.element.addClassName(this.options.savingClassName);
9993    this.element.style.backgroundColor = this._originalBackgroun
9993d;
9994    this.element.show();
9995  },
9996  triggerCallback: function(cbName, arg) {
9997    if ('function' == typeof this.options[cbName]) {
9998      this.options[cbName](this, arg);
9999    }
10000  },
10001  unregisterListeners: function() {
10002    $H(this._listeners).each(function(pair) {
10003      if (!this.options.externalControlOnly)
10004        this.element.stopObserving(pair.key, pair.value);
10005      if (this.options.externalControl)
10006        this.options.externalControl.stopObserving(pair.key, pair.value);
10007    }.bind(this));
10008  },
10009  wrapUp: function(transport) {
10010    this.leaveEditMode();
10011    // Can't use triggerCallback due to backward compatibility: requires
10012    // binding + direct element
10013    this._boundComplete(transport, this.element);
10014  }
10015});
10016
10017Object.extend(Ajax.InPlaceEditor.prototype, {
10018  dispose: Ajax.InPlaceEditor.prototype.destroy
10019});
10020
10021Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
10022  initialize: function($super, element, url, options) {
10023    this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
10024    $super(element, url, options);
10025  },
10026
10027  createEditField: function() {
10028    var list = document.createElement('select');
10029    list.name = this.options.paramName;
10030    list.size = 1;
10031    this._controls.editor = list;
10032    this._collection = this.options.collection || [];
10033    if (this.options.loadCollectionURL)
10034      this.loadCollection();
10035    else
10036      this.checkForExternalText();
10037    this._form.appendChild(this._controls.editor);
10038  },
10039
10040  loadCollection: function() {
10041    this._form.addClassName(this.options.loadingClassName);
10042    this.showLoadingText(this.options.loadingCollectionText);
10043    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
10044    Object.extend(options, {
10045      parameters: 'editorId=' + encodeURIComponent(this.element.id),
10046      onComplete: Prototype.emptyFunction,
10047      onSuccess: function(transport) {
10048        var js = transport.responseText.strip();
10049        if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
10050          throw('Server returned an invalid collection representation.');
10051        this._collection = eval(js);
10052        this.checkForExternalText();
10053      }.bind(this),
10054      onFailure: this.onFailure
10055    });
10056    new Ajax.Request(this.options.loadCollectionURL, options);
10057  },
10058
10059  showLoadingText: function(text) {
10060    this._controls.editor.disabled = true;
10061    var tempOption = this._controls.editor.firstChild;
10062    if (!tempOption) {
10063      tempOption = document.createElement('option');
10064      tempOption.value = '';
10065      this._controls.editor.appendChild(tempOption);
10066      tempOption.selected = true;
10067    }
10068    tempOption.update((text || '').stripScripts().stripTags());
10069  },
10070
10071  checkForExternalText: function() {
10072    this._text = this.getText();
10073    if (this.options.loadTextURL)
10074      this.loadExternalText();
10075    else
10076      this.buildOptionList();
10077  },
10078
10079  loadExternalText: function() {
10080    this.showLoadingText(this.options.loadingText);
10081    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
10082    Object.extend(options, {
10083      parameters: 'editorId=' + encodeURIComponent(this.element.id),
10084      onComplete: Prototype.emptyFunction,
10085      onSuccess: function(transport) {
10086        this._text = transport.responseText.strip();
10087        this.buildOptionList();
10088      }.bind(this),
10089      onFailure: this.onFailure
10090    });
10091    new Ajax.Request(this.options.loadTextURL, options);
10092  },
10093
10094  buildOptionList: function() {
10095    this._form.removeClassName(this.options.loadingClassName);
10096    this._collection = this._collection.map(function(entry) {
10097      return 2 === entry.length ? entry : [entry, entry].flatten();
10098    });
10099    var marker = ('value' in this.options) ? this.options.value : this._text;
10100    var textFound = this._collection.any(function(entry) {
10101      return entry[0] == marker;
10102    }.bind(this));
10103    this._controls.editor.update('');
10104    var option;
10105    this._collection.each(function(entry, index) {
10106      option = document.createElement('option');
10107      option.value = entry[0];
10108      option.selected = textFound ? entry[0] == marker : 0 == index;
10109      option.appendChild(document.createTextNode(entry[1]));
10110      this._controls.editor.appendChild(option);
10111    }.bind(this));
10112    this._controls.editor.disabled = false;
10113    Field.scrollFreeActivate(this._controls.editor);
10114  }
10115});
10116
10117//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
10118//**** This only  exists for a while,  in order to  let ****
10119//**** users adapt to  the new API.  Read up on the new ****
10120//**** API and convert your code to it ASAP!            ****
10121
10122Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
10123  if (!options) return;
10124  function fallback(name, expr) {
10125    if (name in options || expr === undefined) return;
10126    options[name] = expr;
10127  };
10128  fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
10129    options.cancelLink == options.cancelButton == false ? false : undefined)));
10130  fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
10131    options.okLink == options.okButton == false ? false : undefined)));
10132  fallback('highlightColor', options.highlightcolor);
10133  fallback('highlightEndColor', options.highlightendcolor);
10134};
10135
10136Object.extend(Ajax.InPlaceEditor, {
10137  DefaultOptions: {
10138    ajaxOptions: { },
10139    autoRows: 3,                                // Use when multi-line w/ rows == 1
10140    cancelControl: 'link',                      // 'link'|'button'|false
10141    cancelText: 'cancel',
10142    clickToEditText: 'Click to edit',
10143    externalControl: null,                      // id|elt
10144    externalControlOnly: false,
10145    fieldPostCreation: 'activate',              // 'activate'|'focus'|false
10146    formClassName: 'inplaceeditor-form',
10147    formId: null,                               // id|elt
10148    highlightColor: '#ffff99',
10149    highlightEndColor: '#ffffff',
10150    hoverClassName: '',
10151    htmlResponse: true,
10152    loadingClassName: 'inplaceeditor-loading',
10153    loadingText: 'Loading...',
10154    okControl: 'button',                        // 'link'|'button'|false
10155    okText: 'ok',
10156    paramName: 'value',
10157    rows: 1,                                    // If 1 and multi-line, uses autoRows
10158    savingClassName: 'inplaceeditor-saving',
10159    savingText: 'Saving...',
10160    size: 0,
10161    stripLoadedTextTags: false,
10162    submitOnBlur: false,
10163    textAfterControls: '',
10164    textBeforeControls: '',
10165    textBetweenControls: ''
10166  },
10167  DefaultCallbacks: {
10168    callback: function(form) {
10169      return Form.serialize(form);
10170    },
10171    onComplete: function(transport, element) {
10172      // For backward compatibility, this one is bound to the IPE, and passes
10173      // the element directly.  It was too often customized, so we don't break it.
10174      new Effect.Highlight(element, {
10175        startcolor: this.options.highlightColor, keepBackgroundImage: true });
10176    },
10177    onEnterEditMode: null,
10178    onEnterHover: function(ipe) {
10179      ipe.element.style.backgroundColor = ipe.options.highlightColor;
10180      if (ipe._effect)
10181        ipe._effect.cancel();
10182    },
10183    onFailure: function(transport, ipe) {
10184      alert('Error communication with the server: ' + transport.responseText.stripTags());
10185    },
10186    onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
10187    onLeaveEditMode: null,
10188    onLeaveHover: function(ipe) {
10189      ipe._effect = new Effect.Highlight(ipe.element, {
10190        startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
10191        restorecolor: ipe._originalBackground, keepBackgroundImage: true
10192      });
10193    }
10194  },
10195  Listeners: {
10196    click: 'enterEditMode',
10197    keydown: 'checkForEscapeOrReturn',
10198    mouseover: 'enterHover',
10199    mouseout: 'leaveHover'
10200  }
10201});
10202
10203Ajax.InPlaceCollectionEditor.DefaultOptions = {
10204  loadingCollectionText: 'Loading options...'
10205};
10206
10207// Delayed observer, like Form.Element.Observer,
10208// but waits for delay after last key input
10209// Ideal for live-search fields
10210
10211Form.Element.DelayedObserver = Class.create({
10212  initialize: function(element, delay, callback) {
10213    this.delay     = delay || 0.5;
10214    this.element   = $(element);
10215    this.callback  = callback;
10216    this.timer     = null;
10217    this.lastValue = $F(this.element);
10218    Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
10219  },
10220  delayedListener: function(event) {
10221    if(this.lastValue == $F(this.element)) return;
10222    if(this.timer) clearTimeout(this.timer);
10223    this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
10224    this.lastValue = $F(this.element);
10225  },
10226  onTimerEvent: function() {
10227    this.timer = null;
10228    this.callback(this.element, $F(this.element));
10229  }
10230});
10231// script.aculo.us slider.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
10232
10233// Copyright (c) 2005-2008 Marty Haught, Thomas Fuchs
10234//
10235// script.aculo.us is freely distributable under the terms of an MIT-style license.
10236// For details, see the script.aculo.us web site: http://script.aculo.us/
10237
10238if (!Control) var Control = { };
10239
10240// options:
10241//  axis: 'vertical', or 'horizontal' (default)
10242//
10243// callbacks:
10244//  onChange(value)
10245//  onSlide(value)
10246Control.Slider = Class.create({
10247  initialize: function(handle, track, options) {
10248    var slider = this;
10249
10250    if (Object.isArray(handle)) {
10251      this.handles = handle.collect( function(e) { return $(e) });
10252    } else {
10253      this.handles = [$(handle)];
10254    }
10255
10256    this.track   = $(track);
10257    this.options = options || { };
10258
10259    this.axis      = this.options.axis || 'horizontal';
10260    this.increment = this.options.increment || 1;
10261    this.step      = parseInt(this.options.step || '1');
10262    this.range     = this.options.range || $R(0,1);
10263
10264    this.value     = 0; // assure backwards compat
10265    this.values    = this.handles.map( function() { return 0 });
10266    this.spans     = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
10267    this.options.startSpan = $(this.options.startSpan || null);
10268    this.options.endSpan   = $(this.options.endSpan || null);
10269
10270    this.restricted = this.options.restricted || false;
10271
10272    this.maximum   = this.options.maximum || this.range.end;
10273    this.minimum   = this.options.minimum || this.range.start;
10274
10275    // Will be used to align the handle onto the track, if necessary
10276    this.alignX = parseInt(this.options.alignX || '0');
10277    this.alignY = parseInt(this.options.alignY || '0');
10278
10279    this.trackLength = this.maximumOffset() - this.minimumOffset();
10280
10281    this.handleLength = this.isVertical() ?
10282      (this.handles[0].offsetHeight != 0 ?
10283        this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) :
10284      (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth :
10285        this.handles[0].style.width.replace(/px$/,""));
10286
10287    this.active   = false;
10288    this.dragging = false;
10289    this.disabled = false;
10290
10291    if (this.options.disabled) this.setDisabled();
10292
10293    // Allowed values array
10294    this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
10295    if (this.allowedValues) {
10296      this.minimum = this.allowedValues.min();
10297      this.maximum = this.allowedValues.max();
10298    }
10299
10300    this.eventMouseDown = this.startDrag.bindAsEventListener(this);
10301    this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
10302    this.eventMouseMove = this.update.bindAsEventListener(this);
10303
10304    // Initialize handles in reverse (make sure first handle is active)
10305    this.handles.each( function(h,i) {
10306      i = slider.handles.length-1-i;
10307      slider.setValue(parseFloat(
10308        (Object.isArray(slider.options.sliderValue) ?
10309          slider.options.sliderValue[i] : slider.options.sliderValue) ||
10310         slider.range.start), i);
10311      h.makePositioned().observe("mousedown", slider.eventMouseDown);
10312    });
10313
10314    this.track.observe("mousedown", this.eventMouseDown);
10315    document.observe("mouseup", this.eventMouseUp);
10316    $(this.track.parentNode.parentNode).observe("mousemove", this.eventMouseMove);
10317
10318
10319    this.initialized = true;
10320  },
10321  dispose: function() {
10322    var slider = this;
10323    Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
10324    Event.stopObserving(document, "mouseup", this.eventMouseUp);
10325    Event.stopObserving(this.track.parentNode.parentNode, "mousemove", this.eventMouseMove);
10326    this.handles.each( function(h) {
10327      Event.stopObserving(h, "mousedown", slider.eventMouseDown);
10328    });
10329  },
10330  setDisabled: function(){
10331    this.disabled = true;
10332    this.track.parentNode.className = this.track.parentNode.className + ' disabled';
10333  },
10334  setEnabled: function(){
10335    this.disabled = false;
10336  },
10337  getNearestValue: function(value){
10338    if (this.allowedValues){
10339      if (value >= this.allowedValues.max()) return(this.allowedValues.max());
10340      if (value <= this.allowedValues.min()) return(this.allowedValues.min());
10341
10342      var offset = Math.abs(this.allowedValues[0] - value);
10343      var newValue = this.allowedValues[0];
10344      this.allowedValues.each( function(v) {
10345        var currentOffset = Math.abs(v - value);
10346        if (currentOffset <= offset){
10347          newValue = v;
10348          offset = currentOffset;
10349        }
10350      });
10351      return newValue;
10352    }
10353    if (value > this.range.end) return this.range.end;
10354    if (value < this.range.start) return this.range.start;
10355    return value;
10356  },
10357  setValue: function(sliderValue, handleIdx){
10358    if (!this.active) {
10359      this.activeHandleIdx = handleIdx || 0;
10360      this.activeHandle    = this.handles[this.activeHandleIdx];
10361      this.updateStyles();
10362    }
10363    handleIdx = handleIdx || this.activeHandleIdx || 0;
10364    if (this.initialized && this.restricted) {
10365      if ((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
10366        sliderValue = this.values[handleIdx-1];
10367      if ((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
10368        sliderValue = this.values[handleIdx+1];
10369    }
10370    sliderValue = this.getNearestValue(sliderValue);
10371    this.values[handleIdx] = sliderValue;
10372    this.value = this.values[0]; // assure backwards compat
10373
10374    this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
10375      this.translateToPx(sliderValue);
10376
10377    this.drawSpans();
10378    if (!this.dragging || !this.event) this.updateFinished();
10379  },
10380  setValueBy: function(delta, handleIdx) {
10381    this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
10382      handleIdx || this.activeHandleIdx || 0);
10383  },
10384  translateToPx: function(value) {
10385    return Math.round(
10386      ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
10387      (value - this.range.start)) + "px";
10388  },
10389  translateToValue: function(offset) {
10390    return ((offset/(this.trackLength-this.handleLength) *
10391      (this.range.end-this.range.start)) + this.range.start);
10392  },
10393  getRange: function(range) {
10394    var v = this.values.sortBy(Prototype.K);
10395    range = range || 0;
10396    return $R(v[range],v[range+1]);
10397  },
10398  minimumOffset: function(){
10399    return(this.isVertical() ? this.alignY : this.alignX);
10400  },
10401  maximumOffset: function(){
10402    return(this.isVertical() ?
10403      (this.track.offsetHeight != 0 ? this.track.offsetHeight :
10404        this.track.style.height.replace(/px$/,"")) - this.alignY :
10405      (this.track.offsetWidth != 0 ? this.track.offsetWidth :
10406        this.track.style.width.replace(/px$/,"")) - this.alignX);
10407  },
10408  isVertical:  function(){
10409    return (this.axis == 'vertical');
10410  },
10411  drawSpans: function() {
10412    var slider = this;
10413    if (this.spans)
10414      $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
10415    if (this.options.startSpan)
10416      this.setSpan(this.options.startSpan,
10417        $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
10418    if (this.options.endSpan)
10419      this.setSpan(this.options.endSpan,
10420        $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
10421  },
10422  setSpan: function(span, range) {
10423    if (this.isVertical()) {
10424      span.style.top = this.translateToPx(range.start);
10425      span.style.height = this.translateToPx(range.end - range.start + this.range.start);
10426    } else {
10427      span.style.left = this.translateToPx(range.start);
10428      span.style.width = this.translateToPx(range.end - range.start + this.range.start);
10429    }
10430  },
10431  updateStyles: function() {
10432    this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
10433    Element.addClassName(this.activeHandle, 'selected');
10434  },
10435  startDrag: function(event) {
10436    if (Event.isLeftClick(event)) {
10437      if (!this.disabled){
10438        this.active = true;
10439
10440        var handle = Event.element(event);
10441        var pointer  = [Event.pointerX(event), Event.pointerY(event)];
10442        var track = handle;
10443        if (track==this.track) {
10444          var offsets  = Position.cumulativeOffset(this.track);
10445          this.event = event;
10446          this.setValue(this.translateToValue(
10447           (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
10448          ));
10449          var offsets  = Position.cumulativeOffset(this.activeHandle);
10450          this.offsetX = (pointer[0] - offsets[0]);
10451          this.offsetY = (pointer[1] - offsets[1]);
10452        } else {
10453          // find the handle (prevents issues with Safari)
10454          while((this.handles.indexOf(handle) == -1) && handle.parentNode)
10455            handle = handle.parentNode;
10456
10457          if (this.handles.indexOf(handle)!=-1) {
10458            this.activeHandle    = handle;
10459            this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
10460            this.updateStyles();
10461
10462            var offsets  = Position.cumulativeOffset(this.activeHandle);
10463            this.offsetX = (pointer[0] - offsets[0]);
10464            this.offsetY = (pointer[1] - offsets[1]);
10465          }
10466        }
10467      }
10468      Event.stop(event);
10469    }
10470  },
10471  update: function(event) {
10472   if (this.active) {
10473      if (!this.dragging) this.dragging = true;
10474      this.draw(event);
10475      if (Prototype.Browser.WebKit) window.scrollBy(0,0);
10476      Event.stop(event);
10477   }
10478  },
10479  draw: function(event) {
10480    var pointer = [Event.pointerX(event), Event.pointerY(event)];
10481    var offsets = Position.cumulativeOffset(this.track);
10482    pointer[0] -= this.offsetX + offsets[0];
10483    pointer[1] -= this.offsetY + offsets[1];
10484    this.event = event;
10485    this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
10486    if (this.initialized && this.options.onSlide)
10487      this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
10488  },
10489  endDrag: function(event) {
10490    if (this.active && this.dragging) {
10491      this.finishDrag(event, true);
10492      Event.stop(event);
10493    }
10494    this.active = false;
10495    this.dragging = false;
10496  },
10497  finishDrag: function(event, success) {
10498    this.active = false;
10499    this.dragging = false;
10500    this.updateFinished();
10501  },
10502  updateFinished: function() {
10503    if (this.initialized && this.options.onChange)
10504      this.options.onChange(this.values.length>1 ? this.values : this.value, this);
10505    this.event = null;
10506  }
10507});
10508/**
10509 * Magento
10510 *
10511 * NOTICE OF LICENSE
10512 *
10513 * This source file is subject to the Academic Free License (AFL 3.0)
10514 * that is bundled with this package in the file LICENSE_AFL.txt.
10515 * It is also available through the world-wide-web at this URL:
10516 * http://opensource.org/licenses/afl-3.0.php
10517 * If you did not receive a copy of the license and are unable to
10518 * obtain it through the world-wide-web, please send an email
10519 * to [email protected] so we can send you a copy immediately.
10520 *
10521 * DISCLAIMER
10522 *
10523 * Do not edit or add to this file if you wish to upgrade Magento to newer
10524 * versions in the future. If you wish to customize Magento for your
10525 * needs please refer to http://www.magentocommerce.com for more information.
10526 *
10527 * @category    Varien
10528 * @package     js
10529 * @copyright   Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
10530 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
10531 */
10532function popWin(url,win,para) {
10533    var win = window.open(url,win,para);
10534    win.focus();
10535}
10536
10537function setLocation(url){
10538    window.location.href = url;
10539}
10540
10541function setPLocation(url, setFocus){
10542    if( setFocus ) {
10543        window.opener.focus();
10544    }
10545    window.opener.location.href = url;
10546}
10547
10548function setLanguageCode(code, fromCode){
10549    //TODO: javascript cookies have different domain and path than php cookies
10550    var href = window.location.href;
10551    var after = '', dash;
10552    if (dash = href.match(/\#(.*)$/)) {
10553        href = href.replace(/\#(.*)$/, '');
10554        after = dash[0];
10555    }
10556
10557    if (href.match(/[?]/)) {
10558        var re = /([?&]store=)[a-z0-9_]*/;
10559        if (href.match(re)) {
10560            href = href.replace(re, '$1'+code);
10561        } else {
10562            href += '&store='+code;
10563        }
10564
10565        var re = /([?&]from_store=)[a-z0-9_]*/;
10566        if (href.match(re)) {
10567            href = href.replace(re, '');
10568        }
10569    } else {
10570        href += '?store='+code;
10571    }
10572    if (typeof(fromCode) != 'undefined') {
10573        href += '&from_store='+fromCode;
10574    }
10575    href += after;
10576
10577    setLocation(href);
10578}
10579
10580/**
10581 * Add classes to specified elements.
10582 * Supported classes are: 'odd', 'even', 'first', 'last'
10583 *
10584 * @param elements - array of elements to be decorated
10585 * [@param decorateParams] - array of classes to be set. If omitted, all available will be used
10586 */
10587function decorateGeneric(elements, decorateParams)
10588{
10589    var allSupportedParams = ['odd', 'even', 'first', 'last'];
10590    var _decorateParams = {};
10591    var total = elements.length;
10592
10593    if (total) {
10594        // determine params called
10595        if (typeof(decorateParams) == 'undefined') {
10596            decorateParams = allSupportedParams;
10597        }
10598        if (!decorateParams.length) {
10599            return;
10600        }
10601        for (var k in allSupportedParams) {
10602            _decorateParams[allSupportedParams[k]] = false;
10603        }
10604        for (var k in decorateParams) {
10605            _decorateParams[decorateParams[k]] = true;
10606        }
10607
10608        // decorate elements
10609        // elements[0].addClassName('first'); // will cause bug in IE (#5587)
10610        if (_decorateParams.first) {
10611            Element.addClassName(elements[0], 'first');
10612        }
10613        if (_decorateParams.last) {
10614            Element.addClassName(elements[total-1], 'last');
10615        }
10616        for (var i = 0; i < total; i++) {
10617            if ((i + 1) % 2 == 0) {
10618                if (_decorateParams.even) {
10619                    Element.addClassName(elements[i], 'even');
10620                }
10621            }
10622            else {
10623                if (_decorateParams.odd) {
10624                    Element.addClassName(elements[i], 'odd');
10625                }
10626            }
10627        }
10628    }
10629}
10630
10631/**
10632 * Decorate table rows and cells, tbody etc
10633 * @see decorateGeneric()
10634 */
10635function decorateTable(table, options) {
10636    var table = $(table);
10637    if (table) {
10638        // set default options
10639        var _options = {
10640            'tbody'    : false,
10641            'tbody tr' : ['odd', 'even', 'first', 'last'],
10642            'thead tr' : ['first', 'last'],
10643            'tfoot tr' : ['first', 'last'],
10644            'tr td'    : ['last']
10645        };
10646        // overload options
10647        if (typeof(options) != 'undefined') {
10648            for (var k in options) {
10649                _options[k] = options[k];
10650            }
10651        }
10652        // decorate
10653        if (_options['tbody']) {
10654            decorateGeneric(table.select('tbody'), _options['tbody']);
10655        }
10656        if (_options['tbody tr']) {
10657            decorateGeneric(table.select('tbody tr'), _options['tbody tr']);
10658        }
10659        if (_options['thead tr']) {
10660            decorateGeneric(table.select('thead tr'), _options['thead tr']);
10661        }
10662        if (_options['tfoot tr']) {
10663            decorateGeneric(table.select('tfoot tr'), _options['tfoot tr']);
10664        }
10665        if (_options['tr td']) {
10666            var allRows = table.select('tr');
10667            if (allRows.length) {
10668                for (var i = 0; i < allRows.length; i++) {
10669                    decorateGeneric(allRows[i].getElementsByTagName('TD'), _options['tr td']);
10670                }
10671            }
10672        }
10673    }
10674}
10675
10676/**
10677 * Set "odd", "even" and "last" CSS classes for list items
10678 * @see decorateGeneric()
10679 */
10680function decorateList(list, nonRecursive) {
10681    if ($(list)) {
10682        if (typeof(nonRecursive) == 'undefined') {
10683            var items = $(list).select('li')
10684        }
10685        else {
10686            var items = $(list).childElements();
10687        }
10688        decorateGeneric(items, ['odd', 'even', 'last']);
10689    }
10690}
10691
10692/**
10693 * Set "odd", "even" and "last" CSS classes for list items
10694 * @see decorateGeneric()
10695 */
10696function decorateDataList(list) {
10697    list = $(list);
10698    if (list) {
10699        decorateGeneric(list.select('dt'), ['odd', 'even', 'last']);
10700        decorateGeneric(list.select('dd'), ['odd', 'even', 'last']);
10701    }
10702}
10703
10704/**
10705 * Parse SID and produces the correct URL
10706 */
10707function parseSidUrl(baseUrl, urlExt) {
10708    var sidPos = baseUrl.indexOf('/?SID=');
10709    var sid = '';
10710    urlExt = (urlExt != undefined) ? urlExt : '';
10711
10712    if(sidPos > -1) {
10713        sid = '?' + baseUrl.substring(sidPos + 2);
10714        baseUrl = baseUrl.substring(0, sidPos + 1);
10715    }
10716
10717    return baseUrl+urlExt+sid;
10718}
10719
10720/**
10721 * Formats currency using patern
10722 * format - JSON (pattern, decimal, decimalsDelimeter, groupsDelimeter)
10723 * showPlus - true (always show '+'or '-'),
10724 *      false (never show '-' even if number is negative)
10725 *      null (show '-' if number is negative)
10726 */
10727
10728function formatCurrency(price, format, showPlus){
10729    var precision = isNaN(format.precision = Math.abs(format.precision)) ? 2 : format.precision;
10730    var requiredPrecision = isNaN(format.requiredPrecision = Math.abs(format.requiredPrecision)) ? 2 : format.requiredPrecision;
10731
10732    //precision = (precision > requiredPrecision) ? precision : requiredPrecision;
10733    //for now we don't need this difference so precision is requiredPrecision
10734    precision = requiredPrecision;
10735
10736    var integerRequired = isNaN(format.integerRequired = Math.abs(format.integerRequired)) ? 1 : format.integerRequired;
10737
10738    var decimalSymbol = format.decimalSymbol == undefined ? "," : format.decimalSymbol;
10739    var groupSymbol = format.groupSymbol == undefined ? "." : format.groupSymbol;
10740    var groupLength = format.groupLength == undefined ? 3 : format.groupLength;
10741
10742    var s = '';
10743
10744    if (showPlus == undefined || showPlus == true) {
10745        s = price < 0 ? "-" : ( showPlus ? "+" : "");
10746    } else if (showPlus == false) {
10747        s = '';
10748    }
10749
10750    var i = parseInt(price = Math.abs(+price || 0).toFixed(precision)) + "";
10751    var pad = (i.length < integerRequired) ? (integerRequired - i.length) : 0;
10752    while (pad) { i = '0' + i; pad--; }
10753    j = (j = i.length) > groupLength ? j % groupLength : 0;
10754    re = new RegExp("(\\d{" + groupLength + "})(?=\\d)", "g");
10755
10756    /**
10757     * replace(/-/, 0) is only for fixing Safari bug which appears
10758     * when Math.abs(0).toFixed() executed on "0" number.
10759     * Result is "0.-0" :(
10760     */
10761    var r = (j ? i.substr(0, j) + groupSymbol : "") + i.substr(j).replace(re, "$1" + groupSymbol) + (precision ? decimalSymbol + Math.abs(price - i).toFixed(precision).replace(/-/, 0).slice(2) : "")
10762    var pattern = '';
10763    if (format.pattern.indexOf('{sign}') == -1) {
10764        pattern = s + format.pattern;
10765    } else {
10766        pattern = format.pattern.replace('{sign}', s);
10767    }
10768
10769    return pattern.replace('%s', r).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
10770};
10771
10772function expandDetails(el, childClass) {
10773    if (Element.hasClassName(el,'show-details')) {
10774        $$(childClass).each(function(item){item.hide()});
10775        Element.removeClassName(el,'show-details');
10776    }
10777    else {
10778        $$(childClass).each(function(item){item.show()});
10779        Element.addClassName(el,'show-details');
10780    }
10781}
10782
10783// Version 1.0
10784var isIE = navigator.appVersion.match(/MSIE/) == "MSIE";
10785
10786if (!window.Varien)
10787    var Varien = new Object();
10788
10789Varien.showLoading = function(){
10790    var loader = $('loading-process');
10791    loader && loader.show();
10792}
10793Varien.hideLoading = function(){
10794    var loader = $('loading-process');
10795    loader && loader.hide();
10796}
10797Varien.GlobalHandlers = {
10798    onCreate: function() {
10799        Varien.showLoading();
10800    },
10801
10802    onComplete: function() {
10803        if(Ajax.activeRequestCount == 0) {
10804            Varien.hideLoading();
10805        }
10806    }
10807};
10808
10809Ajax.Responders.register(Varien.GlobalHandlers);
10810
10811/**
10812 * Quick Search form client model
10813 */
10814Varien.searchForm = Class.create();
10815Varien.searchForm.prototype = {
10816    initialize : function(form, field, emptyText){
10817        this.form   = $(form);
10818        this.field  = $(field);
10819        this.emptyText = emptyText;
10820
10821        Event.observe(this.form,  'submit', this.submit.bind(this));
10822        Event.observe(this.field, 'focus', this.focus.bind(this));
10823        Event.observe(this.field, 'blur', this.blur.bind(this));
10824        this.blur();
10825    },
10826
10827    submit : function(event){
10828        if (this.field.value == this.emptyText || this.field.value == ''){
10829            Event.stop(event);
10830            return false;
10831        }
10832        return true;
10833    },
10834
10835    focus : function(event){
10836        if(this.field.value==this.emptyText){
10837            this.field.value='';
10838        }
10839
10840    },
10841
10842    blur : function(event){
10843        if(this.field.value==''){
10844            this.field.value=this.emptyText;
10845        }
10846    },
10847
10848    initAutocomplete : function(url, destinationElement){
10849        new Ajax.Autocompleter(
10850            this.field,
10851            destinationElement,
10852            url,
10853            {
10854                paramName: this.field.name,
10855                method: 'get',
10856                minChars: 2,
10857                updateElement: this._selectAutocompleteItem.bind(this),
10858                onShow : function(element, update) {
10859                    if(!update.style.position || update.style.position=='absolute') {
10860                        update.style.position = 'absolute';
10861                        Position.clone(element, update, {
10862                            setHeight: false,
10863                            offsetTop: element.offsetHeight
10864                        });
10865                    }
10866                    Effect.Appear(update,{duration:0});
10867                }
10868
10869            }
10870        );
10871    },
10872
10873    _selectAutocompleteItem : function(element){
10874        if(element.title){
10875            this.field.value = element.title;
10876        }
10877        this.form.submit();
10878    }
10879}
10880
10881Varien.Tabs = Class.create();
10882Varien.Tabs.prototype = {
10883  initialize: function(selector) {
10884    var self=this;
10885    $$(selector+' a').each(this.initTab.bind(this));
10886  },
10887
10888  initTab: function(el) {
10889      el.href = 'javascript:void(0)';
10890      if ($(el.parentNode).hasClassName('active')) {
10891        this.showContent(el);
10892      }
10893      el.observe('click', this.showContent.bind(this, el));
10894  },
10895
10896  showContent: function(a) {
10897    var li = $(a.parentNode), ul = $(li.parentNode);
10898    ul.getElementsBySelector('li', 'ol').each(function(el){
10899      var contents = $(el.id+'_contents');
10900      if (el==li) {
10901        el.addClassName('active');
10902        contents.show();
10903      } else {
10904        el.removeClassName('active');
10905        contents.hide();
10906      }
10907    });
10908  }
10909}
10910
10911Varien.DateElement = Class.create();
10912Varien.DateElement.prototype = {
10913    initialize: function(type, content, required, format) {
10914        if (type == 'id') {
10915            // id prefix
10916            this.day    = $(content + 'day');
10917            this.month  = $(content + 'month');
10918            this.year   = $(content + 'year');
10919            this.full   = $(content + 'full');
10920            this.advice = $(content + 'date-advice');
10921        } else if (type == 'container') {
10922            // content must be container with data
10923            this.day    = content.day;
10924            this.month  = content.month;
10925            this.year   = content.year;
10926            this.full   = content.full;
10927            this.advice = content.advice;
10928        } else {
10929            return;
10930        }
10931
10932        this.required = required;
10933        this.format   = format;
10934
10935        this.day.addClassName('validate-custom');
10936        this.day.validate = this.validate.bind(this);
10937        this.month.addClassName('validate-custom');
10938        this.month.validate = this.validate.bind(this);
10939        this.year.addClassName('validate-custom');
10940        this.year.validate = this.validate.bind(this);
10941
10942        this.setDateRange(false, false);
10943        this.year.setAttribute('autocomplete','off');
10944
10945        this.advice.hide();
10946    },
10947    validate: function() {
10948        var error = false,
10949            day   = parseInt(this.day.value, 10)   || 0,
10950            month = parseInt(this.month.value, 10) || 0,
10951            year  = parseInt(this.year.value, 10)  || 0;
10952        if (this.day.value.strip().empty()
10953            && this.month.value.strip().empty()
10954            && this.year.value.strip().empty()
10955        ) {
10956            if (this.required) {
10957                error = 'This date is a required value.';
10958            } else {
10959                this.full.value = '';
10960            }
10961        } else if (!day || !month || !year) {
10962            error = 'Please enter a valid full date.';
10963        } else {
10964            var date = new Date, countDaysInMonth = 0, errorType = null;
10965            date.setYear(year);date.setMonth(month-1);date.setDate(32);
10966            countDaysInMonth = 32 - date.getDate();
10967            if(!countDaysInMonth || countDaysInMonth>31) countDaysInMonth = 31;
10968
10969            if (day<1 || day>countDaysInMonth) {
10970                errorType = 'day';
10971                error = 'Please enter a valid day (1-%d).';
10972            } else if (month<1 || month>12) {
10973                errorType = 'month';
10974                error = 'Please enter a valid month (1-12).';
10975            } else {
10976                if(day % 10 == day) this.day.value = '0'+day;
10977                if(month % 10 == month) this.month.value = '0'+month;
10978                this.full.value = this.format.replace(/%[mb]/i, this.month.value).replace(/%[de]/i, this.day.value).replace(/%y/i, this.year.value);
10979                var testFull = this.month.value + '/' + this.day.value + '/'+ this.year.value;
10980                var test = new Date(testFull);
10981                if (isNaN(test)) {
10982                    error = 'Please enter a valid date.';
10983                } else {
10984                    this.setFullDate(test);
10985                }
10986            }
10987            var valueError = false;
10988            if (!error && !this.validateData()){//(year<1900 || year>curyear) {
10989                errorType = this.validateDataErrorType;//'year';
10990                valueError = this.validateDataErrorText;//'Please enter a valid year (1900-%d).';
10991                error = valueError;
10992            }
10993        }
10994
10995        if (error !== false) {
10996            try {
10997                error = Translator.translate(error);
10998            }
10999            catch (e) {}
11000            if (!valueError) {
11001                this.advice.innerHTML = error.replace('%d', countDaysInMonth);
11002            } else {
11003                this.advice.innerHTML = this.errorTextModifier(error);
11004            }
11005            this.advice.show();
11006            return false;
11007        }
11008
11009        // fixing elements class
11010        this.day.removeClassName('validation-failed');
11011        this.month.removeClassName('validation-failed');
11012        this.year.removeClassName('validation-failed');
11013
11014        this.advice.hide();
11015        return true;
11016    },
11017    validateData: function() {
11018        var year = this.fullDate.getFullYear();
11019        var date = new Date;
11020        this.curyear = date.getFullYear();
11021        return (year>=1900 && year<=this.curyear);
11022    },
11023    validateDataErrorType: 'year',
11024    validateDataErrorText: 'Please enter a valid year (1900-%d).',
11025    errorTextModifier: function(text) {
11026        return text.replace('%d', this.curyear);
11027    },
11028    setDateRange: function(minDate, maxDate) {
11029        this.minDate = minDate;
11030        this.maxDate = maxDate;
11031    },
11032    setFullDate: function(date) {
11033        this.fullDate = date;
11034    }
11035};
11036
11037Varien.DOB = Class.create();
11038Varien.DOB.prototype = {
11039    initialize: function(selector, required, format) {
11040        var el = $$(selector)[0];
11041        var container       = {};
11042        container.day       = Element.select(el, '.dob-day input')[0];
11043        container.month     = Element.select(el, '.dob-month input')[0];
11044        container.year      = Element.select(el, '.dob-year input')[0];
11045        container.full      = Element.select(el, '.dob-full input')[0];
11046        container.advice    = Element.select(el, '.validation-advice')[0];
11047
11048        new Varien.DateElement('container', container, required, format);
11049    }
11050};
11051
11052Varien.dateRangeDate = Class.create();
11053Varien.dateRangeDate.prototype = Object.extend(new Varien.DateElement(), {
11054    validateData: function() {
11055        var validate = true;
11056        if (this.minDate || this.maxValue) {
11057            if (this.minDate) {
11058                this.minDate = new Date(this.minDate);
11059                this.minDate.setHours(0);
11060                if (isNaN(this.minDate)) {
11061                    this.minDate = new Date('1/1/1900');
11062                }
11063                validate = validate && (this.fullDate >= this.minDate)
11064            }
11065            if (this.maxDate) {
11066                this.maxDate = new Date(this.maxDate)
11067                this.minDate.setHours(0);
11068                if (isNaN(this.maxDate)) {
11069                    this.maxDate = new Date();
11070                }
11071                validate = validate && (this.fullDate <= this.maxDate)
11072            }
11073            if (this.maxDate && this.minDate) {
11074                this.validateDataErrorText = 'Please enter a valid date between %s and %s';
11075            } else if (this.maxDate) {
11076                this.validateDataErrorText = 'Please enter a valid date less than or equal to %s';
11077            } else if (this.minDate) {
11078                this.validateDataErrorText = 'Please enter a valid date equal to or greater than %s';
11079            } else {
11080                this.validateDataErrorText = '';
11081            }
11082        }
11083        return validate;
11084    },
11085    validateDataErrorText: 'Date should be between %s and %s',
11086    errorTextModifier: function(text) {
11087        if (this.minDate) {
11088            text = text.sub('%s', this.dateFormat(this.minDate));
11089        }
11090        if (this.maxDate) {
11091            text = text.sub('%s', this.dateFormat(this.maxDate));
11092        }
11093        return text;
11094    },
11095    dateFormat: function(date) {
11096        return (date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear();
11097    }
11098});
11099
11100Varien.FileElement = Class.create();
11101Varien.FileElement.prototype = {
11102    initialize: function (id) {
11103        this.fileElement = $(id);
11104        this.hiddenElement = $(id + '_value');
11105
11106        this.fileElement.observe('change', this.selectFile.bind(this));
11107    },
11108    selectFile: function(event) {
11109        this.hiddenElement.value = this.fileElement.getValue();
11110    }
11111};
11112
11113/**
11114 * Create form element. Set parameters into it and send
11115 *
11116 * @param url
11117 * @param parametersArray
11118 * @param method
11119 */
11120Varien.formCreator = Class.create();
11121Varien.formCreator.prototype = {
11122    initialize : function(url, parametersArray, method) {
11123        this.url = url;
11124        this.parametersArray = JSON.parse(parametersArray);
11125        this.method = method;
11126        this.form = '';
11127
11128        this.createForm();
11129        this.setFormData();
11130    },
11131    createForm : function() {
11132        this.form = new Element('form', { 'method': this.method, action: this.url });
11133    },
11134    setFormData : function () {
11135        for (var key in this.parametersArray) {
11136            Element.insert(
11137                this.form,
11138                new Element('input', { name: key, value: this.parametersArray[key], type: 'hidden' })
11139            );
11140        }
11141    }
11142};
11143
11144Validation.addAllThese([
11145    ['validate-custom', ' ', function(v,elm) {
11146        return elm.validate();
11147    }]
11148]);
11149
11150function truncateOptions() {
11151    $$('.truncated').each(function(element){
11152        Event.observe(element, 'mouseover', function(){
11153            if (element.down('div.truncated_full_value')) {
11154                element.down('div.truncated_full_value').addClassName('show')
11155            }
11156        });
11157        Event.observe(element, 'mouseout', function(){
11158            if (element.down('div.truncated_full_value')) {
11159                element.down('div.truncated_full_value').removeClassName('show')
11160            }
11161        });
11162
11163    });
11164}
11165
11166if (typeof jQuery != 'undefined') {
11167    jQuery.noConflict();
11168}
11169
11170Event.observe(window, 'load', function(){
11171   truncateOptions();
11172});
11173
11174Element.addMethods({
11175    getInnerText: function(element)
11176    {
11177        element = $(element);
11178        if(element.innerText && !Prototype.Browser.Opera) {
11179            return element.innerText
11180        }
11181        return element.innerHTML.stripScripts().unescapeHTML().replace(/[\n\r\s]+/g, ' ').strip();
11182    }
11183});
11184
11185/*
11186if (!("console" in window) || !("firebug" in console))
11187{
11188    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
11189    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
11190
11191    window.console = {};
11192    for (var i = 0; i < names.length; ++i)
11193        window.console[names[i]] = function() {}
11194}
11195*/
11196
11197/**
11198 * Executes event handler on the element. Works with event handlers attached by Prototype,
11199 * in a browser-agnostic fashion.
11200 * @param element The element object
11201 * @param event Event name, like 'change'
11202 *
11203 * @example fireEvent($('my-input', 'click'));
11204 */
11205function fireEvent(element, event) {
11206    if (document.createEvent) {
11207        // dispatch for all browsers except IE before version 9
11208        var evt = document.createEvent("HTMLEvents");
11209        evt.initEvent(event, true, true ); // event type, bubbling, cancelable
11210        return element.dispatchEvent(evt);
11211    } else {
11212        // dispatch for IE before version 9
11213        var evt = document.createEventObject();
11214        return element.fireEvent('on' + event, evt)
11215    }
11216}
11217
11218/**
11219 * Returns more accurate results of floating-point modulo division
11220 * E.g.:
11221 * 0.6 % 0.2 = 0.19999999999999996
11222 * modulo(0.6, 0.2) = 0
11223 *
11224 * @param dividend
11225 * @param divisor
11226 */
11227function modulo(dividend, divisor)
11228{
11229    var epsilon = divisor / 10000;
11230    var remainder = dividend % divisor;
11231
11232    if (Math.abs(remainder - divisor) < epsilon || Math.abs(remainder) < epsilon) {
11233        remainder = 0;
11234    }
11235
11236    return remainder;
11237}
11238
11239/**
11240 * createContextualFragment is not supported in IE9. Adding its support.
11241 */
11242if ((typeof Range != "undefined") && !Range.prototype.createContextualFragment)
11243{
11244    Range.prototype.createContextualFragment = function(html)
11245    {
11246        var frag = document.createDocumentFragment(),
11247        div = document.createElement("div");
11248        frag.appendChild(div);
11249        div.outerHTML = html;
11250        return frag;
11251    };
11252}
11253
11254function customFormSubmit(url, parametersArray, method) {
11255    var createdForm = new Varien.formCreator(url, parametersArray, method);
11256    Element.insert($$('body')[0], createdForm.form);
11257    createdForm.form.submit();
11258}
11259
11260function customFormSubmitToParent(url, parametersArray, method) {
11261    new Ajax.Request(url, {
11262        method: method,
11263        parameters: JSON.parse(parametersArray),
11264        onSuccess: function (response) {
11265            var node = document.createElement('div');
11266            node.innerHTML = response.responseText;
11267            var responseMessage = node.getElementsByClassName('messages')[0];
11268            var pageTitle = window.document.body.getElementsByClassName('page-title')[0];
11269            pageTitle.insertAdjacentHTML('afterend', responseMessage.outerHTML);
11270            window.opener.focus();
11271            window.opener.location.href = response.transport.responseURL;
11272        }
11273    });
11274}
11275
11276/**
11277 * Magento
11278 *
11279 * NOTICE OF LICENSE
11280 *
11281 * This source file is subject to the Academic Free License (AFL 3.0)
11282 * that is bundled with this package in the file LICENSE_AFL.txt.
11283 * It is also available through the world-wide-web at this URL:
11284 * http://opensource.org/licenses/afl-3.0.php
11285 * If you did not receive a copy of the license and are unable to
11286 * obtain it through the world-wide-web, please send an email
11287 * to [email protected] so we can send you a copy immediately.
11288 *
11289 * DISCLAIMER
11290 *
11291 * Do not edit or add to this file if you wish to upgrade Magento to newer
11292 * versions in the future. If you wish to customize Magento for your
11293 * needs please refer to http://www.magentocommerce.com for more information.
11294 *
11295 * @category    Varien
11296 * @package     js
11297 * @copyright   Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
11298 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
11299 */
11300VarienForm = Class.create();
11301VarienForm.prototype = {
11302    initialize: function(formId, firstFieldFocus){
11303        this.form       = $(formId);
11304        if (!this.form) {
11305            return;
11306        }
11307        this.cache      = $A();
11308        this.currLoader = false;
11309        this.currDataIndex = false;
11310        this.validator  = new Validation(this.form);
11311        this.elementFocus   = this.elementOnFocus.bindAsEventListener(this);
11312        this.elementBlur    = this.elementOnBlur.bindAsEventListener(this);
11313        this.childLoader    = this.onChangeChildLoad.bindAsEventListener(this);
11314        this.highlightClass = 'highlight';
11315        this.extraChildParams = '';
11316        this.firstFieldFocus= firstFieldFocus || false;
11317        this.bindElements();
11318        if(this.firstFieldFocus){
11319            try{
11320                Form.Element.focus(Form.findFirstElement(this.form))
11321            }
11322            catch(e){}
11323        }
11324    },
11325
11326    submit : function(url){
11327        if(this.validator && this.validator.validate()){
11328             this.form.submit();
11329        }
11330        return false;
11331    },
11332
11333    bindElements:function (){
11334        var elements = Form.getElements(this.form);
11335        for (var row in elements) {
11336            if (elements[row].id) {
11337                Event.observe(elements[row],'focus',this.elementFocus);
11338                Event.observe(elements[row],'blur',this.elementBlur);
11339            }
11340        }
11341    },
11342
11343    elementOnFocus: function(event){
11344        var element = Event.findElement(event, 'fieldset');
11345        if(element){
11346            Element.addClassName(element, this.highlightClass);
11347        }
11348    },
11349
11350    elementOnBlur: function(event){
11351        var element = Event.findElement(event, 'fieldset');
11352        if(element){
11353            Element.removeClassName(element, this.highlightClass);
11354        }
11355    },
11356
11357    setElementsRelation: function(parent, child, dataUrl, first){
11358        if (parent=$(parent)) {
11359            // TODO: array of relation and caching
11360            if (!this.cache[parent.id]){
11361                this.cache[parent.id] = $A();
11362                this.cache[parent.id]['child']     = child;
11363                this.cache[parent.id]['dataUrl']   = dataUrl;
11364                this.cache[parent.id]['data']      = $A();
11365                this.cache[parent.id]['first']      = first || false;
11366            }
11367            Event.observe(parent,'change',this.childLoader);
11368        }
11369    },
11370
11371    onChangeChildLoad: function(event){
11372        element = Event.element(event);
11373        this.elementChildLoad(element);
11374    },
11375
11376    elementChildLoad: function(element, callback){
11377        this.callback = callback || false;
11378        if (element.value) {
11379            this.currLoader = element.id;
11380            this.currDataIndex = element.value;
11381            if (this.cache[element.id]['data'][element.value]) {
11382                this.setDataToChild(this.cache[element.id]['data'][element.value]);
11383            }
11384            else{
11385                new Ajax.Request(this.cache[this.currLoader]['dataUrl'],{
11386                        method: 'post',
11387                        parameters: {"parent":element.value},
11388                        onComplete: this.reloadChildren.bind(this)
11389                });
11390            }
11391        }
11392    },
11393
11394    reloadChildren: function(transport){
11395        var data = eval('(' + transport.responseText + ')');
11396        this.cache[this.currLoader]['data'][this.currDataIndex] = data;
11397        this.setDataToChild(data);
11398    },
11399
11400    setDataToChild: function(data){
11401        if (data.length) {
11402            var child = $(this.cache[this.currLoader]['child']);
11403            if (child){
11404                var html = '<select name="'+child.name+'" id="'+child.id+'" class="'+child.className+'" title="'+child.title+'" '+this.extraChildParams+'>';
11405                if(this.cache[this.currLoader]['first']){
11406                    html+= '<option value="">'+this.cache[this.currLoader]['first']+'</option>';
11407                }
11408                for (var i in data){
11409                    if(data[i].value) {
11410                        html+= '<option value="'+data[i].value+'"';
11411                        if(child.value && (child.value == data[i].value || child.value == data[i].label)){
11412                            html+= ' selected';
11413                        }
11414                        html+='>'+data[i].label+'</option>';
11415                    }
11416                }
11417                html+= '</select>';
11418                Element.insert(child, {before: html});
11419                Element.remove(child);
11420            }
11421        }
11422        else{
11423            var child = $(this.cache[this.currLoader]['child']);
11424            if (child){
11425                var html = '<input type="text" name="'+child.name+'" id="'+child.id+'" class="'+child.className+'" title="'+child.title+'" '+this.extraChildParams+'>';
11426                Element.insert(child, {before: html});
11427                Element.remove(child);
11428            }
11429        }
11430
11431        this.bindElements();
11432        if (this.callback) {
11433            this.callback();
11434        }
11435    }
11436}
11437
11438RegionUpdater = Class.create();
11439RegionUpdater.prototype = {
11440    initialize: function (countryEl, regionTextEl, regionSelectEl, regions, disableAction, zipEl)
11441    {
11442        this.countryEl = $(countryEl);
11443        this.regionTextEl = $(regionTextEl);
11444        this.regionSelectEl = $(regionSelectEl);
11445        this.zipEl = $(zipEl);
11446        this.config = regions['config'];
11447        delete regions.config;
11448        this.regions = regions;
11449
11450        this.disableAction = (typeof disableAction=='undefined') ? 'hide' : disableAction;
11451        this.zipOptions = (typeof zipOptions=='undefined') ? false : zipOptions;
11452
11453        if (this.regionSelectEl.options.length<=1) {
11454            this.update();
11455        }
11456
11457        Event.observe(this.countryEl, 'change', this.update.bind(this));
11458    },
11459
11460    _checkRegionRequired: function()
11461    {
11462        var label, wildCard;
11463        var elements = [this.regionTextEl, this.regionSelectEl];
11464        var that = this;
11465        if (typeof this.config == 'undefined') {
11466            return;
11467        }
11468        var regionRequired = this.config.regions_required.indexOf(this.countryEl.value) >= 0;
11469
11470        elements.each(function(currentElement) {
11471            Validation.reset(currentElement);
11472            label = $$('label[for="' + currentElement.id + '"]')[0];
11473            if (label) {
11474                wildCard = label.down('em') || label.down('span.required');
11475                if (!that.config.show_all_regions) {
11476                    if (regionRequired) {
11477                        label.up().show();
11478                    } else {
11479                        label.up().hide();
11480                    }
11481                }
11482            }
11483
11484            if (label && wildCard) {
11485                if (!regionRequired) {
11486                    wildCard.hide();
11487                    if (label.hasClassName('required')) {
11488                        label.removeClassName('required');
11489                    }
11490                } else if (regionRequired) {
11491                    wildCard.show();
11492                    if (!label.hasClassName('required')) {
11493                        label.addClassName('required')
11494                    }
11495                }
11496            }
11497
11498            if (!regionRequired) {
11499                if (currentElement.hasClassName('required-entry')) {
11500                    currentElement.removeClassName('required-entry');
11501                }
11502                if ('select' == currentElement.tagName.toLowerCase() &&
11503                    currentElement.hasClassName('validate-select')) {
11504                    currentElement.removeClassName('validate-select');
11505                }
11506            } else {
11507                if (!currentElement.hasClassName('required-entry')) {
11508                    currentElement.addClassName('required-entry');
11509                }
11510                if ('select' == currentElement.tagName.toLowerCase() &&
11511                    !currentElement.hasClassName('validate-select')) {
11512                    currentElement.addClassName('validate-select');
11513                }
11514            }
11515        });
11516    },
11517
11518    update: function()
11519    {
11520        if (this.regions[this.countryEl.value]) {
11521            var i, option, region, def;
11522
11523            def = this.regionSelectEl.getAttribute('defaultValue');
11524            if (this.regionTextEl) {
11525                if (!def) {
11526                    def = this.regionTextEl.value.toLowerCase();
11527                }
11528                this.regionTextEl.value = '';
11529            }
11530
11531            this.regionSelectEl.options.length = 1;
11532            for (regionId in this.regions[this.countryEl.value]) {
11533                region = this.regions[this.countryEl.value][regionId];
11534
11535                option = document.createElement('OPTION');
11536                option.value = regionId;
11537                option.text = region.name.stripTags();
11538                option.title = region.name;
11539
11540                if (this.regionSelectEl.options.add) {
11541                    this.regionSelectEl.options.add(option);
11542                } else {
11543                    this.regionSelectEl.appendChild(option);
11544                }
11545
11546                if (regionId==def || (region.name && region.name.toLowerCase()==def) ||
11547                    (region.name && region.code.toLowerCase()==def)
11548                ) {
11549                    this.regionSelectEl.value = regionId;
11550                }
11551            }
11552
11553            if (this.disableAction=='hide') {
11554                if (this.regionTextEl) {
11555                    this.regionTextEl.style.display = 'none';
11556                }
11557
11558                this.regionSelectEl.style.display = '';
11559            } else if (this.disableAction=='disable') {
11560                if (this.regionTextEl) {
11561                    this.regionTextEl.disabled = true;
11562                }
11563                this.regionSelectEl.disabled = false;
11564            }
11565            this.setMarkDisplay(this.regionSelectEl, true);
11566        } else {
11567            this.regionSelectEl.options.length = 1;
11568            if (this.disableAction=='hide') {
11569                if (this.regionTextEl) {
11570                    this.regionTextEl.style.display = '';
11571                }
11572                this.regionSelectEl.style.display = 'none';
11573                Validation.reset(this.regionSelectEl);
11574            } else if (this.disableAction=='disable') {
11575                if (this.regionTextEl) {
11576                    this.regionTextEl.disabled = false;
11577                }
11578                this.regionSelectEl.disabled = true;
11579            } else if (this.disableAction=='nullify') {
11580                this.regionSelectEl.options.length = 1;
11581                this.regionSelectEl.value = '';
11582                this.regionSelectEl.selectedIndex = 0;
11583                this.lastCountryId = '';
11584            }
11585            this.setMarkDisplay(this.regionSelectEl, false);
11586        }
11587
11588        this._checkRegionRequired();
11589        // Make Zip and its label required/optional
11590        var zipUpdater = new ZipUpdater(this.countryEl.value, this.zipEl);
11591        zipUpdater.update();
11592    },
11593
11594    setMarkDisplay: function(elem, display){
11595        elem = $(elem);
11596        var labelElement = elem.up(0).down('label > span.required') ||
11597                           elem.up(1).down('label > span.required') ||
11598                           elem.up(0).down('label.required > em') ||
11599                           elem.up(1).down('label.required > em');
11600        if(labelElement) {
11601            inputElement = labelElement.up().next('input');
11602            if (display) {
11603                labelElement.show();
11604                if (inputElement) {
11605                    inputElement.addClassName('required-entry');
11606                }
11607            } else {
11608                labelElement.hide();
11609                if (inputElement) {
11610                    inputElement.removeClassName('required-entry');
11611                }
11612            }
11613        }
11614    }
11615}
11616
11617ZipUpdater = Class.create();
11618ZipUpdater.prototype = {
11619    initialize: function(country, zipElement)
11620    {
11621        this.country = country;
11622        this.zipElement = $(zipElement);
11623    },
11624
11625    update: function()
11626    {
11627        // Country ISO 2-letter codes must be pre-defined
11628        if (typeof optionalZipCountries == 'undefined') {
11629            return false;
11630        }
11631
11632        // Ajax-request and normal content load compatibility
11633        if (this.zipElement != undefined) {
11634            Validation.reset(this.zipElement)
11635            this._setPostcodeOptional();
11636        } else {
11637            Event.observe(window, "load", this._setPostcodeOptional.bind(this));
11638        }
11639    },
11640
11641    _setPostcodeOptional: function()
11642    {
11643        this.zipElement = $(this.zipElement);
11644        if (this.zipElement == undefined) {
11645            return false;
11646        }
11647
11648        // find label
11649        var label = $$('label[for="' + this.zipElement.id + '"]')[0];
11650        if (label != undefined) {
11651            var wildCard = label.down('em') || label.down('span.required');
11652        }
11653
11654        // Make Zip and its label required/optional
11655        if (optionalZipCountries.indexOf(this.country) != -1) {
11656            while (this.zipElement.hasClassName('required-entry')) {
11657                this.zipElement.removeClassName('required-entry');
11658            }
11659            if (wildCard != undefined) {
11660                wildCard.hide();
11661            }
11662        } else {
11663            this.zipElement.addClassName('required-entry');
11664            if (wildCard != undefined) {
11665                wildCard.show();
11666            }
11667        }
11668    }
11669}
11670
11671/**
11672 * Magento
11673 *
11674 * NOTICE OF LICENSE
11675 *
11676 * This source file is subject to the Academic Free License (AFL 3.0)
11677 * that is bundled with this package in the file LICENSE_AFL.txt.
11678 * It is also available through the world-wide-web at this URL:
11679 * http://opensource.org/licenses/afl-3.0.php
11680 * If you did not receive a copy of the license and are unable to
11681 * obtain it through the world-wide-web, please send an email
11682 * to [email protected] so we can send you a copy immediately.
11683 *
11684 * DISCLAIMER
11685 *
11686 * Do not edit or add to this file if you wish to upgrade Magento to newer
11687 * versions in the future. If you wish to customize Magento for your
11688 * needs please refer to http://www.magentocommerce.com for more information.
11689 *
11690 * @category    Mage
11691 * @package     js
11692 * @copyright   Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
11693 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
11694 */
11695
11696var Translate = Class.create();
11697Translate.prototype = {
11698    initialize: function(data){
11699        this.data = $H(data);
11700    },
11701
11702    translate : function(){
11703        var args = arguments;
11704        var text = arguments[0];
11705
11706        if(this.data.get(text)){
11707            return this.data.get(text);
11708        }
11709        return text;
11710    },
11711    add : function() {
11712        if (arguments.length > 1) {
11713            this.data.set(arguments[0], arguments[1]);
11714        } else if (typeof arguments[0] =='object') {
11715            $H(arguments[0]).each(function (pair){
11716                this.data.set(pair.key, pair.value);
11717            }.bind(this));
11718        }
11719    }
11720}
11721
11722/**
11723 * Magento
11724 *
11725 * NOTICE OF LICENSE
11726 *
11727 * This source file is subject to the Academic Free License (AFL 3.0)
11728 * that is bundled with this package in the file LICENSE_AFL.txt.
11729 * It is also available through the world-wide-web at this URL:
11730 * http://opensource.org/licenses/afl-3.0.php
11731 * If you did not receive a copy of the license and are unable to
11732 * obtain it through the world-wide-web, please send an email
11733 * to [email protected] so we can send you a copy immediately.
11734 *
11735 * DISCLAIMER
11736 *
11737 * Do not edit or add to this file if you wish to upgrade Magento to newer
11738 * versions in the future. If you wish to customize Magento for your
11739 * needs please refer to http://www.magentocommerce.com for more information.
11740 *
11741 * @category    Mage
11742 * @package     js
11743 * @copyright   Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
11744 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
11745 */
11746// old school cookie functions grabbed off the web
11747
11748if (!window.Mage) var Mage = {};
11749
11750Mage.Cookies = {};
11751Mage.Cookies.expires  = null;
11752Mage.Cookies.path     = '/';
11753Mage.Cookies.domain   = null;
11754Mage.Cookies.secure   = false;
11755Mage.Cookies.set = function(name, value){
11756     var argv = arguments;
11757     var argc = arguments.length;
11758     var expires = (argc > 2) ? argv[2] : Mage.Cookies.expires;
11759     var path = (argc > 3) ? argv[3] : Mage.Cookies.path;
11760     var domain = (argc > 4) ? argv[4] : Mage.Cookies.domain;
11761     var secure = (argc > 5) ? argv[5] : Mage.Cookies.secure;
11762     document.cookie = name + "=" + escape (value) +
11763       ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
11764       ((path == null) ? "" : ("; path=" + path)) +
11765       ((domain == null) ? "" : ("; domain=" + domain)) +
11766       ((secure == true) ? "; secure" : "");
11767};
11768
11769Mage.Cookies.get = function(name){
11770    var arg = name + "=";
11771    var alen = arg.length;
11772    var clen = document.cookie.length;
11773    var i = 0;
11774    var j = 0;
11775    while(i < clen){
11776        j = i + alen;
11777        if (document.cookie.substring(i, j) == arg)
11778            return Mage.Cookies.getCookieVal(j);
11779        i = document.cookie.indexOf(" ", i) + 1;
11780        if(i == 0)
11781            break;
11782    }
11783    return null;
11784};
11785
11786Mage.Cookies.clear = function(name) {
11787  if(Mage.Cookies.get(name)){
11788    document.cookie = name + "=" +
11789    "; expires=Thu, 01-Jan-70 00:00:01 GMT";
11790  }
11791};
11792
11793Mage.Cookies.getCookieVal = function(offset){
11794   var endstr = document.cookie.indexOf(";", offset);
11795   if(endstr == -1){
11796       endstr = document.cookie.length;
11797   }
11798   return unescape(document.cookie.substring(offset, endstr));
11799};
11800
11801/**
11802 * Magento
11803 *
11804 * NOTICE OF LICENSE
11805 *
11806 * This source file is subject to the Academic Free License (AFL 3.0)
11807 * that is bundled with this package in the file LICENSE_AFL.txt.
11808 * It is also available through the world-wide-web at this URL:
11809 * http://opensource.org/licenses/afl-3.0.php
11810 * If you did not receive a copy of the license and are unable to
11811 * obtain it through the world-wide-web, please send an email
11812 * to [email protected] so we can send you a copy immediately.
11813 *
11814 * DISCLAIMER
11815 *
11816 * Do not edit or add to this file if you wish to upgrade Magento to newer
11817 * versions in the future. If you wish to customize Magento for your
11818 * needs please refer to http://www.magentocommerce.com for more information.
11819 *
11820 * @category    Varien
11821 * @package     js
11822 * @copyright   Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
11823 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
11824 */
11825
11826/**************************** WEEE STUFF ********************************/
11827function taxToggle(details, switcher, expandedClassName)
11828{
11829    if ($(details).style.display == 'none') {
11830        $(details).show();
11831        $(switcher).addClassName(expandedClassName);
11832    } else {
11833        $(details).hide();
11834        $(switcher).removeClassName(expandedClassName);
11835    }
11836}
11837
11838/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
11839 * Build: http://modernizr.com/download/#-localstorage-touch-shiv-mq-cssclasses-teststyles-prefixes-load
11840 */
11841;window.Modernizr=function(a,b,c){function x(a){j.cssText=a}function y(a,b){return x(m.join(a+";")+(b||""))}function z(a,b){return typeof a===b}function A(a,b){return!!~(""+a).indexOf(b)}function B(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:z(f,"function")?f.bind(d||b):f}return!1}var d="2.6.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n={},o={},p={},q=[],r=q.slice,s,t=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["&#173;",'<style id="s',h,'">',a,"</style>"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},u=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return t("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},v={}.hasOwnProperty,w;
vendor: 8,013 bytes, lines 11841-11863
11841!z(v,"undefined")&&!z(v.call,"undefined")?w=function(a,b){return v.call(a,b)}:w=function(a,b){return b in a&&z(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=r.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(r.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(r.call(arguments)))};return e}),n.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:t(["@media (",m.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},n.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}};for(var C in n)w(n,C)&&(s=C.toLowerCase(),e[s]=n[C](),q.push((e[s]?"":"no-")+s));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)w(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},x(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e<g;e++)d.createElement(f[e]);return d}function p(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return r.shivMethods?n(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+l().join().replace(/\w+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(r,b.frag)}function q(a){a||(a=b);var c=m(a);return r.shivCSS&&!f&&!c.hasCSS&&(c.hasCSS=!!k(a,"article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}mark{background:#FF0;color:#000}")),j||p(a,c),a}var c=a.html5||{},d=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,e=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,f,g="_html5shiv",h=0,i={},j;(function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=m,e.mq=u,e.testStyles=t,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+q.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))};
11842
11843/*
11844selectivizr v1.0.2 - (c) Keith Clark, freely distributable under the terms 
11845of the MIT license.
11846
11847selectivizr.com
11848*/
11849/* 
11850  
11851Notes about this source
11852-----------------------
11853
11854 * The #DEBUG_START and #DEBUG_END comments are used to mark blocks of code
11855   that will be removed prior to building a final release version (using a
11856   pre-compression script)
11857  
11858  
11859References:
11860-----------
11861 
11862 * CSS Syntax          : http://www.w3.org/TR/2003/WD-css3-syntax-20030813/#style
11863 * Selectors           : http://www.w3.org/TR/css3-selectors/#selectors
vendor: 11,973 bytes, lines 11864-12125
11864 * IE Compatability    : http://msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx
11865 * W3C Selector Tests  : http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/
11866 
11867*/
11868
11869(function(win) {
11870
11871    // If browser isn't IE, then stop execution! This handles the script 
11872    // being loaded by non IE browsers because the developer didn't use 
11873    // conditional comments.
11874    if (/*@cc_on!@*/true) return;
11875
11876    // =========================== Init Objects ============================
11877
11878    var doc = document;
11879    var root = doc.documentElement;
11880    var xhr = getXHRObject();
11881    var ieVersion = /MSIE (\d+)/.exec(navigator.userAgent)[1];
11882    
11883    // If were not in standards mode, IE is too old / new or we can't create
11884    // an XMLHttpRequest object then we should get out now.
11885    if (doc.compatMode != 'CSS1Compat' || ieVersion<6 || ieVersion>8 || !xhr) {
11886        return;
11887    }
11888    
11889    
11890    // ========================= Common Objects ============================
11891
11892    // Compatiable selector engines in order of CSS3 support. Note: '*' is
11893    // a placholder for the object key name. (basically, crude compression)
11894    var selectorEngines = {
11895        "NW"                                : "*.Dom.select",
11896        "MooTools"                          : "$$",
11897        "DOMAssistant"                      : "*.$", 
11898        "Prototype"                         : "$$",
11899        "YAHOO"                             : "*.util.Selector.query",
11900        "Sizzle"                            : "*", 
11901        "jQuery"                            : "*",
11902        "dojo"                              : "*.query"
11903    };
11904
11905    var selectorMethod;
11906    var enabledWatchers                     = [];     // array of :enabled/:disabled elements to poll
11907    var ie6PatchID                          = 0;      // used to solve ie6's multiple class bug
11908    var patchIE6MultipleClasses             = true;   // if true adds class bloat to ie6
11909    var namespace                           = "slvzr";
11910    
11911    // Stylesheet parsing regexp's
11912    var RE_COMMENT                          = /(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)\s*/g;
11913    var RE_IMPORT                           = /@import\s*(?:(?:(?:url\(\s*(['"]?)(.*)\1)\s*\))|(?:(['"])(.*)\3))[^;]*;/g;
11914    var RE_ASSET_URL                        = /\burl\(\s*(["']?)(?!data:)([^"')]+)\1\s*\)/g;
11915    var RE_PSEUDO_STRUCTURAL                = /^:(empty|(first|last|only|nth(-last)?)-(child|of-type))$/;
11916    var RE_PSEUDO_ELEMENTS                  = /:(:first-(?:line|letter))/g;
11917    var RE_SELECTOR_GROUP                   = /(^|})\s*([^\{]*?[\[:][^{]+)/g;
11918    var RE_SELECTOR_PARSE                   = /([ +~>])|(:[a-z-]+(?:\(.*?\)+)?)|(\[.*?\])/g; 
11919    var RE_LIBRARY_INCOMPATIBLE_PSEUDOS     = /(:not\()?:(hover|enabled|disabled|focus|checked|target|active|visited|first-line|first-letter)\)?/g;
11920    var RE_PATCH_CLASS_NAME_REPLACE         = /[^\w-]/g;
11921    
11922    // HTML UI element regexp's
11923    var RE_INPUT_ELEMENTS                   = /^(INPUT|SELECT|TEXTAREA|BUTTON)$/;
11924    var RE_INPUT_CHECKABLE_TYPES            = /^(checkbox|radio)$/;
11925
11926    // Broken attribute selector implementations (IE7/8 native [^=""], [$=""] and [*=""])
11927    var BROKEN_ATTR_IMPLEMENTATIONS         = ieVersion>6 ? /[\$\^*]=(['"])\1/ : null;
11928
11929    // Whitespace normalization regexp's
11930    var RE_TIDY_TRAILING_WHITESPACE         = /([(\[+~])\s+/g;
11931    var RE_TIDY_LEADING_WHITESPACE          = /\s+([)\]+~])/g;
11932    var RE_TIDY_CONSECUTIVE_WHITESPACE      = /\s+/g;
11933    var RE_TIDY_TRIM_WHITESPACE             = /^\s*((?:[\S\s]*\S)?)\s*$/;
11934    
11935    // String constants
11936    var EMPTY_STRING                        = "";
11937    var SPACE_STRING                        = " ";
11938    var PLACEHOLDER_STRING                  = "$1";
11939
11940    // =========================== Patching ================================
11941
11942    // --[ patchStyleSheet() ]----------------------------------------------
11943    // Scans the passed cssText for selectors that require emulation and
11944    // creates one or more patches for each matched selector.
11945    function patchStyleSheet( cssText ) {
11946        return cssText.replace(RE_PSEUDO_ELEMENTS, PLACEHOLDER_STRING).
11947            replace(RE_SELECTOR_GROUP, function(m, prefix, selectorText) {  
11948                var selectorGroups = selectorText.split(",");
11949                for (var c = 0, cs = selectorGroups.length; c < cs; c++) {
11950                    var selector = normalizeSelectorWhitespace(selectorGroups[c]) + SPACE_STRING;
11951                    var patches = [];
11952                    selectorGroups[c] = selector.replace(RE_SELECTOR_PARSE, 
11953                        function(match, combinator, pseudo, attribute, index) {
11954                            if (combinator) {
11955                                if (patches.length>0) {
11956                                    applyPatches( selector.substring(0, index), patches );
11957                                    patches = [];
11958                                }
11959                                return combinator;
11960                            }       
11961                            else {
11962                                var patch = (pseudo) ? patchPseudoClass( pseudo ) : patchAttribute( attribute );
11963                                if (patch) {
11964                                    patches.push(patch);
11965                                    return "." + patch.className;
11966                                }
11967                                return match;
11968                            }
11969                        }
11970                    );
11971                }
11972                return prefix + selectorGroups.join(",");
11973            });
11974    };
11975
11976    // --[ patchAttribute() ]-----------------------------------------------
11977    // returns a patch for an attribute selector.
11978    function patchAttribute( attr ) {
11979        return (!BROKEN_ATTR_IMPLEMENTATIONS || BROKEN_ATTR_IMPLEMENTATIONS.test(attr)) ? 
11980            { className: createClassName(attr), applyClass: true } : null;
11981    };
11982
11983    // --[ patchPseudoClass() ]---------------------------------------------
11984    // returns a patch for a pseudo-class
11985    function patchPseudoClass( pseudo ) {
11986
11987        var applyClass = true;
11988        var className = createClassName(pseudo.slice(1));
11989        var isNegated = pseudo.substring(0, 5) == ":not(";
11990        var activateEventName;
11991        var deactivateEventName;
11992
11993        // if negated, remove :not() 
11994        if (isNegated) {
11995            pseudo = pseudo.slice(5, -1);
11996        }
11997        
11998        // bracket contents are irrelevant - remove them
11999        var bracketIndex = pseudo.indexOf("(")
12000        if (bracketIndex > -1) {
12001            pseudo = pseudo.substring(0, bracketIndex);
12002        }       
12003        
12004        // check we're still dealing with a pseudo-class
12005        if (pseudo.charAt(0) == ":") {
12006            switch (pseudo.slice(1)) {
12007
12008                case "root":
12009                    applyClass = function(e) {
12010                        return isNegated ? e != root : e == root;
12011                    }
12012                    break;
12013
12014                case "target":
12015                    // :target is only supported in IE8
12016                    if (ieVersion == 8) {
12017                        applyClass = function(e) {
12018                            var handler = function() { 
12019                                var hash = location.hash;
12020                                var hashID = hash.slice(1);
12021                                return isNegated ? (hash == EMPTY_STRING || e.id != hashID) : (hash != EMPTY_STRING && e.id == hashID);
12022                            };
12023                            addEvent( win, "hashchange", function() {
12024                                toggleElementClass(e, className, handler());
12025                            })
12026                            return handler();
12027                        }
12028                        break;
12029                    }
12030                    return false;
12031                
12032                case "checked":
12033                    applyClass = function(e) { 
12034                        if (RE_INPUT_CHECKABLE_TYPES.test(e.type)) {
12035                            addEvent( e, "propertychange", function() {
12036                                if (event.propertyName == "checked") {
12037                                    toggleElementClass( e, className, e.checked !== isNegated );
12038                                }                           
12039                            })
12040                        }
12041                        return e.checked !== isNegated;
12042                    }
12043                    break;
12044                    
12045                case "disabled":
12046                    isNegated = !isNegated;
12047
12048                case "enabled":
12049                    applyClass = function(e) { 
12050                        if (RE_INPUT_ELEMENTS.test(e.tagName)) {
12051                            addEvent( e, "propertychange", function() {
12052                                if (event.propertyName == "$disabled") {
12053                                    toggleElementClass( e, className, e.$disabled === isNegated );
12054                                } 
12055                            });
12056                            enabledWatchers.push(e);
12057                            e.$disabled = e.disabled;
12058                            return e.disabled === isNegated;
12059                        }
12060                        return pseudo == ":enabled" ? isNegated : !isNegated;
12061                    }
12062                    break;
12063                    
12064                case "focus":
12065                    activateEventName = "focus";
12066                    deactivateEventName = "blur";
12067                                
12068                case "hover":
12069                    if (!activateEventName) {
12070                        activateEventName = "mouseenter";
12071                        deactivateEventName = "mouseleave";
12072                    }
12073                    applyClass = function(e) {
12074                        addEvent( e, isNegated ? deactivateEventName : activateEventName, function() {
12075                            toggleElementClass( e, className, true );
12076                        })
12077                        addEvent( e, isNegated ? activateEventName : deactivateEventName, function() {
12078                            toggleElementClass( e, className, false );
12079                        })
12080                        return isNegated;
12081                    }
12082                    break;
12083                    
12084                // everything else
12085                default:
12086                    // If we don't support this pseudo-class don't create 
12087                    // a patch for it
12088                    if (!RE_PSEUDO_STRUCTURAL.test(pseudo)) {
12089                        return false;
12090                    }
12091                    break;
12092            }
12093        }
12094        return { className: className, applyClass: applyClass };
12095    };
12096
12097    // --[ applyPatches() ]-------------------------------------------------
12098    // uses the passed selector text to find DOM nodes and patch them   
12099    function applyPatches(selectorText, patches) {
12100        var elms;
12101        
12102        // Although some selector libraries can find :checked :enabled etc. 
12103        // we need to find all elements that could have that state because 
12104        // it can be changed by the user.
12105        var domSelectorText = selectorText.replace(RE_LIBRARY_INCOMPATIBLE_PSEUDOS, EMPTY_STRING);
12106        
12107        // If the dom selector equates to an empty string or ends with 
12108        // whitespace then we need to append a universal selector (*) to it.
12109        if (domSelectorText == EMPTY_STRING || domSelectorText.charAt(domSelectorText.length - 1) == SPACE_STRING) {
12110            domSelectorText += "*";
12111        }
12112        
12113        // Ensure we catch errors from the selector library
12114        try {
12115            elms = selectorMethod( domSelectorText );
12116        } catch (ex) {
12117            // #DEBUG_START
12118            log( "Selector '" + selectorText + "' threw exception '" + ex + "'" );
12119            // #DEBUG_END
12120        }
12121
12122
12123        if (elms) {
12124            for (var d = 0, dl = elms.length; d < dl; d++) {    
12125                var elm = elms[d];
12126                var cssClasses = elm.className;
12127                for (var f = 0, fl = patches.length; f < fl; f++) {
12128                    var patch = patches[f];
12129                    
12130                    if (!hasPatch(elm, patch)) {
12131                        if (patch.applyClass && (patch.applyClass === true || patch.applyClass(elm) === true)) {
12132                            cssClasses = toggleClass(cssClasses, patch.className, true );
12133                        }
12134                    }
12135                }
12136                elm.className = cssClasses;
12137            }
12138        }
12139    };
12140
12141    // --[ hasPatch() ]-----------------------------------------------------
12142    // checks for the exsistence of a patch on an element
12143    function hasPatch( elm, patch ) {
12144        return new RegExp("(^|\\s)" + patch.className + "(\\s|$)").test(elm.className);
12145    };
12146    
12147    
12148    // =========================== Utility =================================
12149    
12150    function createClassName( className ) {
12151        return namespace + "-" + ((ieVersion == 6 && patchIE6MultipleClasses) ?
12152            ie6PatchID++
12153        :
12154            className.replace(RE_PATCH_CLASS_NAME_REPLACE, function(a) { return a.charCodeAt(0) }));
12155    };
12156
12157    // --[ log() ]----------------------------------------------------------
12158    // #DEBUG_START
12159    function log( message ) {
12160        if (win.console) {
12161            win.console.log(message);
12162        }
12163    };
12164    // #DEBUG_END
12165
12166    // --[ trim() ]---------------------------------------------------------
12167    // removes leading, trailing whitespace from a string
12168    function trim( text ) {
12169        return text.replace(RE_TIDY_TRIM_WHITESPACE, PLACEHOLDER_STRING);
12170    };
12171
12172    // --[ normalizeWhitespace() ]------------------------------------------
12173    // removes leading, trailing and consecutive whitespace from a string
12174    function normalizeWhitespace( text ) {
12175        return trim(text).replace(RE_TIDY_CONSECUTIVE_WHITESPACE, SPACE_STRING);
12176    };
12177
12178    // --[ normalizeSelectorWhitespace() ]----------------------------------
12179    // tidies whitespace around selector brackets and combinators
12180    function normalizeSelectorWhitespace( selectorText ) {
12181        return normalizeWhitespace(selectorText.
12182            replace(RE_TIDY_TRAILING_WHITESPACE, PLACEHOLDER_STRING).
12183            replace(RE_TIDY_LEADING_WHITESPACE, PLACEHOLDER_STRING)
12184        );
12185    };
12186
12187    // --[ toggleElementClass() ]-------------------------------------------
12188    // toggles a single className on an element
12189    function toggleElementClass( elm, className, on ) {
12190        var oldClassName = elm.className;
12191        var newClassName = toggleClass(oldClassName, className, on);
12192        if (newClassName != oldClassName) {
12193            elm.className = newClassName;
12194            elm.parentNode.className += EMPTY_STRING;
12195        }
12196    };
12197
12198    // --[ toggleClass() ]--------------------------------------------------
12199    // adds / removes a className from a string of classNames. Used to 
12200    // manage multiple class changes without forcing a DOM redraw
12201    function toggleClass( classList, className, on ) {
12202        var re = RegExp("(^|\\s)" + className + "(\\s|$)");
12203        var classExists = re.test(classList);
12204        if (on) {
12205            return classExists ? classList : classList + SPACE_STRING + className;
12206        } else {
12207            return classExists ? trim(classList.replace(re, PLACEHOLDER_STRING)) : classList;
12208        }
12209    };
12210    
12211    // --[ addEvent() ]-----------------------------------------------------
12212    function addEvent(elm, eventName, eventHandler) {
12213        elm.attachEvent("on" + eventName, eventHandler);
12214    };
12215
12216    // --[ getXHRObject() ]-------------------------------------------------
12217    function getXHRObject()
12218    {
12219        if (win.XMLHttpRequest) {
12220            return new XMLHttpRequest;
12221        }
12222        try { 
12223            return new ActiveXObject('Microsoft.XMLHTTP');
12224        } catch(e) { 
12225            return null;
12226        }
12227    };
12228
12229    // --[ loadStyleSheet() ]-----------------------------------------------
12230    function loadStyleSheet( url ) {
12231        xhr.open("GET", url, false);
12232        xhr.send();
12233        return (xhr.status==200) ? xhr.responseText : EMPTY_STRING; 
12234    };
12235    
12236    // --[ resolveUrl() ]---------------------------------------------------
12237    // Converts a URL fragment to a fully qualified URL using the specified
12238    // context URL. Returns null if same-origin policy is broken
12239    function resolveUrl( url, contextUrl ) {
12240    
12241        function getProtocolAndHost( url ) {
12242            return url.substring(0, url.indexOf("/", 8));
12243        };
12244        
12245        // absolute path
12246        if (/^https?:\/\//i.test(url)) {
12247            return getProtocolAndHost(contextUrl) == getProtocolAndHost(url) ? url : null;
12248        }
12249        
12250        // root-relative path
12251        if (url.charAt(0)=="/") {
12252            return getProtocolAndHost(contextUrl) + url;
12253        }
12254
12255        // relative path
12256        var contextUrlPath = contextUrl.split(/[?#]/)[0]; // ignore query string in the contextUrl  
12257        if (url.charAt(0) != "?" && contextUrlPath.charAt(contextUrlPath.length - 1) != "/") {
12258            contextUrlPath = contextUrlPath.substring(0, contextUrlPath.lastIndexOf("/") + 1);
12259        }
12260        
12261        return contextUrlPath + url;
12262    };
12263    
12264    // --[ parseStyleSheet() ]----------------------------------------------
12265    // Downloads the stylesheet specified by the URL, removes it's comments
12266    // and recursivly replaces @import rules with their contents, ultimately
12267    // returning the full cssText.
12268    function parseStyleSheet( url ) {
12269        if (url) {
12270            return loadStyleSheet(url).replace(RE_COMMENT, EMPTY_STRING).
12271            replace(RE_IMPORT, function( match, quoteChar, importUrl, quoteChar2, importUrl2 ) { 
12272                return parseStyleSheet(resolveUrl(importUrl || importUrl2, url));
12273            }).
12274            replace(RE_ASSET_URL, function( match, quoteChar, assetUrl ) { 
12275                quoteChar = quoteChar || EMPTY_STRING;
12276                return " url(" + quoteChar + resolveUrl(assetUrl, url) + quoteChar + ") "; 
12277            });
12278        }
12279        return EMPTY_STRING;
12280    };
12281    
12282    // --[ init() ]---------------------------------------------------------
12283    function init() {
12284        // honour the <base> tag
12285        var url, stylesheet;
12286        var baseTags = doc.getElementsByTagName("BASE");
12287        var baseUrl = (baseTags.length > 0) ? baseTags[0].href : doc.location.href;
12288        
12289        /* Note: This code prevents IE from freezing / crashing when using 
12290        @font-face .eot files but it modifies the <head> tag and could
12291        trigger the IE stylesheet limit. It will also cause FOUC issues.
12292        If you choose to use it, make sure you comment out the for loop 
12293        directly below this comment.
12294
12295        var head = doc.getElementsByTagName("head")[0];
12296        for (var c=doc.styleSheets.length-1; c>=0; c--) {
12297            stylesheet = doc.styleSheets[c]
12298            head.appendChild(doc.createElement("style"))
12299            var patchedStylesheet = doc.styleSheets[doc.styleSheets.length-1];
12300            
12301            if (stylesheet.href != EMPTY_STRING) {
12302                url = resolveUrl(stylesheet.href, baseUrl)
12303                if (url) {
12304                    patchedStylesheet.cssText = patchStyleSheet( parseStyleSheet( url ) )
12305                    stylesheet.disabled = true
12306                    setTimeout( function () {
12307                        stylesheet.owningElement.parentNode.removeChild(stylesheet.owningElement)
12308                    })
12309                }
12310            }
12311        }
12312        */
12313        
12314        for (var c = 0; c < doc.styleSheets.length; c++) {
12315            stylesheet = doc.styleSheets[c]
12316            if (stylesheet.href != EMPTY_STRING) {
12317                url = resolveUrl(stylesheet.href, baseUrl);
12318                if (url) {
12319                    stylesheet.cssText = patchStyleSheet( parseStyleSheet( url ) );
12320                }
12321            }
12322        }
12323        
12324        // :enabled & :disabled polling script (since we can't hook 
12325        // onpropertychange event when an element is disabled) 
12326        if (enabledWatchers.length > 0) {
12327            setInterval( function() {
12328                for (var c = 0, cl = enabledWatchers.length; c < cl; c++) {
12329                    var e = enabledWatchers[c];
12330                    if (e.disabled !== e.$disabled) {
12331                        if (e.disabled) {
12332                            e.disabled = false;
12333                            e.$disabled = true;
12334                            e.disabled = true;
12335                        }
12336                        else {
12337                            e.$disabled = e.disabled;
12338                        }
12339                    }
12340                }
12341            },250)
12342        }
12343    };
12344    
12345    // Bind selectivizr to the ContentLoaded event. 
12346    ContentLoaded(win, function() {
12347        // Determine the "best fit" selector engine
12348        for (var engine in selectorEngines) {
12349            var members, member, context = win;
12350            if (win[engine]) {
12351                members = selectorEngines[engine].replace("*", engine).split(".");
12352                while ((member = members.shift()) && (context = context[member])) {}
12353                if (typeof context == "function") {
12354                    selectorMethod = context;
12355                    init();
12356                    return;
12357                }
12358            }
12359        }
12360    });
12361    
12362    
12363    /*!
12364     * ContentLoaded.js by Diego Perini, modified for IE<9 only (to save space)
12365     *
12366     * Author: Diego Perini (diego.perini at gmail.com)
12367     * Summary: cross-browser wrapper for DOMContentLoaded
12368     * Updated: 20101020
12369     * License: MIT
12370     * Version: 1.2
12371     *
12372     * URL:
12373     * http://javascript.nwbox.com/ContentLoaded/
12374     * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
12375     *
12376     */
12377
12378    // @w window reference
12379    // @f function reference
12380    function ContentLoaded(win, fn) {
12381
12382        var done = false, top = true,
12383        init = function(e) {
12384            if (e.type == "readystatechange" && doc.readyState != "complete") return;
12385            (e.type == "load" ? win : doc).detachEvent("on" + e.type, init, false);
12386            if (!done && (done = true)) fn.call(win, e.type || e);
12387        },
12388        poll = function() {
12389            try { root.doScroll("left"); } catch(e) { setTimeout(poll, 50); return; }
12390            init('poll');
12391        };
12392
12393        if (doc.readyState == "complete") fn.call(win, EMPTY_STRING);
12394        else {
12395            if (doc.createEventObject && root.doScroll) {
12396                try { top = !win.frameElement; } catch(e) { }
12397                if (top) poll();
12398            }
12399            addEvent(doc,"readystatechange", init);
12400            addEvent(win,"load", init);
12401        }
12402    };
12403})(this);
12404
12405/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */
12406
12407window.matchMedia || (window.matchMedia = function() {
12408    "use strict";
12409
12410    // For browsers that support matchMedium api such as IE 9 and webkit
12411    var styleMedia = (window.styleMedia || window.media);
12412
12413    // For those that don't support matchMedium
12414    if (!styleMedia) {
12415        var style       = document.createElement('style'),
12416            script      = document.getElementsByTagName('script')[0],
12417            info        = null;
12418
12419        style.type  = 'text/css';
12420        style.id    = 'matchmediajs-test';
12421
12422        script.parentNode.insertBefore(style, script);
12423
12424        // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
12425        info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;
12426
12427        styleMedia = {
12428            matchMedium: function(media) {
12429                var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';
12430
12431                // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
12432                if (style.styleSheet) {
12433                    style.styleSheet.cssText = text;
12434                } else {
12435                    style.textContent = text;
12436                }
12437
12438                // Test if media query is true or false
12439                return info.width === '1px';
12440            }
12441        };
12442    }
12443
12444    return function(media) {
12445        return {
12446            matches: styleMedia.matchMedium(media || 'all'),
12447            media: media || 'all'
12448        };
12449    };
12450}());
12451
12452/*! matchMedia() polyfill addListener/removeListener extension. Author & copyright (c) 2012: Scott Jehl. Dual MIT/BSD license */
12453(function(){
12454    // Bail out for browsers that have addListener support
12455    if (window.matchMedia && window.matchMedia('all').addListener) {
12456        return false;
12457    }
12458
12459    var localMatchMedia = window.matchMedia,
12460        hasMediaQueries = localMatchMedia('only all').matches,
12461        isListening     = false,
12462        timeoutID       = 0,    // setTimeout for debouncing 'handleChange'
12463        queries         = [],   // Contains each 'mql' and associated 'listeners' if 'addListener' is used
12464        handleChange    = function(evt) {
12465            // Debounce
12466            clearTimeout(timeoutID);
12467
12468            timeoutID = setTimeout(function() {
12469                for (var i = 0, il = queries.length; i < il; i++) {
12470                    var mql         = queries[i].mql,
12471                        listeners   = queries[i].listeners || [],
12472                        matches     = localMatchMedia(mql.media).matches;
12473
12474                    // Update mql.matches value and call listeners
12475                    // Fire listeners only if transitioning to or from matched state
12476                    if (matches !== mql.matches) {
12477                        mql.matches = matches;
12478
12479                        for (var j = 0, jl = listeners.length; j < jl; j++) {
12480                            listeners[j].call(window, mql);
12481                        }
12482                    }
12483                }
12484            }, 30);
12485        };
12486
12487    window.matchMedia = function(media) {
12488        var mql         = localMatchMedia(media),
12489            listeners   = [],
12490            index       = 0;
12491
12492        mql.addListener = function(listener) {
12493            // Changes would not occur to css media type so return now (Affects IE <= 8)
12494            if (!hasMediaQueries) {
12495                return;
12496            }
12497
12498            // Set up 'resize' listener for browsers that support CSS3 media queries (Not for IE <= 8)
12499            // There should only ever be 1 resize listener running for performance
12500            if (!isListening) {
12501                isListening = true;
12502                window.addEventListener('resize', handleChange, true);
12503            }
12504
12505            // Push object only if it has not been pushed already
12506            if (index === 0) {
12507                index = queries.push({
12508                    mql         : mql,
12509                    listeners   : listeners
12510                });
12511            }
12512
12513            listeners.push(listener);
12514        };
12515
12516        mql.removeListener = function(listener) {
12517            for (var i = 0, il = listeners.length; i < il; i++){
12518                if (listeners[i] === listener){
12519                    listeners.splice(i, 1);
12520                }
12521            }
12522        };
12523
12524        return mql;
12525    };
12526}());
12527
12528/*!
12529 * enquire.js v2.1.0 - Awesome Media Queries in JavaScript
12530 * Copyright (c) 2013 Nick Williams - http://wicky.nillia.ms/enquire.js
12531 * License: MIT (http://www.opensource.org/licenses/mit-license.php)
12532 */
12533
12534;(function (name, context, factory) {
12535    var matchMedia = context.matchMedia;
12536
12537    if (typeof module !== 'undefined' && module.exports) {
12538        module.exports = factory(matchMedia);
12539    }
12540    else if (typeof define === 'function' && define.amd) {
12541        define(function() {
12542            return (context[name] = factory(matchMedia));
12543        });
12544    }
12545    else {
12546        context[name] = factory(matchMedia);
12547    }
12548}('enquire', this, function (matchMedia) {
12549
12550    'use strict';
12551
12552    /*jshint unused:false */
12553    /**
12554     * Helper function for iterating over a collection
12555     *
12556     * @param collection
12557     * @param fn
12558     */
12559    function each(collection, fn) {
12560        var i      = 0,
12561            length = collection.length,
12562            cont;
12563
12564        for(i; i < length; i++) {
12565            cont = fn(collection[i], i);
12566            if(cont === false) {
12567                break; //allow early exit
12568            }
12569        }
12570    }
12571
12572    /**
12573     * Helper function for determining whether target object is an array
12574     *
12575     * @param target the object under test
12576     * @return {Boolean} true if array, false otherwise
12577     */
12578    function isArray(target) {
12579        return Object.prototype.toString.apply(target) === '[object Array]';
12580    }
12581
12582    /**
12583     * Helper function for determining whether target object is a function
12584     *
12585     * @param target the object under test
12586     * @return {Boolean} true if function, false otherwise
12587     */
12588    function isFunction(target) {
12589        return typeof target === 'function';
12590    }
12591
12592    /**
12593     * Delegate to handle a media query being matched and unmatched.
12594     *
12595     * @param {object} options
12596     * @param {function} options.match callback for when the media query is matched
12597     * @param {function} [options.unmatch] callback for when the media query is unmatched
12598     * @param {function} [options.setup] one-time callback triggered the first time a query is matched
12599     * @param {boolean} [options.deferSetup=false] should the setup callback be run immediately, rather than first time query is matched?
12600     * @constructor
12601     */
12602    function QueryHandler(options) {
12603        this.options = options;
12604        !options.deferSetup && this.setup();
12605    }
12606    QueryHandler.prototype = {
12607
12608        /**
12609         * coordinates setup of the handler
12610         *
12611         * @function
12612         */
12613        setup : function() {
12614            if(this.options.setup) {
12615                this.options.setup();
12616            }
12617            this.initialised = true;
12618        },
12619
12620        /**
12621         * coordinates setup and triggering of the handler
12622         *
12623         * @function
12624         */
12625        on : function() {
12626            !this.initialised && this.setup();
12627            this.options.match && this.options.match();
12628        },
12629
12630        /**
12631         * coordinates the unmatch event for the handler
12632         *
12633         * @function
12634         */
12635        off : function() {
12636            this.options.unmatch && this.options.unmatch();
12637        },
12638
12639        /**
12640         * called when a handler is to be destroyed.
12641         * delegates to the destroy or unmatch callbacks, depending on availability.
12642         *
12643         * @function
12644         */
12645        destroy : function() {
12646            this.options.destroy ? this.options.destroy() : this.off();
12647        },
12648
12649        /**
12650         * determines equality by reference.
12651         * if object is supplied compare options, if function, compare match callback
12652         *
12653         * @function
12654         * @param {object || function} [target] the target for comparison
12655         */
12656        equals : function(target) {
12657            return this.options === target || this.options.match === target;
12658        }
12659
12660    };
12661    /**
12662     * Represents a single media query, manages it's state and registered handlers for this query
12663     *
12664     * @constructor
12665     * @param {string} query the media query string
12666     * @param {boolean} [isUnconditional=false] whether the media query should run regardless of whether the conditions are met. Primarily for helping older browsers deal with mobile-first design
12667     */
12668    function MediaQuery(query, isUnconditional) {
12669        this.query = query;
12670        this.isUnconditional = isUnconditional;
12671        this.handlers = [];
12672        this.mql = matchMedia(query);
12673
12674        var self = this;
12675        this.listener = function(mql) {
12676            self.mql = mql;
12677            self.assess();
12678        };
12679        this.mql.addListener(this.listener);
12680    }
12681    MediaQuery.prototype = {
12682
12683        /**
12684         * add a handler for this query, triggering if already active
12685         *
12686         * @param {object} handler
12687         * @param {function} handler.match callback for when query is activated
12688         * @param {function} [handler.unmatch] callback for when query is deactivated
12689         * @param {function} [handler.setup] callback for immediate execution when a query handler is registered
12690         * @param {boolean} [handler.deferSetup=false] should the setup callback be deferred until the first time the handler is matched?
12691         */
12692        addHandler : function(handler) {
12693            var qh = new QueryHandler(handler);
12694            this.handlers.push(qh);
12695
12696            this.matches() && qh.on();
12697        },
12698
12699        /**
12700         * removes the given handler from the collection, and calls it's destroy methods
12701         * 
12702         * @param {object || function} handler the handler to remove
12703         */
12704        removeHandler : function(handler) {
12705            var handlers = this.handlers;
12706            each(handlers, function(h, i) {
12707                if(h.equals(handler)) {
12708                    h.destroy();
12709                    return !handlers.splice(i,1); //remove from array and exit each early
12710                }
12711            });
12712        },
12713
12714        /**
12715         * Determine whether the media query should be considered a match
12716         * 
12717         * @return {Boolean} true if media query can be considered a match, false otherwise
12718         */
12719        matches : function() {
12720            return this.mql.matches || this.isUnconditional;
12721        },
12722
12723        /**
12724         * Clears all handlers and unbinds events
12725         */
12726        clear : function() {
12727            each(this.handlers, function(handler) {
12728                handler.destroy();
12729            });
12730            this.mql.removeListener(this.listener);
12731            this.handlers.length = 0; //clear array
12732        },
12733
12734        /*
12735         * Assesses the query, turning on all handlers if it matches, turning them off if it doesn't match
12736         */
12737        assess : function() {
12738            var action = this.matches() ? 'on' : 'off';
12739
12740            each(this.handlers, function(handler) {
12741                handler[action]();
12742            });
12743        }
12744    };
12745    /**
12746     * Allows for registration of query handlers.
12747     * Manages the query handler's state and is responsible for wiring up browser events
12748     *
12749     * @constructor
12750     */
12751    function MediaQueryDispatch () {
12752        if(!matchMedia) {
12753            throw new Error('matchMedia not present, legacy browsers require a polyfill');
12754        }
12755
12756        this.queries = {};
12757        this.browserIsIncapable = !matchMedia('only all').matches;
12758    }
12759
12760    MediaQueryDispatch.prototype = {
12761
12762        /**
12763         * Registers a handler for the given media query
12764         *
12765         * @param {string} q the media query
12766         * @param {object || Array || Function} options either a single query handler object, a function, or an array of query handlers
12767         * @param {function} options.match fired when query matched
12768         * @param {function} [options.unmatch] fired when a query is no longer matched
12769         * @param {function} [options.setup] fired when handler first triggered
12770         * @param {boolean} [options.deferSetup=false] whether setup should be run immediately or deferred until query is first matched
12771         * @param {boolean} [shouldDegrade=false] whether this particular media query should always run on incapable browsers
12772         */
12773        register : function(q, options, shouldDegrade) {
12774            var queries         = this.queries,
12775                isUnconditional = shouldDegrade && this.browserIsIncapable;
12776
12777            if(!queries[q]) {
12778                queries[q] = new MediaQuery(q, isUnconditional);
12779            }
12780
12781            //normalise to object in an array
12782            if(isFunction(options)) {
12783                options = { match : options };
12784            }
12785            if(!isArray(options)) {
12786                options = [options];
12787            }
12788            each(options, function(handler) {
12789                queries[q].addHandler(handler);
12790            });
12791
12792            return this;
12793        },
12794
12795        /**
12796         * unregisters a query and all it's handlers, or a specific handler for a query
12797         *
12798         * @param {string} q the media query to target
12799         * @param {object || function} [handler] specific handler to unregister
12800         */
12801        unregister : function(q, handler) {
12802            var query = this.queries[q];
12803
12804            if(query) {
12805                if(handler) {
12806                    query.removeHandler(handler);
12807                }
12808                else {
12809                    query.clear();
12810                    delete this.queries[q];
12811                }
12812            }
12813
12814            return this;
12815        }
12816    };
12817
12818    return new MediaQueryDispatch();
12819
12820}));
12821
12822/**
12823 * Magento
12824 *
12825 * NOTICE OF LICENSE
12826 *
12827 * This source file is subject to the Academic Free License (AFL 3.0)
12828 * that is bundled with this package in the file LICENSE_AFL.txt.
12829 * It is also available through the world-wide-web at this URL:
12830 * http://opensource.org/licenses/afl-3.0.php
12831 * If you did not receive a copy of the license and are unable to
12832 * obtain it through the world-wide-web, please send an email
12833 * to [email protected] so we can send you a copy immediately.
12834 *
12835 * DISCLAIMER
12836 *
12837 * Do not edit or add to this file if you wish to upgrade Magento to newer
12838 * versions in the future. If you wish to customize Magento for your
12839 * needs please refer to http://www.magentocommerce.com for more information.
12840 *
12841 * @category    design
12842 * @package     default_default
12843 * @copyright   Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
12844 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
12845 */
12846
12847// =============================================
12848// Primary Break Points
12849// =============================================
12850
12851// These should be used with the bp (max-width, xx) mixin
12852// where a min-width is used, remember to +1 to break correctly
12853// If these are changed, they must also be updated in _var.scss
12854
12855var bp = {
12856    xsmall: 479,
12857    small: 599,
12858    medium: 770,
12859    large: 979,
12860    xlarge: 1199
12861}
12862
12863// ==============================================
12864// Search
12865// ==============================================
12866
12867Varien.searchForm.prototype.initialize = function (form, field, emptyText) {
12868    this.form = $(form);
12869    this.field = $(field);
12870    this.emptyText = emptyText;
12871
12872    this.validator = new Validation(this.form);
12873
12874    Event.observe(this.form, 'submit', this.submit.bind(this));
12875    Event.observe(this.field, 'focus', this.focus.bind(this));
12876    Event.observe(this.field, 'blur', this.blur.bind(this));
12877    this.blur();
12878}
12879
12880Varien.searchForm.prototype.submit = function (event) {
12881    if (!this.validator || !this.validator.validate()) {
12882        Event.stop(event);
12883        return false;
12884    }
12885    return true;
12886}
12887
12888// ==============================================
12889// jQuery Init
12890// ==============================================
12891
12892// Avoid PrototypeJS conflicts, assign jQuery to $j instead of $
12893var $j = jQuery.noConflict();
12894
12895// Use $j(document).ready() because Magento executes Prototype inline
12896$j(document).ready(function () {
12897
12898    // ==============================================
12899    // Shared Vars
12900    // ==============================================
12901
12902    // Document
12903    var w = $j(window);
12904    var d = $j(document);
12905    var body = $j('body');
12906
12907    // =============================================
12908    // Skip Links
12909    // =============================================
12910
12911    var skipContents = $j('.skip-content');
12912    var skipLinks = $j('.skip-link');
12913
12914    skipLinks.on('click', function (e) {
12915        e.preventDefault();
12916
12917        var self = $j(this);
12918        var target = self.attr('href');
12919
12920        // Get target element
12921        var elem = $j(target);
12922
12923        // Check if stub is open
12924        var isSkipContentOpen = elem.hasClass('skip-active') ? 1 : 0;
12925
12926        // Hide all stubs
12927        skipLinks.removeClass('skip-active');
12928        skipContents.removeClass('skip-active');
12929
12930        // Toggle stubs
12931        if (isSkipContentOpen) {
12932            self.removeClass('skip-active');
12933        } else {
12934            self.addClass('skip-active');
12935            elem.addClass('skip-active');
12936        }
12937    });
12938
12939    $j('#header-cart').on('click', '.skip-link-close', function(e) {
12940        var parent = $j(this).parents('.skip-content');
12941        var link = parent.siblings('.skip-link');
12942
12943        parent.removeClass('skip-active');
12944        link.removeClass('skip-active');
12945
12946        e.preventDefault();
12947    });
12948
12949
12950    // ==============================================
12951    // Header Menus
12952    // ==============================================
12953
12954    var nav = $j('#nav');
12955
12956    // ----------------------------------------------
12957    // Top Menus
12958
12959    var MenuManagerState = {
12960        TOUCH_SCROLL_THRESHOLD: 20,
12961
12962        touchStartPosition: null,
12963
12964        shouldCancelTouch: function() {
12965            if(!this.touchStartPosition) {
12966                return false;
12967            }
12968
12969            var scroll = $j(window).scrollTop() - this.touchStartPosition;
12970            return Math.abs(scroll) > this.TOUCH_SCROLL_THRESHOLD;
12971        }
12972    };
12973
12974    var pointerEvent = 'touchend';
12975    // If device has implemented touch/click agnostic event, use it instead of "click"
12976    if (window.navigator.pointerEnabled) {
12977        pointerEvent = 'pointerdown';
12978    } else if (window.navigator.msPointerEnabled) {
12979        pointerEvent = 'MSPointerDown';
12980    }
12981    nav.find('a.has-children.level0').on(pointerEvent,function (event) {
12982        //scroll occurred, cancel event
12983        if(MenuManagerState.shouldCancelTouch()) {
12984            return;
12985        }
12986
12987        // If mouse is being used on large viewport, use native hover state
12988        if (window.navigator.msPointerEnabled
12989            && event.originalEvent.pointerType == 'mouse'
12990            && Modernizr.mq("screen and (min-width:" + (bp.medium + 1) + "px)")
12991        ) {
12992            $j(this).data('has-touch', false);
12993            return;
12994        }
12995        $j(this).data('has-touch', true);
12996        var elem = $j(this).parent();
12997
12998        var alreadyExpanded = elem.hasClass('menu-active');
12999
13000        nav.find('li.level0').removeClass('menu-active');
13001
13002        // Collapse all active sub-menus
13003        nav.find('.sub-menu-active').removeClass('sub-menu-active');
13004
13005        if (!alreadyExpanded) {
13006            elem.addClass('menu-active');
13007        }
13008
13009        event.preventDefault();
13010    }).on('click', function (event) {
13011        var elem = $j(this);
13012        if (elem.data('has-touch')) {
13013            elem.data('has-touch', false);
13014            event.preventDefault();
13015            return;
13016        }
13017
13018        if(Modernizr.mq("screen and (max-width:" + bp.medium + "px)")) {
13019            var elem = $j(this).parent();
13020
13021            var alreadyExpanded = elem.hasClass('menu-active');
13022
13023            nav.find('li.level0').removeClass('menu-active');
13024
13025            // Collapse all active sub-menus
13026            nav.find('.sub-menu-active').removeClass('sub-menu-active');
13027
13028            if (!alreadyExpanded) {
13029                elem.addClass('menu-active');
13030            }
13031
13032            event.preventDefault();
13033        }
13034    }).on('touchstart', function(event) {
13035        $j(this).data('has-touch');
13036        MenuManagerState.touchStartPosition = $j(window).scrollTop();
13037    });
13038
13039    // ----------------------------------------------
13040    // Sub Menus
13041
13042    nav.find('li.level1 a.has-children').on('click', function (e) {
13043        e.preventDefault();
13044        e.stopPropagation();
13045
13046        var elem = $j(this).parent();
13047
13048        // Check if sub-menu is open
13049        var isSubMenuActive = elem.hasClass('sub-menu-active') ? 1 : 0;
13050
13051        // On smaller screens, allow multiple sibling sub-menus to show at once,
13052        // but this is a large touch device, avoid multiple sub-menus showing at once.
13053        if (Modernizr.mq("screen and (min-width:" + (bp.medium + 1) + "px)")) {
13054            elem
13055                .siblings('.sub-menu-active')
13056                .removeClass('sub-menu-active')
13057                .find('.sub-menu-active')
13058                .removeClass('sub-menu-active');
13059        }
13060        if (isSubMenuActive) {
13061            elem.removeClass('sub-menu-active');
13062        } else {
13063            elem.addClass('sub-menu-active');
13064        }
13065    });
13066
13067    // Prevent sub menus from spilling out of the window.
13068    function preventMenuSpill() {
13069        var windowWidth = $j(window).width();
13070        $j('ul.level0').each(function(){
13071            var ul = $j(this);
13072            //Show it long enough to get info, then hide it.
13073            ul.addClass('position-test');
13074            ul.removeClass('spill');
13075            var width = ul.outerWidth();
13076            var offset = ul.offset().left;
13077            ul.removeClass('position-test');
13078            //Add the spill class if it will spill off the page.
13079            if ((offset + width) > windowWidth) {
13080                ul.addClass('spill');
13081            }
13082        });
13083    }
13084    preventMenuSpill();
13085    $j(window).on('delayed-resize', preventMenuSpill);
13086
13087
13088    // ==============================================
13089    // Language Switcher
13090    // ==============================================
13091
13092    // In order to display the language switcher next to the logo, we are moving the content at different viewports,
13093    // rather than having duplicate markup or changing the design
13094    enquire.register('(max-width: ' + bp.medium + 'px)', {
13095        match: function () {
13096            $j('.page-header-container .store-language-container').prepend($j('.form-language'));
13097        },
13098        unmatch: function () {
13099            $j('.header-language-container .store-language-container').prepend($j('.form-language'));
13100        }
13101    });
13102
13103    // ==============================================
13104    // Enquire JS
13105    // ==============================================
13106
13107    enquire.register('screen and (min-width: ' + (bp.medium + 1) + 'px)', {
13108        match: function () {
13109            $j('.menu-active').removeClass('menu-active');
13110            $j('.sub-menu-active').removeClass('sub-menu-active');
13111            $j('.skip-active').removeClass('skip-active');
13112        },
13113        unmatch: function () {
13114            $j('.menu-active').removeClass('menu-active');
13115            $j('.sub-menu-active').removeClass('sub-menu-active');
13116            $j('.skip-active').removeClass('skip-active');
13117        }
13118    });
13119
13120    // ==============================================
13121    // UI Pattern - Media Switcher
13122    // ==============================================
13123
13124    // Used to swap primary product photo from thumbnails.
13125
13126    var mediaListLinks = $j('.media-list').find('a');
13127    var mediaPrimaryImage = $j('.primary-image').find('img');
13128
13129    if (mediaListLinks.length) {
13130        mediaListLinks.on('click', function (e) {
13131            e.preventDefault();
13132
13133            var self = $j(this);
13134
13135            mediaPrimaryImage.attr('src', self.attr('href'));
13136        });
13137    }
13138
13139    // ==============================================
13140    // UI Pattern - ToggleSingle
13141    // ==============================================
13142
13143    // Use this plugin to toggle the visibility of content based on a toggle link/element.
13144    // This pattern differs from the accordion functionality in the Toggle pattern in that each toggle group acts
13145    // independently of the others. It is named so as not to be confused with the Toggle pattern below
13146    //
13147    // This plugin requires a specific markup structure. The plugin expects a set of elements that it
13148    // will use as the toggle link. It then hides all immediately following siblings and toggles the sibling's
13149    // visibility when the toggle link is clicked.
13150    //
13151    // Example markup:
13152    // <div class="block">
13153    //     <div class="block-title">Trigger</div>
13154    //     <div class="block-content">Content that should show when </div>
13155    // </div>
13156    //
13157    // JS: jQuery('.block-title').toggleSingle();
13158    //
13159    // Options:
13160    //     destruct: defaults to false, but if true, the plugin will remove itself, display content, and remove event handlers
13161
13162
13163    jQuery.fn.toggleSingle = function (options) {
13164
13165        // passing destruct: true allows
13166        var settings = $j.extend({
13167            destruct: false
13168        }, options);
13169
13170        return this.each(function () {
13171            if (!settings.destruct) {
13172                $j(this).on('click', function () {
13173                    $j(this)
13174                        .toggleClass('active')
13175                        .next()
13176                        .toggleClass('no-display');
13177                });
13178                // Hide the content
13179                $j(this).next().addClass('no-display');
13180            } else {
13181                // Remove event handler so that the toggle link can no longer be used
13182                $j(this).off('click');
13183                // Remove all classes that were added by this plugin
13184                $j(this)
13185                    .removeClass('active')
13186                    .next()
13187                    .removeClass('no-display');
13188            }
13189
13190        });
13191    }
13192
13193    // ==============================================
13194    // UI Pattern - Toggle Content (tabs and accordions in one setup)
13195    // ==============================================
13196    
13197    $j('.toggle-content').each(function () {
13198        var wrapper = jQuery(this);
13199
13200        var hasTabs = wrapper.hasClass('tabs');
13201        var hasAccordion = wrapper.hasClass('accordion');
13202        var startOpen = wrapper.hasClass('open');
13203
13204        var dl = wrapper.children('dl:first');
13205        var dts = dl.children('dt');
13206        var panes = dl.children('dd');
13207        var groups = new Array(dts, panes);
13208
13209        //Create a ul for tabs if necessary.
13210        if (hasTabs) {
13211            var ul = jQuery('<ul class="toggle-tabs"></ul>');
13212            dts.each(function () {
13213                var dt = jQuery(this);
13214                var li = jQuery('<li></li>');
13215                li.html(dt.html());
13216                ul.append(li);
13217            });
13218            ul.insertBefore(dl);
13219            var lis = ul.children();
13220            groups.push(lis);
13221        }
13222
13223        //Add "last" classes.
13224        var i;
13225        for (i = 0; i < groups.length; i++) {
13226            groups[i].filter(':last').addClass('last');
13227        }
13228
13229        function toggleClasses(clickedItem, group) {
13230            var index = group.index(clickedItem);
13231            var i;
13232            for (i = 0; i < groups.length; i++) {
13233                groups[i].removeClass('current');
13234                groups[i].eq(index).addClass('current');
13235            }
13236        }
13237
13238        //Toggle on tab (dt) click.
13239        dts.on('click', function (e) {
13240            //They clicked the current dt to close it. Restore the wrapper to unclicked state.
13241            if (jQuery(this).hasClass('current') && wrapper.hasClass('accordion-open')) {
13242                wrapper.removeClass('accordion-open');
13243            } else {
13244                //They're clicking something new. Reflect the explicit user interaction.
13245                wrapper.addClass('accordion-open');
13246            }
13247            toggleClasses(jQuery(this), dts);
13248        });
13249
13250        //Toggle on tab (li) click.
13251        if (hasTabs) {
13252            lis.on('click', function (e) {
13253                toggleClasses(jQuery(this), lis);
13254            });
13255            //Open the first tab.
13256            lis.eq(0).trigger('click');
13257        }
13258
13259        //Open the first accordion if desired.
13260        if (startOpen) {
13261            dts.eq(0).trigger('click');
13262        }
13263
13264    });
13265
13266
13267    // ==============================================
13268    // Layered Navigation Block
13269    // ==============================================
13270
13271    // On product list pages, we want to show the layered nav/category menu immediately above the product list.
13272    // While it would make more sense to just move the .block-layered-nav block rather than .col-left-first
13273    // (since other blocks can be inserted into left_first), it creates simpler code to move the entire
13274    // .col-left-first block, so that is the approach we're taking
13275    /*if ($j('.col-left-first > .block').length && $j('.category-products').length) {
13276        enquire.register('screen and (max-width: ' + bp.medium + 'px)', {
13277            match: function () {
13278                $j('.col-left-first').insertBefore($j('.category-products'))
13279            },
13280            unmatch: function () {
13281                // Move layered nav back to left column
13282                $j('.col-left-first').insertBefore($j('.col-main'))
13283            }
13284        });
13285    }*/
13286
13287    // ==============================================
13288    // 3 column layout
13289    // ==============================================
13290
13291    // On viewports smaller than 1000px, move the right column into the left column
13292    if ($j('.main-container.col3-layout').length > 0) {
13293        enquire.register('screen and (max-width: 1000px)', {
13294            match: function () {
13295                var rightColumn = $j('.col-right');
13296                var colWrapper = $j('.col-wrapper');
13297
13298                rightColumn.appendTo(colWrapper);
13299            },
13300            unmatch: function () {
13301                var rightColumn = $j('.col-right');
13302                var main = $j('.main');
13303
13304                rightColumn.appendTo(main);
13305            }
13306        });
13307    }
13308
13309
13310    // ==============================================
13311    // Block collapsing (on smaller viewports)
13312    // ==============================================
13313
13314    enquire.register('(max-width: ' + bp.medium + 'px)', {
13315        setup: function () {
13316            this.toggleElements = $j(
13317                // This selects the menu on the My Account and CMS pages
13318                '.col-left-first .block:not(.block-layered-nav) .block-title, ' +
13319                    '.col-left-first .block-layered-nav .block-subtitle--filter, ' +
13320                    '.sidebar:not(.col-left-first) .block .block-title'
13321            );
13322        },
13323        match: function () {
13324            this.toggleElements.toggleSingle();
13325        },
13326        unmatch: function () {
13327            this.toggleElements.toggleSingle({destruct: true});
13328        }
13329    });
13330
13331
13332    // ==============================================
13333    // OPC - Progress Block
13334    // ==============================================
13335
13336    // if ($j('body.checkout-onepage-index').length) {
13337    //     enquire.register('(max-width: ' + bp.large + 'px)', {
13338    //         match: function () {
13339    //             $j('#checkout-step-review').prepend($j('#checkout-progress-wrapper'));
13340    //         },
13341    //         unmatch: function () {
13342    //             $j('.col-right').prepend($j('#checkout-progress-wrapper'));
13343    //         }
13344    //     });
13345    // }
13346
13347
13348    // ==============================================
13349    // Checkout Cart - events
13350    // ==============================================
13351
13352    if ($j('body.checkout-cart-index').length) {
13353        $j('input[name^="cart"]').focus(function () {
13354            $j(this).siblings('button').fadeIn();
13355        });
13356    }
13357
13358    // ==============================================
13359    // Product Listing - Align action buttons/links
13360    // ==============================================
13361
13362    // Since the number of columns per grid will vary based on the viewport size, the only way to align the action
13363    // buttons/links is via JS
13364
13365    if ($j('.products-grid').length) {
13366
13367        var alignProductGridActions = function () {
13368            var gridRows = []; // This will store an array per row
13369            var tempRow = [];
13370            productGridElements = $j('.products-grid > li');
13371            productGridElements.each(function (index) {
13372                // The JS ought to be agnostic of the specific CSS breakpoints, so we are dynamically checking to find
13373                // each row by grouping all cells (eg, li elements) up until we find an element that is cleared.
13374                // We are ignoring the first cell since it will always be cleared.
13375                if ($j(this).css('clear') != 'none' && index != 0) {
13376                    gridRows.push(tempRow); // Add the previous set of rows to the main array
13377                    tempRow = []; // Reset the array since we're on a new row
13378                }
13379                tempRow.push(this);
13380
13381                // The last row will not contain any cells that clear that row, so we check to see if this is the last cell
13382                // in the grid, and if so, we add its row to the array
13383                if (productGridElements.length == index + 1) {
13384                    gridRows.push(tempRow);
13385                }
13386            });
13387
13388            $j.each(gridRows, function () {
13389                var tallestHeight = 0;
13390                $j.each(this, function () {
13391                    // Since this function is called every time the page is resized, we need to remove the min-height
13392                    // so each cell can return to its natural size before being measured.
13393                    $j(this).find('.product-info').css('min-height', '');
13394                    // We are checking the height of .product-info (rather than the entire li), because the images
13395                    // will not be loaded when this JS is run.
13396                    elHeight = parseInt($j(this).find('.product-info').css('height'));
13397                    if (elHeight > tallestHeight) {
13398                        tallestHeight = elHeight;
13399                    }
13400                });
13401                // Set the height of all .product-info elements in a row to the tallest height
13402                $j.each(this, function () {
13403                    $j(this).find('.product-info').css('minHeight', tallestHeight);
13404                });
13405            });
13406        }
13407        alignProductGridActions();
13408
13409        // Since the height of each cell and the number of columns per page may change when the page is resized, we are
13410        // going to run the alignment function each time the page is resized.
13411        $j(window).on('delayed-resize', function (e, resizeEvent) {
13412            alignProductGridActions();
13413        });
13414    }
13415
13416    // ==============================================
13417    // Generic, efficient window resize handler
13418    // ==============================================
13419
13420    // Using setTimeout since Web-Kit and some other browsers call the resize function constantly upon window resizing.
13421    var resizeTimer;
13422    $j(window).resize(function (e) {
13423        clearTimeout(resizeTimer);
13424        resizeTimer = setTimeout(function () {
13425            $j(window).trigger('delayed-resize', e);
13426        }, 250);
13427    });
13428});
13429
13430// ==============================================
13431// PDP - image zoom - needs to be available outside document.ready scope
13432// ==============================================
13433
13434var ProductMediaManager = {
13435    IMAGE_ZOOM_THRESHOLD: 20,
13436    zoomEnabled: Modernizr.mq("screen and (min-width:768px)"),
13437    imageWrapper: null,
13438
13439    destroyZoom: function() {
13440        $j('.zoomContainer').remove();
13441        $j('.product-image-gallery .gallery-image').removeData('elevateZoom');
13442    },
13443
13444    createZoom: function(image) {
13445        ProductMediaManager.destroyZoom();
13446
13447        if(!ProductMediaManager.zoomEnabled) { //zoom not enabled
13448            return;
13449        }
13450
13451        if(image.length <= 0) { //no image found
13452            return;
13453        }
13454
13455        if(image[0].naturalWidth && image[0].naturalHeight) {
13456            var widthDiff = image[0].naturalWidth - image.width() - ProductMediaManager.IMAGE_ZOOM_THRESHOLD;
13457            var heightDiff = image[0].naturalHeight - image.height() - ProductMediaManager.IMAGE_ZOOM_THRESHOLD;
13458
13459            if(widthDiff < 0 && heightDiff < 0) {
13460                //image not big enough
13461
13462                image.parents('.product-image').removeClass('zoom-available');
13463
13464                return;
13465            } else {
13466                image.parents('.product-image').addClass('zoom-available');
13467            }
13468        }
13469
13470        image.elevateZoom();
13471    },
13472
13473    swapImage: function(targetImage) {
13474        targetImage = $j(targetImage);
13475        targetImage.addClass('gallery-image');
13476
13477        ProductMediaManager.destroyZoom();
13478
13479        var imageGallery = $j('.product-image-gallery');
13480
13481        if(targetImage[0].complete) { //image already loaded -- swap immediately
13482
13483            imageGallery.find('.gallery-image').removeClass('visible');
13484
13485            //move target image to correct place, in case it's necessary
13486            imageGallery.append(targetImage);
13487
13488            //reveal new image
13489            targetImage.addClass('visible');
13490
13491            //wire zoom on new image
13492            ProductMediaManager.createZoom(targetImage);
13493
13494        } else { //need to wait for image to load
13495
13496            //add spinner
13497            imageGallery.addClass('loading');
13498
13499            //move target image to correct place, in case it's necessary
13500            imageGallery.append(targetImage);
13501
13502            //wait until image is loaded
13503            imagesLoaded(targetImage, function() {
13504                //remove spinner
13505                imageGallery.removeClass('loading');
13506
13507                //hide old image
13508                imageGallery.find('.gallery-image').removeClass('visible');
13509
13510                //reveal new image
13511                targetImage.addClass('visible');
13512
13513                //wire zoom on new image
13514                ProductMediaManager.createZoom(targetImage);
13515            });
13516
13517        }
13518    },
13519
13520    wireThumbnails: function() {
13521        //trigger image change event on thumbnail click
13522        $j('.product-image-thumbs .thumb-link').click(function(e) {
13523            e.preventDefault();
13524            var jlink = $j(this);
13525            var target = $j('#image-' + jlink.data('image-index'));
13526
13527            ProductMediaManager.swapImage(target);
13528        });
13529    },
13530
13531    initZoom: function() {
13532        ProductMediaManager.createZoom($j(".no-touch .gallery-image.visible")); //set zoom on first image
13533    },
13534
13535    init: function() {
13536        ProductMediaManager.imageWrapper = $j('.product-img-box');
13537
13538        enquire.register("screen and (min-width:768px)", {
13539            match : function() {
13540                ProductMediaManager.zoomEnabled = true;
13541                ProductMediaManager.initZoom();
13542            },
13543            unmatch : function() {
13544                ProductMediaManager.destroyZoom();
13545                ProductMediaManager.zoomEnabled = false;
13546            }
13547        });
13548
13549        //resizing the window causes problems with zoom -- reinitialize
13550        $j(window).on('delayed-resize', function(e, resizeEvent) {
13551            ProductMediaManager.destroyZoom();
13552            ProductMediaManager.initZoom();
13553        });
13554
13555        ProductMediaManager.wireThumbnails();
13556
13557        $j(document).trigger('product-media-loaded', ProductMediaManager);
13558    }
13559};
13560
13561$j(document).ready(function() {
13562    ProductMediaManager.init();
13563});
13564
13565/*!
13566* jQuery Cycle2; build: v20131022
13567* http://jquery.malsup.com/cycle2/
13568* Copyright (c) 2013 M. Alsup; Dual licensed: MIT/GPL
13569*/
13570/*! core engine; version: 20131003 */
13571(function(e){"use strict";function t(e){return(e||"").toLowerCase()}var i="20131003";e.fn.cycle=function(i){var n;return 0!==this.length||e.isReady?this.each(function(){var n,s,o,c,r=e(this),l=e.fn.cycle.log;if(!r.data("cycle.opts")){(r.data("cycle-log")===!1||i&&i.log===!1||s&&s.log===!1)&&(l=e.noop),l("--c2 init--"),n=r.data();for(var a in n)n.hasOwnProperty(a)&&/^cycle[A-Z]+/.test(a)&&(c=n[a],o=a.match(/^cycle(.*)/)[1].replace(/^[A-Z]/,t),l(o+":",c,"("+typeof c+")"),n[o]=c);s=e.extend({},e.fn.cycle.defaults,n,i||{}),s.timeoutId=0,s.paused=s.paused||!1,s.container=r,s._maxZ=s.maxZ,s.API=e.extend({_container:r},e.fn.cycle.API),s.API.log=l,s.API.trigger=function(e,t){return s.container.trigger(e,t),s.API},r.data("cycle.opts",s),r.data("cycle.API",s.API),s.API.trigger("cycle-bootstrap",[s,s.API]),s.API.addInitialSlides(),s.API.preInitSlideshow(),s.slides.length&&s.API.initSlideshow()}}):(n={s:this.selector,c:this.context},e.fn.cycle.log("requeuing slideshow (dom not ready)"),e(function(){e(n.s,n.c).cycle(i)}),this)},e.fn.cycle.API={opts:function(){return this._container.data("cycle.opts")},addInitialSlides:function(){var t=this.opts(),i=t.slides;t.slideCount=0,t.slides=e(),i=i.jquery?i:t.container.find(i),t.random&&i.sort(function(){return Math.random()-.5}),t.API.add(i)},preInitSlideshow:function(){var t=this.opts();t.API.trigger("cycle-pre-initialize",[t]);var i=e.fn.cycle.transitions[t.fx];i&&e.isFunction(i.preInit)&&i.preInit(t),t._preInitialized=!0},postInitSlideshow:function(){var t=this.opts();t.API.trigger("cycle-post-initialize",[t]);var i=e.fn.cycle.transitions[t.fx];i&&e.isFunction(i.postInit)&&i.postInit(t)}
vendor: 7,197 bytes, line 13571
13571,initSlideshow:function(){var t,i=this.opts(),n=i.container;i.API.calcFirstSlide(),"static"==i.container.css("position")&&i.container.css("position","relative"),e(i.slides[i.currSlide]).css("opacity",1).show(),i.API.stackSlides(i.slides[i.currSlide],i.slides[i.nextSlide],!i.reverse),i.pauseOnHover&&(i.pauseOnHover!==!0&&(n=e(i.pauseOnHover)),n.hover(function(){i.API.pause(!0)},function(){i.API.resume(!0)})),i.timeout&&(t=i.API.getSlideOpts(i.currSlide),i.API.queueTransition(t,t.timeout+i.delay)),i._initialized=!0,i.API.updateView(!0),i.API.trigger("cycle-initialized",[i]),i.API.postInitSlideshow()},pause:function(t){var i=this.opts(),n=i.API.getSlideOpts(),s=i.hoverPaused||i.paused;t?i.hoverPaused=!0:i.paused=!0,s||(i.container.addClass("cycle-paused"),i.API.trigger("cycle-paused",[i]).log("cycle-paused"),n.timeout&&(clearTimeout(i.timeoutId),i.timeoutId=0,i._remainingTimeout-=e.now()-i._lastQueue,(0>i._remainingTimeout||isNaN(i._remainingTimeout))&&(i._remainingTimeout=void 0)))},resume:function(e){var t=this.opts(),i=!t.hoverPaused&&!t.paused;e?t.hoverPaused=!1:t.paused=!1,i||(t.container.removeClass("cycle-paused"),0===t.slides.filter(":animated").length&&t.API.queueTransition(t.API.getSlideOpts(),t._remainingTimeout),t.API.trigger("cycle-resumed",[t,t._remainingTimeout]).log("cycle-resumed"))},add:function(t,i){var n,s=this.opts(),o=s.slideCount,c=!1;"string"==e.type(t)&&(t=e.trim(t)),e(t).each(function(){var t,n=e(this);i?s.container.prepend(n):s.container.append(n),s.slideCount++,t=s.API.buildSlideOpts(n),s.slides=i?e(n).add(s.slides):s.slides.add(n),s.API.initSlide(t,n,--s._maxZ),n.data("cycle.opts",t),s.API.trigger("cycle-slide-added",[s,t,n])}),s.API.updateView(!0),c=s._preInitialized&&2>o&&s.slideCount>=1,c&&(s._initialized?s.timeout&&(n=s.slides.length,s.nextSlide=s.reverse?n-1:1,s.timeoutId||s.API.queueTransition(s)):s.API.initSlideshow())},calcFirstSlide:function(){var e,t=this.opts();e=parseInt(t.startingSlide||0,10),(e>=t.slides.length||0>e)&&(e=0),t.currSlide=e,t.reverse?(t.nextSlide=e-1,0>t.nextSlide&&(t.nextSlide=t.slides.length-1)):(t.nextSlide=e+1,t.nextSlide==t.slides.length&&(t.nextSlide=0))},calcNextSlide:function(){var e,t=this.opts();t.reverse?(e=0>t.nextSlide-1,t.nextSlide=e?t.slideCount-1:t.nextSlide-1,t.currSlide=e?0:t.nextSlide+1):(e=t.nextSlide+1==t.slides.length,t.nextSlide=e?0:t.nextSlide+1,t.currSlide=e?t.slides.length-1:t.nextSlide-1)},calcTx:function(t,i){var n,s=t;return i&&s.manualFx&&(n=e.fn.cycle.transitions[s.manualFx]),n||(n=e.fn.cycle.transitions[s.fx]),n||(n=e.fn.cycle.transitions.fade,s.API.log('Transition "'+s.fx+'" not found.  Using fade.')),n},prepareTx:function(e,t){var i,n,s,o,c,r=this.opts();return 2>r.slideCount?(r.timeoutId=0,void 0):(!e||r.busy&&!r.manualTrump||(r.API.stopTransition(),r.busy=!1,clearTimeout(r.timeoutId),r.timeoutId=0),r.busy||(0!==r.timeoutId||e)&&(n=r.slides[r.currSlide],s=r.slides[r.nextSlide],o=r.API.getSlideOpts(r.nextSlide),c=r.API.calcTx(o,e),r._tx=c,e&&void 0!==o.manualSpeed&&(o.speed=o.manualSpeed),r.nextSlide!=r.currSlide&&(e||!r.paused&&!r.hoverPaused&&r.timeout)?(r.API.trigger("cycle-before",[o,n,s,t]),c.before&&c.before(o,n,s,t),i=function(){r.busy=!1,r.container.data("cycle.opts")&&(c.after&&c.after(o,n,s,t),r.API.trigger("cycle-after",[o,n,s,t]),r.API.queueTransition(o),r.API.updateView(!0))},r.busy=!0,c.transition?c.transition(o,n,s,t,i):r.API.doTransition(o,n,s,t,i),r.API.calcNextSlide(),r.API.updateView()):r.API.queueTransition(o)),void 0)},doTransition:function(t,i,n,s,o){var c=t,r=e(i),l=e(n),a=function(){l.animate(c.animIn||{opacity:1},c.speed,c.easeIn||c.easing,o)};l.css(c.cssBefore||{}),r.animate(c.animOut||{},c.speed,c.easeOut||c.easing,function(){r.css(c.cssAfter||{}),c.sync||a()}),c.sync&&a()},queueTransition:function(t,i){var n=this.opts(),s=void 0!==i?i:t.timeout;return 0===n.nextSlide&&0===--n.loop?(n.API.log("terminating; loop=0"),n.timeout=0,s?setTimeout(function(){n.API.trigger("cycle-finished",[n])},s):n.API.trigger("cycle-finished",[n]),n.nextSlide=n.currSlide,void 0):(s&&(n._lastQueue=e.now(),void 0===i&&(n._remainingTimeout=t.timeout),n.paused||n.hoverPaused||(n.timeoutId=setTimeout(function(){n.API.prepareTx(!1,!n.reverse)},s))),void 0)},stopTransition:function(){var e=this.opts();e.slides.filter(":animated").length&&(e.slides.stop(!1,!0),e.API.trigger("cycle-transition-stopped",[e])),e._tx&&e._tx.stopTransition&&e._tx.stopTransition(e)},advanceSlide:function(e){var t=this.opts();return clearTimeout(t.timeoutId),t.timeoutId=0,t.nextSlide=t.currSlide+e,0>t.nextSlide?t.nextSlide=t.slides.length-1:t.nextSlide>=t.slides.length&&(t.nextSlide=0),t.API.prepareTx(!0,e>=0),!1},buildSlideOpts:function(i){var n,s,o=this.opts(),c=i.data()||{};for(var r in c)c.hasOwnProperty(r)&&/^cycle[A-Z]+/.test(r)&&(n=c[r],s=r.match(/^cycle(.*)/)[1].replace(/^[A-Z]/,t),o.API.log("["+(o.slideCount-1)+"]",s+":",n,"("+typeof n+")"),c[s]=n);c=e.extend({},e.fn.cycle.defaults,o,c),c.slideNum=o.slideCount;try{delete c.API,delete c.slideCount,delete c.currSlide,delete c.nextSlide,delete c.slides}catch(l){}return c},getSlideOpts:function(t){var i=this.opts();void 0===t&&(t=i.currSlide);var n=i.slides[t],s=e(n).data("cycle.opts");return e.extend({},i,s)},initSlide:function(t,i,n){var s=this.opts();i.css(t.slideCss||{}),n>0&&i.css("zIndex",n),isNaN(t.speed)&&(t.speed=e.fx.speeds[t.speed]||e.fx.speeds._default),t.sync||(t.speed=t.speed/2),i.addClass(s.slideClass)},updateView:function(e,t){var i=this.opts();if(i._initialized){var n=i.API.getSlideOpts(),s=i.slides[i.currSlide];!e&&t!==!0&&(i.API.trigger("cycle-update-view-before",[i,n,s]),0>i.updateView)||(i.slideActiveClass&&i.slides.removeClass(i.slideActiveClass).eq(i.currSlide).addClass(i.slideActiveClass),e&&i.hideNonActive&&i.slides.filter(":not(."+i.slideActiveClass+")").hide(),0===i.updateView&&setTimeout(function(){i.API.trigger("cycle-update-view",[i,n,s,e])},n.speed/(i.sync?2:1)),0!==i.updateView&&i.API.trigger("cycle-update-view",[i,n,s,e]),e&&i.API.trigger("cycle-update-view-after",[i,n,s]))}},getComponent:function(t){var i=this.opts(),n=i[t];return"string"==typeof n?/^\s*[\>|\+|~]/.test(n)?i.container.find(n):e(n):n.jquery?n:e(n)},stackSlides:function(t,i,n){var s=this.opts();t||(t=s.slides[s.currSlide],i=s.slides[s.nextSlide],n=!s.reverse),e(t).css("zIndex",s.maxZ);var o,c=s.maxZ-2,r=s.slideCount;if(n){for(o=s.currSlide+1;r>o;o++)e(s.slides[o]).css("zIndex",c--);for(o=0;s.currSlide>o;o++)e(s.slides[o]).css("zIndex",c--)}else{for(o=s.currSlide-1;o>=0;o--)e(s.slides[o]).css("zIndex",c--);for(o=r-1;o>s.currSlide;o--)e(s.slides[o]).css("zIndex",c--)}e(i).css("zIndex",s.maxZ-1)},getSlideIndex:function(e){return this.opts().slides.index(e)}},e.fn.cycle.log=function(){window.console&&console.log&&console.log("[cycle2] "+Array.prototype.join.call(arguments," "))},e.fn.cycle.version=function(){return"Cycle2: "+i},e.fn.cycle.transitions={custom:{},none:{before:function(e,t,i,n){e.API.stackSlides(i,t,n),e.cssBefore={opacity:1,display:"block"}}},fade:{before:function(t,i,n,s){var o=t.API.getSlideOpts(t.nextSlide).slideCss||{};t.API.stackSlides(i,n,s),t.cssBefore=e.extend(o,{opacity:0,display:"block"}),t.animIn={opacity:1},t.animOut={opacity:0}
13571}},fadeout:{before:function(t,i,n,s){var o=t.API.getSlideOpts(t.nextSlide).slideCss||{};t.API.stackSlides(i,n,s),t.cssBefore=e.extend(o,{opacity:1,display:"block"}),t.animOut={opacity:0}}},scrollHorz:{before:function(e,t,i,n){e.API.stackSlides(t,i,n);var s=e.container.css("overflow","hidden").width();e.cssBefore={left:n?s:-s,top:0,opacity:1,display:"block"},e.cssAfter={zIndex:e._maxZ-2,left:0},e.animIn={left:0},e.animOut={left:n?-s:s}}}},e.fn.cycle.defaults={allowWrap:!0,autoSelector:".cycle-slideshow[data-cycle-auto-init!=false]",delay:0,easing:null,fx:"fade",hideNonActive:!0,loop:0,manualFx:void 0,manualSpeed:void 0,manualTrump:!0,maxZ:100,pauseOnHover:!1,reverse:!1,slideActiveClass:"cycle-slide-active",slideClass:"cycle-slide",slideCss:{position:"absolute",top:0,left:0},slides:"> img",speed:500,startingSlide:0,sync:!0,timeout:4e3,updateView:0},e(document).ready(function(){e(e.fn.cycle.defaults.autoSelector).cycle()})})(jQuery),/*! Cycle2 autoheight plugin; Copyright (c) M.Alsup, 2012; version: 20130304 */
13572function(e){"use strict";function t(t,n){var s,o,c,r=n.autoHeight;if("container"==r)o=e(n.slides[n.currSlide]).outerHeight(),n.container.height(o);else if(n._autoHeightRatio)n.container.height(n.container.width()/n._autoHeightRatio);else if("calc"===r||"number"==e.type(r)&&r>=0){if(c="calc"===r?i(t,n):r>=n.slides.length?0:r,c==n._sentinelIndex)return;n._sentinelIndex=c,n._sentinel&&n._sentinel.remove(),s=e(n.slides[c].cloneNode(!0)),s.removeAttr("id name rel").find("[id],[name],[rel]").removeAttr("id name rel"),s.css({position:"static",visibility:"hidden",display:"block"}).prependTo(n.container).addClass("cycle-sentinel cycle-slide").removeClass("cycle-slide-active"),s.find("*").css("visibility","hidden"),n._sentinel=s}}function i(t,i){var n=0,s=-1;return i.slides.each(function(t){var i=e(this).height();i>s&&(s=i,n=t)}),n}function n(t,i,n,s){var o=e(s).outerHeight(),c=i.sync?i.speed/2:i.speed;i.container.animate({height:o},c)}function s(i,o){o._autoHeightOnResize&&(e(window).off("resize orientationchange",o._autoHeightOnResize),o._autoHeightOnResize=null),o.container.off("cycle-slide-added cycle-slide-removed",t),o.container.off("cycle-destroyed",s),o.container.off("cycle-before",n),o._sentinel&&(o._sentinel.remove(),o._sentinel=null)}e.extend(e.fn.cycle.defaults,{autoHeight:0}),e(document).on("cycle-initialized",function(i,o){function c(){t(i,o)}var r,l=o.autoHeight,a=e.type(l),d=null;("string"===a||"number"===a)&&(o.container.on("cycle-slide-added cycle-slide-removed",t),o.container.on("cycle-destroyed",s),"container"==l?o.container.on("cycle-before",n):"string"===a&&/\d+\:\d+/.test(l)&&(r=l.match(/(\d+)\:(\d+)/),r=r[1]/r[2],o._autoHeightRatio=r),"number"!==a&&(o._autoHeightOnResize=function(){clearTimeout(d),d=setTimeout(c,50)},e(window).on("resize orientationchange",o._autoHeightOnResize)),setTimeout(c,30))})}(jQuery),/*! caption plugin for Cycle2;  version: 20130306 */
13573function(e){"use strict";e.extend(e.fn.cycle.defaults,{caption:"> .cycle-caption",captionTemplate:"{{slideNum}} / {{slideCount}}",overlay:"> .cycle-overlay",overlayTemplate:"<div>{{title}}</div><div>{{desc}}</div>",captionModule:"caption"}),e(document).on("cycle-update-view",function(t,i,n,s){"caption"===i.captionModule&&e.each(["caption","overlay"],function(){var e=this,t=n[e+"Template"],o=i.API.getComponent(e);o.length&&t?(o.html(i.API.tmpl(t,n,i,s)),o.show()):o.hide()})}),e(document).on("cycle-destroyed",function(t,i){var n;e.each(["caption","overlay"],function(){var e=this,t=i[e+"Template"];i[e]&&t&&(n=i.API.getComponent("caption"),n.empty())})})}(jQuery),/*! command plugin for Cycle2;  version: 20130707 */
13574function(e){"use strict";var t=e.fn.cycle;e.fn.cycle=function(i){var n,s,o,c=e.makeArray(arguments);return"number"==e.type(i)?this.cycle("goto",i):"string"==e.type(i)?this.each(function(){var r;return n=i,o=e(this).data("cycle.opts"),void 0===o?(t.log('slideshow must be initialized before sending commands; "'+n+'" ignored'),void 0):(n="goto"==n?"jump":n,s=o.API[n],e.isFunction(s)?(r=e.makeArray(c),r.shift(),s.apply(o.API,r)):(t.log("unknown command: ",n
13574),void 0))}):t.apply(this,arguments)},e.extend(e.fn.cycle,t),e.extend(t.API,{next:function(){var e=this.opts();if(!e.busy||e.manualTrump){var t=e.reverse?-1:1;e.allowWrap===!1&&e.currSlide+t>=e.slideCount||(e.API.advanceSlide(t),e.API.trigger("cycle-next",[e]).log("cycle-next"))}},prev:function(){var e=this.opts();if(!e.busy||e.manualTrump){var t=e.reverse?1:-1;e.allowWrap===!1&&0>e.currSlide+t||(e.API.advanceSlide(t),e.API.trigger("cycle-prev",[e]).log("cycle-prev"))}},destroy:function(){this.stop();var t=this.opts(),i=e.isFunction(e._data)?e._data:e.noop;clearTimeout(t.timeoutId),t.timeoutId=0,t.API.stop(),t.API.trigger("cycle-destroyed",[t]).log("cycle-destroyed"),t.container.removeData(),i(t.container[0],"parsedAttrs",!1),t.retainStylesOnDestroy||(t.container.removeAttr("style"),t.slides.removeAttr("style"),t.slides.removeClass(t.slideActiveClass)),t.slides.each(function(){e(this).removeData(),i(this,"parsedAttrs",!1)})},jump:function(e){var t,i=this.opts();if(!i.busy||i.manualTrump){var n=parseInt(e,10);if(isNaN(n)||0>n||n>=i.slides.length)return i.API.log("goto: invalid slide index: "+n),void 0;if(n==i.currSlide)return i.API.log("goto: skipping, already on slide",n),void 0;i.nextSlide=n,clearTimeout(i.timeoutId),i.timeoutId=0,i.API.log("goto: ",n," (zero-index)"),t=i.currSlide<i.nextSlide,i.API.prepareTx(!0,t)}},stop:function(){var t=this.opts(),i=t.container;clearTimeout(t.timeoutId),t.timeoutId=0,t.API.stopTransition(),t.pauseOnHover&&(t.pauseOnHover!==!0&&(i=e(t.pauseOnHover)),i.off("mouseenter mouseleave")),t.API.trigger("cycle-stopped",[t]).log("cycle-stopped")},reinit:function(){var e=this.opts();e.API.destroy(),e.container.cycle()},remove:function(t){for(var i,n,s=this.opts(),o=[],c=1,r=0;s.slides.length>r;r++)i=s.slides[r],r==t?n=i:(o.push(i),e(i).data("cycle.opts").slideNum=c,c++);n&&(s.slides=e(o),s.slideCount--,e(n).remove(),t==s.currSlide?s.API.advanceSlide(1):s.currSlide>t?s.currSlide--:s.currSlide++,s.API.trigger("cycle-slide-removed",[s,t,n]).log("cycle-slide-removed"),s.API.updateView())}}),e(document).on("click.cycle","[data-cycle-cmd]",function(t){t.preventDefault();var i=e(this),n=i.data("cycle-cmd"),s=i.data("cycle-context")||".cycle-slideshow";e(s).cycle(n,i.data("cycle-arg"))})}(jQuery),/*! hash plugin for Cycle2;  version: 20130905 */
13575function(e){"use strict";function t(t,i){var n;return t._hashFence?(t._hashFence=!1,void 0):(n=window.location.hash.substring(1),t.slides.each(function(s){if(e(this).data("cycle-hash")==n){if(i===!0)t.startingSlide=s;else{var o=s>t.currSlide;t.nextSlide=s,t.API.prepareTx(!0,o)}return!1}}),void 0)}e(document).on("cycle-pre-initialize",function(i,n){t(n,!0),n._onHashChange=function(){t(n,!1)},e(window).on("hashchange",n._onHashChange)}),e(document).on("cycle-update-view",function(e,t,i){i.hash&&"#"+i.hash!=window.location.hash&&(t._hashFence=!0,window.location.hash=i.hash)}),e(document).on("cycle-destroyed",function(t,i){i._onHashChange&&e(window).off("hashchange",i._onHashChange)})}(jQuery),/*! loader plugin for Cycle2;  version: 20131020 */
13576function(e){"use strict";e.extend(e.fn.cycle.defaults,{loader:!1}),e(document).on("cycle-bootstrap",function(t,i){function n(t,n){function o(t){var o;"wait"==i.loader?(r.push(t),0===a&&(r.sort(c),s.apply(i.API,[r,n]),i.container.removeClass("cycle-loading"))):(o=e(i.slides[i.currSlide]),s.apply(i.API,[t,n]),o.show(),i.container.removeClass("cycle-loading"))}function c(e,t){return e.data("index")-t.data("index")}var r=[];if("string"==e.type(t))t=e.trim(t);else if("array"===e.type(t))for(var l=0;t.length>l;l++)t[l]=e(t[l])[0];t=e(t);var a=t.length;a&&(i.eventualSlideCount=i.slideCount+a,t.hide().appendTo("body").each(function(t){function c(){0===--l&&(--a,o(d))}var l=0,d=e(this),u=d.is("img")?d:d.find("img");return d.data("index",t),u=u.filter(":not(.cycle-loader-ignore)").filter(':not([src=""])'),u.length?(l=u.length,u.each(function(){this.complete?c():e(this).load(function(){c()}).error(function(){0===--l&&(i.API.log("slide skipped; img not loaded:",this.src),0===--a&&"wait"==i.loader&&s.apply(i.API,[r,n]))})}),void 0):(--a,r.push(d),void 0)}),a&&i.container.addClass("cycle-loading"))}var s;i.loader&&(s=i.API.add,i.API.add=n)})}(jQuery),/*! pager plugin for Cycle2;  version: 20130525 */
13577function(e){"use strict";function t(t,i,n){var s,o=t.API.getComponent("pager");o.each(function(){var o=e(this);if(i.pagerTemplate){var c=t.API.tmpl(i.pagerTemplate,i,t,n[0]);s=e(c).appendTo(o)}else s=o.children().eq(t.slideCount-1);s.on(t.pagerEvent,function(e){e.preventDefault(),t.API.page(o,e.currentTarget)})})}function i(e,t){var i=this.opts();if(!i.busy||i.manualTrump){var n=e.children().index(t),s=n,o=s>i.currSlide;i.currSlide!=s&&(i.nextSlide=s,i.API.prepareTx(!0,o),i.API.trigger("cycle-pager-activated",[i,e,t]))}}e.extend(e.fn.cycle.defaults,{pager:"> .cycle-pager",pagerActiveClass:"cycle-pager-active",pagerEvent:"click.cycle",pagerTemplate:"<span>&bull;</span>"}),e(document).on("cycle-bootstrap",function(e,i,n){n.buildPagerLink=t}),e(document).on("cycle-slide-added",function(e,t,n,s){t.pager&&(t.API.buildPagerLink(t,n,s),t.API.page=i)}),e(document).on("cycle-slide-removed",function(t,i,n){if(i.pager){var s=i.API.getComponent("pager");s.each(function(){var t=e(this);e(t.children()[n]).remove()})}}),e(document).on("cycle-update-view",function(t,i){var n;i.pager&&(n=i.API.getComponent("pager"),n.each(function(){e(this).children().removeClass(i.pagerActiveClass).eq(i.currSlide).addClass(i.pagerActiveClass)}))}),e(document).on("cycle-destroyed",function(e,t){var i=t.API.getComponent("pager");i&&(i.children().off(t.pagerEvent),t.pagerTemplate&&i.empty())})}(jQuery),/*! prevnext plugin for Cycle2;  version: 20130709 */
13578function(e){"use strict";e.extend(e.fn.cycle.defaults,{next:"> .cycle-next",nextEvent:"click.cycle",disabledClass:"disabled",prev:"> .cycle-prev",prevEvent:"click.cycle",swipe:!1}),e(document).on("cycle-initialized",function(e,t){if(t.API.getComponent("next").on(t.nextEvent,function(e){e.preventDefault(),t.API.next()}),t.API.getComponent("prev").on(t.prevEvent,function(e){e.preventDefault(),t.API.prev()}
13578),t.swipe){var i=t.swipeVert?"swipeUp.cycle":"swipeLeft.cycle swipeleft.cycle",n=t.swipeVert?"swipeDown.cycle":"swipeRight.cycle swiperight.cycle";t.container.on(i,function(){t.API.next()}),t.container.on(n,function(){t.API.prev()})}}),e(document).on("cycle-update-view",function(e,t){if(!t.allowWrap){var i=t.disabledClass,n=t.API.getComponent("next"),s=t.API.getComponent("prev"),o=t._prevBoundry||0,c=void 0!==t._nextBoundry?t._nextBoundry:t.slideCount-1;t.currSlide==c?n.addClass(i).prop("disabled",!0):n.removeClass(i).prop("disabled",!1),t.currSlide===o?s.addClass(i).prop("disabled",!0):s.removeClass(i).prop("disabled",!1)}}),e(document).on("cycle-destroyed",function(e,t){t.API.getComponent("prev").off(t.nextEvent),t.API.getComponent("next").off(t.prevEvent),t.container.off("swipeleft.cycle swiperight.cycle swipeLeft.cycle swipeRight.cycle swipeUp.cycle swipeDown.cycle")})}(jQuery),/*! progressive loader plugin for Cycle2;  version: 20130315 */
13579function(e){"use strict";e.extend(e.fn.cycle.defaults,{progressive:!1}),e(document).on("cycle-pre-initialize",function(t,i){if(i.progressive){var n,s,o=i.API,c=o.next,r=o.prev,l=o.prepareTx,a=e.type(i.progressive);if("array"==a)n=i.progressive;else if(e.isFunction(i.progressive))n=i.progressive(i);else if("string"==a){if(s=e(i.progressive),n=e.trim(s.html()),!n)return;if(/^(\[)/.test(n))try{n=e.parseJSON(n)}catch(d){return o.log("error parsing progressive slides",d),void 0}else n=n.split(RegExp(s.data("cycle-split")||"\n")),n[n.length-1]||n.pop()}l&&(o.prepareTx=function(e,t){var s,o;return e||0===n.length?(l.apply(i.API,[e,t]),void 0):(t&&i.currSlide==i.slideCount-1?(o=n[0],n=n.slice(1),i.container.one("cycle-slide-added",function(e,t){setTimeout(function(){t.API.advanceSlide(1)},50)}),i.API.add(o)):t||0!==i.currSlide?l.apply(i.API,[e,t]):(s=n.length-1,o=n[s],n=n.slice(0,s),i.container.one("cycle-slide-added",function(e,t){setTimeout(function(){t.currSlide=1,t.API.advanceSlide(-1)},50)}),i.API.add(o,!0)),void 0)}),c&&(o.next=function(){var e=this.opts();if(n.length&&e.currSlide==e.slideCount-1){var t=n[0];n=n.slice(1),e.container.one("cycle-slide-added",function(e,t){c.apply(t.API),t.container.removeClass("cycle-loading")}),e.container.addClass("cycle-loading"),e.API.add(t)}else c.apply(e.API)}),r&&(o.prev=function(){var e=this.opts();if(n.length&&0===e.currSlide){var t=n.length-1,i=n[t];n=n.slice(0,t),e.container.one("cycle-slide-added",function(e,t){t.currSlide=1,t.API.advanceSlide(-1),t.container.removeClass("cycle-loading")}),e.container.addClass("cycle-loading"),e.API.add(i,!0)}else r.apply(e.API)})}})}(jQuery),/*! tmpl plugin for Cycle2;  version: 20121227 */
13580function(e){"use strict";e.extend(e.fn.cycle.defaults,{tmplRegex:"{{((.)?.*?)}}"}),e.extend(e.fn.cycle.API,{tmpl:function(t,i){var n=RegExp(i.tmplRegex||e.fn.cycle.defaults.tmplRegex,"g"),s=e.makeArray(arguments);return s.shift(),t.replace(n,function(t,i){var n,o,c,r,l=i.split(".");for(n=0;s.length>n;n++)if(c=s[n]){if(l.length>1)for(r=c,o=0;l.length>
13580o;o++)c=r,r=r[l[o]]||i;else r=c[i];if(e.isFunction(r))return r.apply(c,s);if(void 0!==r&&null!==r&&r!=i)return r}return i})}})}(jQuery);
13581
13582/*! Plugin for Cycle2; Copyright (c) 2012 M. Alsup; ver: 20121120 */
13583(function(a){"use strict";var b="ontouchend"in document;a.event.special.swipe=a.event.special.swipe||{scrollSupressionThreshold:10,durationThreshold:1e3,horizontalDistanceThreshold:30,verticalDistanceThreshold:75,setup:function(){var b=a(this);b.bind("touchstart",function(c){function g(b){if(!f)return;var c=b.originalEvent.touches?b.originalEvent.touches[0]:b;e={time:(new Date).getTime(),coords:[c.pageX,c.pageY]},Math.abs(f.coords[0]-e.coords[0])>a.event.special.swipe.scrollSupressionThreshold&&b.preventDefault()}var d=c.originalEvent.touches?c.originalEvent.touches[0]:c,e,f={time:(new Date).getTime(),coords:[d.pageX,d.pageY],origin:a(c.target)};b.bind("touchmove",g).one("touchend",function(c){b.unbind("touchmove",g),f&&e&&e.time-f.time<a.event.special.swipe.durationThreshold&&Math.abs(f.coords[0]-e.coords[0])>a.event.special.swipe.horizontalDistanceThreshold&&Math.abs(f.coords[1]-e.coords[1])<a.event.special.swipe.verticalDistanceThreshold&&f.origin.trigger("swipe").trigger(f.coords[0]>e.coords[0]?"swipeleft":"swiperight"),f=e=undefined})})}},a.event.special.swipeleft=a.event.special.swipeleft||{setup:function(){a(this).bind("swipe",a.noop)}},a.event.special.swiperight=a.event.special.swiperight||a.event.special.swipeleft})(jQuery);
13584
13585/**
13586 * Magento
13587 *
13588 * NOTICE OF LICENSE
13589 *
13590 * This source file is subject to the Academic Free License (AFL 3.0)
13591 * that is bundled with this package in the file LICENSE_AFL.txt.
13592 * It is also available through the world-wide-web at this URL:
13593 * http://opensource.org/licenses/afl-3.0.php
13594 * If you did not receive a copy of the license and are unable to
13595 * obtain it through the world-wide-web, please send an email
13596 * to [email protected] so we can send you a copy immediately.
13597 *
13598 * DISCLAIMER
13599 *
13600 * Do not edit or add to this file if you wish to upgrade Magento to newer
13601 * versions in the future. If you wish to customize Magento for your
13602 * needs please refer to http://www.magentocommerce.com for more information.
13603 *
13604 * @category    design
13605 * @package     default_default
13606 * @copyright   Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
13607 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
13608 */
13609
13610$j(document).ready(function () {
13611
13612    // ==============================================
13613    // UI Pattern - Slideshow
13614    // ==============================================
13615
13616    $j('.slideshow-container .slideshow')
13617        .cycle({
13618            slides: '> li',
13619            pager: '.slideshow-pager',
13620            pagerTemplate: '<span class="pager-box"></span>',
13621            speed: 600,
13622            pauseOnHover: true,
13623            swipe: true,
13624            prev: '.slideshow-prev',
13625            next: '.slideshow-next',
13626            fx: 'scrollHorz'
13627        });
13628});
13629
13630/*!
13631 * imagesLoaded PACKAGED v3.1.4
13632 * JavaScript is all like "You images are done yet or what?"
13633 * MIT License
13634 */
13635
13636(function(){function e(){}function t(e,t){for(var n=e.length;n--;)if(e[n].listener===t)return n;return-1}function n(e){return function(){return this[e].apply(this,arguments)}}var i=e.prototype,r=this,o=r.EventEmitter;i.getListeners=function(e){var t,n,i=this._getEvents();if("object"==typeof e){t={};for(n in i)i.hasOwnProperty(n)&&e.test(n)&&(t[n]=i[n])}else t=i[e]||(i[e]=[]);return t},i.flattenListeners=function(e){var t,n=[];for(t=0;e.length>t;t+=1)n.push(e[t].listener);return n},i.getListenersAsObject=function(e){var t,n=this.getListeners(e);return n instanceof Array&&(t={},t[e]=n),t||n},i.addListener=function(e,n){var i,r=this.getListenersAsObject(e),o="object"==typeof n;for(i in r)r.hasOwnProperty(i)&&-1===t(r[i],n)&&r[i].push(o?n:{listener:n,once:!1});return this},i.on=n("addListener"),i.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},i.once=n("addOnceListener"),i.defineEvent=function(e){return this.getListeners(e),this},i.defineEvents=function(e){for(var t=0;e.length>t;t+=1)this.defineEvent(e[t]);return this},i.removeListener=function(e,n){var i,r,o=this.getListenersAsObject(e);for(r in o)o.hasOwnProperty(r)&&(i=t(o[r],n),-1!==i&&o[r].splice(i,1));return this},i.off=n("removeListener"),i.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},i.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},i.manipulateListeners=function(e,t,n){var i,r,o=e?this.removeListener:this.addListener,s=e?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(i=n.length;i--;)o.call(this,t,n[i]);else for(i in t)t.hasOwnProperty(i)&&(r=t[i])&&("function"==typeof r?o.call(this,i,r):s.call(this,i,r));return this},i.removeEvent=function(e){var t,n=typeof e,i=this._getEvents();if("string"===n)delete i[e];else if("object"===n)for(t in i)i.hasOwnProperty(t)&&e.test(t)&&delete i[t];else delete this._events;return this},i.removeAllListeners=n("removeEvent"),i.emitEvent=function(e,t){var n,i,r,o,s=this.getListenersAsObject(e);for(r in s)if(s.hasOwnProperty(r))for(i=s[r].length;i--;)n=s[r][i],n.once===!0&&this.removeListener(e,n.listener),o=n.listener.apply(this,t||[]),o===this._getOnceReturnValue()&&this.removeListener(e,n.listener);return this},i.trigger=n("emitEvent"),i.emit=function(e){var t=Array.prototype.slice.call(arguments,1
13636);return this.emitEvent(e,t)},i.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},i._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},i._getEvents=function(){return this._events||(this._events={})},e.noConflict=function(){return r.EventEmitter=o,e},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return e}):"object"==typeof module&&module.exports?module.exports=e:this.EventEmitter=e}).call(this),function(e){function t(t){var n=e.event;return n.target=n.target||n.srcElement||t,n}var n=document.documentElement,i=function(){};n.addEventListener?i=function(e,t,n){e.addEventListener(t,n,!1)}:n.attachEvent&&(i=function(e,n,i){e[n+i]=i.handleEvent?function(){var n=t(e);i.handleEvent.call(i,n)}:function(){var n=t(e);i.call(e,n)},e.attachEvent("on"+n,e[n+i])});var r=function(){};n.removeEventListener?r=function(e,t,n){e.removeEventListener(t,n,!1)}:n.detachEvent&&(r=function(e,t,n){e.detachEvent("on"+t,e[t+n]);try{delete e[t+n]}catch(i){e[t+n]=void 0}});var o={bind:i,unbind:r};"function"==typeof define&&define.amd?define("eventie/eventie",o):e.eventie=o}(this),function(e,t){"function"==typeof define&&define.amd?define(["eventEmitter/EventEmitter","eventie/eventie"],function(n,i){return t(e,n,i)}):"object"==typeof exports?module.exports=t(e,require("eventEmitter"),require("eventie")):e.imagesLoaded=t(e,e.EventEmitter,e.eventie)}(this,function(e,t,n){function i(e,t){for(var n in t)e[n]=t[n];return e}function r(e){return"[object Array]"===d.call(e)}function o(e){var t=[];if(r(e))t=e;else if("number"==typeof e.length)for(var n=0,i=e.length;i>n;n++)t.push(e[n]);else t.push(e);return t}function s(e,t,n){if(!(this instanceof s))return new s(e,t);"string"==typeof e&&(e=document.querySelectorAll(e)),this.elements=o(e),this.options=i({},this.options),"function"==typeof t?n=t:i(this.options,t),n&&this.on("always",n),this.getImages(),a&&(this.jqDeferred=new a.Deferred);var r=this;setTimeout(function(){r.check()})}function c(e){this.img=e}function f(e){this.src=e,v[e]=this}var a=e.jQuery,u=e.console,h=u!==void 0,d=Object.prototype.toString;s.prototype=new t,s.prototype.options={},s.prototype.getImages=function(){this.images=[];for(var e=0,t=this.elements.length;t>e;e++){var n=this.elements[e];"IMG"===n.nodeName&&this.addImage(n);for(var i=n.querySelectorAll("img"),r=0,o=i.length;o>r;r++){var s=i[r];this.addImage(s)}}},s.prototype.addImage=function(e){var t=new c(e);this.images.push(t)},s.prototype.check=function(){function e(e,r){return t.options.debug&&h&&u.log("confirm",e,r),t.progress(e),n++,n===i&&t.complete(),!0}var t=this,n=0,i=this.images.length;if(this.hasAnyBroken=!1,!i)return this.complete(),void 0;for(var r=0;i>r;r++){var o=this.images[r];o.on("confirm",e),o.check()}},s.prototype.progress=function(e){this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded;var t=this;setTimeout(function(){t.emit("progress",t,e),t.jqDeferred&&t.jqDeferred.notify&&t.jqDeferred.notify(t,e)})},s.prototype.complete=function(){var e=this.hasAnyBroken?"fail":"done";this.isComplete=!0;var t=this;setTimeout(function(){if(t.emit(e,t),t.emit("always",t),t.jqDeferred){var n=t.hasAnyBroken?"reject":"resolve";t.jqDeferred[n](t)}})},a&&(a.fn.imagesLoaded=function(e,t){var n=new s(this,e,t);return n.jqDeferred.promise(a(this))}),c.prototype=new t,c.prototype.check=function(){var e=v[this.img.src]||new f(this.img.src);if(e.isConfirmed)return this.confirm(e.isLoaded,"cached was confirmed"),void 0;if(this.img.complete&&void 0!==this.img.naturalWidth)return this.confirm(0!==this.img.naturalWidth,"naturalWidth"),void 0;var t=this;e.on("confirm",function(e,n){return t.confirm(e.isLoaded,n),!0}),e.check()},c.prototype.confirm=function(e,t){this.isLoaded=e,this.emit("confirm",this,t)};var v={};return f.prototype=new t,f.prototype.check=function(){if(!this.isChecked){var e=new Image;n.bind(e,"load",this),n.bind(e,"error",this),e.src=this.src,this.isChecked=!0}},f.prototype.handleEvent=function(e){var t="on"+e.type;this[t]&&this[t](e)},f.prototype.onload=function(e){this.confirm(!0,"onload"),this.unbindProxyEvents(e)},f.prototype.onerror=function(e){this.confirm(!1,"onerror"),this.unbindProxyEvents(e)},f.prototype.confirm=function(e,t){this.isConfirmed=!0,this.isLoaded=e,this.emit
13636("confirm",this,t)},f.prototype.unbindProxyEvents=function(e){n.unbind(e.target,"load",this),n.unbind(e.target,"error",this)},s});
13637
13638/**
13639 * Magento
13640 *
13641 * NOTICE OF LICENSE
13642 *
13643 * This source file is subject to the Academic Free License (AFL 3.0)
13644 * that is bundled with this package in the file LICENSE_AFL.txt.
13645 * It is also available through the world-wide-web at this URL:
13646 * http://opensource.org/licenses/afl-3.0.php
13647 * If you did not receive a copy of the license and are unable to
13648 * obtain it through the world-wide-web, please send an email
13649 * to [email protected] so we can send you a copy immediately.
13650 *
13651 * DISCLAIMER
13652 *
13653 * Do not edit or add to this file if you wish to upgrade Magento to newer
13654 * versions in the future. If you wish to customize Magento for your
13655 * needs please refer to http://www.magentocommerce.com for more information.
13656 *
13657 * @category    design
13658 * @package     default_default
13659 * @copyright   Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
13660 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
13661 */
13662function Minicart(options) {
13663    this.formKey = options.formKey;
13664    this.previousVal = null;
13665
13666    this.defaultErrorMessage = 'Error occurred. Try to refresh page.';
13667
13668    this.selectors = {
13669        itemRemove:           '#cart-sidebar .remove',
13670        container:            '#header-cart',
13671        inputQty:             '.cart-item-quantity',
13672        qty:                  'div.header-minicart span.count',
13673        overlay:              '.minicart-wrapper',
13674        error:                '#minicart-error-message',
13675        success:              '#minicart-success-message',
13676        quantityButtonPrefix: '#qbutton-',
13677        quantityInputPrefix:  '#qinput-',
13678        quantityButtonClass:  '.quantity-button'
13679    };
13680
13681    if (options.selectors) {
13682        $j.extend(this.selectors, options.selectors);
13683    }
13684}
13685
13686Minicart.prototype = {
13687
13688    init: function() {
13689        var cart = this;
13690
13691        // bind remove event
13692        $j(this.selectors.itemRemove).unbind('click.minicart').bind('click.minicart', function(e) {
13693            e.preventDefault();
13694            cart.removeItem($j(this));
13695        });
13696
13697        // bind update qty event
13698        $j(this.selectors.inputQty)
13699            .unbind('blur.minicart')
13700            .unbind('focus.minicart')
13701            .bind('focus.minicart', function() {
13702                cart.previousVal = $j(this).val();
13703                cart.displayQuantityButton($j(this))
13704            })
13705            .bind('blur.minicart', function() {
13706                cart.revertInvalidValue(this);
13707            });
13708
13709        $j(this.selectors.quantityButtonClass)
13710            .unbind('click.quantity')
13711            .bind('click.quantity', function() {
13712                cart.processUpdateQuantity(this);
13713        });
13714    },
13715
13716    removeItem: function(el) {
13717        var cart = this;
13718        if (confirm(el.data('confirm'))) {
13719            cart.hideMessage();
13720            cart.showOverlay();
13721            $j.ajax({
13722                type: 'POST',
13723                dataType: 'json',
13724                data: {form_key: cart.formKey},
13725                url: el.attr('href')
13726            }).done(function(result) {
13727                cart.hideOverlay();
13728                if (result.success) {
13729                    cart.updateCartQty(result.qty);
13730                    cart.updateContentOnRemove(result, el.closest('li'));
13731                } else {
13732                    cart.showMessage(result);
13733                }
13734            }).error(function() {
13735                cart.hideOverlay();
13736                cart.showError(cart.defaultErrorMessage);
13737            });
13738        }
13739    },
13740
13741    revertInvalidValue: function(el) {
13742        if (!this.isValidQty($j(el).val()) || $j(el).val() == this.previousVal) {
13743            $j(el).val(this.previousVal);
13744            this.hideQuantityButton(el);
13745        }
13746    },
13747
13748    displayQuantityButton: function(el) {
13749        var buttonId = this.selectors.quantityButtonPrefix + $j(el).data('item-id');
13750        $j(buttonId).addClass('visible').attr('disabled',null);
13751    },
13752
13753    hideQuantityButton: function(el) {
13754        var buttonId = this.selectors.quantityButtonPrefix + $j(el).data('item-id');
13755        $j(buttonId).removeClass('visible').attr('disabled','disabled');
13756    },
13757
13758    processUpdateQuantity: function(el) {
13759        var input = $j(this.selectors.quantityInputPrefix + $j(el).data('item-id'));
13760        if (this.isValidQty(input.val()) && input.val() != this.previousVal) {
13761            this.updateItem(el);
13762        } else {
13763            this.revertInvalidValue(input);
13764        }
13765    },
13766
13767    updateItem: function(el) {
13768        var cart = this;
13769        var input = $j(this.selectors.quantityInputPrefix + $j(el).data('item-id'));
13770        var quantity = parseInt(input.val(), 10);
13771        cart.hideMessage();
13772        cart.showOverlay();
13773        $j.ajax({
13774            type: 'POST',
13775            dataType: 'json',
13776            url: input.data('link'),
13777            data: {qty: quantity, form_key: cart.formKey}
13778        }).done(function(result) {
13779            cart.hideOverlay();
13780            if (result.success) {
13781                cart.updateCartQty(result.qty);
13782                if (quantity !== 0) {
13783                    cart.updateContentOnUpdate(result);
13784                } else {
13785                    cart.updateContentOnRemove(result, input.closest('li'));
13786                }
13787            } else {
13788                cart.showMessage(result);
13789            }
13790        }).error(function() {
13791            cart.hideOverlay();
13792            cart.showError(cart.defaultErrorMessage);
13793        });
13794        return false;
13795    },
13796
13797    updateContentOnRemove: function(result, el) {
13798        var cart = this;
13799        el.hide('slow', function() {
13800            $j(cart.selectors.container).html(result.content);
13801            cart.showMessage(result);
13802
13803        });
13804    },
13805
13806    updateContentOnUpdate: function(result) {
13807        $j(this.selectors.container).html(result.content);
13808        this.showMessage(result);
13809    },
13810
13811    updateCartQty: function(qty) {
13812        if (typeof qty != 'undefined') {
13813            $j(this.selectors.qty).text(qty);
13814        }
13815    },
13816
13817    isValidQty: function(val) {
13818        return (val.length > 0) && (val - 0 == val) && (val - 0 > 0);
13819    },
13820
13821    showOverlay: function() {
13822        $j(this.selectors.overlay).addClass('loading');
13823    },
13824
13825    hideOverlay: function() {
13826        $j(this.selectors.overlay).removeClass('loading');
13827    },
13828
13829    showMessage: function(result) {
13830        if (typeof result.notice != 'undefined') {
13831            this.showError(result.notice);
13832        } else if (typeof result.error != 'undefined') {
13833            this.showError(result.error);
13834        } else if (typeof result.message != 'undefined') {
13835            this.showSuccess(result.message);
13836        }
13837    },
13838
13839    hideMessage: function() {
13840        $j(this.selectors.error).fadeOut('slow');
13841        $j(this.selectors.success).fadeOut('slow');
13842    },
13843
13844    showError: function(message) {
13845        $j(this.selectors.error).text(message).fadeIn('slow');
13846    },
13847
13848    showSuccess: function(message) {
13849        $j(this.selectors.success).text(message).fadeIn('slow');
13850    }
13851};
13852
13853(function($) {
13854    $.extend(jQuery.fn, {
13855        fabox: function(method, args) {
13856            var scope = this;
13857            var width_screen = $(window).width();
13858            var height_screen = $(window).height();
13859            if (typeof(method) !== 'string') {
13860                args = method;
13861                scope.locked = false;
13862                $(scope).addClass('fabox');
13863                $(scope).addClass('loading').html('<div class="close-box"><i class="fa fa-times"></i></div><div class="framebox"><i class="fa fa-spinner fa-spin"></i><div class="content-frame"></div></div>');
13864                $(scope).unbind();
13865                $(scope).find('.framebox').unbind();
13866                $(scope).find('.close-box').unbind();
13867                $(scope).bind('click', function() {
13868                    if(!scope.locked) {
13869                        $(scope).fabox('close', null);
13870                    }
13871                });
13872                $(scope).find('.framebox').bind('click', function() {
13873                    scope.locked = true;
13874                    window.setTimeout(function() {
13875                        scope.locked = false;
13876                    }, 200);
13877                });
13878                $('body').keydown(function (e) {
13879                    if(e.keyCode == 27) {
13880                        $(scope).fabox('close', null);
13881                    }
13882                })
13883                $(scope).find('.close-box').bind('click', function() {
13884                    $(scope).fabox('close', null);
13885                });
13886            }
13887            else {
13888                switch(method) {
13889                    case 'write':
13890                        var content = (typeof(args.content) != 'undefined') ? args.content : '';
13891                        var width = (typeof(args.width) != 'undefined') ? args.width : 0;
13892                        var height = (typeof(args.height) != 'undefined') ? args.height : 0;
13893                        var control = (typeof(args.control) != 'undefined') ? args.control : true;
13894                        var loaded = (typeof(args.loaded) != 'undefined') ? args.loaded : false;
13895                        var open = (typeof(args.open) != 'undefined') ? args.open : false;
13896                        var full = (typeof(args.full) != 'undefined') ? args.full : false;
13897                        var show = (typeof(args.show) != 'undefined') ? args.show : false;
13898                        var full_text = (typeof(args.full_text) != 'undefined') ? args.full_text : false;
13899                        var mode_closebox = (typeof(args.mode_closebox) != 'undefined') ? args.mode_closebox : 'full';
13900                        $(scope).find('.framebox .content-frame').html(content);
13901                        if(open) {
13902                            $(scope).fabox('open', {speed: '200'});
13903                        }
13904                        if(loaded) {
13905							window.setTimeout(function() {
13906								$(scope).fabox('resize', {width: width, 
13907														  height: height, 
13908														  control: control, 
13909														  full: full, 
13910														  show: show, 
13911														  full_text: full_text, 
13912														  mode_closebox: mode_closebox});
13913							}, 10);
13914                        }
13915                        else {
13916	                        var images_content = [];
13917	                        var iframe = null;
13918	                        $(scope).find('.framebox .content-frame iframe').each(function(k, v) {
13919		                        iframe = $(v);
13920		                    });
13921	                        $(scope).find('.framebox .content-frame img').each(function(k, v) {
13922		                        images_content.push($(v).attr('src'));
13923	                        });
13924	                        if(images_content.length > 0) {
13925		                        var nb_loaded = 0;
13926		                        for(var i = 0; i < images_content.length; i++) {
13927									var image = new Image();
13928									image.onload = function() {
13929										nb_loaded++;
13930										if(nb_loaded == images_content.length) {
13931											$(scope).fabox('write', {content: content, 
13932																	 width: width, 
13933																	 height: height, 
13934																	 control: control, 
13935																	 loaded: true, 
13936																	 full: full, 
13937																	 show: show, 
13938																	 full_text: full_text, 
13939																	 mode_closebox: mode_closebox});
13940										}
13941									};
13942									image.onerror = function() {
13943										nb_loaded++;
13944										if(nb_loaded == images_content.length) {
13945											$(scope).fabox('write', {content: content, 
13946																	 width: width, 
13947																	 height: height, 
13948																	 control: control, 
13949																	 loaded: true, 
13950																	 full: full, 
13951																	 show: show, 
13952																	 full_text: full_text, 
13953																	 mode_closebox: mode_closebox});
13954										}
13955									};
13956									image.src = images_content[i];
13957		                        }   
13958	                        }
13959	                        else if(iframe != null) {
13960								$(iframe).bind('load', function() {
13961			                        $(scope).fabox('write', {content: content, 
13962				                        					 width: $(iframe).outerWidth(), 
13963				                        					 height: $(iframe).outerHeight(), 
13964				                        					 control: control, 
13965				                        					 loaded: true, 
13966				                        					 full: full, 
13967				                        					 show: show, 
13968				                        					 full_text: full_text, 
13969															 mode_closebox: mode_closebox});
13970								});
13971	                        }
13972	                        else {
13973		                        $(scope).fabox('write', {content: content, 
13974			                        					 width: width, 
13975			                        					 height: height, 
13976			                        					 control: control, 
13977			                        					 loaded: true, 
13978			                        					 full: full, 
13979			                        					 show: show, 
13980			                        					 full_text: full_text, 
13981														 mode_closebox: mode_closebox});
13982	                        }
13983                        }
13984                    break;
13985                    case 'open':
13986                        var speed = (typeof(args.speed) != 'undefined') ? args.speed : 0;
13987                        $(scope).fadeIn(speed);
13988                    break;
13989                    case 'close':
13990                        $(scope).fadeOut(200, function() {
13991							$(scope).find('.framebox .content-frame').html('').removeClass('force-relative');
13992							$(scope).removeClass('fullgaz').removeClass('no-control');
13993							$(scope).addClass('loading').find('.framebox').css('width', '300px').css('height', '300px').css('margin-left', '-150px').css('margin-top', '-150px');
13994                        });
13995                    break;
13996                    case 'alert':
13997                        var title = (typeof(args.title) != 'undefined') ? args.title : '';
13998                        var msg = (typeof(args.msg) != 'undefined') ? args.msg : '';
13999                        var width = (typeof(args.width) != 'undefined') ? args.width : 450;
14000                        var msg_with_p = (msg != '') ? '<p>' + msg + '</p>' : '';
14001                        var mode_closebox = (typeof(args.mode_closebox) != 'undefined') ? args.mode_closebox : 'full';
14002                        $(scope).fabox('write', {content: '<div class="fabox-alert"><h3>' + title + '</h3>' + msg_with_p + '<div class="btn_actions"><div class="btn-center">OK</div></div></div>',
14003                                                         width: width,
14004                                                         open: true,
14005														 show: false,
14006                                                         full_text : true,
14007                                                         loaded: true, 
14008														 mode_closebox: mode_closebox});
14009                        $(scope).find('.btn-center').unbind();
14010                        $(scope).find('.btn-center').bind('click', function() {
14011                            $(scope).fabox('close', null);
14012                        });
14013                    break;
14014                    case 'confirm':
14015                        var title = (typeof(args.title) != 'undefined') ? args.title : '';
14016                        var msg = (typeof(args.msg) != 'undefined') ? args.msg : '';
14017                        var left_btn = (typeof(args.left_btn) != 'undefined') ? args.left_btn : 'Cancel';
14018                        var right_btn = (typeof(args.right_btn) != 'undefined') ? args.right_btn : 'Confirm';
14019                        var width = (typeof(args.width) != 'undefined') ? args.width : 450;
14020                        var msg_with_p = (msg != '') ? '<p>' + msg + '</p>' : '';
14021                        var mode_closebox = (typeof(args.mode_closebox) != 'undefined') ? args.mode_closebox : 'full';
14022                        $(scope).fabox('write', {content: '<div class="fabox-confirm"><h3>' + title + '</h3>' + msg_with_p + '<div class="btn_actions bundle"><div class="btn-left">' + left_btn + '</div><a href="/checkout/cart" ><div class="btn-right">' + right_btn + '</div></a><div style="clear:both;"></div></div></div>', width: width, open: true, loaded: false, mode_closebox: mode_closebox});
14023                        window.setTimeout(function() {
14024	                        $(scope).find('.btn-left').unbind();
14025	                        $(scope).find('.btn-right').unbind();
14026	                        $(scope).find('.btn-left').bind('click', function() {
14027                                if(typeof(args.callback_left) != 'undefined') {
14028                                    args.callback_left();
14029                                }
14030	                        });
14031	                        $(scope).find('.btn-right').bind('click', function() {
14032                                if(typeof(args.callback_right) != 'undefined') {
14033                                    args.callback_right();
14034                                }
14035	                        });
14036                        }, 500);
14037                    break;
14038                    case 'ajax':
14039                        var url = (typeof(args.url) != 'undefined') ? args.url : '';
14040                        var data = (typeof(args.data) != 'undefined') ? args.data : {};
14041                        var type = (typeof(args.type) != 'undefined') ? args.type : 'get';
14042                        var width = (typeof(args.width) != 'undefined') ? args.width : 0;
14043                        var height = (typeof(args.height) != 'undefined') ? args.height : 0;
14044                        var control = (typeof(args.control) != 'undefined') ? args.control : true;
14045                        var full = (typeof(args.full) != 'undefined') ? args.full : false;
14046                        var mode_closebox = (typeof(args.mode_closebox) != 'undefined') ? args.mode_closebox : 'full';
14047                        $(scope).fabox('open', {speed: 200});
14048						var request = $.ajax({
14049							url: url,
14050							type: type,
14051							data: data
14052						});						
14053						request.done(function(response) {
14054							$(scope).fabox('write', {content: response, width: width, height: height, control: control, full: full, loaded: false, mode_closebox: mode_closebox});
14055						});
14056						request.fail(function(jqXHR, textStatus) {
14057							$(scope).fabox('write', {content: '<h3 class="fabox-error-msg">The requested content cannot be loaded. Please try again later<h3>', width: width, height: height, control: control, full: full, loaded: false, mode_closebox: mode_closebox});
14058						});
14059                    break;
14060                    /*case 'gallery':
14061                        if (typeof(args.url) != 'undefined' && args.url != '') {
14062                            $(scope).fabox('open', {speed: '200'});
14063                            $(scope).addClass('box-img');
14064                            img = new Image();
14065                            img.onload = function() {
14066                                var width_img = parseInt(this.width);
14067                                var height_img = parseInt(this.height);
14068                                var old_height_img = height_img;
14069                                var old_width_img = width_img;
14070                                var twenty_percent_frame = Math.ceil(parseInt(height_screen) * 0.8);
14071                                if (parseInt(height_img) >= parseInt(twenty_percent_frame)) {
14072                                    // Si la hauteur de l'image est supérieur à 80% de la hauteur de l'écran, on optimise
14073                                    height_img = parseInt(twenty_percent_frame);
14074                                    width_img = parseInt((height_img * old_width_img) / old_height_img);
14075                                    old_width_img = width_img;
14076                                    old_height_img = height_img;
14077                                }
14078                                if (parseInt(width_img) >= width_screen) {
14079                                    // Si la largeur de l'image est supérieur à la largeur de l'écran, on optimise
14080                                    width_img = parseInt(width_screen);
14081                                    height_img = parseInt((width_img * old_height_img) / old_width_img);
14082                                    old_width_img = width_img;
14083                                    old_height_img = height_img;
14084                                }
14085                                $(scope).fabox('write', {content: '<img src="' + args.url + '" />', custom_width: width_img, custom_height: height_img, disable_control: true});
14086                            }
14087                            img.src = args.url;
14088                        }
14089                    break;*/
14090                    case 'resize':
14091                        var control = (typeof(args.control) != 'undefined') ? args.control : true;
14092                        var show = (typeof(args.show) != 'undefined') ? args.show : false;
14093                        var full = (typeof(args.full) != 'undefined') ? args.full : false;
14094                        var full_text = (typeof(args.full_text) != 'undefined') ? args.full_text : false;
14095						var width_frame = parseInt($(scope).find('.content-frame').outerWidth());
14096						var height_frame = parseInt($(scope).find('.content-frame').outerHeight());
14097                        var mode_closebox = (typeof(args.mode_closebox) != 'undefined') ? args.mode_closebox : 'full';
14098                        if(width_frame == 0) {
14099							width_frame = parseInt($(scope).find('.framebox').outerWidth());
14100                            if (width_frame == 0) {
14101                                width_frame = 300;
14102                            }
14103                        }
14104                        if(height_frame == 0) {
14105							height_frame = parseInt($(scope).find('.framebox').outerHeight());
14106                            if (height_frame == 0) {
14107                                height_frame = 300;
14108                            }
14109                        }
14110                        var width = (typeof(args.width) != 'undefined' && parseInt(args.width) > 0) ? parseInt(args.width) : parseInt(width_frame);
14111                        var height = (typeof(args.height) != 'undefined' && parseInt(args.height) > 0) ? parseInt(args.height) : parseInt(height_frame);
14112						var twenty_percent_wscreen = parseInt(Math.ceil(parseInt(width_screen) * 0.8));
14113						var twenty_percent_hscreen = parseInt(Math.ceil(parseInt(height_screen) * 0.8));
14114                        if(width > twenty_percent_wscreen) {
14115							if (width_screen > 500) {
14116								width = twenty_percent_wscreen;
14117							}
14118							else {
14119								if (width > width_screen) {
14120									width = twenty_percent_wscreen;
14121								}
14122							}
14123                        }
14124                        if(height > twenty_percent_hscreen) {
14125	                       height = twenty_percent_hscreen;
14126                        }
14127                        var margin_left = Math.ceil(parseInt(width) / 2);
14128                        var margin_top = Math.ceil(parseInt(height) / 2);
14129                        
14130                        /*console.log('*****************************');
14131                        console.log('width_screen ' + width_screen);
14132                        console.log('height_screen ' + height_screen);
14133                        console.log('twenty_percent_wscreen ' + twenty_percent_wscreen);
14134                        console.log('twenty_percent_hscreen ' + twenty_percent_hscreen);
14135                        console.log('width_frame ' + width_frame);
14136                        console.log('height_frame ' + height_frame);
14137                        console.log('width ' + width);
14138                        console.log('height ' + height);
14139                        console.log('control ' + control);
14140                        console.log('full ' + full);
14141                        console.log('margin_left ' + margin_left);
14142                        console.log('margin_top ' + margin_top);
14143                        console.log('*****************************');*/
14144                        
14145                        if (full) {
14146                            $(scope).addClass('fullgaz');
14147                            var the_elmt = $(scope).find('.framebox .content-frame').children().eq(0);
14148                            var diff_width = $(the_elmt).outerWidth() - width;
14149                            var diff_height = $(the_elmt).outerHeight() - height;
14150							var attr_width = $(the_elmt).attr('width');
14151							var attr_height = $(the_elmt).attr('height');
14152							if (typeof attr_width != 'undefined' && attr_width != '' && attr_width != null && parseInt(attr_width) > 0 &&
14153								typeof attr_height != 'undefined' && attr_height != '' && attr_height != null && parseInt(attr_height) > 0) {
14154								if (diff_width > 0) {
14155									var percent_prop = parseInt((width * 100) / attr_width);
14156									height = parseInt((percent_prop * attr_height) / 100);
14157									margin_top = Math.ceil(parseInt(height) / 2);
14158									$(the_elmt).css('height', height + 'px').css('width', width + 'px');
14159									window.setTimeout(function() {
14160										$(scope).fabox('resize', {width: 0, height: 0, control: control, full: true, show: false, full_text: full_text, mode_closebox: mode_closebox});
14161									}, 300);
14162								}
14163								else if(diff_height > 0) {
14164									var percent_prop = parseInt((height * 100) / attr_height);
14165									width = parseInt((percent_prop * attr_width) / 100);
14166									margin_left = Math.ceil(parseInt(width) / 2);
14167									$(the_elmt).css('height', height + 'px').css('width', width + 'px');						
14168									window.setTimeout(function() {
14169										$(scope).fabox('resize', {width: 0, height: 0, control: control, full: true, show: false, full_text: full_text, mode_closebox: mode_closebox});
14170									}, 300);
14171								}
14172								else {
14173									window.setTimeout(function() {
14174										$(scope).fabox('resize', {width: 0, height: 0, control: control, full: false, show: true, full_text: full_text, mode_closebox: mode_closebox});
14175									}, 300);
14176								}
14177							}
14178							else {
14179								if (diff_height > 0 || diff_width > 0) {
14180									if (diff_height > diff_width) {
14181										$(the_elmt).css('height', height + 'px').css('width', 'auto');
14182									}
14183									else {
14184										$(the_elmt).css('width', width + 'px').css('height', 'auto');
14185									}
14186									window.setTimeout(function() {
14187										$(scope).fabox('resize', {width: 0, height: 0, control: control, full: true, show: false, full_text: full_text, mode_closebox: mode_closebox});
14188									}, 300);
14189								}
14190								else {
14191									window.setTimeout(function() {
14192										$(scope).fabox('resize', {width: 0, height: 0, control: control, full: false, show: true, full_text: full_text, mode_closebox: mode_closebox});
14193									}, 300);
14194								}
14195							}							
14196                        }
14197                        if (!control) {
14198                            $(scope).addClass('no-control');
14199                        }
14200                        if (show) {
14201	                        switch(mode_closebox) {
14202		                        case 'full':
14203		                        	// Mode fullpage, la closebox se situe en haut à droite de l'écran
14204		                        	$(scope).find('.close-box').css('right', '20px').css('top', '20px');
14205		                        break;
14206		                        case 'center':
14207		                        	// Mode center, la closebox se situe en haut à droite de la framebox
14208		                        	var right_position = parseInt(parseInt(width_screen / 2) - margin_left);
14209		                        	var top_position = parseInt(parseInt(height_screen / 2) - margin_top);
14210		                        	$(scope).find('.close-box').css('right', right_position + 'px').css('top', top_position + 'px');
14211		                        break;
14212	                        }
14213                            $(scope).removeClass('loading');
14214                            $(scope).find('.framebox').stop().animate({'margin-left': '-' + margin_left + 'px',
14215                                                                                        'width': width + 'px',
14216                                                                                        'margin-top': '-' + margin_top + 'px',
14217                                                                                        'height': height + 'px'}, 200);
14218                        }
14219                        else {
14220                            $(scope).find('.framebox').css('width', width + 'px').css('height', height + 'px').css('margin-left', '-' + margin_left + 'px').css('margin-top', '-' + margin_top + 'px');
14221                            window.setTimeout(function() {
14222	                            if (!full) {
14223                                    if(!full_text) {
14224                                        width = 0;
14225                                    }
14226                                    else {
14227                                        $(scope).find('.content-frame').addClass('force-relative');
14228                                    }
14229	                                $(scope).fabox('resize', {width: width, height: 0, control: control, full: false, show: true, full_text: full_text, mode_closebox: mode_closebox});
14230	                            }
14231                            }, 0);
14232                        }
14233                    break;
14234                }
14235            }
14236            return this;
14237        }
14238    });
14239})(jQuery);
14240/*
14241     _ _      _       _
14242 ___| (_) ___| | __  (_)___
14243/ __| | |/ __| |/ /  | / __|
14244\__ \ | | (__|   < _ | \__ \
14245|___/_|_|\___|_|\_(_)/ |___/
14246                   |__/
14247
14248 Version: 1.3.11
14249  Author: Ken Wheeler
14250 Website: http://kenwheeler.github.io
14251    Docs: http://kenwheeler.github.io/slick
14252    Repo: http://github.com/kenwheeler/slick
14253  Issues: http://github.com/kenwheeler/slick/issues
14254
14255 */
14256
14257!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):"undefined"!=typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){"use strict";var b=window.Slick||{};b=function(){function c(c,d){var f,g,e=this;if(e.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:a(c),appendDots:a(c),arrows:!0,asNavFor:null,prevArrow:'<button type="button" data-role="none" class="slick-prev">Previous</button>',nextArrow:'<button type="button" data-role="none" class="slick-next">Next</button>',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(a,b){return'<button type="button" data-role="none">'+(b+1)+"</button>"},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",fade:!1,focusOnSelect:!1,infinite:!0,lazyLoad:"ondemand",onBeforeChange:null,onAfterChange:null,onInit:null,onReInit:null,pauseOnHover:!0,pauseOnDotsHover:!1,responsive:null,rtl:!1,slide:"div",slidesToShow:1,slidesToScroll:1,speed:300,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,variableWidth:!1,vertical:!1,waitForAnimate:!0},e.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentSlide:0,currentLeft:null,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,
14257sliding:!1,slideOffset:0,swipeLeft:null,$list:null,touchObject:{},transformsEnabled:!1},a.extend(e,e.initials),e.activeBreakpoint=null,e.animType=null,e.animProp=null,e.breakpoints=[],e.breakpointSettings=[],e.cssTransitions=!1,e.paused=!1,e.positionProp=null,e.$slider=a(c),e.$slidesCache=null,e.transformType=null,e.transitionType=null,e.windowWidth=0,e.windowTimer=null,e.options=a.extend({},e.defaults,d),e.originalSettings=e.options,f=e.options.responsive||null,f&&f.length>-1){for(g in f)f.hasOwnProperty(g)&&(e.breakpoints.push(f[g].breakpoint),e.breakpointSettings[f[g].breakpoint]=f[g].settings);e.breakpoints.sort(function(a,b){return b-a})}e.autoPlay=a.proxy(e.autoPlay,e),e.autoPlayClear=a.proxy(e.autoPlayClear,e),e.changeSlide=a.proxy(e.changeSlide,e),e.selectHandler=a.proxy(e.selectHandler,e),e.setPosition=a.proxy(e.setPosition,e),e.swipeHandler=a.proxy(e.swipeHandler,e),e.dragHandler=a.proxy(e.dragHandler,e),e.keyHandler=a.proxy(e.keyHandler,e),e.autoPlayIterator=a.proxy(e.autoPlayIterator,e),e.instanceUid=b++,e.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,e.init()}var b=0;return c}(),b.prototype.addSlide=function(b,c,d){var e=this;if("boolean"==typeof c)d=c,c=null;else if(0>c||c>=e.slideCount)return!1;e.unload(),"number"==typeof c?0===c&&0===e.$slides.length?a(b).appendTo(e.$slideTrack):d?a(b).insertBefore(e.$slides.eq(c)):a(b).insertAfter(e.$slides.eq(c)):d===!0?a(b).prependTo(e.$slideTrack):a(b).appendTo(e.$slideTrack),e.$slides=e.$slideTrack.children(this.options.slide),e.$slideTrack.children(this.options.slide).detach(),e.$slideTrack.append(e.$slides),e.$slides.each(function(b,c){a(c).attr("index",b)}),e.$slidesCache=e.$slides,e.reinit()},b.prototype.animateSlide=function(b,c){var d={},e=this;if(1===e.options.slidesToShow&&e.options.adaptiveHeight===!0&&e.options.vertical===!1){var f=e.$slides.eq(e.currentSlide).outerHeight(!0);e.$list.animate({height:f},e.options.speed)}e.options.rtl===!0&&e.options.vertical===!1&&(b=-b),e.transformsEnabled===!1?e.options.vertical===!1?e.$slideTrack.animate({left:b},e.options.speed,e.options.easing,c):e.$slideTrack.animate({top:b},e.options.speed,e.options.easing,c):e.cssTransitions===!1?a({animStart:e.currentLeft}).animate({animStart:b},{duration:e.options.speed,easing:e.options.easing,step:function(a){e.options.vertical===!1?(d[e.animType]="translate("+a+"px, 0px)",e.$slideTrack.css(d)):(d[e.animType]="translate(0px,"+a+"px)",e.$slideTrack.css(d))},complete:function(){c&&c.call()}}):(e.applyTransition(),d[e.animType]=e.options.vertical===!1?"translate3d("+b+"px, 0px, 0px)":"translate3d(0px,"+b+"px, 0px)",e.$slideTrack.css(d),c&&setTimeout(function(){e.disableTransition(),c.call()},e.options.speed))},b.prototype.asNavFor=function(b){var c=this,d=null!=c.options.asNavFor?a(c.options.asNavFor).getSlick():null;null!=d&&d.slideHandler(b,!0)},b.prototype.applyTransition=function(a){var b=this,c={};c[b.transitionType]=b.options.fade===!1?b.transformType+" "+b.options.speed+"ms "+b.options.cssEase:"opacity "+b.options.speed+"ms "+b.options.cssEase,b.options.fade===!1?b.$slideTrack.css(c):b.$slides.eq(a).css(c)},b.prototype.autoPlay=function(){var a=this;a.autoPlayTimer&&clearInterval(a.autoPlayTimer),a.slideCount>a.options.slidesToShow&&a.paused!==!0&&(a.autoPlayTimer=setInterval(a.autoPlayIterator,a.options.autoplaySpeed))},b.prototype.autoPlayClear=function(){var a=this;a.autoPlayTimer&&clearInterval(a.autoPlayTimer)},b.prototype.autoPlayIterator=function(){var a=this;a.options.infinite===!1?1===a.direction?(a.currentSlide+1===a.slideCount-1&&(a.direction=0),a.slideHandler(a.currentSlide+a.options.slidesToScroll)):(0===a.currentSlide-1&&(a.direction=1),a.slideHandler(a.currentSlide-a.options.slidesToScroll)):a.slideHandler(a.currentSlide+a.options.slidesToScroll)},b.prototype.buildArrows=function(){var b=this;b.options.arrows===!0&&b.slideCount>b.options.slidesToShow&&(b.$prevArrow=a(b.options.prevArrow),b.$nextArrow=a(b.options.nextArrow),b.htmlExpr.test(b.options.prevArrow)&&b.$prevArrow.appendTo(b.options.appendArrows),b.htmlExpr.test(b.options.nextArrow)&&b.$nextArrow.appendTo(b.options.appendArrows),b.options.infinite!==!0&&b.$prevArrow.addClass("slick-disabled"))},b.prototype.buildDots=function(){var c,d,b=this;if(b.options.dots===!0&&b.slideCount>b.options.slidesToShow){for(d='<ul class="'+b.options.dotsClass+'">',c=0;c<=b.getDotCount();c+=1)d+="<li>"+b.options.customPaging.call(this,b,c)+"</li>";d+="</ul>",b.$dots=a(d).appendTo(b.options.appendDots),b.$dots.find("li").first().addClass("slick-active")}},b.prototype.buildOut=function(){var b=this;b.$slides=b.$slider.children(b.options.slide+":not(.slick-cloned)").addClass("slick-slide"),b.slideCount=b.$slides.length,b.$slides.each(function(b,c){a(c).attr("index",b)}),b.$slidesCache=b.$slides,b.$slider.addClass("slick-slider"),b.$slideTrack=0===b.slideCount?a('<div class="slick-track"/>').appendTo(b.$slider):b.$slides.wrapAll('<div class="slick-track"/>').parent(),b.$list=b.$slideTrack.wrap('<div class="slick-list"/>').parent(),b.$slideTrack.css("opacity",0),b.options.centerMode===!0&&(b.options.slidesToScroll=1,0===b.options.slidesToShow%2&&(b.options.slidesToShow=3)),a("img[data-lazy]",b.$slider).not("[src]").addClass("slick-loading"),b.setupInfinite(),b.buildArrows(),b.buildDots(),b.updateDots(),b.options.accessibility===!0&&b.$list.prop("tabIndex",0),b.setSlideClasses("number"==typeof this.currentSlide?this.currentSlide:0),b.options.draggable===!0&&b.$list.addClass("draggable")},b.prototype.checkResponsive=function(){var c,d,b=this;if(b.originalSettings.responsive&&b.originalSettings.responsive.length>-1&&null!==b.originalSettings.responsive){d=null;for(c in b.breakpoints)b.breakpoints.hasOwnProperty(c)&&a(window).width()<b.breakpoints[c]&&(d=b.breakpoints[c]);null!==d?null!==b.activeBreakpoint?d!==b.activeBreakpoint&&(b.activeBreakpoint=d,b.options=a.extend({},b.options,b.breakpointSettings[d]),b.refresh()):(b.activeBreakpoint=d,b.options=a.extend({},b.options,b.breakpointSettings[d]),b.refresh()):null!==b.activeBreakpoint&&(b.activeBreakpoint=null,b.options=a.extend({},b.options,b.originalSettings),b.refresh())}},b.prototype.changeSlide=function(b){var e,f,g,c=this,d=a(b.target);switch(d.is("a")&&b.preventDefault(),g=0!==c.slideCount%c.options.slidesToScroll,e=g?0:(c.slideCount-c.currentSlide)%c.options.slidesToScroll,b.data.message){case"previous":f=0===e?c.options.slidesToScroll:c.options.slidesToShow-e,c.slideCount>c.options.slidesToShow&&c.slideHandler(c.currentSlide-f);break;case"next":f=0===e?c.options.slidesToScroll:e,c.slideCount>c.options.slidesToShow&&c.slideHandler(c.currentSlide+f);break;case"index":var h=0===b.data.index?0:b.data.index||a(b.target).parent().index()*c.options.slidesToScroll;c.slideHandler(h);default:return!1}},b.prototype.destroy=function(){var b=this;b.autoPlayClear(),b.touchObject={},a(".slick-cloned",b.$slider).remove(),b.$dots&&b.$dots.remove(),b.$prevArrow&&(b.$prevArrow.remove(),b.$nextArrow.remove()),b.$slides.parent().hasClass("slick-track")&&b.$slides.unwrap().unwrap(),b.$slides.removeClass("slick-slide slick-active slick-visible").css("width",""),b.$slider.removeClass("slick-slider"),b.$slider.removeClass("slick-initialized"),b.$list.off(".slick"),a(window).off(".slick-"+b.instanceUid),a(document).off(".slick-"+b.instanceUid)},b.prototype.disableTransition=function(a){var b=this,c={};c[b.transitionType]="",b.options.fade===!1?b.$slideTrack.css(c):b.$slides.eq(a).css(c)},b.prototype.fadeSlide=function(a,b,c){var d=this;d.cssTransitions===!1?(d.$slides.eq(b).css({zIndex:1e3}),d.$slides.eq(b).animate({opacity:1},d.options.speed,d.options.easing,c),d.$slides.eq(a).animate({opacity:0}
14257,d.options.speed,d.options.easing)):(d.applyTransition(b),d.applyTransition(a),d.$slides.eq(b).css({opacity:1,zIndex:1e3}),d.$slides.eq(a).css({opacity:0}),c&&setTimeout(function(){d.disableTransition(b),d.disableTransition(a),c.call()},d.options.speed))},b.prototype.filterSlides=function(a){var b=this;null!==a&&(b.unload(),b.$slideTrack.children(this.options.slide).detach(),b.$slidesCache.filter(a).appendTo(b.$slideTrack),b.reinit())},b.prototype.getCurrent=function(){var a=this;return a.currentSlide},b.prototype.getDotCount=function(){var e,a=this,b=0,c=0,d=0;for(e=a.options.infinite===!0?a.slideCount+a.options.slidesToShow-a.options.slidesToScroll:a.slideCount;e>b;)d++,c+=a.options.slidesToScroll,b=c+a.options.slidesToShow;return d},b.prototype.getLeft=function(a){var c,d,g,b=this,e=0;return b.slideOffset=0,d=b.$slides.first().outerHeight(),b.options.infinite===!0?(b.slideCount>b.options.slidesToShow&&(b.slideOffset=-1*b.slideWidth*b.options.slidesToShow,e=-1*d*b.options.slidesToShow),0!==b.slideCount%b.options.slidesToScroll&&a+b.options.slidesToScroll>b.slideCount&&b.slideCount>b.options.slidesToShow&&(b.slideOffset=-1*b.slideCount%b.options.slidesToShow*b.slideWidth,e=-1*b.slideCount%b.options.slidesToShow*d)):0!==b.slideCount%b.options.slidesToShow&&a+b.options.slidesToScroll>b.slideCount&&b.slideCount>b.options.slidesToShow&&(b.slideOffset=b.options.slidesToShow*b.slideWidth-b.slideCount%b.options.slidesToShow*b.slideWidth,e=b.slideCount%b.options.slidesToShow*d),b.slideCount<=b.options.slidesToShow&&(b.slideOffset=0,e=0),b.options.centerMode===!0&&b.options.infinite===!0?b.slideOffset+=b.slideWidth*Math.floor(b.options.slidesToShow/2)-b.slideWidth:b.options.centerMode===!0&&(b.slideOffset+=b.slideWidth*Math.floor(b.options.slidesToShow/2)),c=b.options.vertical===!1?-1*a*b.slideWidth+b.slideOffset:-1*a*d+e,b.options.variableWidth===!0&&(g=b.slideCount<=b.options.slidesToShow||b.options.infinite===!1?b.$slideTrack.children(".slick-slide").eq(a):b.$slideTrack.children(".slick-slide").eq(a+b.options.slidesToShow),c=g[0]?-1*g[0].offsetLeft:0,b.options.centerMode===!0&&(g=b.options.infinite===!1?b.$slideTrack.children(".slick-slide").eq(a):b.$slideTrack.children(".slick-slide").eq(a+b.options.slidesToShow+1),c=g[0]?-1*g[0].offsetLeft:0,c+=(b.$list.width()-g.outerWidth())/2)),c},b.prototype.init=function(){var b=this;a(b.$slider).hasClass("slick-initialized")||(a(b.$slider).addClass("slick-initialized"),b.buildOut(),b.setProps(),b.startLoad(),b.loadSlider(),b.initializeEvents(),b.checkResponsive()),null!==b.options.onInit&&b.options.onInit.call(this,b)},b.prototype.initArrowEvents=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.on("click.slick",{message:"previous"},a.changeSlide),a.$nextArrow.on("click.slick",{message:"next"},a.changeSlide))},b.prototype.initDotEvents=function(){var b=this;b.options.dots===!0&&b.slideCount>b.options.slidesToShow&&a("li",b.$dots).on("click.slick",{message:"index"},b.changeSlide),b.options.dots===!0&&b.options.pauseOnDotsHover===!0&&b.options.autoplay===!0&&a("li",b.$dots).on("mouseenter.slick",b.autoPlayClear).on("mouseleave.slick",b.autoPlay)},b.prototype.initializeEvents=function(){var b=this;b.initArrowEvents(),b.initDotEvents(),b.$list.on("touchstart.slick mousedown.slick",{action:"start"},b.swipeHandler),b.$list.on("touchmove.slick mousemove.slick",{action:"move"},b.swipeHandler),b.$list.on("touchend.slick mouseup.slick",{action:"end"}
14257,b.swipeHandler),b.$list.on("touchcancel.slick mouseleave.slick",{action:"end"},b.swipeHandler),b.options.pauseOnHover===!0&&b.options.autoplay===!0&&(b.$list.on("mouseenter.slick",b.autoPlayClear),b.$list.on("mouseleave.slick",b.autoPlay)),b.options.accessibility===!0&&b.$list.on("keydown.slick",b.keyHandler),b.options.focusOnSelect===!0&&a(b.options.slide,b.$slideTrack).on("click.slick",b.selectHandler),a(window).on("orientationchange.slick.slick-"+b.instanceUid,function(){b.checkResponsive(),b.setPosition()}),a(window).on("resize.slick.slick-"+b.instanceUid,function(){a(window).width()!==b.windowWidth&&(clearTimeout(b.windowDelay),b.windowDelay=window.setTimeout(function(){b.windowWidth=a(window).width(),b.checkResponsive(),b.setPosition()},50))}),a(window).on("load.slick.slick-"+b.instanceUid,b.setPosition),a(document).on("ready.slick.slick-"+b.instanceUid,b.setPosition)},b.prototype.initUI=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.show(),a.$nextArrow.show()),a.options.dots===!0&&a.slideCount>a.options.slidesToShow&&a.$dots.show(),a.options.autoplay===!0&&a.autoPlay()},b.prototype.keyHandler=function(a){var b=this;37===a.keyCode?b.changeSlide({data:{message:"previous"}}):39===a.keyCode&&b.changeSlide({data:{message:"next"}})},b.prototype.lazyLoad=function(){function g(b){a("img[data-lazy]",b).each(function(){var b=a(this),c=a(this).attr("data-lazy");b.load(function(){b.animate({opacity:1},200)}).css({opacity:0}).attr("src",c).removeAttr("data-lazy").removeClass("slick-loading")})}var c,d,e,f,b=this;b.options.centerMode===!0?b.options.infinite===!0?(e=b.currentSlide+(b.options.slidesToShow/2+1),f=e+b.options.slidesToShow+2):(e=Math.max(0,b.currentSlide-(b.options.slidesToShow/2+1)),f=2+(b.options.slidesToShow/2+1)+b.currentSlide):(e=b.options.infinite?b.options.slidesToShow+b.currentSlide:b.currentSlide,f=e+b.options.slidesToShow,b.options.fade===!0&&(e>0&&e--,f<=b.slideCount&&f++)),c=b.$slider.find(".slick-slide").slice(e,f),g(c),b.slideCount<=b.options.slidesToShow?(d=b.$slider.find(".slick-slide"),g(d)):b.currentSlide>=b.slideCount-b.options.slidesToShow?(d=b.$slider.find(".slick-cloned").slice(0,b.options.slidesToShow),g(d)):0===b.currentSlide&&(d=b.$slider.find(".slick-cloned").slice(-1*b.options.slidesToShow),g(d))},b.prototype.loadSlider=function(){var a=this;a.setPosition(),a.$slideTrack.css({opacity:1}),a.$slider.removeClass("slick-loading"),a.initUI(),"progressive"===a.options.lazyLoad&&a.progressiveLazyLoad()},b.prototype.postSlide=function(a){var b=this;null!==b.options.onAfterChange&&b.options.onAfterChange.call(this,b,a),b.animating=!1,b.setPosition(),b.swipeLeft=null,b.options.autoplay===!0&&b.paused===!1&&b.autoPlay()},b.prototype.progressiveLazyLoad=function(){var c,d,b=this;c=a("img[data-lazy]").length,c>0&&(d=a("img[data-lazy]",b.$slider).first(),d.attr("src",d.attr("data-lazy")).removeClass("slick-loading").load(function(){d.removeAttr("data-lazy"),b.progressiveLazyLoad()}).error(function(){d.removeAttr("data-lazy"),b.progressiveLazyLoad()}))},b.prototype.refresh=function(){var b=this,c=b.currentSlide;b.destroy(),a.extend(b,b.initials),b.currentSlide=c,b.init()},b.prototype.reinit=function(){var b=this;b.$slides=b.$slideTrack.children(b.options.slide).addClass("slick-slide"),b.slideCount=b.$slides.length,b.currentSlide>=b.slideCount&&0!==b.currentSlide&&(b.currentSlide=b.currentSlide-b.options.slidesToScroll),b.slideCount<=b.options.slidesToShow&&(b.currentSlide=0),b.setProps(),b.setupInfinite(),b.buildArrows(),b.updateArrows(),b.initArrowEvents(),b.buildDots(),b.updateDots(),b.initDotEvents(),b.options.focusOnSelect===!0&&a(b.options.slide,b.$slideTrack).on("click.slick",b.selectHandler),b.setSlideClasses(0),b.setPosition(),null!==b.options.onReInit&&b.options.onReInit.call(this,b)},b.prototype.removeSlide=function(a,b){var c=this;return"boolean"==typeof a?(b=a,a=b===!0?0:c.slideCount-1):a=b===!0?--a:a,c.slideCount<1||0>a||a>c.slideCount-1?!1:(c.unload(),c.$slideTrack.children(this.options.slide).eq(a).remove(),c.$slides=c.$slideTrack.children(this.options.slide),c.$slideTrack.children(this.options.slide).detach(),c.$slideTrack.append(c.$slides),c.$slidesCache=c.$slides,c.reinit(),void 0)},b.prototype.setCSS=function(a){var d,e,b=this,c={};b.options.rtl===!0&&(a=-a),d="left"==b.positionProp?a+"px":"0px",e="top"==b.positionProp?a+"px":"0px",c[b.positionProp]=a,b.transformsEnabled===!1?b.$slideTrack.css(c):(c={},b.cssTransitions===!1?(c[b.animType]="translate("+d+", "+e+")",b.$slideTrack.css(c)):(c[b.animType]="translate3d("+d+", "+e+", 0px)",b.$
14257slideTrack.css(c)))},b.prototype.setDimensions=function(){var b=this;b.options.vertical===!1?b.options.centerMode===!0&&b.$list.css({padding:"0px "+b.options.centerPadding}):(b.$list.height(b.$slides.first().outerHeight(!0)*b.options.slidesToShow),b.options.centerMode===!0&&b.$list.css({padding:b.options.centerPadding+" 0px"})),b.listWidth=b.$list.width(),b.listHeight=b.$list.height(),b.options.vertical===!1&&b.options.variableWidth===!1?(b.slideWidth=Math.ceil(b.listWidth/b.options.slidesToShow),b.$slideTrack.width(Math.ceil(b.slideWidth*b.$slideTrack.children(".slick-slide").length))):b.options.variableWidth===!0?(b.slideWidth=0,b.$slideTrack.children(".slick-slide").each(function(){b.slideWidth+=Math.ceil(a(this).outerWidth(!0))}),b.$slideTrack.width(Math.ceil(b.slideWidth)+1)):(b.slideWidth=Math.ceil(b.listWidth),b.$slideTrack.height(Math.ceil(b.$slides.first().outerHeight(!0)*b.$slideTrack.children(".slick-slide").length)));var c=b.$slides.first().outerWidth(!0)-b.$slides.first().width();b.options.variableWidth===!1&&b.$slideTrack.children(".slick-slide").width(b.slideWidth-c)},b.prototype.setFade=function(){var c,b=this;b.$slides.each(function(d,e){c=-1*b.slideWidth*d,a(e).css({position:"relative",left:c,top:0,zIndex:800,opacity:0})}),b.$slides.eq(b.currentSlide).css({zIndex:900,opacity:1})},b.prototype.setHeight=function(){var a=this;if(1===a.options.slidesToShow&&a.options.adaptiveHeight===!0&&a.options.vertical===!1){var b=a.$slides.eq(a.currentSlide).outerHeight(!0);a.$list.css("height",b)}},b.prototype.setPosition=function(){var a=this;a.setDimensions(),a.setHeight(),a.options.fade===!1?a.setCSS(a.getLeft(a.currentSlide)):a.setFade()},b.prototype.setProps=function(){var a=this,b=document.body.style;a.positionProp=a.options.vertical===!0?"top":"left","top"===a.positionProp?a.$slider.addClass("slick-vertical"):a.$slider.removeClass("slick-vertical"),(void 0!==b.WebkitTransition||void 0!==b.MozTransition||void 0!==b.msTransition)&&a.options.useCSS===!0&&(a.cssTransitions=!0),void 0!==b.OTransform&&(a.animType="OTransform",a.transformType="-o-transform",a.transitionType="OTransition",void 0===b.perspectiveProperty&&void 0===b.webkitPerspective&&(a.animType=!1)),void 0!==b.MozTransform&&(a.animType="MozTransform",a.transformType="-moz-transform",a.transitionType="MozTransition",void 0===b.perspectiveProperty&&void 0===b.MozPerspective&&(a.animType=!1)),void 0!==b.webkitTransform&&(a.animType="webkitTransform",a.transformType="-webkit-transform",a.transitionType="webkitTransition",void 0===b.perspectiveProperty&&void 0===b.webkitPerspective&&(a.animType=!1)),void 0!==b.msTransform&&(a.animType="msTransform",a.transformType="-ms-transform",a.transitionType="msTransition",void 0===b.msTransform&&(a.animType=!1)),void 0!==b.transform&&a.animType!==!1&&(a.animType="transform",a.transformType="transform",a.transitionType="transition"),a.transformsEnabled=null!==a.animType&&a.animType!==!1},b.prototype.setSlideClasses=function(a){var c,d,e,f,b=this;b.$slider.find(".slick-slide").removeClass("slick-active").removeClass("slick-center"),d=b.$slider.find(".slick-slide"),b.options.centerMode===!0?(c=Math.floor(b.options.slidesToShow/2),b.options.infinite===!0&&(a>=c&&a<=b.slideCount-1-c?b.$slides.slice(a-c,a+c+1).addClass("slick-active"):(e=b.options.slidesToShow+a,d.slice(e-c+1,e+c+2).addClass("slick-active")),0===a?d.eq(d.length-1-b.o
vendor: 1,297 bytes, line 14257
14257ptions.slidesToShow).addClass("slick-center"):a===b.slideCount-1&&d.eq(b.options.slidesToShow).addClass("slick-center")),b.$slides.eq(a).addClass("slick-center")):a>=0&&a<=b.slideCount-b.options.slidesToShow?b.$slides.slice(a,a+b.options.slidesToShow).addClass("slick-active"):d.length<=b.options.slidesToShow?d.addClass("slick-active"):(f=b.slideCount%b.options.slidesToShow,e=b.options.infinite===!0?b.options.slidesToShow+a:a,b.options.slidesToShow==b.options.slidesToScroll&&b.slideCount-a<b.options.slidesToShow?d.slice(e-(b.options.slidesToShow-f),e+f).addClass("slick-active"):d.slice(e,e+b.options.slidesToShow).addClass("slick-active")),"ondemand"===b.options.lazyLoad&&b.lazyLoad()},b.prototype.setupInfinite=function(){var c,d,e,b=this;if((b.options.fade===!0||b.options.vertical===!0)&&(b.options.centerMode=!1),b.options.infinite===!0&&b.options.fade===!1&&(d=null,b.slideCount>b.options.slidesToShow)){for(e=b.options.centerMode===!0?b.options.slidesToShow+1:b.options.slidesToShow,c=b.slideCount;c>b.slideCount-e;c-=1)d=c-1,a(b.$slides[d]).clone(!0).attr("id","").attr("index",d-b.slideCount).prependTo(b.$slideTrack).addClass("slick-cloned");for(c=0;e>c;c+=1)d=c,a(b.$slides[d]).clone(!0).attr("id","").attr("index",d+b.slideCount).appendTo(b.$slideTrack).addClass("slick-cloned");
14257b.$slideTrack.find(".slick-cloned").find("[id]").each(function(){a(this).attr("id","")})}},b.prototype.selectHandler=function(b){var c=this,d=parseInt(a(b.target).parents(".slick-slide").attr("index"));d||(d=0),c.slideCount<=c.options.slidesToShow||c.slideHandler(d)},b.prototype.slideHandler=function(a,b){var c,d,e,f,g,h=null,i=this;return b=b||!1,i.animating===!0&&i.options.waitForAnimate===!0?!1:(b===!1&&i.asNavFor(a),c=a,h=i.getLeft(c),f=i.getLeft(i.currentSlide),g=0!==i.slideCount%i.options.slidesToScroll?i.options.slidesToScroll:0,i.currentLeft=null===i.swipeLeft?f:i.swipeLeft,i.options.infinite===!1&&i.options.centerMode===!1&&(0>a||a>i.slideCount-i.options.slidesToShow+g)?(i.options.fade===!1&&(c=i.currentSlide,i.animateSlide(f,function(){i.postSlide(c)})),!1):i.options.infinite===!1&&i.options.centerMode===!0&&(0>a||a>i.slideCount-i.options.slidesToScroll)?(i.options.fade===!1&&(c=i.currentSlide,i.animateSlide(f,function(){i.postSlide(c)})),!1):(i.options.autoplay===!0&&clearInterval(i.autoPlayTimer),d=0>c?0!==i.slideCount%i.options.slidesToScroll?i.slideCount-i.slideCount%i.options.slidesToScroll:i.slideCount+c:c>=i.slideCount?0!==i.slideCount%i.options.slidesToScroll?0:c-i.slideCount:c,i.animating=!0,null!==i.options.onBeforeChange&&a!==i.currentSlide&&i.options.onBeforeChange.call(this,i,i.currentSlide,d),e=i.currentSlide,i.currentSlide=d,i.setSlideClasses(i.currentSlide),i.updateDots(),i.updateArrows(),i.options.fade===!0?(i.fadeSlide(e,d,function(){i.postSlide(d)}),!1):(i.animateSlide(h,function(){i.postSlide(d)}),void 0)))},b.prototype.startLoad=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.hide(),a.$nextArrow.hide()),a.options.dots===!0&&a.slideCount>a.options.slidesToShow&&a.$dots.hide(),a.$slider.addClass("slick-loading")},b.prototype.swipeDirection=function(){var a,b,c,d,e=this;return a=e.touchObject.startX-e.touchObject.curX,b=e.touchObject.startY-e.touchObject.curY,c=Math.atan2(b,a),d=Math.round(180*c/Math.PI),0>d&&(d=360-Math.abs(d)),45>=d&&d>=0?"left":360>=d&&d>=315?"left":d>=135&&225>=d?"right":"vertical"},b.prototype.swipeEnd=function(b){var d,e,c=this;if(c.dragging=!1,void 0===c.touchObject.curX)return!1;if(c.touchObject.swipeLength>=c.touchObject.minSwipe)switch(a(b.target).on("click.slick",function(b){b.stopImmediatePropagation(),b.stopPropagation(),b.preventDefault(),a(b.target).off("click.slick")}),c.options.swipeToSlide===!0?(e=Math.round(c.touchObject.swipeLength/c.slideWidth),d=e):d=c.options.slidesToScroll,c.swipeDirection()){case"left":c.slideHandler(c.currentSlide+d),c.touchObject={};break;case"right":c.slideHandler(c.currentSlide-d),c.touchObject={}}else c.touchObject.startX!==c.touchObject.curX&&(c.slideHandler(c.currentSlide),c.touchObject={})},b.prototype.swipeHandler=function(a){var b=this;if(!(b.options.swipe===!1||"ontouchend"in document&&b.options.swipe===!1||b.options.draggable===!1&&-1!==a.type.indexOf("mouse")))switch(b.touchObject.fingerCount=a.originalEvent&&void 0!==a.originalEvent.touches?a.originalEvent.touches.length:1,b.touchObject.minSwipe=b.listWidth/b.options.touchThreshold,a.data.action){case"start":b.swipeStart(a);break;case"move":b.swipeMove(a);break;case"end":b.swipeEnd(a)}},b.prototype.swipeMove=function(a){var c,d,e,f,b=this;return f=void 0!==a.originalEvent?a.originalEvent.touches:null,c=b.getLeft(b.currentSlide),!b.dragging||f&&1!==f.length?!1:(b.touchObject.curX=void 0!==f?f[0].pageX:a.clientX,b.touchObject.curY=void 0!==f?f[0].pageY:a.clientY,b.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(b.touchObject.curX-b.touchObject.startX,2))),d=b.swipeDirection(),"vertical"!==d?(void 0!==a.originalEvent&&b.touchObject.swipeLength>4&&a.preventDefault(),e=b.touchObject.curX>b.touchObject.startX?1:-1,b.swipeLeft=b.options.vertical===!1?c+b.touchObject.swipeLength*e:c+b.touchObject.swipeLength*(b.$list.height()/b.listWidth)*e,b.options.fade===!0||b.options.touchMove===!1?!1:b.animating===!0?(b.swipeLeft=null,!1):(b.setCSS(b.swipeLeft),void 0)):void 0)},b.prototype.swipeStart=function(a){var c,b=this;return 1!==b.touchObject.fingerCount||b.slideCount<=b.options.slidesToShow?(b.touchObject={},!1):(void 0!==a.originalEvent&&void 0!==a.originalEvent.touches&&(c=a.originalEvent.touches[0]),b.touchObject.startX=b.touchObject.curX=void 0!==c?c.pageX:a.clientX,b.touchObject.startY=b.touchObject.curY=void 0!==c?c.pageY:a.clientY,b.dragging=!0,void 0)},b.prototype.unfilterSlides=function(){var a=this;null!==a.$slidesCache&&(a.unload(),a.$slideTrack.children(this.options.slide).detach(),a.$slidesCache.appendTo(a.$slideTrack),a.reinit())},b.prototype.unload=function(){var b=this;a(".slick-cloned",b.$slider).remove(),b.$dots&&b.$dots.remove(),b.$prevArrow&&(b.$prevArrow.remove(),b.$nextArrow.remove()),b.$slides.removeClass("slick-slide slick-active slick-visible").css("width","")},b.prototype.updateArrows=function(){var a=this;a.options.arrows===!0&&a.options.infinite!==!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.removeClass("slick-disabled"),a.$nextArrow.removeClass("slick-disabled"),0===a.currentSlide?(a.$prevArrow.addClass("slick-disabled"),a.$nextArrow.removeClass("slick-disabled")):a.currentSlide>=a.slideCount-a.options.slidesToShow&&(a.$nextArrow.addClass("slick-disabled"),a.$prevArrow.removeClass("slick-disabled")))},b.prototype.updateDots=function(){var a=this;null!==a.$dots&&(a.$dots.find("li").removeClass("slick-active"),a.$dots.find("li").eq(Math.floor(a.currentSlide/a.options.slidesToScroll)).addClass("slick-active"))},a.fn.slick=function(a){var c=this;return c.each(function(c,d){d.slick=new b(d,a)})},a.fn.slickAdd=function(a,b,c){var d=this;return d.each(function(d,e){e.slick.addSlide(a,b,c)})},a.fn.slickCurrentSlide=function(){var a=this;return a.get(0).slick.getCurrent()},a.fn.slickFilter=function(a){var b=this;return b.each(function(b,c){c.slick.filterSlides(a)})},a.fn.slickGoTo=function(a){var b=this;return b.each(function(b,c){c.slick.changeSlide({data:{message:"index",index:
14257parseInt(a)}})})},a.fn.slickNext=function(){var a=this;return a.each(function(a,b){b.slick.changeSlide({data:{message:"next"}})})},a.fn.slickPause=function(){var a=this;return a.each(function(a,b){b.slick.autoPlayClear(),b.slick.paused=!0})},a.fn.slickPlay=function(){var a=this;return a.each(function(a,b){b.slick.paused=!1,b.slick.autoPlay()})},a.fn.slickPrev=function(){var a=this;return a.each(function(a,b){b.slick.changeSlide({data:{message:"previous"}})})},a.fn.slickRemove=function(a,b){var c=this;return c.each(function(c,d){d.slick.removeSlide(a,b)})},a.fn.slickGetOption=function(a){var b=this;return b.get(0).slick.options[a]},a.fn.slickSetOption=function(a,b,c){var d=this;return d.each(function(d,e){e.slick.options[a]=b,c===!0&&(e.slick.unload(),e.slick.reinit())})},a.fn.slickUnfilter=function(){var a=this;return a.each(function(a,b){b.slick.unfilterSlides()})},a.fn.unslick=function(){var a=this;return a.each(function(a,b){b.slick&&b.slick.destroy()})},a.fn.getSlick=function(){var a=null,b=this;return b.each(function(b,c){a=c.slick}),a}});
14258/*
14259* Nivo Lightbox v1.2.0
14260* http://dev7studios.com/nivo-lightbox
14261*
14262* Copyright 2013, Dev7studios
14263* Free to use and abuse under the MIT license.
14264* http://www.opensource.org/licenses/mit-license.php
14265*/
14266(function(e,t,n,r){function o(t,n){this.el=t;this.$el=e(this.el);this.options=e.extend({},s,n);this._defaults=s;this._name=i;this.init()}var i="nivoLightbox",s={effect:"fade",theme:"default",keyboardNav:true,clickOverlayToClose:true,onInit:function(){},beforeShowLightbox:function(){},afterShowLightbox:function(e){},beforeHideLightbox:function(){},afterHideLightbox:function(){},onPrev:function(e){},onNext:function(e){},errorMessage:"The requested content cannot be loaded. Please try again later."};o.prototype={init:function(){var t=this;if(!e("html").hasClass("nivo-lightbox-notouch"))e("html").addClass("nivo-lightbox-notouch");if("ontouchstart"in n)e("html").removeClass("nivo-lightbox-notouch");this.$el.on("click",function(e){t.showLightbox(e)});if(this.options.keyboardNav){e("body").off("keyup").on("keyup",function(n){var r=n.keyCode?n.keyCode:n.which;if(r==27)t.destructLightbox();if(r==37)e(".nivo-lightbox-prev").trigger("click");if(r==39)e(".nivo-lightbox-next").trigger("click")})}this.options.onInit.call(this)},showLightbox:function(t){var n=this,r=this.$el;var i=this.checkContent(r);if(!i)return;t.preventDefault();this.options.beforeShowLightbox.call(this);var s=this.constructLightbox();if(!s)return;var o=s.find(".nivo-lightbox-content");if(!o)return;e("body").addClass("nivo-lightbox-body-effect-"+this.options.effect);this.processContent(o,r);if(this.$el.attr("data-lightbox-gallery")){var u=e('[data-lightbox-gallery="'+this.$el.attr("data-lightbox-gallery")+'"]');e(".nivo-lightbox-nav").show();e(".nivo-lightbox-prev").off("click").on("click",function(t){t.preventDefault();var i=u.index(r);r=u.eq(i-1);if(!e(r).length)r=u.last();n.processContent(o,r);n.options.onPrev.call(this,[r])});e(".nivo-lightbox-next").off("click").on("click",function(t){t.preventDefault();var i=u.index(r);r=u.eq(i+1);if(!e(r).length)r=u.first();n.processContent(o,r);n.options.onNext.call(this,[r])})}setTimeout(function(){s.addClass("nivo-lightbox-open");n.options.afterShowLightbox.call(this,[s])},1)},checkContent:function(e){var t=this,n=e.attr("href"),r=n.match(/(youtube|youtu|vimeo)\.(com|be)\/(watch\?v=([\w-]+)|([\w-]+))/);if(n.match(/\.(jpeg|jpg|gif|png)$/i)!==null){return true}else if(r){return true}else if(e.attr("data-lightbox-type")=="ajax"){return true}else if(n.substring(0,1)=="#"&&e.attr("data-lightbox-type")=="inline"){return true}else if(e.attr("data-lightbox-type")=="iframe"){return true}return false},processContent:function(n,r){var i=this,s=r.attr("href"),o=s.match(/(youtube|youtu|vimeo)\.(com|be)\/(watch\?v=([\w-]+)|([\w-]+))/);n.html("").addClass("nivo-lightbox-loading");if(this.isHidpi()&&r.attr("data-lightbox-hidpi")){s=r.attr("data-lightbox-hidpi")}if(s.match(/\.(jpeg|jpg|gif|png)$/i)!==null){var u=e("<img>",{src:s});u.one("load",function(){var r=e('<div class="nivo-lightbox-image" />');r.append(u);n.html(r).removeClass("nivo-lightbox-loading");r.css({"line-height":e(".nivo-lightbox-content").height()+"px",height:e(".nivo-lightbox-content").height()+"px"});e(t).resize(function(){r.css({"line-height":e(".nivo-lightbox-content").height()+"px",height:e(".nivo-lightbox-content").height()+"px"})})}).each(function(){if(this.complete)e(this).load()});u.error(function(){var t=e('<div class="nivo-lightbox-error"><p>'+i.options.errorMessage+"</p></div>");n.html(t).removeClass("nivo-lightbox-loading")})}else if(o){var a="",f="nivo-lightbox-video";if(o[1]=="youtube"){a="http://www.youtube.com/embed/"+o[4];f="nivo-lightbox-youtube"}if(o[1]=="youtu"){a="http://www.youtube.com/embed/"+o[3];f="nivo-lightbox-youtube"}if(o[1]=="vimeo"){a="http://player.vimeo.com/video/"+o[3];f="nivo-lightbox-vimeo"}if(a){var l=e("<iframe>",{src:a,"class":f,frameborder:0,vspace:0,hspace:0,scrolling:"auto"});n.html(l);l.load(function(){n.removeClass("nivo-lightbox-loading")})}}else if(r.attr("data-lightbox-type")=="ajax"){e.ajax({url:s,cache:false,success:function(r){var i=e('<div class="nivo-lightbox-ajax" />');i.append(r);n.html(i).removeClass("nivo-lightbox-loading");if(i.outerHeight()<n.height()){i.css({position:"relative",top:"50%","margin-top":-(i.outerHeight()/2)+"px"})}e(t).resize(function(){if(i.outerHeight()<n.height()){i.css({position:"relative",top:"50%","margin-top":-(i.outerHeight()/2)+"px"})}})},error:function(){var t=e('<div class="nivo-lightbox-error"><p>'+i.options.errorMessage+"</p></div>");n.html(t).removeClass("nivo-lightbox-loading")}})}else if(s.substring(0,1)=="#"&&r.attr("data-lightbox-type")=="inline"){if(e(s).length){var c=e('<div class="nivo-lightbox-inline" />');c.append(e(s).clone().show());n.html(c).removeClass("nivo-lightbox-loading");if(c.outerHeight()<n.height()){c.css({position:"relative",top:"50%","margin-top":-(c.outerHeight()/2)+"px"})}e(t).resize(function(){if(c.outerHeight()<n.height()){c.css({position:"relative",top:"50%","margin-top":-(c.outerHeight()/2)+"px"})}})}else{var h=e('<div class="nivo-lightbox-error"><p>'+i.options.errorMessage+"</p></div>");n.html(h).removeClass("nivo-lightbox-loading")}}else if(r.attr("data-lightbox-type")=="iframe"){var p=e("<iframe>",{src:s,"class":"nivo-lightbox-item",frameborder:0,vspace:0,hspace:0,scrolling:"auto"});n.html(p);p.load(function(){n.removeClass("nivo-lightbox-loading")})}else{return false}if(r.attr("title")){var d=e("<span>",{"class":"nivo-lightbox-title"});d.text(r.attr("title"));e(".nivo-lightbox-title-wrap").html(d)}else{e(".nivo-lightbox-title-wrap").html("")}},constructLightbox:function(){if(e(".nivo-lightbox-overlay").length)return e(".
14266nivo-lightbox-overlay");var t=e("<div>",{"class":"nivo-lightbox-overlay nivo-lightbox-theme-"+this.options.theme+" nivo-lightbox-effect-"+this.options.effect});var n=e("<div>",{"class":"nivo-lightbox-wrap"});var r=e("<div>",{"class":"nivo-lightbox-content"});var i=e('<a href="#" class="nivo-lightbox-nav nivo-lightbox-prev">Previous</a><a href="#" class="nivo-lightbox-nav nivo-lightbox-next">Next</a>');var s=e('<a href="#" class="nivo-lightbox-close" title="Close">Close</a>');var o=e("<div>",{"class":"nivo-lightbox-title-wrap"});var u=0;if(u)t.addClass("nivo-lightbox-ie");n.append(r);n.append(o);t.append(n);t.append(i);t.append(s);e("body").append(t);var a=this;if(a.options.clickOverlayToClose){t.on("click",function(t){if(t.target===this||e(t.target).hasClass("nivo-lightbox-content")||e(t.target).hasClass("nivo-lightbox-image")){a.destructLightbox()}})}s.on("click",function(e){e.preventDefault();a.destructLightbox()});return t},destructLightbox:function(){var t=this;this.options.beforeHideLightbox.call(this);e(".nivo-lightbox-overlay").removeClass("nivo-lightbox-open");e(".nivo-lightbox-nav").hide();e("body").removeClass("nivo-lightbox-body-effect-"+t.options.effect);var n=0;if(n){e(".nivo-lightbox-overlay iframe").attr("src"," ");e(".nivo-lightbox-overlay iframe").remove()}e(".nivo-lightbox-prev").off("click");e(".nivo-lightbox-next").off("click");e(".nivo-lightbox-content").empty();this.options.afterHideLightbox.call(this)},isHidpi:function(){var e="(-webkit-min-device-pixel-ratio: 1.5),                              (min--moz-device-pixel-ratio: 1.5),                              (-o-min-device-pixel-ratio: 3/2),                              (min-resolution: 1.5dppx)";if(t.devicePixelRatio>1)return true;if(t.matchMedia&&t.matchMedia(e).matches)return true;return false}};e.fn[i]=function(t){return this.each(function(){if(!e.data(this,i)){e.data(this,i,new o(this,t))}})}})(jQuery,window,document)
14267
14268$j(document).ready(function() {
14269
14270	$j('#fabox-1').fabox();
14271	$j('#fabox-2').fabox();
14272	$j('#fabox-3').fabox();
14273	$j('#fabox-4').fabox();
14274	
14275	$j('.smooth-scroll').unbind('click');
14276	$j('.smooth-scroll').bind('click', function(e) {
14277		e.preventDefault();
14278		$j('html,body').stop().animate({scrollTop: '0'}, 400);
14279	});
14280
14281	/*================================
14282	=            LIGHTBOX            =
14283	================================*/
14284	
14285	$j('.lightbox').nivoLightbox({
14286		effect: 'fall',
14287		afterShowLightbox: function() {
14288			$j('.nivo-lightbox-close').attr('title', 'Fermer').text('Fermer');
14289			$j('.nivo-lightbox-next').attr('title', 'Suivant').text('Suivant');
14290			$j('.nivo-lightbox-prev').attr('title', 'Précédent').text('Précédent');
14291		}
14292	});
14293
14294
14295	/*===================================
14296	=            BACK TO TOP            =
14297	===================================*/
14298		
14299	$j(window).scroll(function(e) {
14300		var scrolled = $j(this).scrollTop();
14301
14302		if (scrolled > 150) {
14303			$j('.back-to-top').addClass('is-visible');
14304		}
14305
14306		if (scrolled < 150) {
14307			$j('.back-to-top').removeClass('is-visible');
14308		}
14309	});
14310
14311	/*=================================
14312	=            NAV FIXED            =
14313	=================================*/
14314
14315	if (window.matchMedia("(min-width: 741px)").matches) {
14316		
14317		$j(window).scroll(function(e) {
14318			var scrolled = $j(this).scrollTop();
14319
14320			if (scrolled > 33) {
14321				$j('#header-top-links').addClass('is-fixed');
14322			}
14323
14324			if (scrolled < 33) {
14325				$j('#header-top-links').removeClass('is-fixed');
14326			}
14327		});
14328	}
14329
14330	/*==============================================
14331	=            CATALOG SEARCH RESULTS            =
14332	==============================================*/
14333
14334	if($j('#meccano-search-results').length > 0) {
14335		$j('#begin-mod-sidebar').hide();
14336	}
14337
14338	/*==============================================
14339	=            UNIRGY GIFT CERT                  =
14340	==============================================*/
14341
14342	$j(".gift-card-info #amount").on('change', function() {
14343        $j(".product-shop .price").html($j(this).val()+",00 €");
14344    });
14345
14346	/*==================================
14347	=            RESPONSIVE            =
14348	==================================*/
14349
14350	$j('#parametre-trigger').on('click', function(e) {
14351		e.preventDefault();
14352
14353		$j('#main-overlay').fadeIn(150);
14354		$j('.list-parametre').fadeIn().addClass('is-visible');
14355	});
14356
14357	$j('#recherche-trigger').on('click', function(e) {
14358		e.preventDefault();
14359
14360		$j('#main-overlay').fadeIn(150);
14361		$j('.header-search, .header-search-title').fadeIn();
14362	});
14363
14364	$j('#overlay-close-trigger').on('click', function(e) {
14365		e.preventDefault();
14366
14367		$j('#main-overlay, .header-search, .header-search-title, .list-parametre').removeClass('is-visible').fadeOut();
14368	});
14369
14370	$j('#site-menu-trigger').on('click', function(e) {
14371		e.preventDefault();
14372
14373		if ($j('.site-menu').hasClass('is-closed')) {
14374			$j('.site-menu').toggleClass('is-closed is-opened');
14375			$j(this).find('i').addClass('is-inverse');
14376		} else {
14377			$j('.site-menu').toggleClass('is-opened is-closed');
14378			$j(this).find('i').removeClass('is-inverse');
14379		}
14380	});
14381
14382	/*==========  DISABLE LINK  ==========*/	
14383
14384	if (window.matchMedia("(max-width: 960px)").matches) {
14385		disableLink();
14386	}
14387	
14388	// ==============================================
14389    // Layered Navigation Block
14390    // ==============================================
14391
14392    // On product list pages, we want to show the layered nav/category menu immediately above the product list.
14393    // While it would make more sense to just move the .block-layered-nav block rather than .col-left-first
14394    // (since other blocks can be inserted into left_first), it creates simpler code to move the entire
14395    // .col-left-first block, so that is the approach we're taking
14396    if ($j('.col-left-first > .block').length && $j('.category-products').length) {
14397        enquire.register('screen and (max-width: ' + bp.medium + 'px)', {
14398            match: function () {
14399                $j('.col-left-first').insertBefore($j('#amshopby-page-container'))
14400            },
14401            unmatch: function () {
14402                // Move layered nav back to left column
14403                $j('.col-left-first').insertBefore($j('.col-main'))
14404            }
14405        });
14406        $j('.amshopby-filters-left #narrow-by-list').removeClass('no-display');
14407        $j('.amshopby-filters-left .block-subtitle.block-subtitle--filter').remove();
14408    }
14409
14410    // ==============================================
14411    // OPC - Progress Block
14412    // ==============================================
14413
14414    if ($j('body.checkout-onepage-index').length) {
14415        enquire.register('(max-width: ' + bp.large + 'px)', {
14416            match: function () {
14417                $j('#checkout-step-review').prepend($j('#checkout-progress-wrapper'));
14418            },
14419            unmatch: function () {
14420                $j('.col-left').prepend($j('#checkout-progress-wrapper'));
14421            }
14422        });
14423    }
14424    $j('body').on('click', '#fabox-1 .btn-left', function () {
14425        $j('#fabox-1').hide();
14426    });
14427});
14428
14429function is_object(mixed_var) {
14430  if (Object.prototype.toString.call(mixed_var) === '[object Array]') {
14431    return false;
14432  }
14433  return mixed_var !== null && typeof mixed_var === 'object';
14434}
14435
14436function disableLink() {
14437	$j('.js-disable-link').on('click', function(e) {
14438		e.preventDefault();
14439	});
14440}
14441
14442function getColorByMinimumAgeJS(age) {
14443	age = parseInt(age);
14444	var color = '';
14445	switch(age) {
14446		case 0:
14447			color = 'grey';
14448		break;
14449		case 1:
14450			color = 'grey';			
14451		break;
14452		case 2:
14453			color = 'grey';
14454		break;
14455		case 3:
14456			color = 'grey';
14457		break;
14458		case 4:
14459			color = 'grey';
14460		break;
14461		case 5:
14462			color = 'orange';
14463		break;
14464		case 6:
14465			color = 'purple';
14466		break;
14467		case 7:
14468			color = 'green';
14469		break;
14470		case 8:
14471			color = 'brown';
14472		break;
14473		case 9:
14474			color = 'clementine';
14475		break;
14476		case 10:
14477			color = 'grey';
14478		break;
14479		case 11:
14480			color = 'grey';
14481		break;
14482		case 12:
14483			color = 'grey';
14484		break;
14485	}
14486	return color;
14487}
14488
14489function transformFormToAjax(id_form, callbackSuccess, callbackError, other_data) {
14490	$j(id_form).unbind('submit');
14491	$j(id_form).bind('submit', function(e) {
14492		e.preventDefault();
14493
14494		if(jQuery.isEmptyObject(other_data) == false && $j('.product-shop .price').length) {
14495			other_data_json = JSON.parse(other_data);
14496			other_data_json.price = $j('.product-shop .price').html();
14497			other_data = JSON.stringify(other_data_json);
14498		}
14499                
14500		$j('#main-loader').fadeIn(400);
14501		var url_form = $j(id_form).attr('action');
14502		if(url_form == '') {
14503			url_form = window.location.href;
14504		}
14505		var method = $j(id_form).attr('method');
14506		if(method == '') {
14507			method = 'post';
14508		}	
14509                
14510		var request = $j.ajax({
14511			url: url_form,
14512			type: method,
14513			data: $j(id_form).serialize()
14514		});
14515		
14516		request.done(function(response) {
14517			$j('#main-loader').fadeOut(400);
14518			callbackSuccess(response, other_data);
14519		});
14520		
14521		request.fail(function(jqXHR, textStatus) {
14522			$j('#main-loader').fadeOut(400);
14523			callbackError(jqXHR, textStatus, other_data);
14524		});
14525	});
14526}
14527
14528function transformUrlToAjax(url, method, callbackSuccess, callbackError, other_data) {
14529	$j('#main-loader').fadeIn(400);
14530	var url_form = url;
14531	if(url_form == '') {
14532		url_form = window.location.href;
14533	}
14534	var request = $j.ajax({
14535		url: url_form,
14536		type: method
14537	});
14538	
14539	request.done(function(response) {
14540		$j('#main-loader').fadeOut(400);
14541		callbackSuccess(response, other_data);
14542	});
14543	
14544	request.fail(function(jqXHR, textStatus) {
14545		$j('#main-loader').fadeOut(400);
14546		callbackError(jqXHR, textStatus, other_data);
14547	});
14548}
14549
14550function strip_tags(input, allowed) {
14551	allowed = (((allowed || '') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('');
14552	var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
14553	return input.replace(commentsAndPhpTags, '').replace(tags, function($0, $1) {
14554		return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
14555	});
14556}
14557
14558function customIFrameSoCol() {
14559	var wrap_socol_module = $j('#socolissimosimplicite_iframe_wrapper iframe').clone();
14560	$j('#socolissimosimplicite_iframe_wrapper iframe').remove();
14561	$j('#fabox-1').fabox('write', {content : wrap_socol_module,
14562								   open: true,
14563								   mode_closebox: 'center'});
14564	$j('#socolissimosimplicite_iframe_wrapper').hide();
14565	$j('#socolissimosimplicite_iframe_wrapper').children().eq(0).trigger('click');
14566}
14567
14568$j(document).ready(function() {
14569	
14570    
14571});
14572
14573function playVideo(url) {
14574	$j('#fabox-1').fabox('write', {content : '<iframe width="800" height="480" src="' + url + '" frameborder="0" allowfullscreen></iframe>',
14575									full: true,
14576								   open: true,
14577								   mode_closebox: 'center'});
14578}
14579
14580function showDescriptionVideo(title, desc) {
14581	$j('#fabox-1').fabox('write', {content: '<div style="padding: 15px;"><h1 style="text-align: center;margin-top: 0;">' + title + '</h1><p>' + desc + '</p></div>',
14582                open: true,
14583                width: 500,
14584                mode_closebox: 'center'});
14585}
14586$j(document).ready(function() {});
14587
14588function successAddToCart(response, other_data) {
14589	other_data_json = JSON.parse(other_data);
14590	var img = '';
14591	var urlproduct = '';
14592	var productName = '';
14593	var refProduct = '';
14594	var descProduct = '';
14595
14596	var message_gift_step = $j(response).find('.gift-step-msg').children().eq(0).text();
14597	if(message_gift_step.length > 1) { message_gift_step = '<div class="gift-step-msg">' + message_gift_step + '</div>'; } 
14598        
14599	if(other_data_json != null && other_data_json.img != null && other_data_json.img != '') {
14600		img = '<img src="' + other_data_json.img + '" />';
14601	}
14602	if(other_data_json != null && other_data_json.name != null && other_data_json.name != '') {
14603		productName = other_data_json.name;
14604	}
14605	if(other_data_json != null && other_data_json.ref != null && other_data_json.ref != '') {
14606		refProduct = '<p class="ref">Ref. ' + other_data_json.ref + '</p>';
14607	}
14608	if(other_data_json != null && other_data_json.desc != null && other_data_json.desc != '') {
14609		descProduct = '<p class="desc">' + other_data_json.desc + '</p>';
14610	}
14611	if(other_data_json != null && other_data_json.url_product != null && other_data_json.url_product != '') {
14612		urlproduct = '<a href="' + other_data_json.url_product + '"><i class="meccano-arrow-right"></i> Voir le produit</a>';
14613	}
14614	var headertoplinks = $j(response).find('#header-top-cart');
14615	if(headertoplinks != null && headertoplinks.length > 0) {
14616		$j('#header-top-cart').replaceWith(headertoplinks);
14617	}
14618	var contentMess = '<h4>' + productName + '</h4>' + refProduct + /*descProduct +*/ urlproduct;
14619	var messages = $j(response).find('.messages').text();
14620	if(messages != null && messages.length > 0) {
14621		if(messages.match(/a été ajouté à votre panier/gi)) {
14622			$j('#fabox-1').fabox('confirm', {title: 'Article ajouté à votre panier : ',
14623                                                msg: '<div class="img-product left">' + img + '</div>' +
14624													   '<div class="descriptions-product right">' + contentMess + '</div>' +
14625													   '<div class="cf"></div>' +
14626													   message_gift_step,
14627												mode_closebox: 'center',
14628                                                left_btn: 'Poursuivre mes achats',
14629                                                right_btn: 'Voir mon panier',
14630                                                width: 600,
14631                                                callback_left: function() {
14632											       $j('#fabox-1').fabox('close');
14633                                                },
14634                                                callback_right: function() {
14635													if(other_data_json != null && other_data_json.url_cart != null && other_data_json.url_cart != '') {
14636														document.location.href = other_data_json.url_cart;
14637													}
14638													else {
14639														$j('#fabox-1').fabox('close');
14640													}
14641                                                }});
14642		}
14643		else {
14644			$j('#fabox-1').fabox('alert', {msg: '', title: messages, mode_closebox: 'center'});
14645		}
14646	}
14647	else if (is_object(response)) {
14648		$j('#fabox-1').fabox('confirm', {title: 'Article ajouté à votre panier : ',
14649                                        msg: '<div class="img-product left">' + img + '</div>' +
14650											   '<div class="descriptions-product right">' + contentMess + '</div>' +
14651											   '<div class="cf"></div>' +
14652											   message_gift_step,
14653										mode_closebox: 'center',
14654                                        left_btn: 'Poursuivre mes achats',
14655                                        right_btn: 'Voir mon panier',
14656										width: 600,
14657                                        callback_left: function() {
14658									       $j('#fabox-1').fabox('close');
14659                                        },
14660                                        callback_right: function() {
14661											if(other_data_json != null && other_data_json.url_cart != null && other_data_json.url_cart != '') {
14662												document.location.href = other_data_json.url_cart;
14663											}
14664											else {
14665												$j('#fabox-1').fabox('close');
14666											}
14667                                        }});
14668	}
14669	else {
14670		errorAddToCart(null, null, other_data);
14671	}
14672}
14673
14674function errorAddToCart(jqXHR, textStatus, other_data) {
14675	other_data_json = JSON.parse(other_data);
14676	if(other_data_json != null && other_data_json.url_cart != null && other_data_json.url_cart != '') {
14677		document.location.href = other_data_json.url_cart;
14678	}
14679	else {
14680		window.location.reload();
14681	}
14682}
14683
14684function successAddToCartDetail(response, other_data) {
14685	other_data_json = JSON.parse(other_data);
14686	var img = '';
14687	var urlproduct = '';
14688    var isGift = $j('#u_pdf_template').size() > 0;
14689    var imageUrl =  other_data_json.img;
14690
14691    console.log(other_data);
14692
14693    var message_gift_step = $j(response).find('.gift-step-msg').children().eq(0).text();
14694    if(message_gift_step.length > 1) { message_gift_step = '<div class="gift-step-msg">' + message_gift_step + '</div>'; } 
14695        
14696        if(isGift)
14697        {
14698            var templateId = $j('#u_pdf_template').val();
14699            imageUrl = $j('#pdf-visuel-'+templateId+' img').attr('src');
14700        }
14701        
14702	if(other_data_json != null && other_data_json.img != null && other_data_json.img != '') {
14703		img = '<img src="' + imageUrl + '" />';
14704	}
14705	if(other_data_json != null && other_data_json.name != null && other_data_json.name != '') {
14706		productName = other_data_json.name;
14707	}
14708	if(other_data_json != null && other_data_json.ref != null && other_data_json.ref != '') {
14709		refProduct = '<p class="ref">Ref. ' + other_data_json.ref + '</p>';
14710	}
14711
14712		if(isGift)
14713        {
14714            refProduct += '<p class="desc">
14714Montant du chèque cadeau : <strong>'+other_data_json.price+'</strong></p>';
14715        }
14716
14717	if(other_data_json != null && other_data_json.desc != null && other_data_json.desc != '') {
14718		descProduct = '<p class="desc">' + other_data_json.desc + '</p>';
14719	}
14720	if(other_data_json != null && other_data_json.url_product != null && other_data_json.url_product != '') {
14721		urlproduct = '<br><a href="' + other_data_json.url_product + '">Voir le produit</a>';
14722	}
14723	var headertoplinks = $j(response).find('#header-top-links');
14724	if(headertoplinks != null && headertoplinks.length > 0) {
14725		$j('#header-top-links').replaceWith(headertoplinks);
14726	}
14727	var contentMess = '<h4>' + productName + '</h4>' + refProduct /*+ descProduct*/;
14728	var messages = $j(response).find('.messages').text();
14729	if(messages != null && messages.length > 0) {
14730		if(messages.match(/a été ajouté à votre panier/gi)) {
14731			$j('#fabox-1').fabox('confirm', {msg: '<div class="img-product left">' + img + '</div>' +
14732													   '<div class="descriptions-product right">' + contentMess + '</div>' +
14733													   '<div class="cf"></div>' +
14734													   message_gift_step,
14735												   title: 'Article ajouté à votre panier : ',
14736											       left_btn: 'Poursuivre mes achats',
14737											       right_btn: 'Voir mon panier',
14738												   width: 600,
14739												   mode_closebox: 'center',
14740											       callback_left: function() {
14741											       	   $j('#fabox-1').fabox('close');
14742											       }, 
14743											       callback_right: function() {
14744														if(other_data_json != null && other_data_json.url_cart != null && other_data_json.url_cart != '') {
14745															document.location.href = other_data_json.url_cart;
14746														}
14747														else {
14748															$j('#fabox-1').fabox('close');
14749														}
14750											       }});
14751		}
14752		else {			
14753			$j('#fabox-1').fabox('alert', {msg: '', title: messages, mode_closebox: 'center'});
14754		}
14755	}
14756	else {
14757		errorAddToCartDetail(null, null, other_data);
14758	}
14759}
14760
14761function errorAddToCartDetail(response, other_data) {
14762	other_data_json = JSON.parse(other_data);
14763	if(other_data_json != null && other_data_json.url_cart != null && other_data_json.url_cart != '') {
14764		document.location.href = other_data_json.url_cart;
14765	}
14766	else {
14767		window.location.reload();
14768	}
14769}
14770
14771function successForgottenPasswd(response, other_data) {
14772	var contentHtml = $j(response).find('.col-main').html();
14773	if(contentHtml != null && contentHtml != '') {
14774		$j('#fabox-1').fabox('write', {content: '<div style="padding: 20px;">' + contentHtml + '</div>', width: 600, open: true, mode_closebox: 'center'});
14775	}
14776	else {
14777		errorForgottenPasswd(response, other_data);
14778	}
14779}
14780
14781function errorForgottenPasswd(response, other_data) {
14782	other_data_json = JSON.parse(other_data);
14783	if(other_data_json != null && other_data_json.urlError != null && other_data_json.urlError != '') {
14784		document.location.href = other_data_json.urlError;
14785	}
14786	else {
14787		window.location.reload();
14788	}
14789}
14790
14791function successLogin(response, other_data) {
14792	var contentHtml = $j(response).find('.messages').html();
14793	if(contentHtml != null && contentHtml != '') {
14794		contentHtml = strip_tags(contentHtml, '<a>');
14795		$j('#fabox-1').fabox('alert', {title: contentHtml, msg: '', mode_closebox: 'center'});
14796	}
14797	else {
14798		errorLogin(response, other_data);
14799	}
14800}
14801
14802function errorLogin(response, other_data) {
14803	window.location.reload();
14804}
14805
14806function successContact(response, other_data) {
14807	var contentHtml = strip_tags($j(response).find('.messages').html(), '<a>');
14808	if(contentHtml != null && contentHtml != '') {
14809		$j('#fabox-1').fabox('alert', {title: contentHtml, msg: '', mode_closebox: 'center'});
14810		__refreshCAPTCHA('.btn_refresh_captcha');
14811		if(contentHtml.match(/merci/gi) || contentHtml.match(/thank/gi)) {
14812			$j('#contactForm').find("input[type=text], textarea").val("");
14813			$j('#contactForm').find("select").val(1);
14814			changeWhoContact(1);
14815		}
14816	}
14817	else {
14818		errorLogin(response, other_data);
14819	}
14820}
14821
14822function errorContact(response, other_data) {
14823	window.location.reload();
14824}
14825
14826function successSubscribeNewsletter(response, other_data) {
14827	var contentHtml = $j(response).find('.messages').html();
14828	if(contentHtml != null && contentHtml != '') {
14829		contentHtml = strip_tags(contentHtml, '<a>');
14830		$j('#fabox-1').fabox('alert', {title: contentHtml, msg: '', mode_closebox: 'center'});
14831		if(contentHtml.match(/merci/gi) || contentHtml.match(/thank/gi)) {
14832			$j('#newsletter').val('');
14833		}
14834	}
14835	else {
14836		errorSubscribeNewsletter(response, other_data);
14837	}
14838}
14839
14840function errorSubscribeNewsletter(response, other_data) {
14841	window.location.reload();
14842}
14843
14844function successCart(response, other_data) {
14845	var contentHtml = $j(response).find('.page').html();
14846	if(contentHtml != null && contentHtml != '') {
14847		$j('.page').html(contentHtml);
14848	}
14849	else {
14850		errorSubscribeNewsletter(response, other_data);
14851	}
14852}
14853
14854function errorCart(response, other_data) {
14855	window.location.reload();
14856}
14857
14858function successCartCoupon(response, other_data) {
14859	console.log(response);
14860	var contentHtml = $j(response).find('.messages').html();
14861	if(contentHtml != null && contentHtml != '') {
14862		contentHtml = strip_tags(contentHtml, '<a>');
14863		if(contentHtml.match(/a été appliqué/gi) || contentHtml.match(/a été annulé/gi)) {
14864			var contentHtmlPage = $j(response).find('.page').html();
14865			if(contentHtmlPage != null && contentHtmlPage != '') {
14866				$j('.page').html(contentHtmlPage);
14867				$j('.page').find('.messages').hide();
14868				$j('.btn-update').trigger('click');
14869			}
14870			else {				
14871				errorCartCoupon(response, other_data);
14872			}
14873		}
14874		$j('#fabox-1').fabox('alert', {title: contentHtml, msg: '', mode_closebox: 'center'});
14875	}
14876	else {
14877		errorLogin(response, other_data);
14878	}
14879}
14880
14881function errorCartCoupon(response, other_data) {
14882	window.location.reload();
14883}
14884
14885function successArticleFidelity(response, other_data) {
14886	var contentHtml = $j(response).find('.col-main').html();
14887	if(contentHtml != null && contentHtml != '') {
14888		$j('#fabox-1').fabox('write', {content: '<div style="padding: 20px;">' + contentHtml + '</div>', width: 600, open: true, mode_closebox: 'center'});
14889	}
14890	else {
14891		errorArticleFidelity(response, other_data);
14892	}
14893}
14894
14895function errorArticleFidelity(response, other_data) {
14896	other_data_json = JSON.parse(other_data);
14897	if(other_data_json != null && other_data_json.urlError != null && other_data_json.urlError != '') {
14898		document.location.href = other_data_json.urlError;
14899	}
14900	else {
14901		window.location.reload();
14902	}
14903}
14904var timerMagnifizerAgeMin = null;
14905var timerMagnifizerPager = null;
14906
14907$j(document).ready(function() {
14908	
14909	if($j('.amshopby-attr').length > 0 || $j('.amshopby-attr-selected').length > 0) {
14910		magnifizerFilter(true);
14911		window.clearInterval(timerMagnifizerAgeMin);
14912		timerMagnifizerAgeMin = window.setInterval(function() {
14913			magnifizerFilter(false);
14914		}, 500);
14915	}
14916	
14917	if($j('.a-open-slide-accordion').length > 0) {
14918		autoBindSlideAcordionCategory();
14919	}
14920	
14921	if($j('#toolbar-pager').length > 0) {
14922		magnifizerPager();
14923		window.clearInterval(timerMagnifizerPager);
14924		timerMagnifizerPager = window.setInterval(function() {
14925			magnifizerPager(false);
14926		}, 200);
14927	}
14928	
14929});
14930
14931function magnifizerPager() {
14932	$j('#toolbar-pager li').each(function(k, v) {
14933		var strhtml = parseInt($j(v).text());
14934		if(!isNaN(strhtml) && strhtml > 0) {
14935			$j(v).addClass('page-item');
14936		}
14937	});
14938}
14939
14940function autoBindSlideAcordionCategory() {
14941	$j('.a-open-slide-accordion').unbind('click');
14942	
14943	$j('.a-open-slide-accordion').bind('click', function() {
14944		if ($j('.slide-accordion').hasClass('opened')) {
14945			$j('.slide-accordion').removeClass('opened');
14946			$j('.slide-accordion').slideUp(200);
14947			$j('.a-open-slide-accordion').show();
14948			$j('.a-open-slide-accordion.btn-hide').hide();
14949		}
14950		else {
14951			$j('.slide-accordion').addClass('opened');
14952			$j('.slide-accordion').slideDown(200);
14953			$j('.a-open-slide-accordion').hide();
14954			$j('.a-open-slide-accordion.btn-hide').show().css('display', 'block');
14955		}
14956	});
14957	
14958	closeSlideAcordionCategory();
14959}
14960
14961function closeSlideAcordionCategory() {
14962	$j('.slide-accordion').removeClass('opened');
14963	$j('.slide-accordion').hide();
14964	$j('.a-open-slide-accordion').show();
14965	$j('.a-open-slide-accordion.btn-hide').hide();	
14966}
14967
14968function magnifizerFilter(firstCall) {
14969	$j('.amshopby-attr').each(function(k, v) {
14970		if($j(v).text() == '0+' || $j(v).text() == '1+' || $j(v).text() == '2+' || $j(v).text() == '3+' ||
14971		   $j(v).text() == '4+' || $j(v).text() == '5+' || $j(v).text() == '6+' || $j(v).text() == '7+' ||
14972		   $j(v).text() == '8+' || $j(v).text() == '9+' || $j(v).text() == '10+' || $j(v).text() == '11+' ||
14973		   $j(v).text() == '12+' || $j(v).text() == '13+' || $j(v).text() == '14+' || $j(v).text() == '15+') {
14974			var replaceHtml = '<span class="macaron mi-stack macaron-bordered">' +
14975									'<i class="mi mi-stack-2x meccano-macaron macaron-' + getColorByMinimumAgeJS($j(v).text()) + '"></i>' +
14976									'<span class="mi mi-stack-1x macaron-text animate">' + $j(v).text().replace('+', '') + '<sup>+</sup></span>' +
14977								'</span>';
14978		    $j(v).html(replaceHtml);
14979		}
14980	});
14981	
14982	$j('.amshopby-attr-selected').each(function(k, v) {
14983		if($j(v).text() == '0+' || $j(v).text() == '1+' || $j(v).text() == '2+' || $j(v).text() == '3+' ||
14984		   $j(v).text() == '4+' || $j(v).text() == '5+' || $j(v).text() == '6+' || $j(v).text() == '7+' ||
14985		   $j(v).text() == '8+' || $j(v).text() == '9+' || $j(v).text() == '10+' || $j(v).text() == '11+' ||
14986		   $j(v).text() == '12+' || $j(v).text() == '13+' || $j(v).text() == '14+' || $j(v).text() == '15+') {
14987			var replaceHtml = '<span class="macaron mi-stack mi-inverse macaron-bordered">' +
14988									'<i class="mi mi-stack-2x meccano-macaron macaron-' + getColorByMinimumAgeJS($j(v).text()) + '"></i>' +
14989									'<span class="mi mi-stack-1x macaron-text">' + $j(v).text().replace('+', '') + '<sup>+</sup></span>' +
14990								'</span>';
14991		    $j(v).html(replaceHtml);
14992		}
14993	});
14994	
14995	$j('.block-layered-nav .currently .btn-remove-inline').each(function(k, v) {
14996		$j(v).children().remove();
14997	});
14998	
14999	/*if(firstCall) {
15000		var ddAge = $j('#narrow-by-list .macaron').parent().parent().parent().parent().clone();
15001		var dtAge = $j('#narrow-by-list .macaron').parent().parent().parent().parent().prev().clone();
15002		$j('#narrow-by-list .macaron').parent().parent().parent().parent().prev().remove();
15003		$j('#narrow-by-list .macaron').parent().parent().parent().parent().remove();
15004		$j('#narrow-by-list').append('<dt class="odd">' + $j(dtAge).html() + '</dt><dd class="odd">' + $j(ddAge).html() + '</dd>');	
15005	}*/
15006	$j('#narrow-by-list .macaron').parent().parent().parent().parent().removeClass('filter-age');
15007	$j('#narrow-by-list .macaron').parent().parent().parent().parent().addClass('filter-age');
15008	$j('.amshopby-filters-left .block-subtitle.block-subtitle--filter').remove();
15009}
15010var who_contact = 1;
15011
15012
15013$j(document).ready(function() {
15014		
15015	if($j('#contactForm').length > 0) {
15016		bindContactFormPage();
15017	}
15018	
15019});
15020
15021function __refreshCAPTCHA(elt) {
15022	$j(elt).children().addClass('fa-spin');
15023	var srcImg = $j(elt).parent().parent().parent().find('img').attr('src');
15024	if(srcImg.indexOf('?') != -1) {
15025		var sep = '&';
15026	}
15027	else {
15028		var sep = '?';
15029	}
15030	$j(elt).parent().parent().parent().find('img').attr('src', srcImg + sep + Math.random());
15031	window.setTimeout(function() {
15032		$j(elt).children().removeClass('fa-spin');
15033	}, 1000);
15034}
15035
15036function changeForm() {
15037	if (who_contact == 1) {
15038		$j('.order_id').hide();
15039		$j('#order_id').val('');
15040	}
15041	else if (who_contact == 2) {
15042		$j('.order_id').show();
15043	}
15044	else if (who_contact == 3) {
15045		$j('.order_id').hide();
15046		$j('#order_id').val('');
15047	}
15048}
15049
15050function bindContactFormPage() {
15051	$j('.who_contact').bind('change', function() {
15052		who_contact = $j(this).val();
15053		changeForm();
15054	});
15055}
15056
15057function changeWhoContact(num) {
15058	who_contact = num;
15059	changeForm();
15060}
15061$j(document).ready(function() {
15062	
15063	$j('#filter-notice-range').unbind('change');
15064	$j('#filter-notice-range').bind('change', function() {
15065		filterNoticeByRange($j(this).val());
15066	});
15067	
15068});
15069
15070function filterNoticeByRange(val) {
15071	$j('.row-notice .product-block').each(function(k, v) {
15072        window.setTimeout(function() {
15073            $j(v).show();
15074        }, 200);
15075        $j(v).addClass('js-hidden');
15076        window.setTimeout(function() {
15077            $j(v).hide();
15078            if ($j(v).attr('gamme') == val || val == 'null') {
15079                $j(v).show();
15080                $j(v).removeClass('js-hidden');
15081            }
15082        }, 500);
15083    });	
15084}
15085$j(document).ready(function() {
15086		
15087	$j('.btn-empty').unbind('click');
15088	$j('.btn-empty').bind('click', function(e) {
15089		e.preventDefault();
15090		$j('input.qty').each(function(k, v) {
15091			$j(v).val(0);
15092		});
15093		window.setTimeout(function() {
15094			$j('.btn-update').trigger('click');
15095		}, 100);
15096	});
15097
15098	if ($j('#shopping-cart-table').size() > 0) {
15099		$j('.btn-update').trigger('click');
15100	}
15101		
15102});
15103
15104function chQtyItemCart(opt, id) {
15105	var newVal = 1;
15106	var oldVal = parseInt($j('#' + id).val());
15107	var incrementQty = parseInt($j('#' + id).attr('data-qty-step'));
15108	switch(opt) {
15109		case 0:
15110			// Moins
15111			if($j('#' + id).val() > 0) {
15112				newVal = parseInt(oldVal - incrementQty);
15113			}
15114			else {
15115				newVal = 0;
15116			}
15117		break;
15118		case 1:
15119			// Plus
15120			newVal = parseInt(oldVal + incrementQty);
15121		break;
15122	}
15123	if(oldVal != newVal) {	
15124		$j('#' + id).val(parseInt(newVal));
15125		window.setTimeout(function() {
15126			$j('.btn-update').trigger('click');
15127		}, 50);
15128	}
15129}
15130
15131function openBoxAgreementsError(msg) {
15132    $j('#fabox-1').fabox('alert', {msg: '', title: msg, mode_closebox: 'center'});
15133}
15134
15135function removeItemFromCart( id ) {
15136	$j( '#qty-cart-item-' + id ).val( 0 );
15137	window.setTimeout( function() {
15138		$j( '.button2.btn-update' ).trigger( 'click' );
15139	}, 10 );
15140}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.