PageSourceSearch

https://www.meccanodirect.fr/media/js/d16cf50e7738ab16d111d2932fec7a18.js

js meccanodirect.fr collected 2026-10-07 17:12:33 UTC 664,571 bytes, 15,103 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/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
11802 * Build: http://modernizr.com/download/#-localstorage-touch-shiv-mq-cssclasses-teststyles-prefixes-load
11803 */
11804;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;!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;
vendor: 7,744 bytes, lines 11804-11826
11804var 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))};
11805
11806/*
11807selectivizr v1.0.2 - (c) Keith Clark, freely distributable under the terms 
11808of the MIT license.
11809
11810selectivizr.com
11811*/
11812/* 
11813  
11814Notes about this source
11815-----------------------
11816
11817 * The #DEBUG_START and #DEBUG_END comments are used to mark blocks of code
11818   that will be removed prior to building a final release version (using a
11819   pre-compression script)
11820  
11821  
11822References:
11823-----------
11824 
11825 * CSS Syntax          : http://www.w3.org/TR/2003/WD-css3-syntax-20030813/#style
11826 * Selectors           : http://www.w3.org/TR/css3-selectors/#selectors
vendor: 11,973 bytes, lines 11827-12088
11827 * IE Compatability    : http://msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx
11828 * W3C Selector Tests  : http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/
11829 
11830*/
11831
11832(function(win) {
11833
11834    // If browser isn't IE, then stop execution! This handles the script 
11835    // being loaded by non IE browsers because the developer didn't use 
11836    // conditional comments.
11837    if (/*@cc_on!@*/true) return;
11838
11839    // =========================== Init Objects ============================
11840
11841    var doc = document;
11842    var root = doc.documentElement;
11843    var xhr = getXHRObject();
11844    var ieVersion = /MSIE (\d+)/.exec(navigator.userAgent)[1];
11845    
11846    // If were not in standards mode, IE is too old / new or we can't create
11847    // an XMLHttpRequest object then we should get out now.
11848    if (doc.compatMode != 'CSS1Compat' || ieVersion<6 || ieVersion>8 || !xhr) {
11849        return;
11850    }
11851    
11852    
11853    // ========================= Common Objects ============================
11854
11855    // Compatiable selector engines in order of CSS3 support. Note: '*' is
11856    // a placholder for the object key name. (basically, crude compression)
11857    var selectorEngines = {
11858        "NW"                                : "*.Dom.select",
11859        "MooTools"                          : "$$",
11860        "DOMAssistant"                      : "*.$", 
11861        "Prototype"                         : "$$",
11862        "YAHOO"                             : "*.util.Selector.query",
11863        "Sizzle"                            : "*", 
11864        "jQuery"                            : "*",
11865        "dojo"                              : "*.query"
11866    };
11867
11868    var selectorMethod;
11869    var enabledWatchers                     = [];     // array of :enabled/:disabled elements to poll
11870    var ie6PatchID                          = 0;      // used to solve ie6's multiple class bug
11871    var patchIE6MultipleClasses             = true;   // if true adds class bloat to ie6
11872    var namespace                           = "slvzr";
11873    
11874    // Stylesheet parsing regexp's
11875    var RE_COMMENT                          = /(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)\s*/g;
11876    var RE_IMPORT                           = /@import\s*(?:(?:(?:url\(\s*(['"]?)(.*)\1)\s*\))|(?:(['"])(.*)\3))[^;]*;/g;
11877    var RE_ASSET_URL                        = /\burl\(\s*(["']?)(?!data:)([^"')]+)\1\s*\)/g;
11878    var RE_PSEUDO_STRUCTURAL                = /^:(empty|(first|last|only|nth(-last)?)-(child|of-type))$/;
11879    var RE_PSEUDO_ELEMENTS                  = /:(:first-(?:line|letter))/g;
11880    var RE_SELECTOR_GROUP                   = /(^|})\s*([^\{]*?[\[:][^{]+)/g;
11881    var RE_SELECTOR_PARSE                   = /([ +~>])|(:[a-z-]+(?:\(.*?\)+)?)|(\[.*?\])/g; 
11882    var RE_LIBRARY_INCOMPATIBLE_PSEUDOS     = /(:not\()?:(hover|enabled|disabled|focus|checked|target|active|visited|first-line|first-letter)\)?/g;
11883    var RE_PATCH_CLASS_NAME_REPLACE         = /[^\w-]/g;
11884    
11885    // HTML UI element regexp's
11886    var RE_INPUT_ELEMENTS                   = /^(INPUT|SELECT|TEXTAREA|BUTTON)$/;
11887    var RE_INPUT_CHECKABLE_TYPES            = /^(checkbox|radio)$/;
11888
11889    // Broken attribute selector implementations (IE7/8 native [^=""], [$=""] and [*=""])
11890    var BROKEN_ATTR_IMPLEMENTATIONS         = ieVersion>6 ? /[\$\^*]=(['"])\1/ : null;
11891
11892    // Whitespace normalization regexp's
11893    var RE_TIDY_TRAILING_WHITESPACE         = /([(\[+~])\s+/g;
11894    var RE_TIDY_LEADING_WHITESPACE          = /\s+([)\]+~])/g;
11895    var RE_TIDY_CONSECUTIVE_WHITESPACE      = /\s+/g;
11896    var RE_TIDY_TRIM_WHITESPACE             = /^\s*((?:[\S\s]*\S)?)\s*$/;
11897    
11898    // String constants
11899    var EMPTY_STRING                        = "";
11900    var SPACE_STRING                        = " ";
11901    var PLACEHOLDER_STRING                  = "$1";
11902
11903    // =========================== Patching ================================
11904
11905    // --[ patchStyleSheet() ]----------------------------------------------
11906    // Scans the passed cssText for selectors that require emulation and
11907    // creates one or more patches for each matched selector.
11908    function patchStyleSheet( cssText ) {
11909        return cssText.replace(RE_PSEUDO_ELEMENTS, PLACEHOLDER_STRING).
11910            replace(RE_SELECTOR_GROUP, function(m, prefix, selectorText) {  
11911                var selectorGroups = selectorText.split(",");
11912                for (var c = 0, cs = selectorGroups.length; c < cs; c++) {
11913                    var selector = normalizeSelectorWhitespace(selectorGroups[c]) + SPACE_STRING;
11914                    var patches = [];
11915                    selectorGroups[c] = selector.replace(RE_SELECTOR_PARSE, 
11916                        function(match, combinator, pseudo, attribute, index) {
11917                            if (combinator) {
11918                                if (patches.length>0) {
11919                                    applyPatches( selector.substring(0, index), patches );
11920                                    patches = [];
11921                                }
11922                                return combinator;
11923                            }       
11924                            else {
11925                                var patch = (pseudo) ? patchPseudoClass( pseudo ) : patchAttribute( attribute );
11926                                if (patch) {
11927                                    patches.push(patch);
11928                                    return "." + patch.className;
11929                                }
11930                                return match;
11931                            }
11932                        }
11933                    );
11934                }
11935                return prefix + selectorGroups.join(",");
11936            });
11937    };
11938
11939    // --[ patchAttribute() ]-----------------------------------------------
11940    // returns a patch for an attribute selector.
11941    function patchAttribute( attr ) {
11942        return (!BROKEN_ATTR_IMPLEMENTATIONS || BROKEN_ATTR_IMPLEMENTATIONS.test(attr)) ? 
11943            { className: createClassName(attr), applyClass: true } : null;
11944    };
11945
11946    // --[ patchPseudoClass() ]---------------------------------------------
11947    // returns a patch for a pseudo-class
11948    function patchPseudoClass( pseudo ) {
11949
11950        var applyClass = true;
11951        var className = createClassName(pseudo.slice(1));
11952        var isNegated = pseudo.substring(0, 5) == ":not(";
11953        var activateEventName;
11954        var deactivateEventName;
11955
11956        // if negated, remove :not() 
11957        if (isNegated) {
11958            pseudo = pseudo.slice(5, -1);
11959        }
11960        
11961        // bracket contents are irrelevant - remove them
11962        var bracketIndex = pseudo.indexOf("(")
11963        if (bracketIndex > -1) {
11964            pseudo = pseudo.substring(0, bracketIndex);
11965        }       
11966        
11967        // check we're still dealing with a pseudo-class
11968        if (pseudo.charAt(0) == ":") {
11969            switch (pseudo.slice(1)) {
11970
11971                case "root":
11972                    applyClass = function(e) {
11973                        return isNegated ? e != root : e == root;
11974                    }
11975                    break;
11976
11977                case "target":
11978                    // :target is only supported in IE8
11979                    if (ieVersion == 8) {
11980                        applyClass = function(e) {
11981                            var handler = function() { 
11982                                var hash = location.hash;
11983                                var hashID = hash.slice(1);
11984                                return isNegated ? (hash == EMPTY_STRING || e.id != hashID) : (hash != EMPTY_STRING && e.id == hashID);
11985                            };
11986                            addEvent( win, "hashchange", function() {
11987                                toggleElementClass(e, className, handler());
11988                            })
11989                            return handler();
11990                        }
11991                        break;
11992                    }
11993                    return false;
11994                
11995                case "checked":
11996                    applyClass = function(e) { 
11997                        if (RE_INPUT_CHECKABLE_TYPES.test(e.type)) {
11998                            addEvent( e, "propertychange", function() {
11999                                if (event.propertyName == "checked") {
12000                                    toggleElementClass( e, className, e.checked !== isNegated );
12001                                }                           
12002                            })
12003                        }
12004                        return e.checked !== isNegated;
12005                    }
12006                    break;
12007                    
12008                case "disabled":
12009                    isNegated = !isNegated;
12010
12011                case "enabled":
12012                    applyClass = function(e) { 
12013                        if (RE_INPUT_ELEMENTS.test(e.tagName)) {
12014                            addEvent( e, "propertychange", function() {
12015                                if (event.propertyName == "$disabled") {
12016                                    toggleElementClass( e, className, e.$disabled === isNegated );
12017                                } 
12018                            });
12019                            enabledWatchers.push(e);
12020                            e.$disabled = e.disabled;
12021                            return e.disabled === isNegated;
12022                        }
12023                        return pseudo == ":enabled" ? isNegated : !isNegated;
12024                    }
12025                    break;
12026                    
12027                case "focus":
12028                    activateEventName = "focus";
12029                    deactivateEventName = "blur";
12030                                
12031                case "hover":
12032                    if (!activateEventName) {
12033                        activateEventName = "mouseenter";
12034                        deactivateEventName = "mouseleave";
12035                    }
12036                    applyClass = function(e) {
12037                        addEvent( e, isNegated ? deactivateEventName : activateEventName, function() {
12038                            toggleElementClass( e, className, true );
12039                        })
12040                        addEvent( e, isNegated ? activateEventName : deactivateEventName, function() {
12041                            toggleElementClass( e, className, false );
12042                        })
12043                        return isNegated;
12044                    }
12045                    break;
12046                    
12047                // everything else
12048                default:
12049                    // If we don't support this pseudo-class don't create 
12050                    // a patch for it
12051                    if (!RE_PSEUDO_STRUCTURAL.test(pseudo)) {
12052                        return false;
12053                    }
12054                    break;
12055            }
12056        }
12057        return { className: className, applyClass: applyClass };
12058    };
12059
12060    // --[ applyPatches() ]-------------------------------------------------
12061    // uses the passed selector text to find DOM nodes and patch them   
12062    function applyPatches(selectorText, patches) {
12063        var elms;
12064        
12065        // Although some selector libraries can find :checked :enabled etc. 
12066        // we need to find all elements that could have that state because 
12067        // it can be changed by the user.
12068        var domSelectorText = selectorText.replace(RE_LIBRARY_INCOMPATIBLE_PSEUDOS, EMPTY_STRING);
12069        
12070        // If the dom selector equates to an empty string or ends with 
12071        // whitespace then we need to append a universal selector (*) to it.
12072        if (domSelectorText == EMPTY_STRING || domSelectorText.charAt(domSelectorText.length - 1) == SPACE_STRING) {
12073            domSelectorText += "*";
12074        }
12075        
12076        // Ensure we catch errors from the selector library
12077        try {
12078            elms = selectorMethod( domSelectorText );
12079        } catch (ex) {
12080            // #DEBUG_START
12081            log( "Selector '" + selectorText + "' threw exception '" + ex + "'" );
12082            // #DEBUG_END
12083        }
12084
12085
12086        if (elms) {
12087            for (var d = 0, dl = elms.length; d < dl; d++) {    
12088                var elm = elms[d];
12089                var cssClasses = elm.className;
12090                for (var f = 0, fl = patches.length; f < fl; f++) {
12091                    var patch = patches[f];
12092                    
12093                    if (!hasPatch(elm, patch)) {
12094                        if (patch.applyClass && (patch.applyClass === true || patch.applyClass(elm) === true)) {
12095                            cssClasses = toggleClass(cssClasses, patch.className, true );
12096                        }
12097                    }
12098                }
12099                elm.className = cssClasses;
12100            }
12101        }
12102    };
12103
12104    // --[ hasPatch() ]-----------------------------------------------------
12105    // checks for the exsistence of a patch on an element
12106    function hasPatch( elm, patch ) {
12107        return new RegExp("(^|\\s)" + patch.className + "(\\s|$)").test(elm.className);
12108    };
12109    
12110    
12111    // =========================== Utility =================================
12112    
12113    function createClassName( className ) {
12114        return namespace + "-" + ((ieVersion == 6 && patchIE6MultipleClasses) ?
12115            ie6PatchID++
12116        :
12117            className.replace(RE_PATCH_CLASS_NAME_REPLACE, function(a) { return a.charCodeAt(0) }));
12118    };
12119
12120    // --[ log() ]----------------------------------------------------------
12121    // #DEBUG_START
12122    function log( message ) {
12123        if (win.console) {
12124            win.console.log(message);
12125        }
12126    };
12127    // #DEBUG_END
12128
12129    // --[ trim() ]---------------------------------------------------------
12130    // removes leading, trailing whitespace from a string
12131    function trim( text ) {
12132        return text.replace(RE_TIDY_TRIM_WHITESPACE, PLACEHOLDER_STRING);
12133    };
12134
12135    // --[ normalizeWhitespace() ]------------------------------------------
12136    // removes leading, trailing and consecutive whitespace from a string
12137    function normalizeWhitespace( text ) {
12138        return trim(text).replace(RE_TIDY_CONSECUTIVE_WHITESPACE, SPACE_STRING);
12139    };
12140
12141    // --[ normalizeSelectorWhitespace() ]----------------------------------
12142    // tidies whitespace around selector brackets and combinators
12143    function normalizeSelectorWhitespace( selectorText ) {
12144        return normalizeWhitespace(selectorText.
12145            replace(RE_TIDY_TRAILING_WHITESPACE, PLACEHOLDER_STRING).
12146            replace(RE_TIDY_LEADING_WHITESPACE, PLACEHOLDER_STRING)
12147        );
12148    };
12149
12150    // --[ toggleElementClass() ]-------------------------------------------
12151    // toggles a single className on an element
12152    function toggleElementClass( elm, className, on ) {
12153        var oldClassName = elm.className;
12154        var newClassName = toggleClass(oldClassName, className, on);
12155        if (newClassName != oldClassName) {
12156            elm.className = newClassName;
12157            elm.parentNode.className += EMPTY_STRING;
12158        }
12159    };
12160
12161    // --[ toggleClass() ]--------------------------------------------------
12162    // adds / removes a className from a string of classNames. Used to 
12163    // manage multiple class changes without forcing a DOM redraw
12164    function toggleClass( classList, className, on ) {
12165        var re = RegExp("(^|\\s)" + className + "(\\s|$)");
12166        var classExists = re.test(classList);
12167        if (on) {
12168            return classExists ? classList : classList + SPACE_STRING + className;
12169        } else {
12170            return classExists ? trim(classList.replace(re, PLACEHOLDER_STRING)) : classList;
12171        }
12172    };
12173    
12174    // --[ addEvent() ]-----------------------------------------------------
12175    function addEvent(elm, eventName, eventHandler) {
12176        elm.attachEvent("on" + eventName, eventHandler);
12177    };
12178
12179    // --[ getXHRObject() ]-------------------------------------------------
12180    function getXHRObject()
12181    {
12182        if (win.XMLHttpRequest) {
12183            return new XMLHttpRequest;
12184        }
12185        try { 
12186            return new ActiveXObject('Microsoft.XMLHTTP');
12187        } catch(e) { 
12188            return null;
12189        }
12190    };
12191
12192    // --[ loadStyleSheet() ]-----------------------------------------------
12193    function loadStyleSheet( url ) {
12194        xhr.open("GET", url, false);
12195        xhr.send();
12196        return (xhr.status==200) ? xhr.responseText : EMPTY_STRING; 
12197    };
12198    
12199    // --[ resolveUrl() ]---------------------------------------------------
12200    // Converts a URL fragment to a fully qualified URL using the specified
12201    // context URL. Returns null if same-origin policy is broken
12202    function resolveUrl( url, contextUrl ) {
12203    
12204        function getProtocolAndHost( url ) {
12205            return url.substring(0, url.indexOf("/", 8));
12206        };
12207        
12208        // absolute path
12209        if (/^https?:\/\//i.test(url)) {
12210            return getProtocolAndHost(contextUrl) == getProtocolAndHost(url) ? url : null;
12211        }
12212        
12213        // root-relative path
12214        if (url.charAt(0)=="/") {
12215            return getProtocolAndHost(contextUrl) + url;
12216        }
12217
12218        // relative path
12219        var contextUrlPath = contextUrl.split(/[?#]/)[0]; // ignore query string in the contextUrl  
12220        if (url.charAt(0) != "?" && contextUrlPath.charAt(contextUrlPath.length - 1) != "/") {
12221            contextUrlPath = contextUrlPath.substring(0, contextUrlPath.lastIndexOf("/") + 1);
12222        }
12223        
12224        return contextUrlPath + url;
12225    };
12226    
12227    // --[ parseStyleSheet() ]----------------------------------------------
12228    // Downloads the stylesheet specified by the URL, removes it's comments
12229    // and recursivly replaces @import rules with their contents, ultimately
12230    // returning the full cssText.
12231    function parseStyleSheet( url ) {
12232        if (url) {
12233            return loadStyleSheet(url).replace(RE_COMMENT, EMPTY_STRING).
12234            replace(RE_IMPORT, function( match, quoteChar, importUrl, quoteChar2, importUrl2 ) { 
12235                return parseStyleSheet(resolveUrl(importUrl || importUrl2, url));
12236            }).
12237            replace(RE_ASSET_URL, function( match, quoteChar, assetUrl ) { 
12238                quoteChar = quoteChar || EMPTY_STRING;
12239                return " url(" + quoteChar + resolveUrl(assetUrl, url) + quoteChar + ") "; 
12240            });
12241        }
12242        return EMPTY_STRING;
12243    };
12244    
12245    // --[ init() ]---------------------------------------------------------
12246    function init() {
12247        // honour the <base> tag
12248        var url, stylesheet;
12249        var baseTags = doc.getElementsByTagName("BASE");
12250        var baseUrl = (baseTags.length > 0) ? baseTags[0].href : doc.location.href;
12251        
12252        /* Note: This code prevents IE from freezing / crashing when using 
12253        @font-face .eot files but it modifies the <head> tag and could
12254        trigger the IE stylesheet limit. It will also cause FOUC issues.
12255        If you choose to use it, make sure you comment out the for loop 
12256        directly below this comment.
12257
12258        var head = doc.getElementsByTagName("head")[0];
12259        for (var c=doc.styleSheets.length-1; c>=0; c--) {
12260            stylesheet = doc.styleSheets[c]
12261            head.appendChild(doc.createElement("style"))
12262            var patchedStylesheet = doc.styleSheets[doc.styleSheets.length-1];
12263            
12264            if (stylesheet.href != EMPTY_STRING) {
12265                url = resolveUrl(stylesheet.href, baseUrl)
12266                if (url) {
12267                    patchedStylesheet.cssText = patchStyleSheet( parseStyleSheet( url ) )
12268                    stylesheet.disabled = true
12269                    setTimeout( function () {
12270                        stylesheet.owningElement.parentNode.removeChild(stylesheet.owningElement)
12271                    })
12272                }
12273            }
12274        }
12275        */
12276        
12277        for (var c = 0; c < doc.styleSheets.length; c++) {
12278            stylesheet = doc.styleSheets[c]
12279            if (stylesheet.href != EMPTY_STRING) {
12280                url = resolveUrl(stylesheet.href, baseUrl);
12281                if (url) {
12282                    stylesheet.cssText = patchStyleSheet( parseStyleSheet( url ) );
12283                }
12284            }
12285        }
12286        
12287        // :enabled & :disabled polling script (since we can't hook 
12288        // onpropertychange event when an element is disabled) 
12289        if (enabledWatchers.length > 0) {
12290            setInterval( function() {
12291                for (var c = 0, cl = enabledWatchers.length; c < cl; c++) {
12292                    var e = enabledWatchers[c];
12293                    if (e.disabled !== e.$disabled) {
12294                        if (e.disabled) {
12295                            e.disabled = false;
12296                            e.$disabled = true;
12297                            e.disabled = true;
12298                        }
12299                        else {
12300                            e.$disabled = e.disabled;
12301                        }
12302                    }
12303                }
12304            },250)
12305        }
12306    };
12307    
12308    // Bind selectivizr to the ContentLoaded event. 
12309    ContentLoaded(win, function() {
12310        // Determine the "best fit" selector engine
12311        for (var engine in selectorEngines) {
12312            var members, member, context = win;
12313            if (win[engine]) {
12314                members = selectorEngines[engine].replace("*", engine).split(".");
12315                while ((member = members.shift()) && (context = context[member])) {}
12316                if (typeof context == "function") {
12317                    selectorMethod = context;
12318                    init();
12319                    return;
12320                }
12321            }
12322        }
12323    });
12324    
12325    
12326    /*!
12327     * ContentLoaded.js by Diego Perini, modified for IE<9 only (to save space)
12328     *
12329     * Author: Diego Perini (diego.perini at gmail.com)
12330     * Summary: cross-browser wrapper for DOMContentLoaded
12331     * Updated: 20101020
12332     * License: MIT
12333     * Version: 1.2
12334     *
12335     * URL:
12336     * http://javascript.nwbox.com/ContentLoaded/
12337     * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
12338     *
12339     */
12340
12341    // @w window reference
12342    // @f function reference
12343    function ContentLoaded(win, fn) {
12344
12345        var done = false, top = true,
12346        init = function(e) {
12347            if (e.type == "readystatechange" && doc.readyState != "complete") return;
12348            (e.type == "load" ? win : doc).detachEvent("on" + e.type, init, false);
12349            if (!done && (done = true)) fn.call(win, e.type || e);
12350        },
12351        poll = function() {
12352            try { root.doScroll("left"); } catch(e) { setTimeout(poll, 50); return; }
12353            init('poll');
12354        };
12355
12356        if (doc.readyState == "complete") fn.call(win, EMPTY_STRING);
12357        else {
12358            if (doc.createEventObject && root.doScroll) {
12359                try { top = !win.frameElement; } catch(e) { }
12360                if (top) poll();
12361            }
12362            addEvent(doc,"readystatechange", init);
12363            addEvent(win,"load", init);
12364        }
12365    };
12366})(this);
12367
12368/*! 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 */
12369
12370window.matchMedia || (window.matchMedia = function() {
12371    "use strict";
12372
12373    // For browsers that support matchMedium api such as IE 9 and webkit
12374    var styleMedia = (window.styleMedia || window.media);
12375
12376    // For those that don't support matchMedium
12377    if (!styleMedia) {
12378        var style       = document.createElement('style'),
12379            script      = document.getElementsByTagName('script')[0],
12380            info        = null;
12381
12382        style.type  = 'text/css';
12383        style.id    = 'matchmediajs-test';
12384
12385        script.parentNode.insertBefore(style, script);
12386
12387        // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
12388        info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;
12389
12390        styleMedia = {
12391            matchMedium: function(media) {
12392                var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';
12393
12394                // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
12395                if (style.styleSheet) {
12396                    style.styleSheet.cssText = text;
12397                } else {
12398                    style.textContent = text;
12399                }
12400
12401                // Test if media query is true or false
12402                return info.width === '1px';
12403            }
12404        };
12405    }
12406
12407    return function(media) {
12408        return {
12409            matches: styleMedia.matchMedium(media || 'all'),
12410            media: media || 'all'
12411        };
12412    };
12413}());
12414
12415/*! matchMedia() polyfill addListener/removeListener extension. Author & copyright (c) 2012: Scott Jehl. Dual MIT/BSD license */
12416(function(){
12417    // Bail out for browsers that have addListener support
12418    if (window.matchMedia && window.matchMedia('all').addListener) {
12419        return false;
12420    }
12421
12422    var localMatchMedia = window.matchMedia,
12423        hasMediaQueries = localMatchMedia('only all').matches,
12424        isListening     = false,
12425        timeoutID       = 0,    // setTimeout for debouncing 'handleChange'
12426        queries         = [],   // Contains each 'mql' and associated 'listeners' if 'addListener' is used
12427        handleChange    = function(evt) {
12428            // Debounce
12429            clearTimeout(timeoutID);
12430
12431            timeoutID = setTimeout(function() {
12432                for (var i = 0, il = queries.length; i < il; i++) {
12433                    var mql         = queries[i].mql,
12434                        listeners   = queries[i].listeners || [],
12435                        matches     = localMatchMedia(mql.media).matches;
12436
12437                    // Update mql.matches value and call listeners
12438                    // Fire listeners only if transitioning to or from matched state
12439                    if (matches !== mql.matches) {
12440                        mql.matches = matches;
12441
12442                        for (var j = 0, jl = listeners.length; j < jl; j++) {
12443                            listeners[j].call(window, mql);
12444                        }
12445                    }
12446                }
12447            }, 30);
12448        };
12449
12450    window.matchMedia = function(media) {
12451        var mql         = localMatchMedia(media),
12452            listeners   = [],
12453            index       = 0;
12454
12455        mql.addListener = function(listener) {
12456            // Changes would not occur to css media type so return now (Affects IE <= 8)
12457            if (!hasMediaQueries) {
12458                return;
12459            }
12460
12461            // Set up 'resize' listener for browsers that support CSS3 media queries (Not for IE <= 8)
12462            // There should only ever be 1 resize listener running for performance
12463            if (!isListening) {
12464                isListening = true;
12465                window.addEventListener('resize', handleChange, true);
12466            }
12467
12468            // Push object only if it has not been pushed already
12469            if (index === 0) {
12470                index = queries.push({
12471                    mql         : mql,
12472                    listeners   : listeners
12473                });
12474            }
12475
12476            listeners.push(listener);
12477        };
12478
12479        mql.removeListener = function(listener) {
12480            for (var i = 0, il = listeners.length; i < il; i++){
12481                if (listeners[i] === listener){
12482                    listeners.splice(i, 1);
12483                }
12484            }
12485        };
12486
12487        return mql;
12488    };
12489}());
12490
12491/*!
12492 * enquire.js v2.1.0 - Awesome Media Queries in JavaScript
12493 * Copyright (c) 2013 Nick Williams - http://wicky.nillia.ms/enquire.js
12494 * License: MIT (http://www.opensource.org/licenses/mit-license.php)
12495 */
12496
12497;(function (name, context, factory) {
12498    var matchMedia = context.matchMedia;
12499
12500    if (typeof module !== 'undefined' && module.exports) {
12501        module.exports = factory(matchMedia);
12502    }
12503    else if (typeof define === 'function' && define.amd) {
12504        define(function() {
12505            return (context[name] = factory(matchMedia));
12506        });
12507    }
12508    else {
12509        context[name] = factory(matchMedia);
12510    }
12511}('enquire', this, function (matchMedia) {
12512
12513    'use strict';
12514
12515    /*jshint unused:false */
12516    /**
12517     * Helper function for iterating over a collection
12518     *
12519     * @param collection
12520     * @param fn
12521     */
12522    function each(collection, fn) {
12523        var i      = 0,
12524            length = collection.length,
12525            cont;
12526
12527        for(i; i < length; i++) {
12528            cont = fn(collection[i], i);
12529            if(cont === false) {
12530                break; //allow early exit
12531            }
12532        }
12533    }
12534
12535    /**
12536     * Helper function for determining whether target object is an array
12537     *
12538     * @param target the object under test
12539     * @return {Boolean} true if array, false otherwise
12540     */
12541    function isArray(target) {
12542        return Object.prototype.toString.apply(target) === '[object Array]';
12543    }
12544
12545    /**
12546     * Helper function for determining whether target object is a function
12547     *
12548     * @param target the object under test
12549     * @return {Boolean} true if function, false otherwise
12550     */
12551    function isFunction(target) {
12552        return typeof target === 'function';
12553    }
12554
12555    /**
12556     * Delegate to handle a media query being matched and unmatched.
12557     *
12558     * @param {object} options
12559     * @param {function} options.match callback for when the media query is matched
12560     * @param {function} [options.unmatch] callback for when the media query is unmatched
12561     * @param {function} [options.setup] one-time callback triggered the first time a query is matched
12562     * @param {boolean} [options.deferSetup=false] should the setup callback be run immediately, rather than first time query is matched?
12563     * @constructor
12564     */
12565    function QueryHandler(options) {
12566        this.options = options;
12567        !options.deferSetup && this.setup();
12568    }
12569    QueryHandler.prototype = {
12570
12571        /**
12572         * coordinates setup of the handler
12573         *
12574         * @function
12575         */
12576        setup : function() {
12577            if(this.options.setup) {
12578                this.options.setup();
12579            }
12580            this.initialised = true;
12581        },
12582
12583        /**
12584         * coordinates setup and triggering of the handler
12585         *
12586         * @function
12587         */
12588        on : function() {
12589            !this.initialised && this.setup();
12590            this.options.match && this.options.match();
12591        },
12592
12593        /**
12594         * coordinates the unmatch event for the handler
12595         *
12596         * @function
12597         */
12598        off : function() {
12599            this.options.unmatch && this.options.unmatch();
12600        },
12601
12602        /**
12603         * called when a handler is to be destroyed.
12604         * delegates to the destroy or unmatch callbacks, depending on availability.
12605         *
12606         * @function
12607         */
12608        destroy : function() {
12609            this.options.destroy ? this.options.destroy() : this.off();
12610        },
12611
12612        /**
12613         * determines equality by reference.
12614         * if object is supplied compare options, if function, compare match callback
12615         *
12616         * @function
12617         * @param {object || function} [target] the target for comparison
12618         */
12619        equals : function(target) {
12620            return this.options === target || this.options.match === target;
12621        }
12622
12623    };
12624    /**
12625     * Represents a single media query, manages it's state and registered handlers for this query
12626     *
12627     * @constructor
12628     * @param {string} query the media query string
12629     * @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
12630     */
12631    function MediaQuery(query, isUnconditional) {
12632        this.query = query;
12633        this.isUnconditional = isUnconditional;
12634        this.handlers = [];
12635        this.mql = matchMedia(query);
12636
12637        var self = this;
12638        this.listener = function(mql) {
12639            self.mql = mql;
12640            self.assess();
12641        };
12642        this.mql.addListener(this.listener);
12643    }
12644    MediaQuery.prototype = {
12645
12646        /**
12647         * add a handler for this query, triggering if already active
12648         *
12649         * @param {object} handler
12650         * @param {function} handler.match callback for when query is activated
12651         * @param {function} [handler.unmatch] callback for when query is deactivated
12652         * @param {function} [handler.setup] callback for immediate execution when a query handler is registered
12653         * @param {boolean} [handler.deferSetup=false] should the setup callback be deferred until the first time the handler is matched?
12654         */
12655        addHandler : function(handler) {
12656            var qh = new QueryHandler(handler);
12657            this.handlers.push(qh);
12658
12659            this.matches() && qh.on();
12660        },
12661
12662        /**
12663         * removes the given handler from the collection, and calls it's destroy methods
12664         * 
12665         * @param {object || function} handler the handler to remove
12666         */
12667        removeHandler : function(handler) {
12668            var handlers = this.handlers;
12669            each(handlers, function(h, i) {
12670                if(h.equals(handler)) {
12671                    h.destroy();
12672                    return !handlers.splice(i,1); //remove from array and exit each early
12673                }
12674            });
12675        },
12676
12677        /**
12678         * Determine whether the media query should be considered a match
12679         * 
12680         * @return {Boolean} true if media query can be considered a match, false otherwise
12681         */
12682        matches : function() {
12683            return this.mql.matches || this.isUnconditional;
12684        },
12685
12686        /**
12687         * Clears all handlers and unbinds events
12688         */
12689        clear : function() {
12690            each(this.handlers, function(handler) {
12691                handler.destroy();
12692            });
12693            this.mql.removeListener(this.listener);
12694            this.handlers.length = 0; //clear array
12695        },
12696
12697        /*
12698         * Assesses the query, turning on all handlers if it matches, turning them off if it doesn't match
12699         */
12700        assess : function() {
12701            var action = this.matches() ? 'on' : 'off';
12702
12703            each(this.handlers, function(handler) {
12704                handler[action]();
12705            });
12706        }
12707    };
12708    /**
12709     * Allows for registration of query handlers.
12710     * Manages the query handler's state and is responsible for wiring up browser events
12711     *
12712     * @constructor
12713     */
12714    function MediaQueryDispatch () {
12715        if(!matchMedia) {
12716            throw new Error('matchMedia not present, legacy browsers require a polyfill');
12717        }
12718
12719        this.queries = {};
12720        this.browserIsIncapable = !matchMedia('only all').matches;
12721    }
12722
12723    MediaQueryDispatch.prototype = {
12724
12725        /**
12726         * Registers a handler for the given media query
12727         *
12728         * @param {string} q the media query
12729         * @param {object || Array || Function} options either a single query handler object, a function, or an array of query handlers
12730         * @param {function} options.match fired when query matched
12731         * @param {function} [options.unmatch] fired when a query is no longer matched
12732         * @param {function} [options.setup] fired when handler first triggered
12733         * @param {boolean} [options.deferSetup=false] whether setup should be run immediately or deferred until query is first matched
12734         * @param {boolean} [shouldDegrade=false] whether this particular media query should always run on incapable browsers
12735         */
12736        register : function(q, options, shouldDegrade) {
12737            var queries         = this.queries,
12738                isUnconditional = shouldDegrade && this.browserIsIncapable;
12739
12740            if(!queries[q]) {
12741                queries[q] = new MediaQuery(q, isUnconditional);
12742            }
12743
12744            //normalise to object in an array
12745            if(isFunction(options)) {
12746                options = { match : options };
12747            }
12748            if(!isArray(options)) {
12749                options = [options];
12750            }
12751            each(options, function(handler) {
12752                queries[q].addHandler(handler);
12753            });
12754
12755            return this;
12756        },
12757
12758        /**
12759         * unregisters a query and all it's handlers, or a specific handler for a query
12760         *
12761         * @param {string} q the media query to target
12762         * @param {object || function} [handler] specific handler to unregister
12763         */
12764        unregister : function(q, handler) {
12765            var query = this.queries[q];
12766
12767            if(query) {
12768                if(handler) {
12769                    query.removeHandler(handler);
12770                }
12771                else {
12772                    query.clear();
12773                    delete this.queries[q];
12774                }
12775            }
12776
12777            return this;
12778        }
12779    };
12780
12781    return new MediaQueryDispatch();
12782
12783}));
12784
12785/**
12786 * Magento
12787 *
12788 * NOTICE OF LICENSE
12789 *
12790 * This source file is subject to the Academic Free License (AFL 3.0)
12791 * that is bundled with this package in the file LICENSE_AFL.txt.
12792 * It is also available through the world-wide-web at this URL:
12793 * http://opensource.org/licenses/afl-3.0.php
12794 * If you did not receive a copy of the license and are unable to
12795 * obtain it through the world-wide-web, please send an email
12796 * to [email protected] so we can send you a copy immediately.
12797 *
12798 * DISCLAIMER
12799 *
12800 * Do not edit or add to this file if you wish to upgrade Magento to newer
12801 * versions in the future. If you wish to customize Magento for your
12802 * needs please refer to http://www.magentocommerce.com for more information.
12803 *
12804 * @category    design
12805 * @package     default_default
12806 * @copyright   Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
12807 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
12808 */
12809
12810// =============================================
12811// Primary Break Points
12812// =============================================
12813
12814// These should be used with the bp (max-width, xx) mixin
12815// where a min-width is used, remember to +1 to break correctly
12816// If these are changed, they must also be updated in _var.scss
12817
12818var bp = {
12819    xsmall: 479,
12820    small: 599,
12821    medium: 770,
12822    large: 979,
12823    xlarge: 1199
12824}
12825
12826// ==============================================
12827// Search
12828// ==============================================
12829
12830Varien.searchForm.prototype.initialize = function (form, field, emptyText) {
12831    this.form = $(form);
12832    this.field = $(field);
12833    this.emptyText = emptyText;
12834
12835    this.validator = new Validation(this.form);
12836
12837    Event.observe(this.form, 'submit', this.submit.bind(this));
12838    Event.observe(this.field, 'focus', this.focus.bind(this));
12839    Event.observe(this.field, 'blur', this.blur.bind(this));
12840    this.blur();
12841}
12842
12843Varien.searchForm.prototype.submit = function (event) {
12844    if (!this.validator || !this.validator.validate()) {
12845        Event.stop(event);
12846        return false;
12847    }
12848    return true;
12849}
12850
12851// ==============================================
12852// jQuery Init
12853// ==============================================
12854
12855// Avoid PrototypeJS conflicts, assign jQuery to $j instead of $
12856var $j = jQuery.noConflict();
12857
12858// Use $j(document).ready() because Magento executes Prototype inline
12859$j(document).ready(function () {
12860
12861    // ==============================================
12862    // Shared Vars
12863    // ==============================================
12864
12865    // Document
12866    var w = $j(window);
12867    var d = $j(document);
12868    var body = $j('body');
12869
12870    // =============================================
12871    // Skip Links
12872    // =============================================
12873
12874    var skipContents = $j('.skip-content');
12875    var skipLinks = $j('.skip-link');
12876
12877    skipLinks.on('click', function (e) {
12878        e.preventDefault();
12879
12880        var self = $j(this);
12881        var target = self.attr('href');
12882
12883        // Get target element
12884        var elem = $j(target);
12885
12886        // Check if stub is open
12887        var isSkipContentOpen = elem.hasClass('skip-active') ? 1 : 0;
12888
12889        // Hide all stubs
12890        skipLinks.removeClass('skip-active');
12891        skipContents.removeClass('skip-active');
12892
12893        // Toggle stubs
12894        if (isSkipContentOpen) {
12895            self.removeClass('skip-active');
12896        } else {
12897            self.addClass('skip-active');
12898            elem.addClass('skip-active');
12899        }
12900    });
12901
12902    $j('#header-cart').on('click', '.skip-link-close', function(e) {
12903        var parent = $j(this).parents('.skip-content');
12904        var link = parent.siblings('.skip-link');
12905
12906        parent.removeClass('skip-active');
12907        link.removeClass('skip-active');
12908
12909        e.preventDefault();
12910    });
12911
12912
12913    // ==============================================
12914    // Header Menus
12915    // ==============================================
12916
12917    var nav = $j('#nav');
12918
12919    // ----------------------------------------------
12920    // Top Menus
12921
12922    var MenuManagerState = {
12923        TOUCH_SCROLL_THRESHOLD: 20,
12924
12925        touchStartPosition: null,
12926
12927        shouldCancelTouch: function() {
12928            if(!this.touchStartPosition) {
12929                return false;
12930            }
12931
12932            var scroll = $j(window).scrollTop() - this.touchStartPosition;
12933            return Math.abs(scroll) > this.TOUCH_SCROLL_THRESHOLD;
12934        }
12935    };
12936
12937    var pointerEvent = 'touchend';
12938    // If device has implemented touch/click agnostic event, use it instead of "click"
12939    if (window.navigator.pointerEnabled) {
12940        pointerEvent = 'pointerdown';
12941    } else if (window.navigator.msPointerEnabled) {
12942        pointerEvent = 'MSPointerDown';
12943    }
12944    nav.find('a.has-children.level0').on(pointerEvent,function (event) {
12945        //scroll occurred, cancel event
12946        if(MenuManagerState.shouldCancelTouch()) {
12947            return;
12948        }
12949
12950        // If mouse is being used on large viewport, use native hover state
12951        if (window.navigator.msPointerEnabled
12952            && event.originalEvent.pointerType == 'mouse'
12953            && Modernizr.mq("screen and (min-width:" + (bp.medium + 1) + "px)")
12954        ) {
12955            $j(this).data('has-touch', false);
12956            return;
12957        }
12958        $j(this).data('has-touch', true);
12959        var elem = $j(this).parent();
12960
12961        var alreadyExpanded = elem.hasClass('menu-active');
12962
12963        nav.find('li.level0').removeClass('menu-active');
12964
12965        // Collapse all active sub-menus
12966        nav.find('.sub-menu-active').removeClass('sub-menu-active');
12967
12968        if (!alreadyExpanded) {
12969            elem.addClass('menu-active');
12970        }
12971
12972        event.preventDefault();
12973    }).on('click', function (event) {
12974        var elem = $j(this);
12975        if (elem.data('has-touch')) {
12976            elem.data('has-touch', false);
12977            event.preventDefault();
12978            return;
12979        }
12980
12981        if(Modernizr.mq("screen and (max-width:" + bp.medium + "px)")) {
12982            var elem = $j(this).parent();
12983
12984            var alreadyExpanded = elem.hasClass('menu-active');
12985
12986            nav.find('li.level0').removeClass('menu-active');
12987
12988            // Collapse all active sub-menus
12989            nav.find('.sub-menu-active').removeClass('sub-menu-active');
12990
12991            if (!alreadyExpanded) {
12992                elem.addClass('menu-active');
12993            }
12994
12995            event.preventDefault();
12996        }
12997    }).on('touchstart', function(event) {
12998        $j(this).data('has-touch');
12999        MenuManagerState.touchStartPosition = $j(window).scrollTop();
13000    });
13001
13002    // ----------------------------------------------
13003    // Sub Menus
13004
13005    nav.find('li.level1 a.has-children').on('click', function (e) {
13006        e.preventDefault();
13007        e.stopPropagation();
13008
13009        var elem = $j(this).parent();
13010
13011        // Check if sub-menu is open
13012        var isSubMenuActive = elem.hasClass('sub-menu-active') ? 1 : 0;
13013
13014        // On smaller screens, allow multiple sibling sub-menus to show at once,
13015        // but this is a large touch device, avoid multiple sub-menus showing at once.
13016        if (Modernizr.mq("screen and (min-width:" + (bp.medium + 1) + "px)")) {
13017            elem
13018                .siblings('.sub-menu-active')
13019                .removeClass('sub-menu-active')
13020                .find('.sub-menu-active')
13021                .removeClass('sub-menu-active');
13022        }
13023        if (isSubMenuActive) {
13024            elem.removeClass('sub-menu-active');
13025        } else {
13026            elem.addClass('sub-menu-active');
13027        }
13028    });
13029
13030    // Prevent sub menus from spilling out of the window.
13031    function preventMenuSpill() {
13032        var windowWidth = $j(window).width();
13033        $j('ul.level0').each(function(){
13034            var ul = $j(this);
13035            //Show it long enough to get info, then hide it.
13036            ul.addClass('position-test');
13037            ul.removeClass('spill');
13038            var width = ul.outerWidth();
13039            var offset = ul.offset().left;
13040            ul.removeClass('position-test');
13041            //Add the spill class if it will spill off the page.
13042            if ((offset + width) > windowWidth) {
13043                ul.addClass('spill');
13044            }
13045        });
13046    }
13047    preventMenuSpill();
13048    $j(window).on('delayed-resize', preventMenuSpill);
13049
13050
13051    // ==============================================
13052    // Language Switcher
13053    // ==============================================
13054
13055    // In order to display the language switcher next to the logo, we are moving the content at different viewports,
13056    // rather than having duplicate markup or changing the design
13057    enquire.register('(max-width: ' + bp.medium + 'px)', {
13058        match: function () {
13059            $j('.page-header-container .store-language-container').prepend($j('.form-language'));
13060        },
13061        unmatch: function () {
13062            $j('.header-language-container .store-language-container').prepend($j('.form-language'));
13063        }
13064    });
13065
13066    // ==============================================
13067    // Enquire JS
13068    // ==============================================
13069
13070    enquire.register('screen and (min-width: ' + (bp.medium + 1) + 'px)', {
13071        match: function () {
13072            $j('.menu-active').removeClass('menu-active');
13073            $j('.sub-menu-active').removeClass('sub-menu-active');
13074            $j('.skip-active').removeClass('skip-active');
13075        },
13076        unmatch: function () {
13077            $j('.menu-active').removeClass('menu-active');
13078            $j('.sub-menu-active').removeClass('sub-menu-active');
13079            $j('.skip-active').removeClass('skip-active');
13080        }
13081    });
13082
13083    // ==============================================
13084    // UI Pattern - Media Switcher
13085    // ==============================================
13086
13087    // Used to swap primary product photo from thumbnails.
13088
13089    var mediaListLinks = $j('.media-list').find('a');
13090    var mediaPrimaryImage = $j('.primary-image').find('img');
13091
13092    if (mediaListLinks.length) {
13093        mediaListLinks.on('click', function (e) {
13094            e.preventDefault();
13095
13096            var self = $j(this);
13097
13098            mediaPrimaryImage.attr('src', self.attr('href'));
13099        });
13100    }
13101
13102    // ==============================================
13103    // UI Pattern - ToggleSingle
13104    // ==============================================
13105
13106    // Use this plugin to toggle the visibility of content based on a toggle link/element.
13107    // This pattern differs from the accordion functionality in the Toggle pattern in that each toggle group acts
13108    // independently of the others. It is named so as not to be confused with the Toggle pattern below
13109    //
13110    // This plugin requires a specific markup structure. The plugin expects a set of elements that it
13111    // will use as the toggle link. It then hides all immediately following siblings and toggles the sibling's
13112    // visibility when the toggle link is clicked.
13113    //
13114    // Example markup:
13115    // <div class="block">
13116    //     <div class="block-title">Trigger</div>
13117    //     <div class="block-content">Content that should show when </div>
13118    // </div>
13119    //
13120    // JS: jQuery('.block-title').toggleSingle();
13121    //
13122    // Options:
13123    //     destruct: defaults to false, but if true, the plugin will remove itself, display content, and remove event handlers
13124
13125
13126    jQuery.fn.toggleSingle = function (options) {
13127
13128        // passing destruct: true allows
13129        var settings = $j.extend({
13130            destruct: false
13131        }, options);
13132
13133        return this.each(function () {
13134            if (!settings.destruct) {
13135                $j(this).on('click', function () {
13136                    $j(this)
13137                        .toggleClass('active')
13138                        .next()
13139                        .toggleClass('no-display');
13140                });
13141                // Hide the content
13142                $j(this).next().addClass('no-display');
13143            } else {
13144                // Remove event handler so that the toggle link can no longer be used
13145                $j(this).off('click');
13146                // Remove all classes that were added by this plugin
13147                $j(this)
13148                    .removeClass('active')
13149                    .next()
13150                    .removeClass('no-display');
13151            }
13152
13153        });
13154    }
13155
13156    // ==============================================
13157    // UI Pattern - Toggle Content (tabs and accordions in one setup)
13158    // ==============================================
13159    
13160    $j('.toggle-content').each(function () {
13161        var wrapper = jQuery(this);
13162
13163        var hasTabs = wrapper.hasClass('tabs');
13164        var hasAccordion = wrapper.hasClass('accordion');
13165        var startOpen = wrapper.hasClass('open');
13166
13167        var dl = wrapper.children('dl:first');
13168        var dts = dl.children('dt');
13169        var panes = dl.children('dd');
13170        var groups = new Array(dts, panes);
13171
13172        //Create a ul for tabs if necessary.
13173        if (hasTabs) {
13174            var ul = jQuery('<ul class="toggle-tabs"></ul>');
13175            dts.each(function () {
13176                var dt = jQuery(this);
13177                var li = jQuery('<li></li>');
13178                li.html(dt.html());
13179                ul.append(li);
13180            });
13181            ul.insertBefore(dl);
13182            var lis = ul.children();
13183            groups.push(lis);
13184        }
13185
13186        //Add "last" classes.
13187        var i;
13188        for (i = 0; i < groups.length; i++) {
13189            groups[i].filter(':last').addClass('last');
13190        }
13191
13192        function toggleClasses(clickedItem, group) {
13193            var index = group.index(clickedItem);
13194            var i;
13195            for (i = 0; i < groups.length; i++) {
13196                groups[i].removeClass('current');
13197                groups[i].eq(index).addClass('current');
13198            }
13199        }
13200
13201        //Toggle on tab (dt) click.
13202        dts.on('click', function (e) {
13203            //They clicked the current dt to close it. Restore the wrapper to unclicked state.
13204            if (jQuery(this).hasClass('current') && wrapper.hasClass('accordion-open')) {
13205                wrapper.removeClass('accordion-open');
13206            } else {
13207                //They're clicking something new. Reflect the explicit user interaction.
13208                wrapper.addClass('accordion-open');
13209            }
13210            toggleClasses(jQuery(this), dts);
13211        });
13212
13213        //Toggle on tab (li) click.
13214        if (hasTabs) {
13215            lis.on('click', function (e) {
13216                toggleClasses(jQuery(this), lis);
13217            });
13218            //Open the first tab.
13219            lis.eq(0).trigger('click');
13220        }
13221
13222        //Open the first accordion if desired.
13223        if (startOpen) {
13224            dts.eq(0).trigger('click');
13225        }
13226
13227    });
13228
13229
13230    // ==============================================
13231    // Layered Navigation Block
13232    // ==============================================
13233
13234    // On product list pages, we want to show the layered nav/category menu immediately above the product list.
13235    // While it would make more sense to just move the .block-layered-nav block rather than .col-left-first
13236    // (since other blocks can be inserted into left_first), it creates simpler code to move the entire
13237    // .col-left-first block, so that is the approach we're taking
13238    /*if ($j('.col-left-first > .block').length && $j('.category-products').length) {
13239        enquire.register('screen and (max-width: ' + bp.medium + 'px)', {
13240            match: function () {
13241                $j('.col-left-first').insertBefore($j('.category-products'))
13242            },
13243            unmatch: function () {
13244                // Move layered nav back to left column
13245                $j('.col-left-first').insertBefore($j('.col-main'))
13246            }
13247        });
13248    }*/
13249
13250    // ==============================================
13251    // 3 column layout
13252    // ==============================================
13253
13254    // On viewports smaller than 1000px, move the right column into the left column
13255    if ($j('.main-container.col3-layout').length > 0) {
13256        enquire.register('screen and (max-width: 1000px)', {
13257            match: function () {
13258                var rightColumn = $j('.col-right');
13259                var colWrapper = $j('.col-wrapper');
13260
13261                rightColumn.appendTo(colWrapper);
13262            },
13263            unmatch: function () {
13264                var rightColumn = $j('.col-right');
13265                var main = $j('.main');
13266
13267                rightColumn.appendTo(main);
13268            }
13269        });
13270    }
13271
13272
13273    // ==============================================
13274    // Block collapsing (on smaller viewports)
13275    // ==============================================
13276
13277    enquire.register('(max-width: ' + bp.medium + 'px)', {
13278        setup: function () {
13279            this.toggleElements = $j(
13280                // This selects the menu on the My Account and CMS pages
13281                '.col-left-first .block:not(.block-layered-nav) .block-title, ' +
13282                    '.col-left-first .block-layered-nav .block-subtitle--filter, ' +
13283                    '.sidebar:not(.col-left-first) .block .block-title'
13284            );
13285        },
13286        match: function () {
13287            this.toggleElements.toggleSingle();
13288        },
13289        unmatch: function () {
13290            this.toggleElements.toggleSingle({destruct: true});
13291        }
13292    });
13293
13294
13295    // ==============================================
13296    // OPC - Progress Block
13297    // ==============================================
13298
13299    // if ($j('body.checkout-onepage-index').length) {
13300    //     enquire.register('(max-width: ' + bp.large + 'px)', {
13301    //         match: function () {
13302    //             $j('#checkout-step-review').prepend($j('#checkout-progress-wrapper'));
13303    //         },
13304    //         unmatch: function () {
13305    //             $j('.col-right').prepend($j('#checkout-progress-wrapper'));
13306    //         }
13307    //     });
13308    // }
13309
13310
13311    // ==============================================
13312    // Checkout Cart - events
13313    // ==============================================
13314
13315    if ($j('body.checkout-cart-index').length) {
13316        $j('input[name^="cart"]').focus(function () {
13317            $j(this).siblings('button').fadeIn();
13318        });
13319    }
13320
13321    // ==============================================
13322    // Product Listing - Align action buttons/links
13323    // ==============================================
13324
13325    // Since the number of columns per grid will vary based on the viewport size, the only way to align the action
13326    // buttons/links is via JS
13327
13328    if ($j('.products-grid').length) {
13329
13330        var alignProductGridActions = function () {
13331            var gridRows = []; // This will store an array per row
13332            var tempRow = [];
13333            productGridElements = $j('.products-grid > li');
13334            productGridElements.each(function (index) {
13335                // The JS ought to be agnostic of the specific CSS breakpoints, so we are dynamically checking to find
13336                // each row by grouping all cells (eg, li elements) up until we find an element that is cleared.
13337                // We are ignoring the first cell since it will always be cleared.
13338                if ($j(this).css('clear') != 'none' && index != 0) {
13339                    gridRows.push(tempRow); // Add the previous set of rows to the main array
13340                    tempRow = []; // Reset the array since we're on a new row
13341                }
13342                tempRow.push(this);
13343
13344                // The last row will not contain any cells that clear that row, so we check to see if this is the last cell
13345                // in the grid, and if so, we add its row to the array
13346                if (productGridElements.length == index + 1) {
13347                    gridRows.push(tempRow);
13348                }
13349            });
13350
13351            $j.each(gridRows, function () {
13352                var tallestHeight = 0;
13353                $j.each(this, function () {
13354                    // Since this function is called every time the page is resized, we need to remove the min-height
13355                    // so each cell can return to its natural size before being measured.
13356                    $j(this).find('.product-info').css('min-height', '');
13357                    // We are checking the height of .product-info (rather than the entire li), because the images
13358                    // will not be loaded when this JS is run.
13359                    elHeight = parseInt($j(this).find('.product-info').css('height'));
13360                    if (elHeight > tallestHeight) {
13361                        tallestHeight = elHeight;
13362                    }
13363                });
13364                // Set the height of all .product-info elements in a row to the tallest height
13365                $j.each(this, function () {
13366                    $j(this).find('.product-info').css('minHeight', tallestHeight);
13367                });
13368            });
13369        }
13370        alignProductGridActions();
13371
13372        // Since the height of each cell and the number of columns per page may change when the page is resized, we are
13373        // going to run the alignment function each time the page is resized.
13374        $j(window).on('delayed-resize', function (e, resizeEvent) {
13375            alignProductGridActions();
13376        });
13377    }
13378
13379    // ==============================================
13380    // Generic, efficient window resize handler
13381    // ==============================================
13382
13383    // Using setTimeout since Web-Kit and some other browsers call the resize function constantly upon window resizing.
13384    var resizeTimer;
13385    $j(window).resize(function (e) {
13386        clearTimeout(resizeTimer);
13387        resizeTimer = setTimeout(function () {
13388            $j(window).trigger('delayed-resize', e);
13389        }, 250);
13390    });
13391});
13392
13393// ==============================================
13394// PDP - image zoom - needs to be available outside document.ready scope
13395// ==============================================
13396
13397var ProductMediaManager = {
13398    IMAGE_ZOOM_THRESHOLD: 20,
13399    zoomEnabled: Modernizr.mq("screen and (min-width:768px)"),
13400    imageWrapper: null,
13401
13402    destroyZoom: function() {
13403        $j('.zoomContainer').remove();
13404        $j('.product-image-gallery .gallery-image').removeData('elevateZoom');
13405    },
13406
13407    createZoom: function(image) {
13408        ProductMediaManager.destroyZoom();
13409
13410        if(!ProductMediaManager.zoomEnabled) { //zoom not enabled
13411            return;
13412        }
13413
13414        if(image.length <= 0) { //no image found
13415            return;
13416        }
13417
13418        if(image[0].naturalWidth && image[0].naturalHeight) {
13419            var widthDiff = image[0].naturalWidth - image.width() - ProductMediaManager.IMAGE_ZOOM_THRESHOLD;
13420            var heightDiff = image[0].naturalHeight - image.height() - ProductMediaManager.IMAGE_ZOOM_THRESHOLD;
13421
13422            if(widthDiff < 0 && heightDiff < 0) {
13423                //image not big enough
13424
13425                image.parents('.product-image').removeClass('zoom-available');
13426
13427                return;
13428            } else {
13429                image.parents('.product-image').addClass('zoom-available');
13430            }
13431        }
13432
13433        image.elevateZoom();
13434    },
13435
13436    swapImage: function(targetImage) {
13437        targetImage = $j(targetImage);
13438        targetImage.addClass('gallery-image');
13439
13440        ProductMediaManager.destroyZoom();
13441
13442        var imageGallery = $j('.product-image-gallery');
13443
13444        if(targetImage[0].complete) { //image already loaded -- swap immediately
13445
13446            imageGallery.find('.gallery-image').removeClass('visible');
13447
13448            //move target image to correct place, in case it's necessary
13449            imageGallery.append(targetImage);
13450
13451            //reveal new image
13452            targetImage.addClass('visible');
13453
13454            //wire zoom on new image
13455            ProductMediaManager.createZoom(targetImage);
13456
13457        } else { //need to wait for image to load
13458
13459            //add spinner
13460            imageGallery.addClass('loading');
13461
13462            //move target image to correct place, in case it's necessary
13463            imageGallery.append(targetImage);
13464
13465            //wait until image is loaded
13466            imagesLoaded(targetImage, function() {
13467                //remove spinner
13468                imageGallery.removeClass('loading');
13469
13470                //hide old image
13471                imageGallery.find('.gallery-image').removeClass('visible');
13472
13473                //reveal new image
13474                targetImage.addClass('visible');
13475
13476                //wire zoom on new image
13477                ProductMediaManager.createZoom(targetImage);
13478            });
13479
13480        }
13481    },
13482
13483    wireThumbnails: function() {
13484        //trigger image change event on thumbnail click
13485        $j('.product-image-thumbs .thumb-link').click(function(e) {
13486            e.preventDefault();
13487            var jlink = $j(this);
13488            var target = $j('#image-' + jlink.data('image-index'));
13489
13490            ProductMediaManager.swapImage(target);
13491        });
13492    },
13493
13494    initZoom: function() {
13495        ProductMediaManager.createZoom($j(".no-touch .gallery-image.visible")); //set zoom on first image
13496    },
13497
13498    init: function() {
13499        ProductMediaManager.imageWrapper = $j('.product-img-box');
13500
13501        enquire.register("screen and (min-width:768px)", {
13502            match : function() {
13503                ProductMediaManager.zoomEnabled = true;
13504                ProductMediaManager.initZoom();
13505            },
13506            unmatch : function() {
13507                ProductMediaManager.destroyZoom();
13508                ProductMediaManager.zoomEnabled = false;
13509            }
13510        });
13511
13512        //resizing the window causes problems with zoom -- reinitialize
13513        $j(window).on('delayed-resize', function(e, resizeEvent) {
13514            ProductMediaManager.destroyZoom();
13515            ProductMediaManager.initZoom();
13516        });
13517
13518        ProductMediaManager.wireThumbnails();
13519
13520        $j(document).trigger('product-media-loaded', ProductMediaManager);
13521    }
13522};
13523
13524$j(document).ready(function() {
13525    ProductMediaManager.init();
13526});
13527
13528/*!
13529* jQuery Cycle2; build: v20131022
13530* http://jquery.malsup.com/cycle2/
13531* Copyright (c) 2013 M. Alsup; Dual licensed: MIT/GPL
13532*/
13533/*! core engine; version: 20131003 */
13534(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 13534
13534,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}
13534}},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 */
13535function(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 */
13536function(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 */
13537function(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
13537),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 */
13538function(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 */
13539function(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 */
13540function(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 */
13541function(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()}
13541),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 */
13542function(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 */
13543function(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>
13543o;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);
13544
13545/*! Plugin for Cycle2; Copyright (c) 2012 M. Alsup; ver: 20121120 */
13546(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);
13547
13548/**
13549 * Magento
13550 *
13551 * NOTICE OF LICENSE
13552 *
13553 * This source file is subject to the Academic Free License (AFL 3.0)
13554 * that is bundled with this package in the file LICENSE_AFL.txt.
13555 * It is also available through the world-wide-web at this URL:
13556 * http://opensource.org/licenses/afl-3.0.php
13557 * If you did not receive a copy of the license and are unable to
13558 * obtain it through the world-wide-web, please send an email
13559 * to [email protected] so we can send you a copy immediately.
13560 *
13561 * DISCLAIMER
13562 *
13563 * Do not edit or add to this file if you wish to upgrade Magento to newer
13564 * versions in the future. If you wish to customize Magento for your
13565 * needs please refer to http://www.magentocommerce.com for more information.
13566 *
13567 * @category    design
13568 * @package     default_default
13569 * @copyright   Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
13570 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
13571 */
13572
13573$j(document).ready(function () {
13574
13575    // ==============================================
13576    // UI Pattern - Slideshow
13577    // ==============================================
13578
13579    $j('.slideshow-container .slideshow')
13580        .cycle({
13581            slides: '> li',
13582            pager: '.slideshow-pager',
13583            pagerTemplate: '<span class="pager-box"></span>',
13584            speed: 600,
13585            pauseOnHover: true,
13586            swipe: true,
13587            prev: '.slideshow-prev',
13588            next: '.slideshow-next',
13589            fx: 'scrollHorz'
13590        });
13591});
13592
13593/*!
13594 * imagesLoaded PACKAGED v3.1.4
13595 * JavaScript is all like "You images are done yet or what?"
13596 * MIT License
13597 */
13598
13599(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
13599);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
13599("confirm",this,t)},f.prototype.unbindProxyEvents=function(e){n.unbind(e.target,"load",this),n.unbind(e.target,"error",this)},s});
13600
13601/**
13602 * Magento
13603 *
13604 * NOTICE OF LICENSE
13605 *
13606 * This source file is subject to the Academic Free License (AFL 3.0)
13607 * that is bundled with this package in the file LICENSE_AFL.txt.
13608 * It is also available through the world-wide-web at this URL:
13609 * http://opensource.org/licenses/afl-3.0.php
13610 * If you did not receive a copy of the license and are unable to
13611 * obtain it through the world-wide-web, please send an email
13612 * to [email protected] so we can send you a copy immediately.
13613 *
13614 * DISCLAIMER
13615 *
13616 * Do not edit or add to this file if you wish to upgrade Magento to newer
13617 * versions in the future. If you wish to customize Magento for your
13618 * needs please refer to http://www.magentocommerce.com for more information.
13619 *
13620 * @category    design
13621 * @package     default_default
13622 * @copyright   Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
13623 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
13624 */
13625function Minicart(options) {
13626    this.formKey = options.formKey;
13627    this.previousVal = null;
13628
13629    this.defaultErrorMessage = 'Error occurred. Try to refresh page.';
13630
13631    this.selectors = {
13632        itemRemove:           '#cart-sidebar .remove',
13633        container:            '#header-cart',
13634        inputQty:             '.cart-item-quantity',
13635        qty:                  'div.header-minicart span.count',
13636        overlay:              '.minicart-wrapper',
13637        error:                '#minicart-error-message',
13638        success:              '#minicart-success-message',
13639        quantityButtonPrefix: '#qbutton-',
13640        quantityInputPrefix:  '#qinput-',
13641        quantityButtonClass:  '.quantity-button'
13642    };
13643
13644    if (options.selectors) {
13645        $j.extend(this.selectors, options.selectors);
13646    }
13647}
13648
13649Minicart.prototype = {
13650
13651    init: function() {
13652        var cart = this;
13653
13654        // bind remove event
13655        $j(this.selectors.itemRemove).unbind('click.minicart').bind('click.minicart', function(e) {
13656            e.preventDefault();
13657            cart.removeItem($j(this));
13658        });
13659
13660        // bind update qty event
13661        $j(this.selectors.inputQty)
13662            .unbind('blur.minicart')
13663            .unbind('focus.minicart')
13664            .bind('focus.minicart', function() {
13665                cart.previousVal = $j(this).val();
13666                cart.displayQuantityButton($j(this))
13667            })
13668            .bind('blur.minicart', function() {
13669                cart.revertInvalidValue(this);
13670            });
13671
13672        $j(this.selectors.quantityButtonClass)
13673            .unbind('click.quantity')
13674            .bind('click.quantity', function() {
13675                cart.processUpdateQuantity(this);
13676        });
13677    },
13678
13679    removeItem: function(el) {
13680        var cart = this;
13681        if (confirm(el.data('confirm'))) {
13682            cart.hideMessage();
13683            cart.showOverlay();
13684            $j.ajax({
13685                type: 'POST',
13686                dataType: 'json',
13687                data: {form_key: cart.formKey},
13688                url: el.attr('href')
13689            }).done(function(result) {
13690                cart.hideOverlay();
13691                if (result.success) {
13692                    cart.updateCartQty(result.qty);
13693                    cart.updateContentOnRemove(result, el.closest('li'));
13694                } else {
13695                    cart.showMessage(result);
13696                }
13697            }).error(function() {
13698                cart.hideOverlay();
13699                cart.showError(cart.defaultErrorMessage);
13700            });
13701        }
13702    },
13703
13704    revertInvalidValue: function(el) {
13705        if (!this.isValidQty($j(el).val()) || $j(el).val() == this.previousVal) {
13706            $j(el).val(this.previousVal);
13707            this.hideQuantityButton(el);
13708        }
13709    },
13710
13711    displayQuantityButton: function(el) {
13712        var buttonId = this.selectors.quantityButtonPrefix + $j(el).data('item-id');
13713        $j(buttonId).addClass('visible').attr('disabled',null);
13714    },
13715
13716    hideQuantityButton: function(el) {
13717        var buttonId = this.selectors.quantityButtonPrefix + $j(el).data('item-id');
13718        $j(buttonId).removeClass('visible').attr('disabled','disabled');
13719    },
13720
13721    processUpdateQuantity: function(el) {
13722        var input = $j(this.selectors.quantityInputPrefix + $j(el).data('item-id'));
13723        if (this.isValidQty(input.val()) && input.val() != this.previousVal) {
13724            this.updateItem(el);
13725        } else {
13726            this.revertInvalidValue(input);
13727        }
13728    },
13729
13730    updateItem: function(el) {
13731        var cart = this;
13732        var input = $j(this.selectors.quantityInputPrefix + $j(el).data('item-id'));
13733        var quantity = parseInt(input.val(), 10);
13734        cart.hideMessage();
13735        cart.showOverlay();
13736        $j.ajax({
13737            type: 'POST',
13738            dataType: 'json',
13739            url: input.data('link'),
13740            data: {qty: quantity, form_key: cart.formKey}
13741        }).done(function(result) {
13742            cart.hideOverlay();
13743            if (result.success) {
13744                cart.updateCartQty(result.qty);
13745                if (quantity !== 0) {
13746                    cart.updateContentOnUpdate(result);
13747                } else {
13748                    cart.updateContentOnRemove(result, input.closest('li'));
13749                }
13750            } else {
13751                cart.showMessage(result);
13752            }
13753        }).error(function() {
13754            cart.hideOverlay();
13755            cart.showError(cart.defaultErrorMessage);
13756        });
13757        return false;
13758    },
13759
13760    updateContentOnRemove: function(result, el) {
13761        var cart = this;
13762        el.hide('slow', function() {
13763            $j(cart.selectors.container).html(result.content);
13764            cart.showMessage(result);
13765
13766        });
13767    },
13768
13769    updateContentOnUpdate: function(result) {
13770        $j(this.selectors.container).html(result.content);
13771        this.showMessage(result);
13772    },
13773
13774    updateCartQty: function(qty) {
13775        if (typeof qty != 'undefined') {
13776            $j(this.selectors.qty).text(qty);
13777        }
13778    },
13779
13780    isValidQty: function(val) {
13781        return (val.length > 0) && (val - 0 == val) && (val - 0 > 0);
13782    },
13783
13784    showOverlay: function() {
13785        $j(this.selectors.overlay).addClass('loading');
13786    },
13787
13788    hideOverlay: function() {
13789        $j(this.selectors.overlay).removeClass('loading');
13790    },
13791
13792    showMessage: function(result) {
13793        if (typeof result.notice != 'undefined') {
13794            this.showError(result.notice);
13795        } else if (typeof result.error != 'undefined') {
13796            this.showError(result.error);
13797        } else if (typeof result.message != 'undefined') {
13798            this.showSuccess(result.message);
13799        }
13800    },
13801
13802    hideMessage: function() {
13803        $j(this.selectors.error).fadeOut('slow');
13804        $j(this.selectors.success).fadeOut('slow');
13805    },
13806
13807    showError: function(message) {
13808        $j(this.selectors.error).text(message).fadeIn('slow');
13809    },
13810
13811    showSuccess: function(message) {
13812        $j(this.selectors.success).text(message).fadeIn('slow');
13813    }
13814};
13815
13816(function($) {
13817    $.extend(jQuery.fn, {
13818        fabox: function(method, args) {
13819            var scope = this;
13820            var width_screen = $(window).width();
13821            var height_screen = $(window).height();
13822            if (typeof(method) !== 'string') {
13823                args = method;
13824                scope.locked = false;
13825                $(scope).addClass('fabox');
13826                $(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>');
13827                $(scope).unbind();
13828                $(scope).find('.framebox').unbind();
13829                $(scope).find('.close-box').unbind();
13830                $(scope).bind('click', function() {
13831                    if(!scope.locked) {
13832                        $(scope).fabox('close', null);
13833                    }
13834                });
13835                $(scope).find('.framebox').bind('click', function() {
13836                    scope.locked = true;
13837                    window.setTimeout(function() {
13838                        scope.locked = false;
13839                    }, 200);
13840                });
13841                $('body').keydown(function (e) {
13842                    if(e.keyCode == 27) {
13843                        $(scope).fabox('close', null);
13844                    }
13845                })
13846                $(scope).find('.close-box').bind('click', function() {
13847                    $(scope).fabox('close', null);
13848                });
13849            }
13850            else {
13851                switch(method) {
13852                    case 'write':
13853                        var content = (typeof(args.content) != 'undefined') ? args.content : '';
13854                        var width = (typeof(args.width) != 'undefined') ? args.width : 0;
13855                        var height = (typeof(args.height) != 'undefined') ? args.height : 0;
13856                        var control = (typeof(args.control) != 'undefined') ? args.control : true;
13857                        var loaded = (typeof(args.loaded) != 'undefined') ? args.loaded : false;
13858                        var open = (typeof(args.open) != 'undefined') ? args.open : false;
13859                        var full = (typeof(args.full) != 'undefined') ? args.full : false;
13860                        var show = (typeof(args.show) != 'undefined') ? args.show : false;
13861                        var full_text = (typeof(args.full_text) != 'undefined') ? args.full_text : false;
13862                        var mode_closebox = (typeof(args.mode_closebox) != 'undefined') ? args.mode_closebox : 'full';
13863                        $(scope).find('.framebox .content-frame').html(content);
13864                        if(open) {
13865                            $(scope).fabox('open', {speed: '200'});
13866                        }
13867                        if(loaded) {
13868							window.setTimeout(function() {
13869								$(scope).fabox('resize', {width: width, 
13870														  height: height, 
13871														  control: control, 
13872														  full: full, 
13873														  show: show, 
13874														  full_text: full_text, 
13875														  mode_closebox: mode_closebox});
13876							}, 10);
13877                        }
13878                        else {
13879	                        var images_content = [];
13880	                        var iframe = null;
13881	                        $(scope).find('.framebox .content-frame iframe').each(function(k, v) {
13882		                        iframe = $(v);
13883		                    });
13884	                        $(scope).find('.framebox .content-frame img').each(function(k, v) {
13885		                        images_content.push($(v).attr('src'));
13886	                        });
13887	                        if(images_content.length > 0) {
13888		                        var nb_loaded = 0;
13889		                        for(var i = 0; i < images_content.length; i++) {
13890									var image = new Image();
13891									image.onload = function() {
13892										nb_loaded++;
13893										if(nb_loaded == images_content.length) {
13894											$(scope).fabox('write', {content: content, 
13895																	 width: width, 
13896																	 height: height, 
13897																	 control: control, 
13898																	 loaded: true, 
13899																	 full: full, 
13900																	 show: show, 
13901																	 full_text: full_text, 
13902																	 mode_closebox: mode_closebox});
13903										}
13904									};
13905									image.onerror = function() {
13906										nb_loaded++;
13907										if(nb_loaded == images_content.length) {
13908											$(scope).fabox('write', {content: content, 
13909																	 width: width, 
13910																	 height: height, 
13911																	 control: control, 
13912																	 loaded: true, 
13913																	 full: full, 
13914																	 show: show, 
13915																	 full_text: full_text, 
13916																	 mode_closebox: mode_closebox});
13917										}
13918									};
13919									image.src = images_content[i];
13920		                        }   
13921	                        }
13922	                        else if(iframe != null) {
13923								$(iframe).bind('load', function() {
13924			                        $(scope).fabox('write', {content: content, 
13925				                        					 width: $(iframe).outerWidth(), 
13926				                        					 height: $(iframe).outerHeight(), 
13927				                        					 control: control, 
13928				                        					 loaded: true, 
13929				                        					 full: full, 
13930				                        					 show: show, 
13931				                        					 full_text: full_text, 
13932															 mode_closebox: mode_closebox});
13933								});
13934	                        }
13935	                        else {
13936		                        $(scope).fabox('write', {content: content, 
13937			                        					 width: width, 
13938			                        					 height: height, 
13939			                        					 control: control, 
13940			                        					 loaded: true, 
13941			                        					 full: full, 
13942			                        					 show: show, 
13943			                        					 full_text: full_text, 
13944														 mode_closebox: mode_closebox});
13945	                        }
13946                        }
13947                    break;
13948                    case 'open':
13949                        var speed = (typeof(args.speed) != 'undefined') ? args.speed : 0;
13950                        $(scope).fadeIn(speed);
13951                    break;
13952                    case 'close':
13953                        $(scope).fadeOut(200, function() {
13954							$(scope).find('.framebox .content-frame').html('').removeClass('force-relative');
13955							$(scope).removeClass('fullgaz').removeClass('no-control');
13956							$(scope).addClass('loading').find('.framebox').css('width', '300px').css('height', '300px').css('margin-left', '-150px').css('margin-top', '-150px');
13957                        });
13958                    break;
13959                    case 'alert':
13960                        var title = (typeof(args.title) != 'undefined') ? args.title : '';
13961                        var msg = (typeof(args.msg) != 'undefined') ? args.msg : '';
13962                        var width = (typeof(args.width) != 'undefined') ? args.width : 450;
13963                        var msg_with_p = (msg != '') ? '<p>' + msg + '</p>' : '';
13964                        var mode_closebox = (typeof(args.mode_closebox) != 'undefined') ? args.mode_closebox : 'full';
13965                        $(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>',
13966                                                         width: width,
13967                                                         open: true,
13968														 show: false,
13969                                                         full_text : true,
13970                                                         loaded: true, 
13971														 mode_closebox: mode_closebox});
13972                        $(scope).find('.btn-center').unbind();
13973                        $(scope).find('.btn-center').bind('click', function() {
13974                            $(scope).fabox('close', null);
13975                        });
13976                    break;
13977                    case 'confirm':
13978                        var title = (typeof(args.title) != 'undefined') ? args.title : '';
13979                        var msg = (typeof(args.msg) != 'undefined') ? args.msg : '';
13980                        var left_btn = (typeof(args.left_btn) != 'undefined') ? args.left_btn : 'Cancel';
13981                        var right_btn = (typeof(args.right_btn) != 'undefined') ? args.right_btn : 'Confirm';
13982                        var width = (typeof(args.width) != 'undefined') ? args.width : 450;
13983                        var msg_with_p = (msg != '') ? '<p>' + msg + '</p>' : '';
13984                        var mode_closebox = (typeof(args.mode_closebox) != 'undefined') ? args.mode_closebox : 'full';
13985                        $(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});
13986                        window.setTimeout(function() {
13987	                        $(scope).find('.btn-left').unbind();
13988	                        $(scope).find('.btn-right').unbind();
13989	                        $(scope).find('.btn-left').bind('click', function() {
13990                                if(typeof(args.callback_left) != 'undefined') {
13991                                    args.callback_left();
13992                                }
13993	                        });
13994	                        $(scope).find('.btn-right').bind('click', function() {
13995                                if(typeof(args.callback_right) != 'undefined') {
13996                                    args.callback_right();
13997                                }
13998	                        });
13999                        }, 500);
14000                    break;
14001                    case 'ajax':
14002                        var url = (typeof(args.url) != 'undefined') ? args.url : '';
14003                        var data = (typeof(args.data) != 'undefined') ? args.data : {};
14004                        var type = (typeof(args.type) != 'undefined') ? args.type : 'get';
14005                        var width = (typeof(args.width) != 'undefined') ? args.width : 0;
14006                        var height = (typeof(args.height) != 'undefined') ? args.height : 0;
14007                        var control = (typeof(args.control) != 'undefined') ? args.control : true;
14008                        var full = (typeof(args.full) != 'undefined') ? args.full : false;
14009                        var mode_closebox = (typeof(args.mode_closebox) != 'undefined') ? args.mode_closebox : 'full';
14010                        $(scope).fabox('open', {speed: 200});
14011						var request = $.ajax({
14012							url: url,
14013							type: type,
14014							data: data
14015						});						
14016						request.done(function(response) {
14017							$(scope).fabox('write', {content: response, width: width, height: height, control: control, full: full, loaded: false, mode_closebox: mode_closebox});
14018						});
14019						request.fail(function(jqXHR, textStatus) {
14020							$(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});
14021						});
14022                    break;
14023                    /*case 'gallery':
14024                        if (typeof(args.url) != 'undefined' && args.url != '') {
14025                            $(scope).fabox('open', {speed: '200'});
14026                            $(scope).addClass('box-img');
14027                            img = new Image();
14028                            img.onload = function() {
14029                                var width_img = parseInt(this.width);
14030                                var height_img = parseInt(this.height);
14031                                var old_height_img = height_img;
14032                                var old_width_img = width_img;
14033                                var twenty_percent_frame = Math.ceil(parseInt(height_screen) * 0.8);
14034                                if (parseInt(height_img) >= parseInt(twenty_percent_frame)) {
14035                                    // Si la hauteur de l'image est supérieur à 80% de la hauteur de l'écran, on optimise
14036                                    height_img = parseInt(twenty_percent_frame);
14037                                    width_img = parseInt((height_img * old_width_img) / old_height_img);
14038                                    old_width_img = width_img;
14039                                    old_height_img = height_img;
14040                                }
14041                                if (parseInt(width_img) >= width_screen) {
14042                                    // Si la largeur de l'image est supérieur à la largeur de l'écran, on optimise
14043                                    width_img = parseInt(width_screen);
14044                                    height_img = parseInt((width_img * old_height_img) / old_width_img);
14045                                    old_width_img = width_img;
14046                                    old_height_img = height_img;
14047                                }
14048                                $(scope).fabox('write', {content: '<img src="' + args.url + '" />', custom_width: width_img, custom_height: height_img, disable_control: true});
14049                            }
14050                            img.src = args.url;
14051                        }
14052                    break;*/
14053                    case 'resize':
14054                        var control = (typeof(args.control) != 'undefined') ? args.control : true;
14055                        var show = (typeof(args.show) != 'undefined') ? args.show : false;
14056                        var full = (typeof(args.full) != 'undefined') ? args.full : false;
14057                        var full_text = (typeof(args.full_text) != 'undefined') ? args.full_text : false;
14058						var width_frame = parseInt($(scope).find('.content-frame').outerWidth());
14059						var height_frame = parseInt($(scope).find('.content-frame').outerHeight());
14060                        var mode_closebox = (typeof(args.mode_closebox) != 'undefined') ? args.mode_closebox : 'full';
14061                        if(width_frame == 0) {
14062							width_frame = parseInt($(scope).find('.framebox').outerWidth());
14063                            if (width_frame == 0) {
14064                                width_frame = 300;
14065                            }
14066                        }
14067                        if(height_frame == 0) {
14068							height_frame = parseInt($(scope).find('.framebox').outerHeight());
14069                            if (height_frame == 0) {
14070                                height_frame = 300;
14071                            }
14072                        }
14073                        var width = (typeof(args.width) != 'undefined' && parseInt(args.width) > 0) ? parseInt(args.width) : parseInt(width_frame);
14074                        var height = (typeof(args.height) != 'undefined' && parseInt(args.height) > 0) ? parseInt(args.height) : parseInt(height_frame);
14075						var twenty_percent_wscreen = parseInt(Math.ceil(parseInt(width_screen) * 0.8));
14076						var twenty_percent_hscreen = parseInt(Math.ceil(parseInt(height_screen) * 0.8));
14077                        if(width > twenty_percent_wscreen) {
14078							if (width_screen > 500) {
14079								width = twenty_percent_wscreen;
14080							}
14081							else {
14082								if (width > width_screen) {
14083									width = twenty_percent_wscreen;
14084								}
14085							}
14086                        }
14087                        if(height > twenty_percent_hscreen) {
14088	                       height = twenty_percent_hscreen;
14089                        }
14090                        var margin_left = Math.ceil(parseInt(width) / 2);
14091                        var margin_top = Math.ceil(parseInt(height) / 2);
14092                        
14093                        /*console.log('*****************************');
14094                        console.log('width_screen ' + width_screen);
14095                        console.log('height_screen ' + height_screen);
14096                        console.log('twenty_percent_wscreen ' + twenty_percent_wscreen);
14097                        console.log('twenty_percent_hscreen ' + twenty_percent_hscreen);
14098                        console.log('width_frame ' + width_frame);
14099                        console.log('height_frame ' + height_frame);
14100                        console.log('width ' + width);
14101                        console.log('height ' + height);
14102                        console.log('control ' + control);
14103                        console.log('full ' + full);
14104                        console.log('margin_left ' + margin_left);
14105                        console.log('margin_top ' + margin_top);
14106                        console.log('*****************************');*/
14107                        
14108                        if (full) {
14109                            $(scope).addClass('fullgaz');
14110                            var the_elmt = $(scope).find('.framebox .content-frame').children().eq(0);
14111                            var diff_width = $(the_elmt).outerWidth() - width;
14112                            var diff_height = $(the_elmt).outerHeight() - height;
14113							var attr_width = $(the_elmt).attr('width');
14114							var attr_height = $(the_elmt).attr('height');
14115							if (typeof attr_width != 'undefined' && attr_width != '' && attr_width != null && parseInt(attr_width) > 0 &&
14116								typeof attr_height != 'undefined' && attr_height != '' && attr_height != null && parseInt(attr_height) > 0) {
14117								if (diff_width > 0) {
14118									var percent_prop = parseInt((width * 100) / attr_width);
14119									height = parseInt((percent_prop * attr_height) / 100);
14120									margin_top = Math.ceil(parseInt(height) / 2);
14121									$(the_elmt).css('height', height + 'px').css('width', width + 'px');
14122									window.setTimeout(function() {
14123										$(scope).fabox('resize', {width: 0, height: 0, control: control, full: true, show: false, full_text: full_text, mode_closebox: mode_closebox});
14124									}, 300);
14125								}
14126								else if(diff_height > 0) {
14127									var percent_prop = parseInt((height * 100) / attr_height);
14128									width = parseInt((percent_prop * attr_width) / 100);
14129									margin_left = Math.ceil(parseInt(width) / 2);
14130									$(the_elmt).css('height', height + 'px').css('width', width + 'px');						
14131									window.setTimeout(function() {
14132										$(scope).fabox('resize', {width: 0, height: 0, control: control, full: true, show: false, full_text: full_text, mode_closebox: mode_closebox});
14133									}, 300);
14134								}
14135								else {
14136									window.setTimeout(function() {
14137										$(scope).fabox('resize', {width: 0, height: 0, control: control, full: false, show: true, full_text: full_text, mode_closebox: mode_closebox});
14138									}, 300);
14139								}
14140							}
14141							else {
14142								if (diff_height > 0 || diff_width > 0) {
14143									if (diff_height > diff_width) {
14144										$(the_elmt).css('height', height + 'px').css('width', 'auto');
14145									}
14146									else {
14147										$(the_elmt).css('width', width + 'px').css('height', 'auto');
14148									}
14149									window.setTimeout(function() {
14150										$(scope).fabox('resize', {width: 0, height: 0, control: control, full: true, show: false, full_text: full_text, mode_closebox: mode_closebox});
14151									}, 300);
14152								}
14153								else {
14154									window.setTimeout(function() {
14155										$(scope).fabox('resize', {width: 0, height: 0, control: control, full: false, show: true, full_text: full_text, mode_closebox: mode_closebox});
14156									}, 300);
14157								}
14158							}							
14159                        }
14160                        if (!control) {
14161                            $(scope).addClass('no-control');
14162                        }
14163                        if (show) {
14164	                        switch(mode_closebox) {
14165		                        case 'full':
14166		                        	// Mode fullpage, la closebox se situe en haut à droite de l'écran
14167		                        	$(scope).find('.close-box').css('right', '20px').css('top', '20px');
14168		                        break;
14169		                        case 'center':
14170		                        	// Mode center, la closebox se situe en haut à droite de la framebox
14171		                        	var right_position = parseInt(parseInt(width_screen / 2) - margin_left);
14172		                        	var top_position = parseInt(parseInt(height_screen / 2) - margin_top);
14173		                        	$(scope).find('.close-box').css('right', right_position + 'px').css('top', top_position + 'px');
14174		                        break;
14175	                        }
14176                            $(scope).removeClass('loading');
14177                            $(scope).find('.framebox').stop().animate({'margin-left': '-' + margin_left + 'px',
14178                                                                                        'width': width + 'px',
14179                                                                                        'margin-top': '-' + margin_top + 'px',
14180                                                                                        'height': height + 'px'}, 200);
14181                        }
14182                        else {
14183                            $(scope).find('.framebox').css('width', width + 'px').css('height', height + 'px').css('margin-left', '-' + margin_left + 'px').css('margin-top', '-' + margin_top + 'px');
14184                            window.setTimeout(function() {
14185	                            if (!full) {
14186                                    if(!full_text) {
14187                                        width = 0;
14188                                    }
14189                                    else {
14190                                        $(scope).find('.content-frame').addClass('force-relative');
14191                                    }
14192	                                $(scope).fabox('resize', {width: width, height: 0, control: control, full: false, show: true, full_text: full_text, mode_closebox: mode_closebox});
14193	                            }
14194                            }, 0);
14195                        }
14196                    break;
14197                }
14198            }
14199            return this;
14200        }
14201    });
14202})(jQuery);
14203/*
14204     _ _      _       _
14205 ___| (_) ___| | __  (_)___
14206/ __| | |/ __| |/ /  | / __|
14207\__ \ | | (__|   < _ | \__ \
14208|___/_|_|\___|_|\_(_)/ |___/
14209                   |__/
14210
14211 Version: 1.3.11
14212  Author: Ken Wheeler
14213 Website: http://kenwheeler.github.io
14214    Docs: http://kenwheeler.github.io/slick
14215    Repo: http://github.com/kenwheeler/slick
14216  Issues: http://github.com/kenwheeler/slick/issues
14217
14218 */
14219
14220!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,
14220sliding:!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}
14220,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"}
14220,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.$
14220slideTrack.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 14220
14220ptions.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");
14220b.$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:
14220parseInt(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}});
14221/*
14222* Nivo Lightbox v1.2.0
14223* http://dev7studios.com/nivo-lightbox
14224*
14225* Copyright 2013, Dev7studios
14226* Free to use and abuse under the MIT license.
14227* http://www.opensource.org/licenses/mit-license.php
14228*/
14229(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(".
14229nivo-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)
14230
14231$j(document).ready(function() {
14232
14233	$j('#fabox-1').fabox();
14234	$j('#fabox-2').fabox();
14235	$j('#fabox-3').fabox();
14236	$j('#fabox-4').fabox();
14237	
14238	$j('.smooth-scroll').unbind('click');
14239	$j('.smooth-scroll').bind('click', function(e) {
14240		e.preventDefault();
14241		$j('html,body').stop().animate({scrollTop: '0'}, 400);
14242	});
14243
14244	/*================================
14245	=            LIGHTBOX            =
14246	================================*/
14247	
14248	$j('.lightbox').nivoLightbox({
14249		effect: 'fall',
14250		afterShowLightbox: function() {
14251			$j('.nivo-lightbox-close').attr('title', 'Fermer').text('Fermer');
14252			$j('.nivo-lightbox-next').attr('title', 'Suivant').text('Suivant');
14253			$j('.nivo-lightbox-prev').attr('title', 'Précédent').text('Précédent');
14254		}
14255	});
14256
14257
14258	/*===================================
14259	=            BACK TO TOP            =
14260	===================================*/
14261		
14262	$j(window).scroll(function(e) {
14263		var scrolled = $j(this).scrollTop();
14264
14265		if (scrolled > 150) {
14266			$j('.back-to-top').addClass('is-visible');
14267		}
14268
14269		if (scrolled < 150) {
14270			$j('.back-to-top').removeClass('is-visible');
14271		}
14272	});
14273
14274	/*=================================
14275	=            NAV FIXED            =
14276	=================================*/
14277
14278	if (window.matchMedia("(min-width: 741px)").matches) {
14279		
14280		$j(window).scroll(function(e) {
14281			var scrolled = $j(this).scrollTop();
14282
14283			if (scrolled > 33) {
14284				$j('#header-top-links').addClass('is-fixed');
14285			}
14286
14287			if (scrolled < 33) {
14288				$j('#header-top-links').removeClass('is-fixed');
14289			}
14290		});
14291	}
14292
14293	/*==============================================
14294	=            CATALOG SEARCH RESULTS            =
14295	==============================================*/
14296
14297	if($j('#meccano-search-results').length > 0) {
14298		$j('#begin-mod-sidebar').hide();
14299	}
14300
14301	/*==============================================
14302	=            UNIRGY GIFT CERT                  =
14303	==============================================*/
14304
14305	$j(".gift-card-info #amount").on('change', function() {
14306        $j(".product-shop .price").html($j(this).val()+",00 €");
14307    });
14308
14309	/*==================================
14310	=            RESPONSIVE            =
14311	==================================*/
14312
14313	$j('#parametre-trigger').on('click', function(e) {
14314		e.preventDefault();
14315
14316		$j('#main-overlay').fadeIn(150);
14317		$j('.list-parametre').fadeIn().addClass('is-visible');
14318	});
14319
14320	$j('#recherche-trigger').on('click', function(e) {
14321		e.preventDefault();
14322
14323		$j('#main-overlay').fadeIn(150);
14324		$j('.header-search, .header-search-title').fadeIn();
14325	});
14326
14327	$j('#overlay-close-trigger').on('click', function(e) {
14328		e.preventDefault();
14329
14330		$j('#main-overlay, .header-search, .header-search-title, .list-parametre').removeClass('is-visible').fadeOut();
14331	});
14332
14333	$j('#site-menu-trigger').on('click', function(e) {
14334		e.preventDefault();
14335
14336		if ($j('.site-menu').hasClass('is-closed')) {
14337			$j('.site-menu').toggleClass('is-closed is-opened');
14338			$j(this).find('i').addClass('is-inverse');
14339		} else {
14340			$j('.site-menu').toggleClass('is-opened is-closed');
14341			$j(this).find('i').removeClass('is-inverse');
14342		}
14343	});
14344
14345	/*==========  DISABLE LINK  ==========*/	
14346
14347	if (window.matchMedia("(max-width: 960px)").matches) {
14348		disableLink();
14349	}
14350	
14351	// ==============================================
14352    // Layered Navigation Block
14353    // ==============================================
14354
14355    // On product list pages, we want to show the layered nav/category menu immediately above the product list.
14356    // While it would make more sense to just move the .block-layered-nav block rather than .col-left-first
14357    // (since other blocks can be inserted into left_first), it creates simpler code to move the entire
14358    // .col-left-first block, so that is the approach we're taking
14359    if ($j('.col-left-first > .block').length && $j('.category-products').length) {
14360        enquire.register('screen and (max-width: ' + bp.medium + 'px)', {
14361            match: function () {
14362                $j('.col-left-first').insertBefore($j('#amshopby-page-container'))
14363            },
14364            unmatch: function () {
14365                // Move layered nav back to left column
14366                $j('.col-left-first').insertBefore($j('.col-main'))
14367            }
14368        });
14369        $j('.amshopby-filters-left #narrow-by-list').removeClass('no-display');
14370        $j('.amshopby-filters-left .block-subtitle.block-subtitle--filter').remove();
14371    }
14372
14373    // ==============================================
14374    // OPC - Progress Block
14375    // ==============================================
14376
14377    if ($j('body.checkout-onepage-index').length) {
14378        enquire.register('(max-width: ' + bp.large + 'px)', {
14379            match: function () {
14380                $j('#checkout-step-review').prepend($j('#checkout-progress-wrapper'));
14381            },
14382            unmatch: function () {
14383                $j('.col-left').prepend($j('#checkout-progress-wrapper'));
14384            }
14385        });
14386    }
14387    $j('body').on('click', '#fabox-1 .btn-left', function () {
14388        $j('#fabox-1').hide();
14389    });
14390});
14391
14392function is_object(mixed_var) {
14393  if (Object.prototype.toString.call(mixed_var) === '[object Array]') {
14394    return false;
14395  }
14396  return mixed_var !== null && typeof mixed_var === 'object';
14397}
14398
14399function disableLink() {
14400	$j('.js-disable-link').on('click', function(e) {
14401		e.preventDefault();
14402	});
14403}
14404
14405function getColorByMinimumAgeJS(age) {
14406	age = parseInt(age);
14407	var color = '';
14408	switch(age) {
14409		case 0:
14410			color = 'grey';
14411		break;
14412		case 1:
14413			color = 'grey';			
14414		break;
14415		case 2:
14416			color = 'grey';
14417		break;
14418		case 3:
14419			color = 'grey';
14420		break;
14421		case 4:
14422			color = 'grey';
14423		break;
14424		case 5:
14425			color = 'orange';
14426		break;
14427		case 6:
14428			color = 'purple';
14429		break;
14430		case 7:
14431			color = 'green';
14432		break;
14433		case 8:
14434			color = 'brown';
14435		break;
14436		case 9:
14437			color = 'clementine';
14438		break;
14439		case 10:
14440			color = 'grey';
14441		break;
14442		case 11:
14443			color = 'grey';
14444		break;
14445		case 12:
14446			color = 'grey';
14447		break;
14448	}
14449	return color;
14450}
14451
14452function transformFormToAjax(id_form, callbackSuccess, callbackError, other_data) {
14453	$j(id_form).unbind('submit');
14454	$j(id_form).bind('submit', function(e) {
14455		e.preventDefault();
14456
14457		if(jQuery.isEmptyObject(other_data) == false && $j('.product-shop .price').length) {
14458			other_data_json = JSON.parse(other_data);
14459			other_data_json.price = $j('.product-shop .price').html();
14460			other_data = JSON.stringify(other_data_json);
14461		}
14462                
14463		$j('#main-loader').fadeIn(400);
14464		var url_form = $j(id_form).attr('action');
14465		if(url_form == '') {
14466			url_form = window.location.href;
14467		}
14468		var method = $j(id_form).attr('method');
14469		if(method == '') {
14470			method = 'post';
14471		}	
14472                
14473		var request = $j.ajax({
14474			url: url_form,
14475			type: method,
14476			data: $j(id_form).serialize()
14477		});
14478		
14479		request.done(function(response) {
14480			$j('#main-loader').fadeOut(400);
14481			callbackSuccess(response, other_data);
14482		});
14483		
14484		request.fail(function(jqXHR, textStatus) {
14485			$j('#main-loader').fadeOut(400);
14486			callbackError(jqXHR, textStatus, other_data);
14487		});
14488	});
14489}
14490
14491function transformUrlToAjax(url, method, callbackSuccess, callbackError, other_data) {
14492	$j('#main-loader').fadeIn(400);
14493	var url_form = url;
14494	if(url_form == '') {
14495		url_form = window.location.href;
14496	}
14497	var request = $j.ajax({
14498		url: url_form,
14499		type: method
14500	});
14501	
14502	request.done(function(response) {
14503		$j('#main-loader').fadeOut(400);
14504		callbackSuccess(response, other_data);
14505	});
14506	
14507	request.fail(function(jqXHR, textStatus) {
14508		$j('#main-loader').fadeOut(400);
14509		callbackError(jqXHR, textStatus, other_data);
14510	});
14511}
14512
14513function strip_tags(input, allowed) {
14514	allowed = (((allowed || '') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('');
14515	var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
14516	return input.replace(commentsAndPhpTags, '').replace(tags, function($0, $1) {
14517		return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
14518	});
14519}
14520
14521function customIFrameSoCol() {
14522	var wrap_socol_module = $j('#socolissimosimplicite_iframe_wrapper iframe').clone();
14523	$j('#socolissimosimplicite_iframe_wrapper iframe').remove();
14524	$j('#fabox-1').fabox('write', {content : wrap_socol_module,
14525								   open: true,
14526								   mode_closebox: 'center'});
14527	$j('#socolissimosimplicite_iframe_wrapper').hide();
14528	$j('#socolissimosimplicite_iframe_wrapper').children().eq(0).trigger('click');
14529}
14530
14531$j(document).ready(function() {
14532	
14533    
14534});
14535
14536function playVideo(url) {
14537	$j('#fabox-1').fabox('write', {content : '<iframe width="800" height="480" src="' + url + '" frameborder="0" allowfullscreen></iframe>',
14538									full: true,
14539								   open: true,
14540								   mode_closebox: 'center'});
14541}
14542
14543function showDescriptionVideo(title, desc) {
14544	$j('#fabox-1').fabox('write', {content: '<div style="padding: 15px;"><h1 style="text-align: center;margin-top: 0;">' + title + '</h1><p>' + desc + '</p></div>',
14545                open: true,
14546                width: 500,
14547                mode_closebox: 'center'});
14548}
14549$j(document).ready(function() {});
14550
14551function successAddToCart(response, other_data) {
14552	other_data_json = JSON.parse(other_data);
14553	var img = '';
14554	var urlproduct = '';
14555	var productName = '';
14556	var refProduct = '';
14557	var descProduct = '';
14558
14559	var message_gift_step = $j(response).find('.gift-step-msg').children().eq(0).text();
14560	if(message_gift_step.length > 1) { message_gift_step = '<div class="gift-step-msg">' + message_gift_step + '</div>'; } 
14561        
14562	if(other_data_json != null && other_data_json.img != null && other_data_json.img != '') {
14563		img = '<img src="' + other_data_json.img + '" />';
14564	}
14565	if(other_data_json != null && other_data_json.name != null && other_data_json.name != '') {
14566		productName = other_data_json.name;
14567	}
14568	if(other_data_json != null && other_data_json.ref != null && other_data_json.ref != '') {
14569		refProduct = '<p class="ref">Ref. ' + other_data_json.ref + '</p>';
14570	}
14571	if(other_data_json != null && other_data_json.desc != null && other_data_json.desc != '') {
14572		descProduct = '<p class="desc">' + other_data_json.desc + '</p>';
14573	}
14574	if(other_data_json != null && other_data_json.url_product != null && other_data_json.url_product != '') {
14575		urlproduct = '<a href="' + other_data_json.url_product + '"><i class="meccano-arrow-right"></i> Voir le produit</a>';
14576	}
14577	var headertoplinks = $j(response).find('#header-top-cart');
14578	if(headertoplinks != null && headertoplinks.length > 0) {
14579		$j('#header-top-cart').replaceWith(headertoplinks);
14580	}
14581	var contentMess = '<h4>' + productName + '</h4>' + refProduct + /*descProduct +*/ urlproduct;
14582	var messages = $j(response).find('.messages').text();
14583	if(messages != null && messages.length > 0) {
14584		if(messages.match(/a été ajouté à votre panier/gi)) {
14585			$j('#fabox-1').fabox('confirm', {title: 'Article ajouté à votre panier : ',
14586                                                msg: '<div class="img-product left">' + img + '</div>' +
14587													   '<div class="descriptions-product right">' + contentMess + '</div>' +
14588													   '<div class="cf"></div>' +
14589													   message_gift_step,
14590												mode_closebox: 'center',
14591                                                left_btn: 'Poursuivre mes achats',
14592                                                right_btn: 'Voir mon panier',
14593                                                width: 600,
14594                                                callback_left: function() {
14595											       $j('#fabox-1').fabox('close');
14596                                                },
14597                                                callback_right: function() {
14598													if(other_data_json != null && other_data_json.url_cart != null && other_data_json.url_cart != '') {
14599														document.location.href = other_data_json.url_cart;
14600													}
14601													else {
14602														$j('#fabox-1').fabox('close');
14603													}
14604                                                }});
14605		}
14606		else {
14607			$j('#fabox-1').fabox('alert', {msg: '', title: messages, mode_closebox: 'center'});
14608		}
14609	}
14610	else if (is_object(response)) {
14611		$j('#fabox-1').fabox('confirm', {title: 'Article ajouté à votre panier : ',
14612                                        msg: '<div class="img-product left">' + img + '</div>' +
14613											   '<div class="descriptions-product right">' + contentMess + '</div>' +
14614											   '<div class="cf"></div>' +
14615											   message_gift_step,
14616										mode_closebox: 'center',
14617                                        left_btn: 'Poursuivre mes achats',
14618                                        right_btn: 'Voir mon panier',
14619										width: 600,
14620                                        callback_left: function() {
14621									       $j('#fabox-1').fabox('close');
14622                                        },
14623                                        callback_right: function() {
14624											if(other_data_json != null && other_data_json.url_cart != null && other_data_json.url_cart != '') {
14625												document.location.href = other_data_json.url_cart;
14626											}
14627											else {
14628												$j('#fabox-1').fabox('close');
14629											}
14630                                        }});
14631	}
14632	else {
14633		errorAddToCart(null, null, other_data);
14634	}
14635}
14636
14637function errorAddToCart(jqXHR, textStatus, other_data) {
14638	other_data_json = JSON.parse(other_data);
14639	if(other_data_json != null && other_data_json.url_cart != null && other_data_json.url_cart != '') {
14640		document.location.href = other_data_json.url_cart;
14641	}
14642	else {
14643		window.location.reload();
14644	}
14645}
14646
14647function successAddToCartDetail(response, other_data) {
14648	other_data_json = JSON.parse(other_data);
14649	var img = '';
14650	var urlproduct = '';
14651    var isGift = $j('#u_pdf_template').size() > 0;
14652    var imageUrl =  other_data_json.img;
14653
14654    console.log(other_data);
14655
14656    var message_gift_step = $j(response).find('.gift-step-msg').children().eq(0).text();
14657    if(message_gift_step.length > 1) { message_gift_step = '<div class="gift-step-msg">' + message_gift_step + '</div>'; } 
14658        
14659        if(isGift)
14660        {
14661            var templateId = $j('#u_pdf_template').val();
14662            imageUrl = $j('#pdf-visuel-'+templateId+' img').attr('src');
14663        }
14664        
14665	if(other_data_json != null && other_data_json.img != null && other_data_json.img != '') {
14666		img = '<img src="' + imageUrl + '" />';
14667	}
14668	if(other_data_json != null && other_data_json.name != null && other_data_json.name != '') {
14669		productName = other_data_json.name;
14670	}
14671	if(other_data_json != null && other_data_json.ref != null && other_data_json.ref != '') {
14672		refProduct = '<p class="ref">Ref. ' + other_data_json.ref + '</p>';
14673	}
14674
14675		if(isGift)
14676        {
14677            refProduct += '<p class="desc">
14677Montant du chèque cadeau : <strong>'+other_data_json.price+'</strong></p>';
14678        }
14679
14680	if(other_data_json != null && other_data_json.desc != null && other_data_json.desc != '') {
14681		descProduct = '<p class="desc">' + other_data_json.desc + '</p>';
14682	}
14683	if(other_data_json != null && other_data_json.url_product != null && other_data_json.url_product != '') {
14684		urlproduct = '<br><a href="' + other_data_json.url_product + '">Voir le produit</a>';
14685	}
14686	var headertoplinks = $j(response).find('#header-top-links');
14687	if(headertoplinks != null && headertoplinks.length > 0) {
14688		$j('#header-top-links').replaceWith(headertoplinks);
14689	}
14690	var contentMess = '<h4>' + productName + '</h4>' + refProduct /*+ descProduct*/;
14691	var messages = $j(response).find('.messages').text();
14692	if(messages != null && messages.length > 0) {
14693		if(messages.match(/a été ajouté à votre panier/gi)) {
14694			$j('#fabox-1').fabox('confirm', {msg: '<div class="img-product left">' + img + '</div>' +
14695													   '<div class="descriptions-product right">' + contentMess + '</div>' +
14696													   '<div class="cf"></div>' +
14697													   message_gift_step,
14698												   title: 'Article ajouté à votre panier : ',
14699											       left_btn: 'Poursuivre mes achats',
14700											       right_btn: 'Voir mon panier',
14701												   width: 600,
14702												   mode_closebox: 'center',
14703											       callback_left: function() {
14704											       	   $j('#fabox-1').fabox('close');
14705											       }, 
14706											       callback_right: function() {
14707														if(other_data_json != null && other_data_json.url_cart != null && other_data_json.url_cart != '') {
14708															document.location.href = other_data_json.url_cart;
14709														}
14710														else {
14711															$j('#fabox-1').fabox('close');
14712														}
14713											       }});
14714		}
14715		else {			
14716			$j('#fabox-1').fabox('alert', {msg: '', title: messages, mode_closebox: 'center'});
14717		}
14718	}
14719	else {
14720		errorAddToCartDetail(null, null, other_data);
14721	}
14722}
14723
14724function errorAddToCartDetail(response, other_data) {
14725	other_data_json = JSON.parse(other_data);
14726	if(other_data_json != null && other_data_json.url_cart != null && other_data_json.url_cart != '') {
14727		document.location.href = other_data_json.url_cart;
14728	}
14729	else {
14730		window.location.reload();
14731	}
14732}
14733
14734function successForgottenPasswd(response, other_data) {
14735	var contentHtml = $j(response).find('.col-main').html();
14736	if(contentHtml != null && contentHtml != '') {
14737		$j('#fabox-1').fabox('write', {content: '<div style="padding: 20px;">' + contentHtml + '</div>', width: 600, open: true, mode_closebox: 'center'});
14738	}
14739	else {
14740		errorForgottenPasswd(response, other_data);
14741	}
14742}
14743
14744function errorForgottenPasswd(response, other_data) {
14745	other_data_json = JSON.parse(other_data);
14746	if(other_data_json != null && other_data_json.urlError != null && other_data_json.urlError != '') {
14747		document.location.href = other_data_json.urlError;
14748	}
14749	else {
14750		window.location.reload();
14751	}
14752}
14753
14754function successLogin(response, other_data) {
14755	var contentHtml = $j(response).find('.messages').html();
14756	if(contentHtml != null && contentHtml != '') {
14757		contentHtml = strip_tags(contentHtml, '<a>');
14758		$j('#fabox-1').fabox('alert', {title: contentHtml, msg: '', mode_closebox: 'center'});
14759	}
14760	else {
14761		errorLogin(response, other_data);
14762	}
14763}
14764
14765function errorLogin(response, other_data) {
14766	window.location.reload();
14767}
14768
14769function successContact(response, other_data) {
14770	var contentHtml = strip_tags($j(response).find('.messages').html(), '<a>');
14771	if(contentHtml != null && contentHtml != '') {
14772		$j('#fabox-1').fabox('alert', {title: contentHtml, msg: '', mode_closebox: 'center'});
14773		__refreshCAPTCHA('.btn_refresh_captcha');
14774		if(contentHtml.match(/merci/gi) || contentHtml.match(/thank/gi)) {
14775			$j('#contactForm').find("input[type=text], textarea").val("");
14776			$j('#contactForm').find("select").val(1);
14777			changeWhoContact(1);
14778		}
14779	}
14780	else {
14781		errorLogin(response, other_data);
14782	}
14783}
14784
14785function errorContact(response, other_data) {
14786	window.location.reload();
14787}
14788
14789function successSubscribeNewsletter(response, other_data) {
14790	var contentHtml = $j(response).find('.messages').html();
14791	if(contentHtml != null && contentHtml != '') {
14792		contentHtml = strip_tags(contentHtml, '<a>');
14793		$j('#fabox-1').fabox('alert', {title: contentHtml, msg: '', mode_closebox: 'center'});
14794		if(contentHtml.match(/merci/gi) || contentHtml.match(/thank/gi)) {
14795			$j('#newsletter').val('');
14796		}
14797	}
14798	else {
14799		errorSubscribeNewsletter(response, other_data);
14800	}
14801}
14802
14803function errorSubscribeNewsletter(response, other_data) {
14804	window.location.reload();
14805}
14806
14807function successCart(response, other_data) {
14808	var contentHtml = $j(response).find('.page').html();
14809	if(contentHtml != null && contentHtml != '') {
14810		$j('.page').html(contentHtml);
14811	}
14812	else {
14813		errorSubscribeNewsletter(response, other_data);
14814	}
14815}
14816
14817function errorCart(response, other_data) {
14818	window.location.reload();
14819}
14820
14821function successCartCoupon(response, other_data) {
14822	console.log(response);
14823	var contentHtml = $j(response).find('.messages').html();
14824	if(contentHtml != null && contentHtml != '') {
14825		contentHtml = strip_tags(contentHtml, '<a>');
14826		if(contentHtml.match(/a été appliqué/gi) || contentHtml.match(/a été annulé/gi)) {
14827			var contentHtmlPage = $j(response).find('.page').html();
14828			if(contentHtmlPage != null && contentHtmlPage != '') {
14829				$j('.page').html(contentHtmlPage);
14830				$j('.page').find('.messages').hide();
14831				$j('.btn-update').trigger('click');
14832			}
14833			else {				
14834				errorCartCoupon(response, other_data);
14835			}
14836		}
14837		$j('#fabox-1').fabox('alert', {title: contentHtml, msg: '', mode_closebox: 'center'});
14838	}
14839	else {
14840		errorLogin(response, other_data);
14841	}
14842}
14843
14844function errorCartCoupon(response, other_data) {
14845	window.location.reload();
14846}
14847
14848function successArticleFidelity(response, other_data) {
14849	var contentHtml = $j(response).find('.col-main').html();
14850	if(contentHtml != null && contentHtml != '') {
14851		$j('#fabox-1').fabox('write', {content: '<div style="padding: 20px;">' + contentHtml + '</div>', width: 600, open: true, mode_closebox: 'center'});
14852	}
14853	else {
14854		errorArticleFidelity(response, other_data);
14855	}
14856}
14857
14858function errorArticleFidelity(response, other_data) {
14859	other_data_json = JSON.parse(other_data);
14860	if(other_data_json != null && other_data_json.urlError != null && other_data_json.urlError != '') {
14861		document.location.href = other_data_json.urlError;
14862	}
14863	else {
14864		window.location.reload();
14865	}
14866}
14867var timerMagnifizerAgeMin = null;
14868var timerMagnifizerPager = null;
14869
14870$j(document).ready(function() {
14871	
14872	if($j('.amshopby-attr').length > 0 || $j('.amshopby-attr-selected').length > 0) {
14873		magnifizerFilter(true);
14874		window.clearInterval(timerMagnifizerAgeMin);
14875		timerMagnifizerAgeMin = window.setInterval(function() {
14876			magnifizerFilter(false);
14877		}, 500);
14878	}
14879	
14880	if($j('.a-open-slide-accordion').length > 0) {
14881		autoBindSlideAcordionCategory();
14882	}
14883	
14884	if($j('#toolbar-pager').length > 0) {
14885		magnifizerPager();
14886		window.clearInterval(timerMagnifizerPager);
14887		timerMagnifizerPager = window.setInterval(function() {
14888			magnifizerPager(false);
14889		}, 200);
14890	}
14891	
14892});
14893
14894function magnifizerPager() {
14895	$j('#toolbar-pager li').each(function(k, v) {
14896		var strhtml = parseInt($j(v).text());
14897		if(!isNaN(strhtml) && strhtml > 0) {
14898			$j(v).addClass('page-item');
14899		}
14900	});
14901}
14902
14903function autoBindSlideAcordionCategory() {
14904	$j('.a-open-slide-accordion').unbind('click');
14905	
14906	$j('.a-open-slide-accordion').bind('click', function() {
14907		if ($j('.slide-accordion').hasClass('opened')) {
14908			$j('.slide-accordion').removeClass('opened');
14909			$j('.slide-accordion').slideUp(200);
14910			$j('.a-open-slide-accordion').show();
14911			$j('.a-open-slide-accordion.btn-hide').hide();
14912		}
14913		else {
14914			$j('.slide-accordion').addClass('opened');
14915			$j('.slide-accordion').slideDown(200);
14916			$j('.a-open-slide-accordion').hide();
14917			$j('.a-open-slide-accordion.btn-hide').show().css('display', 'block');
14918		}
14919	});
14920	
14921	closeSlideAcordionCategory();
14922}
14923
14924function closeSlideAcordionCategory() {
14925	$j('.slide-accordion').removeClass('opened');
14926	$j('.slide-accordion').hide();
14927	$j('.a-open-slide-accordion').show();
14928	$j('.a-open-slide-accordion.btn-hide').hide();	
14929}
14930
14931function magnifizerFilter(firstCall) {
14932	$j('.amshopby-attr').each(function(k, v) {
14933		if($j(v).text() == '0+' || $j(v).text() == '1+' || $j(v).text() == '2+' || $j(v).text() == '3+' ||
14934		   $j(v).text() == '4+' || $j(v).text() == '5+' || $j(v).text() == '6+' || $j(v).text() == '7+' ||
14935		   $j(v).text() == '8+' || $j(v).text() == '9+' || $j(v).text() == '10+' || $j(v).text() == '11+' ||
14936		   $j(v).text() == '12+' || $j(v).text() == '13+' || $j(v).text() == '14+' || $j(v).text() == '15+') {
14937			var replaceHtml = '<span class="macaron mi-stack macaron-bordered">' +
14938									'<i class="mi mi-stack-2x meccano-macaron macaron-' + getColorByMinimumAgeJS($j(v).text()) + '"></i>' +
14939									'<span class="mi mi-stack-1x macaron-text animate">' + $j(v).text().replace('+', '') + '<sup>+</sup></span>' +
14940								'</span>';
14941		    $j(v).html(replaceHtml);
14942		}
14943	});
14944	
14945	$j('.amshopby-attr-selected').each(function(k, v) {
14946		if($j(v).text() == '0+' || $j(v).text() == '1+' || $j(v).text() == '2+' || $j(v).text() == '3+' ||
14947		   $j(v).text() == '4+' || $j(v).text() == '5+' || $j(v).text() == '6+' || $j(v).text() == '7+' ||
14948		   $j(v).text() == '8+' || $j(v).text() == '9+' || $j(v).text() == '10+' || $j(v).text() == '11+' ||
14949		   $j(v).text() == '12+' || $j(v).text() == '13+' || $j(v).text() == '14+' || $j(v).text() == '15+') {
14950			var replaceHtml = '<span class="macaron mi-stack mi-inverse macaron-bordered">' +
14951									'<i class="mi mi-stack-2x meccano-macaron macaron-' + getColorByMinimumAgeJS($j(v).text()) + '"></i>' +
14952									'<span class="mi mi-stack-1x macaron-text">' + $j(v).text().replace('+', '') + '<sup>+</sup></span>' +
14953								'</span>';
14954		    $j(v).html(replaceHtml);
14955		}
14956	});
14957	
14958	$j('.block-layered-nav .currently .btn-remove-inline').each(function(k, v) {
14959		$j(v).children().remove();
14960	});
14961	
14962	/*if(firstCall) {
14963		var ddAge = $j('#narrow-by-list .macaron').parent().parent().parent().parent().clone();
14964		var dtAge = $j('#narrow-by-list .macaron').parent().parent().parent().parent().prev().clone();
14965		$j('#narrow-by-list .macaron').parent().parent().parent().parent().prev().remove();
14966		$j('#narrow-by-list .macaron').parent().parent().parent().parent().remove();
14967		$j('#narrow-by-list').append('<dt class="odd">' + $j(dtAge).html() + '</dt><dd class="odd">' + $j(ddAge).html() + '</dd>');	
14968	}*/
14969	$j('#narrow-by-list .macaron').parent().parent().parent().parent().removeClass('filter-age');
14970	$j('#narrow-by-list .macaron').parent().parent().parent().parent().addClass('filter-age');
14971	$j('.amshopby-filters-left .block-subtitle.block-subtitle--filter').remove();
14972}
14973var who_contact = 1;
14974
14975
14976$j(document).ready(function() {
14977		
14978	if($j('#contactForm').length > 0) {
14979		bindContactFormPage();
14980	}
14981	
14982});
14983
14984function __refreshCAPTCHA(elt) {
14985	$j(elt).children().addClass('fa-spin');
14986	var srcImg = $j(elt).parent().parent().parent().find('img').attr('src');
14987	if(srcImg.indexOf('?') != -1) {
14988		var sep = '&';
14989	}
14990	else {
14991		var sep = '?';
14992	}
14993	$j(elt).parent().parent().parent().find('img').attr('src', srcImg + sep + Math.random());
14994	window.setTimeout(function() {
14995		$j(elt).children().removeClass('fa-spin');
14996	}, 1000);
14997}
14998
14999function changeForm() {
15000	if (who_contact == 1) {
15001		$j('.order_id').hide();
15002		$j('#order_id').val('');
15003	}
15004	else if (who_contact == 2) {
15005		$j('.order_id').show();
15006	}
15007	else if (who_contact == 3) {
15008		$j('.order_id').hide();
15009		$j('#order_id').val('');
15010	}
15011}
15012
15013function bindContactFormPage() {
15014	$j('.who_contact').bind('change', function() {
15015		who_contact = $j(this).val();
15016		changeForm();
15017	});
15018}
15019
15020function changeWhoContact(num) {
15021	who_contact = num;
15022	changeForm();
15023}
15024$j(document).ready(function() {
15025	
15026	$j('#filter-notice-range').unbind('change');
15027	$j('#filter-notice-range').bind('change', function() {
15028		filterNoticeByRange($j(this).val());
15029	});
15030	
15031});
15032
15033function filterNoticeByRange(val) {
15034	$j('.row-notice .product-block').each(function(k, v) {
15035        window.setTimeout(function() {
15036            $j(v).show();
15037        }, 200);
15038        $j(v).addClass('js-hidden');
15039        window.setTimeout(function() {
15040            $j(v).hide();
15041            if ($j(v).attr('gamme') == val || val == 'null') {
15042                $j(v).show();
15043                $j(v).removeClass('js-hidden');
15044            }
15045        }, 500);
15046    });	
15047}
15048$j(document).ready(function() {
15049		
15050	$j('.btn-empty').unbind('click');
15051	$j('.btn-empty').bind('click', function(e) {
15052		e.preventDefault();
15053		$j('input.qty').each(function(k, v) {
15054			$j(v).val(0);
15055		});
15056		window.setTimeout(function() {
15057			$j('.btn-update').trigger('click');
15058		}, 100);
15059	});
15060
15061	if ($j('#shopping-cart-table').size() > 0) {
15062		$j('.btn-update').trigger('click');
15063	}
15064		
15065});
15066
15067function chQtyItemCart(opt, id) {
15068	var newVal = 1;
15069	var oldVal = parseInt($j('#' + id).val());
15070	var incrementQty = parseInt($j('#' + id).attr('data-qty-step'));
15071	switch(opt) {
15072		case 0:
15073			// Moins
15074			if($j('#' + id).val() > 0) {
15075				newVal = parseInt(oldVal - incrementQty);
15076			}
15077			else {
15078				newVal = 0;
15079			}
15080		break;
15081		case 1:
15082			// Plus
15083			newVal = parseInt(oldVal + incrementQty);
15084		break;
15085	}
15086	if(oldVal != newVal) {	
15087		$j('#' + id).val(parseInt(newVal));
15088		window.setTimeout(function() {
15089			$j('.btn-update').trigger('click');
15090		}, 50);
15091	}
15092}
15093
15094function openBoxAgreementsError(msg) {
15095    $j('#fabox-1').fabox('alert', {msg: '', title: msg, mode_closebox: 'center'});
15096}
15097
15098function removeItemFromCart( id ) {
15099	$j( '#qty-cart-item-' + id ).val( 0 );
15100	window.setTimeout( function() {
15101		$j( '.button2.btn-update' ).trigger( 'click' );
15102	}, 10 );
15103}

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.