/*** Start of file: jquery/1_jquery.js ***/
/*jsl:ignore*/
/*!
 * jQuery JavaScript Library v1.4.2
 * http://jquery.com/
 *
 * Copyright 2010, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 * Copyright 2010, The Dojo Foundation
 *  Released under the MIT, BSD, and GPL Licenses.
 *
 * Date: Sat Feb 13 22:33:48 2010 -0500
 */
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML="   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.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".split(" "),
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
/*jsl:end*//*** End of file: jquery/1_jquery.js ***/
/*** Start of file: jquery/1_jquery-patch.js ***/
/*
 * Patch for the jQuery JavaScript Library v1.4.2
 * http://jquery.com/
 *
 * This patch resolves issue #6180, where a missing check for script tags' MIME content-type
 * makes script-island based techniques unstable due to the tags being potentially removed
 * from the DOM if they or one of their ancestor nodes are subject to a DOM manipulation
 * by jQuery.
 * http://dev.jquery.com/ticket/6180
 *
 * (Date: 2010-05-07 10:20:00 +0100 (Fri, 07 May 2010)
 */
(function(jQuery){if(typeof jQuery==="undefined"){return;}if(typeof jQuery.clean==="function"){var rinlinejQuery=/ jQuery\d+="(?:\d+|null)"/g,rleadingWhitespace=/^\s+/,rxhtmlTag=/(<([\w:]+)[^>]*?)\/>/g,rselfClosing=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,rtagName=/<([\w:]+)/,rtbody=/<tbody/i,rhtml=/<|&#?\w+;/,rnocache=/<script|<object|<embed|<option|<style/i,rchecked=/checked\s*(?:[^=]|=\s*.checked.)/i,fcloseTag=function(all,front,tag){return rselfClosing.test(tag)?all:front+"></"+tag+">";},wrapMap={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};wrapMap.optgroup=wrapMap.option;wrapMap.tbody=wrapMap.tfoot=wrapMap.colgroup=wrapMap.caption=wrapMap.thead;wrapMap.th=wrapMap.td;if(!jQuery.support.htmlSerialize){wrapMap._default=[1,"div<div>","</div>"];}jQuery.clean=function(elems,context,fragment,scripts){context=context||document;if(typeof context.createElement==="undefined"){context=context.ownerDocument||context[0]&&context[0].ownerDocument||document;}var ret=[];for(var i=0,elem;(elem=elems[i])!=null;i++){if(typeof elem==="number"){elem+="";}if(!elem){continue;}if(typeof elem==="string"&&!rhtml.test(elem)){elem=context.createTextNode(elem);}else{if(typeof elem==="string"){elem=elem.replace(rxhtmlTag,fcloseTag);var tag=(rtagName.exec(elem)||["",""])[1].toLowerCase(),wrap=wrapMap[tag]||wrapMap._default,depth=wrap[0],div=context.createElement("div");div.innerHTML=wrap[1]+elem+wrap[2];while(depth--){div=div.lastChild;}if(!jQuery.support.tbody){var hasBody=rtbody.test(elem),tbody=tag==="table"&&!hasBody?div.firstChild&&div.firstChild.childNodes:wrap[1]==="<table>"&&!hasBody?div.childNodes:[];for(var j=tbody.length-1;j>=0;--j){if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length){tbody[j].parentNode.removeChild(tbody[j]);}}}if(!jQuery.support.leadingWhitespace&&rleadingWhitespace.test(elem)){div.insertBefore(context.createTextNode(rleadingWhitespace.exec(elem)[0]),div.firstChild);}elem=div.childNodes;}}if(elem.nodeType){ret.push(elem);}else{ret=jQuery.merge(ret,elem);}}if(fragment){for(var i=0;ret[i];i++){if(scripts&&jQuery.nodeName(ret[i],"script")&&(!ret[i].type||ret[i].type.toLowerCase()==="text/javascript")){scripts.push(ret[i].parentNode?ret[i].parentNode.removeChild(ret[i]):ret[i]);}else{if(ret[i].nodeType===1){var scripts=$.grep(ret[i].getElementsByTagName("script"),function(node,index){return node.type.toLowerCase()==="text/javascript";});ret.splice.apply(ret,[i+1,0].concat(jQuery.makeArray(scripts)));}fragment.appendChild(ret[i]);}}}return ret;};}})(window.jQuery);/*** End of file: jquery/1_jquery-patch.js ***/
/*** Start of file: jquery/2_jquery-bgiframe.js ***/
/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
 * Licensed under the MIT License (LICENSE.txt).
 *
 * Version 2.1.2
 */

(function($){

$.fn.bgiframe = ($.browser.msie && /msie 6\.0/i.test(navigator.userAgent) ? function(s) {
    s = $.extend({
        top     : 'auto', // auto == .currentStyle.borderTopWidth
        left    : 'auto', // auto == .currentStyle.borderLeftWidth
        width   : 'auto', // auto == offsetWidth
        height  : 'auto', // auto == offsetHeight
        opacity : true,
        src     : 'javascript:false;'
    }, s);
    var html = '<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+
                   'style="display:block;position:absolute;z-index:-1;'+
                       (s.opacity !== false?'filter:Alpha(Opacity=\'0\');':'')+
                       'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+
                       'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+
                       'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+
                       'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+
                '"/>';
    return this.each(function() {
        if ( $(this).children('iframe.bgiframe').length === 0 )
            this.insertBefore( document.createElement(html), this.firstChild );
    });
} : function() { return this; });

// old alias
$.fn.bgIframe = $.fn.bgiframe;

function prop(n) {
    return n && n.constructor === Number ? n + 'px' : n;
}

})(jQuery);/*** End of file: jquery/2_jquery-bgiframe.js ***/
/*** Start of file: jquery/3_jquery-cookie.js ***/
/*jslint browser: true */ /*global jQuery: true */

/**
 * jQuery Cookie plugin
 *
 * Copyright (c) 2010 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

// TODO JsDoc

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

/**
 * Get the value of a cookie with the given key.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String key The key of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.cookie = function (key, value, options) {

    // key and value given, set cookie...
    if (arguments.length > 1 && (value === null || typeof value !== "object")) {
        options = jQuery.extend({}, options);

        if (value === null) {
            options.expires = -1;
        }

        if (typeof options.expires === 'number') {
            var days = options.expires, t = options.expires = new Date();
            t.setDate(t.getDate() + days);
        }

        return (document.cookie = [
            encodeURIComponent(key), '=',
            options.raw ? String(value) : encodeURIComponent(String(value)),
            options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
            options.path ? '; path=' + options.path : '',
            options.domain ? '; domain=' + options.domain : '',
            options.secure ? '; secure' : ''
        ].join(''));
    }

    // key and possibly options given, get cookie...
    options = value || {};
    var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
    return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
};
/*** End of file: jquery/3_jquery-cookie.js ***/
/*** Start of file: jquery/3_jquery-query.js ***/
/**
 * jQuery.query - Query String Modification and Creation for jQuery
 * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)
 * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
 * Date: 2009/8/13
 *
 * @author Blair Mitchelmore
 * @version 2.1.6
 *
 **/
new function(settings) { 
  // Various Settings
  var $separator = settings.separator || '&';
  var $spaces = settings.spaces === false ? false : true;
  var $suffix = settings.suffix === false ? '' : '[]';
  var $prefix = settings.prefix === false ? false : true;
  var $hash = $prefix ? settings.hash === true ? "#" : "?" : "";
  var $numbers = settings.numbers === false ? false : true;
  
  jQuery.query = new function() {
    var is = function(o, t) {
      return o != undefined && o !== null && (!!t ? o.constructor == t : true);
    };
    var parse = function(path) {
      // NOTE: Regular expression adjusted due to a bug with Safari 3.
      // Original:/\[([^[]*)\]/g, match = /^([^[]+?)(\[.*\])?$/
      var m, rx = /\[([^[]*)\]/g, match = /^([^[]+)?(\[.*\])?$/.exec(path), base = match[1], tokens = [];
      while (m = rx.exec(match[2])) tokens.push(m[1]);
      return [base, tokens];
    };
    var set = function(target, tokens, value) {
      var o, token = tokens.shift();
      if (typeof target != 'object') target = null;
      if (token === "") {
        if (!target) target = [];
        if (is(target, Array)) {
          target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
        } else if (is(target, Object)) {
          var i = 0;
          while (target[i++] != null);
          target[--i] = tokens.length == 0 ? value : set(target[i], tokens.slice(0), value);
        } else {
          target = [];
          target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
        }
      } else if (token && token.match(/^\s*[0-9]+\s*$/)) {
        var index = parseInt(token, 10);
        if (!target) target = [];
        target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
      } else if (token) {
        var index = token.replace(/^\s*|\s*$/g, "");
        if (!target) target = {};
        if (is(target, Array)) {
          var temp = {};
          for (var i = 0; i < target.length; ++i) {
            temp[i] = target[i];
          }
          target = temp;
        }
        target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
      } else {
        return value;
      }
      return target;
    };
    
    var queryObject = function(a) {
      var self = this;
      self.keys = {};
      
      if (a.queryObject) {
        jQuery.each(a.get(), function(key, val) {
          self.SET(key, val);
        });
      } else {
        jQuery.each(arguments, function() {
          var q = "" + this;
          q = q.replace(/^[?#]/,''); // remove any leading ? || #
          q = q.replace(/[;&]$/,''); // remove any trailing & || ;
          if ($spaces) q = q.replace(/[+]/g,' '); // replace +'s with spaces
          
          jQuery.each(q.split(/[&;]/), function(){
            var key = decodeURIComponent(this.split('=')[0] || "");
            var val = decodeURIComponent(this.split('=')[1] || "");
            
            if (!key) return;
            
            if ($numbers) {
              if (/^[+-]?[0-9]+\.[0-9]*$/.test(val)) // simple float regex
                val = parseFloat(val);
              else if (/^[+-]?[0-9]+$/.test(val)) // simple int regex
                val = parseInt(val, 10);
            }
            
            val = (!val && val !== 0) ? true : val;
            
            if (val !== false && val !== true && typeof val != 'number')
              val = val;
            
            self.SET(key, val);
          });
        });
      }
      return self;
    };
    
    queryObject.prototype = {
      queryObject: true,
      has: function(key, type) {
        var value = this.get(key);
        return is(value, type);
      },
      GET: function(key) {
        if (!is(key)) return this.keys;
        var parsed = parse(key), base = parsed[0], tokens = parsed[1];
        var target = this.keys[base];
        while (target != null && tokens.length != 0) {
          target = target[tokens.shift()];
        }
        return typeof target == 'number' ? target : target || "";
      },
      get: function(key) {
        var target = this.GET(key);
        if (is(target, Object))
          return jQuery.extend(true, {}, target);
        else if (is(target, Array))
          return target.slice(0);
        return target;
      },
      SET: function(key, val) {
        var value = !is(val) ? null : val;
        var parsed = parse(key), base = parsed[0], tokens = parsed[1];
        var target = this.keys[base];
        this.keys[base] = set(target, tokens.slice(0), value);
        return this;
      },
      set: function(key, val) {
        return this.copy().SET(key, val);
      },
      REMOVE: function(key) {
        return this.SET(key, null).COMPACT();
      },
      remove: function(key) {
        return this.copy().REMOVE(key);
      },
      EMPTY: function() {
        var self = this;
        jQuery.each(self.keys, function(key, value) {
          delete self.keys[key];
        });
        return self;
      },
      load: function(url) {
        var hash = url.replace(/^.*?[#](.+?)(?:\?.+)?$/, "$1");
        var search = url.replace(/^.*?[?](.+?)(?:#.+)?$/, "$1");
        return new queryObject(url.length == search.length ? '' : search, url.length == hash.length ? '' : hash);
      },
      empty: function() {
        return this.copy().EMPTY();
      },
      copy: function() {
        return new queryObject(this);
      },
      COMPACT: function() {
        function build(orig) {
          var obj = typeof orig == "object" ? is(orig, Array) ? [] : {} : orig;
          if (typeof orig == 'object') {
            function add(o, key, value) {
              if (is(o, Array))
                o.push(value);
              else
                o[key] = value;
            }
            jQuery.each(orig, function(key, value) {
              if (!is(value)) return true;
              add(obj, key, build(value));
            });
          }
          return obj;
        }
        this.keys = build(this.keys);
        return this;
      },
      compact: function() {
        return this.copy().COMPACT();
      },
      toString: function() {
        var i = 0, queryString = [], chunks = [], self = this;
        var encode = function(str) {
          str = str + "";
          if ($spaces) str = str.replace(/ /g, "+");
          return encodeURIComponent(str);
        };
        var addFields = function(arr, key, value) {
          if (!is(value) || value === false) return;
          var o = [encode(key)];
          if (value !== true) {
            o.push("=");
            o.push(encode(value));
          }
          arr.push(o.join(""));
        };
        var build = function(obj, base) {
          var newKey = function(key) {
            return !base || base == "" ? [key].join("") : [base, "[", key, "]"].join("");
          };
          jQuery.each(obj, function(key, value) {
            if (typeof value == 'object') 
              build(value, newKey(key));
            else
              addFields(chunks, newKey(key), value);
          });
        };
        
        build(this.keys);
        
        if (chunks.length > 0) queryString.push($hash);
        queryString.push(chunks.join($separator));
        
        return queryString.join("");
      }
    };
    
    return new queryObject(location.search, location.hash);
  };
}(jQuery.query || {}); // Pass in jQuery.query as settings object/*** End of file: jquery/3_jquery-query.js ***/
/*** Start of file: jquery/3_jquery-jHelperTip.1.0.js ***/
/* Copyright (c) 2008 Kean Loong Tan http://www.gimiti.com/kltan
 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * Copyright notice and license must remain intact for legal use
 * jHelpertip
 * Version: 1.0 (Jun 2, 2008)
 * Requires: jQuery 1.2+
 */
/*jsl:ignore*/



var jHelperTipExtensions = function($) {
	var priv = {
		renderedHovers: new Array()
	};
	return {
		AddRenderedHover: function(id, content) {
			priv.renderedHovers[id] = content;
		},
		
		GetRenderedHover: function(id) {
			return priv.renderedHovers[id];
		}
	};
} (jQuery);

(function($) {

	var priv = {
		currentId: -1
	};

    $.fn.jHelperTip = function(options) {
        // merge users option with default options
        var opts = $.extend({}, $.fn.jHelperTip.defaults, options);

        // default actions
        // create a ttC is not found
        if ($(opts.ttC).length == 0)
            $('<div id="' + opts.ttC.slice(1) + '"></div>').appendTo("body");

        // create a dC is not found
        if ($(opts.dC).length == 0)
            $('<div id="' + opts.dC.slice(1) + '"></div>').appendTo("body");

        if ($(opts.aC).length == 0)
            $('<div id="' + opts.aC.slice(1) + '"></div>').appendTo("body");

        var pos = "absolute";
        if (opts.position == "static")
            pos = "fixed";

        // initialize our tooltip and our data container and also the close box    
        $(opts.ttC).add(opts.aC).css({
            position: pos,
            display: "inline"
        }).hide();

        $(opts.dC).hide();

        // close the tooltip box
        var closeBox = function() {
            $('a.btnSelectDate').css({ color: '#333' });
            if (opts.source == "attribute") {
                $(opts.aC).hide().empty();
            } else {
                if (opts.initializeOnce && $(opts.ttC).hasClass('initialized')) {
                    $(opts.ttC).hide();
                } else {
                    $(opts.ttC).hide().empty();
                }
            }
        };

        $(".jHelperTipClose").bind("click", closeBox);

        $(opts.ttC).bind("mouseover", function() {
            $(opts.ttC).show();
            return false;
        });

        // the sources of getting data
        var getData = function(obj, e) {
            if (opts.source == "ajax") {
				priv.currentId = opts.locationId;
                getPosition(e, true);
                if (opts.loadingImg != "" | opts.loadingText != "") {
                    $(opts.ttC).html('<div class="loadcontent"><img src="' + opts.loadingImg + '" class="loadimg"/> ' + opts.loadingText + '</div>').show();
                }

				if (jHelperTipExtensions.GetRenderedHover(opts.locationId) != null) {
					$(opts.ttC).html(jHelperTipExtensions.GetRenderedHover(opts.locationId));
				}
				else {
                $.ajax({
                    type: opts.type,
                    url: opts.url,
						cache: true,
                    data: opts.data,
                    success: function(msg) {
							// don't process any further when result of request doesn't belong to last request.
							if (opts.locationId != priv.currentId) {
								return;
							}
							
                        $(opts.ttC).html(msg);
                        // reInitialize the close controller
                        $(".jHelperTipClose").unbind("click", closeBox);
                        $(".jHelperTipClose").bind("click", closeBox);
                        getPosition(e, false);

							if (opts.onShowCallback != null) {
								opts.onShowCallback(opts.locationId, msg);
                    }
						}
                });
				}
            } else if (opts.source == "container") {
                if (opts.initializeOnce) {
                    if (!$(opts.ttC).hasClass('initialized')) {
                        $(opts.dC).show().appendTo($(opts.ttC));
                        $(opts.ttC).addClass('initialized');
                        $(opts.ttC).show();
                    } else {
                        $(opts.ttC).show();
                    }
                } else {
                    $(opts.ttC).show().empty();
                    $(opts.dC).clone(true).show().appendTo(opts.ttC);
                }
            }

            if (opts.source == "attribute") {
                $(opts.aC).html($(obj).attr(opts.attrName));
            }
        };

        // show the tooltip
        var showTooltip = function(box) {
            $(box).show();

			var msie6 = ($.browser.msie && typeof (XMLHttpRequest) == "undefined" && (/MSIE 6\.0/i.test(window.navigator.userAgent)) && !(/MSIE 7\.0/i.test(window.navigator.userAgent)) && !(/MSIE 8\.0/i.test(window.navigator.userAgent)));
			if (msie6 && $.fn.bgIframe) {
                $(box).bgIframe();
            }
        };

        // used to position the tooltip, optionally also shows it
        var getPosition = function(e, doShow) {

            var top = opts.topOff;
            var left = opts.leftOff;
            var box = (opts.source == "attribute") ? opts.aC : opts.ttC;
            if (opts.position == "dynamic") {
                top = e.pageY + opts.topOff;
                left = e.pageX + opts.leftOff;

                var height = $(box).height();
                var winheight = $(window).height();
                if (top - $(window).scrollTop() + height > winheight) {
                    if (top - $(window).scrollTop() >= height) {
                        top = top - height;
                    }
                    else {
                        if (winheight > height) {
                            top = (winheight - height) / 2 + $(window).scrollTop();
                        }
                        else {
                            top = 0 + $(window).scrollTop();
                        }
                    }
                }
            }

            $(box).css({
                top: top,
                left: left
            });

            if (doShow) {
                showTooltip(box);
            }
        };

        // just close tool tip when not needed usually trigger by anything outside out tooltip target
        if (opts.trigger == "hover") {
            $(this).bind("mouseover", function(e) {
                e.preventDefault();
                getData(this, e);
                return false;
            });
            $(this).bind("mousemove", function(e) {
                getPosition(e, true);
                return false;
            });

            $(this).bind("mouseout", function(e) {
                if (opts.autoClose) {
                    if (opts.source == "attribute")
                        $(opts.aC).hide().empty();
                    else
                        $(opts.ttC).hide().empty();
                }
                return false;
            });
        } else if (opts.trigger == "click") {
            $(this).bind("click", function(e) {
                getData(this, e);
                getPosition(e, true);
                $(document).bind("click", function(e) {
                    if (opts.autoClose) {
                        if ($(e.target).parents().filter(opts.ttC).length <= 0) {
                            closeBox();
                        }
                    }
                });

                return false;
            });

        }
    };

    $.fn.jHelperTip.defaults = {
        trigger: "click",
        topOff: 3,
        leftOff: 10,
        source: "container", /* attribute, container, ajax */
		initializeOnce: true,
        attrName: '',
        position: "dynamic", /* Can be 'static' or 'dynamic' */
        ttC: "#jHelperTipContainer", /* tooltip Container*/
        dC: "#jHelperTipDataContainer", /* data Container */
        aC: "#jHelperTipAttrContainer", /* attr Container */
        opacity: 1.0,
        loadingImg: "ajax-loader.gif",
        loadingText: "Loading...",
        type: "GET", /* data can be inline or CSS selector */
        //url: '',
        //data: '',
		autoClose: true,
		onShowCallback: null,
		locationId: -1
    };
})(jQuery);


/*jsl:end*//*** End of file: jquery/3_jquery-jHelperTip.1.0.js ***/
/*** Start of file: jquery/4_jquery.autocomplete.js ***/
/*
* jQuery Autocomplete plugin 1.1
*
* Copyright (c) 2009 JÃ¶rn Zaefferer
*
* Dual licensed under the MIT and GPL licenses:
*   http://www.opensource.org/licenses/mit-license.php
*   http://www.gnu.org/licenses/gpl.html
*
* Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $
*/




; (function($) {

	$.fn.extend({
		autocomplete: function(urlOrData, options) {
			var isUrl = typeof urlOrData == "string";
			options = $.extend({}, $.Autocompleter.defaults, {
				url: isUrl ? urlOrData : null,
				data: isUrl ? null : urlOrData,
				delay: isUrl ? $.Autocompleter.defaults.delay : 10,
				max: options && !options.scroll ? 10 : 150
			}, options);

			// if highlight is set to false, replace it with a do-nothing function
			options.highlight = options.highlight || function(value) { return value; };

			// if the formatMatch option is not specified, then use formatItem for backwards compatibility
			options.formatMatch = options.formatMatch || options.formatItem;

			return this.each(function() {
				new $.Autocompleter(this, options);
			});
		},
		result: function(handler) {
			return this.bind("result", handler);
		},
		search: function(handler) {
			return this.trigger("search", [handler]);
		},
		flushCache: function() {
			return this.trigger("flushCache");
		},
		setOptions: function(options) {
			return this.trigger("setOptions", [options]);
		},
		unautocomplete: function() {
			return this.trigger("unautocomplete");
		}
	});

	$.Autocompleter = function(input, options) {

		var KEY = {
			UP: 38,
			DOWN: 40,
			DEL: 46,
			TAB: 9,
			RETURN: 13,
			ESC: 27,
			COMMA: 188,
			PAGEUP: 33,
			PAGEDOWN: 34,
			BACKSPACE: 8
		};

		// Create $ object for input element
		var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);

		var timeout;
		var previousValue = "";
		var cache = $.Autocompleter.Cache(options);
		var hasFocus = 0;
		var lastKeyPressCode;
		var config = {
			mouseDownOnSelect: false
		};
		var select = $.Autocompleter.Select(options, input, selectCurrent, config);
		var lastAjaxRequest = null;
		var blockSubmit;

		// prevent form submit in opera when selecting with return key
		$.browser.opera && $(input.form).bind("submit.autocomplete", function() {
			if (blockSubmit) {
				blockSubmit = false;
				return false;
			}
		});

		// only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
		$input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
			// a keypress means the input has focus
			// avoids issue where input had focus before the autocomplete was applied
			hasFocus = 1;
			// track last key pressed
			lastKeyPressCode = event.keyCode;
			switch (event.keyCode) {

				case KEY.UP:
					event.preventDefault();
					if (select.visible()) {
						select.prev();
					} else {
						onChange(0, true);
					}
					break;

				case KEY.DOWN:
					event.preventDefault();
					if (select.visible()) {
						select.next();
					} else {
						onChange(0, true);
					}
					break;

				case KEY.PAGEUP:
					event.preventDefault();
					if (select.visible()) {
						select.pageUp();
					} else {
						onChange(0, true);
					}
					break;

				case KEY.PAGEDOWN:
					event.preventDefault();
					if (select.visible()) {
						select.pageDown();
					} else {
						onChange(0, true);
					}
					break;

				// matches also semicolon 
				case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
				case KEY.TAB:
				case KEY.RETURN:
					if (selectCurrent()) {
						// stop default to prevent a form submit, Opera needs special handling
						event.preventDefault();
						blockSubmit = true;
						return false;
					}
					break;

				case KEY.ESC:
					select.hide();
					break;

				default:
					clearTimeout(timeout);
					timeout = setTimeout(onChange, options.delay);
					break;
			}
		}).focus(function() {
			// track whether the field has focus, we shouldn't process any
			// results if the field no longer has focus
			hasFocus++;
		}).blur(function() {
			hasFocus = 0;
			if (!config.mouseDownOnSelect) {
				hideResults();
			}
		}).click(function() {
			// show select when clicking in a focused field
			if (hasFocus++ > 1 && !select.visible()) {
				onChange(0, true);
			}
		}).bind("search", function() {
			// TODO why not just specifying both arguments?
			var fn = (arguments.length > 1) ? arguments[1] : null;
			function findValueCallback(q, data) {
				var result;
				if (data && data.length) {
					for (var i = 0; i < data.length; i++) {
						if (data[i].result.toLowerCase() == q.toLowerCase()) {
							result = data[i];
							break;
						}
					}
				}
				if (typeof fn == "function") fn(result);
				else $input.trigger("result", result && [result.data, result.value]);
			}
			$.each(trimWords($input.val()), function(i, value) {
				request(value, findValueCallback, findValueCallback);
			});
		}).bind("flushCache", function() {
			cache.flush();
		}).bind("setOptions", function() {
			$.extend(options, arguments[1]);
			// if we've updated the data, repopulate
			if ("data" in arguments[1])
				cache.populate();
		}).bind("unautocomplete", function() {
			select.unbind();
			$input.unbind();
			$(input.form).unbind(".autocomplete");
		});


		function selectCurrent() {
			var selected = select.selected();
			if (!selected)
				return false;

			var v = selected.result;
			previousValue = v;

			if (options.multiple) {
				var words = trimWords($input.val());
				if (words.length > 1) {
					var seperator = options.multipleSeparator.length;
					var cursorAt = $(input).selection().start;
					var wordAt, progress = 0;
					$.each(words, function(i, word) {
						progress += word.length;
						if (cursorAt <= progress) {
							wordAt = i;
							return false;
						}
						progress += seperator;
					});
					words[wordAt] = v;
					// TODO this should set the cursor to the right position, but it gets overriden somewhere
					//$.Autocompleter.Selection(input, progress + seperator, progress + seperator);
					v = words.join(options.multipleSeparator);
				}
				v += options.multipleSeparator;
			}

			$input.val(v);
			hideResultsNow();
			$input.trigger("result", [selected.data, selected.value]);
			return true;
		}

		function onChange(crap, skipPrevCheck) {
			if (lastKeyPressCode == KEY.DEL) {
				select.hide();
				return;
			}

			var currentValue = $input.val();

			if (!skipPrevCheck && currentValue == previousValue)
				return;

			previousValue = currentValue;

			currentValue = lastWord(currentValue);
			if (currentValue.length >= options.minChars) {
				toggleLoadingImage(false);
				$input.addClass(options.loadingClass);
				if (!options.matchCase)
					currentValue = currentValue.toLowerCase();
				request(currentValue, receiveData, hideResultsNow);
			} else {
				stopLoading();
				select.hide();
			}
		};

		function trimWords(value) {
			if (!value)
				return [""];
			if (!options.multiple)
				return [$.trim(value)];
			return $.map(value.split(options.multipleSeparator), function(word) {
				return $.trim(value).length ? $.trim(word) : null;
			});
		}

		function lastWord(value) {
			if (!options.multiple)
				return value;
			var words = trimWords(value);
			if (words.length == 1)
				return words[0];
			var cursorAt = $(input).selection().start;
			if (cursorAt == value.length) {
				words = trimWords(value)
			} else {
				words = trimWords(value.replace(value.substring(cursorAt), ""));
			}
			return words[words.length - 1];
		}

		// fills in the input box w/the first match (assumed to be the best match)
		// q: the term entered
		// sValue: the first matching result
		function autoFill(q, sValue) {
			// autofill in the complete box w/the first match as long as the user hasn't entered in more data
			// if the last user key pressed was backspace, don't autofill
			if (options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE) {
				// fill in the value (keep the case the user has typed)
				$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
				// select the portion of the value not typed by the user (so the next character will erase)
				$(input).selection(previousValue.length, previousValue.length + sValue.length);
			}
		};

		function hideResults() {
			clearTimeout(timeout);
			timeout = setTimeout(hideResultsNow, 200);
		};

		function hideResultsNow() {
			var wasVisible = select.visible();
			select.hide();
			clearTimeout(timeout);
			stopLoading();
			if (options.mustMatch) {
				// call search and run callback
				$input.search(
				function(result) {
					// if no value found, clear the input box
					if (!result) {
						if (options.multiple) {
							var words = trimWords($input.val()).slice(0, -1);
							$input.val(words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : ""));
						}
						else {
							$input.val("");
							$input.trigger("result", null);
						}
					}
				}
			);
			}
		};

		function receiveData(q, data) {
			if (data && data.length && hasFocus) {
				stopLoading();
				select.display(data, q);
				autoFill(q, data[0].value);
				select.show();
			} else {
				hideResultsNow();
			}
		};

		function request(term, success, failure) {
			if (!options.matchCase)
				term = term.toLowerCase();
			var data = cache.load(term);
			// recieve the cached data
			if (data && data.length) {
				success(term, data);
				// if an AJAX url has been supplied, try loading the data now
			} else if ((typeof options.url == "string") && (options.url.length > 0)) {

				var extraParams = {
					timestamp: +new Date()
				};
				$.each(options.extraParams, function(key, param) {
					extraParams[key] = typeof param == "function" ? param() : param;
				});
				//abort the last result if such a request is still running
				if (lastAjaxRequest) {
					lastAjaxRequest.abort();
					lastAjaxRequest = null;
				}

				lastAjaxRequest = $.ajax({					
					dataType: options.dataType,
					url: options.url,
					data: $.extend({
						q: lastWord(term),
						limit: options.max
					}, extraParams),
					success: function(data) {
						lastAjaxRequest = null;
						var parsed = options.parse && options.parse(data) || parse(data);
						cache.add(term, parsed);
						success(term, parsed);
					}
				});
			} else {
				// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
				select.emptyList();
				failure(term);
			}


		};

		function parse(data) {
			var parsed = [];
			var rows = data.split("\n");
			for (var i = 0; i < rows.length; i++) {
				var row = $.trim(rows[i]);
				if (row) {
					row = row.split("|");
					parsed[parsed.length] = {
						data: row,
						value: row[0],
						result: options.formatResult && options.formatResult(row, row[0]) || row[0]
					};
				}
			}
			return parsed;
		};

		function stopLoading() {
			toggleLoadingImage(true);
			$input.removeClass(options.loadingClass);
		};

		function toggleLoadingImage(hide) { if (options.loadImage) { options.loadImage.toggleLoadingImage(hide); } }

	};

	$.Autocompleter.defaults = {
		inputClass: "ac_input",
		resultsClass: "ac_results",
		loadingClass: "ac_loading",
		minChars: 1,
		delay: 400,
		matchCase: false,
		matchSubset: true,
		matchContains: false,
		cacheLength: 10,
		max: 100,
		mustMatch: false,
		extraParams: {},
		selectFirst: true,
		formatItem: function(row) { return row[0]; },
		formatMatch: null,
		autoFill: false,
		width: 0,
		multiple: false,
		multipleSeparator: ", ",
		highlight: function(value, term) {
			return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
		},
		scroll: true,
		scrollHeight: 180
	};

	$.Autocompleter.Cache = function(options) {

		var data = {};
		var length = 0;

		function matchSubset(s, sub) {
			if (!options.matchCase)
				s = s.toLowerCase();
			var i = s.indexOf(sub);
			if (options.matchContains == "word") {
				i = s.toLowerCase().search("\\b" + sub.toLowerCase());
			}
			if (i == -1) return false;
			return i == 0 || options.matchContains;
		};

		function add(q, value) {
			if (length > options.cacheLength) {
				flush();
			}
			if (!data[q]) {
				length++;
			}
			data[q] = value;
		}

		function populate() {
			if (!options.data) return false;
			// track the matches
			var stMatchSets = {},
			nullData = 0;

			// no url was specified, we need to adjust the cache length to make sure it fits the local data store
			if (!options.url) options.cacheLength = 1;

			// track all options for minChars = 0
			stMatchSets[""] = [];

			// loop through the array and create a lookup structure
			for (var i = 0, ol = options.data.length; i < ol; i++) {
				var rawValue = options.data[i];
				// if rawValue is a string, make an array otherwise just reference the array
				rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;

				var value = options.formatMatch(rawValue, i + 1, options.data.length);
				if (value === false)
					continue;

				var firstChar = value.charAt(0).toLowerCase();
				// if no lookup array for this character exists, look it up now
				if (!stMatchSets[firstChar])
					stMatchSets[firstChar] = [];

				// if the match is a string
				var row = {
					value: value,
					data: rawValue,
					result: options.formatResult && options.formatResult(rawValue) || value
				};

				// push the current match into the set list
				stMatchSets[firstChar].push(row);

				// keep track of minChars zero items
				if (nullData++ < options.max) {
					stMatchSets[""].push(row);
				}
			};

			// add the data items to the cache
			$.each(stMatchSets, function(i, value) {
				// increase the cache size
				options.cacheLength++;
				// add to the cache
				add(i, value);
			});
		}

		// populate any existing data
		setTimeout(populate, 25);

		function flush() {
			data = {};
			length = 0;
		}

		return {
			flush: flush,
			add: add,
			populate: populate,
			load: function(q) {
				if (!options.cacheLength || !length)
					return null;
				/* 
				* if dealing w/local data and matchContains than we must make sure
				* to loop through all the data collections looking for matches
				*/
				if (!options.url && options.matchContains) {
					// track all matches
					var csub = [];
					// loop through all the data grids for matches
					for (var k in data) {
						// don't search through the stMatchSets[""] (minChars: 0) cache
						// this prevents duplicates
						if (k.length > 0) {
							var c = data[k];
							$.each(c, function(i, x) {
								// if we've got a match, add it to the array
								if (matchSubset(x.value, q)) {
									csub.push(x);
								}
							});
						}
					}
					return csub;
				} else
				// if the exact item exists, use it
					if (data[q]) {
					return data[q];
				} else
					if (options.matchSubset) {
					for (var i = q.length - 1; i >= options.minChars; i--) {
						var c = data[q.substr(0, i)];
						if (c) {
							var csub = [];
							$.each(c, function(i, x) {
								if (matchSubset(x.value, q)) {
									csub[csub.length] = x;
								}
							});
							return csub;
						}
					}
				}
				return null;
			}
		};
	};

	$.Autocompleter.Select = function(options, input, select, config) {
		var CLASSES = {
			ACTIVE: "ac_over"
		};

		var listItems,
		active = -1,
		data,
		term = "",
		needsInit = true,
		element,
		list;

		// Create results
		function init() {
			if (!needsInit)
				return;
			element = $("<div/>")
		.hide()
		.addClass(options.resultsClass)
		.css("position", "absolute")
		.appendTo(document.body);

			list = $("<ul/>").appendTo(element).mouseover(function(event) {
				if (target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
					active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
					$(target(event)).addClass(CLASSES.ACTIVE);
				}
			}).click(function(event) {
				if (options.overrideDefaultResultClickHandler) {
					return true;
				}
				$(target(event)).addClass(CLASSES.ACTIVE);
				select();
				// TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
				input.focus();
				return false;
			}).mousedown(function() {
				config.mouseDownOnSelect = true;
			}).mouseup(function() {
				config.mouseDownOnSelect = false;
			});

			if (options.width > 0)
				element.css("width", options.width);

			needsInit = false;
		}

		function target(event) {
			var element = event.target;
			while (element && element.tagName != "LI")
				element = element.parentNode;
			// more fun with IE, sometimes event.target is empty, just ignore it then
			if (!element)
				return [];
			return element;
		}

		function moveSelect(step) {
			listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
			movePosition(step);
			var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
			if (options.scroll) {
				var offset = 0;
				listItems.slice(0, active).each(function() {
					offset += this.offsetHeight;
				});
				if ((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
					list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
				} else if (offset < list.scrollTop()) {
					list.scrollTop(offset);
				}
			}
		};

		function movePosition(step) {
			active += step;
			if (active < 0) {
				active = listItems.size() - 1;
			} else if (active >= listItems.size()) {
				active = 0;
			}
		}

		function limitNumberOfItems(available) {
			return options.max && options.max < available
			? options.max
			: available;
		}

		function fillList() {
			list.empty();
			var max = limitNumberOfItems(data.length);
			for (var i = 0; i < max; i++) {
				if (!data[i])
					continue;
				var formatted = options.formatItem(data[i].data, i + 1, max, data[i].value, term);
				if (formatted === false)
					continue;
				var li = $("<li/>").html(options.highlight(formatted, term)).addClass(i % 2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
				$.data(li, "ac_data", data[i]);
			}
			listItems = list.find("li");
			if (options.selectFirst) {
				listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
				active = 0;
			}
			// apply bgiframe if available
			if ($.fn.bgiframe)
				list.bgiframe();
		}

		return {
			display: function(d, q) {
				init();
				data = d;
				term = q;
				fillList();
			},
			next: function() {
				moveSelect(1);
			},
			prev: function() {
				moveSelect(-1);
			},
			pageUp: function() {
				if (active != 0 && active - 8 < 0) {
					moveSelect(-active);
				} else {
					moveSelect(-8);
				}
			},
			pageDown: function() {
				if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
					moveSelect(listItems.size() - 1 - active);
				} else {
					moveSelect(8);
				}
			},
			hide: function() {
				element && element.hide();
				listItems && listItems.removeClass(CLASSES.ACTIVE);
				active = -1;
			},
			visible: function() {
				return element && element.is(":visible");
			},
			current: function() {
				return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
			},
			show: function() {
				var offset = $(input).offset();
				element.css({
					width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
					top: offset.top + input.offsetHeight,
					left: offset.left
				}).show();
				if (options.scroll) {
					list.scrollTop(0);
					list.css({
						maxHeight: options.scrollHeight,
						overflow: 'auto'
					});

					if ($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
						var listHeight = 0;
						listItems.each(function() {
							listHeight += this.offsetHeight;
						});
						var scrollbarsVisible = listHeight > options.scrollHeight;
						list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight);
						if (!scrollbarsVisible) {
							// IE doesn't recalculate width when scrollbar disappears
							listItems.width(list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")));
						}
					}

				}
			},
			selected: function() {
				var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
				return selected && selected.length && $.data(selected[0], "ac_data");
			},
			emptyList: function() {
				list && list.empty();
			},
			unbind: function() {
				element && element.remove();
			}
		};
	};

	$.fn.selection = function(start, end) {
		if (start !== undefined) {
			return this.each(function() {
				if (this.createTextRange) {
					var selRange = this.createTextRange();
					if (end === undefined || start == end) {
						selRange.move("character", start);
						selRange.select();
					} else {
						selRange.collapse(true);
						selRange.moveStart("character", start);
						selRange.moveEnd("character", end);
						selRange.select();
					}
				} else if (this.setSelectionRange) {
					this.setSelectionRange(start, end);
				} else if (this.selectionStart) {
					this.selectionStart = start;
					this.selectionEnd = end;
				}
			});
		}
		var field = this[0];
		if (field.createTextRange) {
			var range = document.selection.createRange(),
			orig = field.value,
			teststring = "<->",
			textLength = range.text.length;
			range.text = teststring;
			var caretAt = field.value.indexOf(teststring);
			field.value = orig;
			this.selection(caretAt, caretAt + textLength);
			return {
				start: caretAt,
				end: caretAt + textLength
			}
		} else if (field.selectionStart !== undefined) {
			return {
				start: field.selectionStart,
				end: field.selectionEnd
			}
		}
	};

})(jQuery);/*** End of file: jquery/4_jquery.autocomplete.js ***/
/*** Start of file: generic/common/log.js ***/
/**
 * Logger utility object; provides simple functionality for logging, allowing different levels of logging and switching all logging on or off across the site.
 * @class Logger object; provides cross-browser logging functionality
 * @constructor
 * @param {jQuery} $ The jQuery object
 */
var Log = function($){

    /**
     * @namespace Private properties and methods
     */
    var priv = {
    
        /**
         * Enables/disables the debug mode. If true, debug mode is enabled.
         * @type Boolean
         * @private
         */
        debug : false,

        /**
         * Default level of debugging (debug : 0, info : 1, warn : 2, error : 3)
         * @type Integer
         * @private
         */
        level : 0,
        
        /**
         * The console html element, as a jQuery object, that can be used for logging
         * @type jQuery
         * @private
         */
        console : $("<ul>").addClass("debug-console"),
        
        /**
         * If the console has not yet been added to the document (when no JS console available), do so now
         * @private
         */
        initConsole : function(){
            if(!priv.console.parentNode){
                $("body").append(priv.console);
            } 
        },
        
        /**
         * Writes the message to the screen, if the error level allows it
         * @param {String} msg The message to log
         * @param {Integer} level The logging level of the message
         * @private
         */
        write : function(msg, level){
            if(typeof(level) == "undefined"){
                level = 0;
            }
            
            if(priv.debug && priv.level <= level){
                //check whether debug console exists
                if(typeof(console) != "undefined" && console.log){
                    console.log(msg);
                }
                //if no debug console exists: create debug div
                else {
                    priv.initConsole();
                    $(priv.console).append($("<li>").html(msg.toString()));
                }
            }
        }
    };
    
    /**
     * @scope Log
     */
    return {
        
        /**
         * Write the supplied message at 'debug' logging level
         * @param {String} msg The message to log
         */
        Debug  : function(msg){
            priv.write(msg, 0);
        },
        
        /**
         * Write the supplied message at 'info' logging level
         * @param {String} msg The message to log
         */
        Info   : function(msg){
            priv.write(msg, 1);
        },
        
        /**
         * Write the supplied message at 'warn' logging level
         * @param {String} msg The message to log
         */
        Warn   : function(msg){
            priv.write(msg, 2);
        },
        
        /**
         * Write the supplied message at 'error' logging level
         * @param {String} msg The message to log
         */
        Error  : function(msg){
            priv.write(msg, 3);
        },
        
        /**
         * Show the supplied message in an alert box, only if 'debug' mode is enabled.
         * @param {String} msg The message to alert
         */
        Alert  : function(msg){
            if(priv.debug){
                alert(msg);
            }
        },
        
        /**
         * Pause program execution and show the user a confirm dialog; after clicking 'ok', program execution is resumed. Only works if 'debug' mode is enabled.
         * @param {String} msg The message to show in a confirm dialog
         */
        Pause	: function(msg){
            if(priv.debug){
                return confirm(msg);
            }
        },
        
        /**
         * Turn 'debug' mode on or off
         * @param {Boolean} value Can be true or false, 0 or 1, to turn debugging on or off
         */
        SetDebugging: function(value){
            priv.debug = value;
        },
        
        /**
         * Set the level for logging. Can be 0, 1, 2, or 3, corresponding with Debug, Info,
         * Warn and Error logging levels.
         * @param {Integer} value The new logging level to set
         */
        SetLevel: function(value) {
            priv.level = value;
        }
    };
}(jQuery);/*** End of file: generic/common/log.js ***/
/*** Start of file: generic/common/timer.js ***/
/**
 * Utility class that creates a handy Timer object. This can be used to time and monitor javascript performance.
 * @class Timer Object providing timing functionality for monitoring performance
 * @constructor
 */
var Timer = function(){

    /**
     * @namespace Private methods and properties
     */
    var priv = {
    
        /**
         * Start time
         * @type Date
         * @private
         */
        startTime : new Date(),
        
        /**
         * End time
         * @type Date
         * @private
         */
        endTime   : null
    };
      
    /**
     * @scope Timer
     */  
    return {
        
        /**
         * Start the timer
         */
        Start   : function(){
            priv.startTime = new Date();
        },
        
        /**
         * Stop the timer and record the time of finishing
         */
        Stop    : function(){
            priv.endTime = new Date();
            return (priv.endTime - priv.startTime);
        },
        
        /**
         * Get the intermediate time: how long has the timer been running now
         * @return {Integer} The running time in milliseconds.
         */
        ShowIntermediate : function(){
            var intermediateTime = new Date();
            return (intermediateTime - priv.startTime); 
        },
        
        /**
         * Get the start time of the timer
         * @return {Date} The time at which the timer was started
         */
        GetStartTime   : function(){
            return priv.startTime;
        }
    };
};/*** End of file: generic/common/timer.js ***/
/*** Start of file: generic/common/resource.js ***/
/**
 * The resource object is used for retrieving text resources, to make the javascript language-independent. 
 * @class Resource Object providing functionality for storing and retrieving strings of text using a simple key-matching mechanism. It will retrieve or store a string of text for a specific key.
 * If the key is not found, a standard error message is returned.
 * @constructor
 * @param {jQuery} $ Reference to the jQuery object
 */
var Resource = function($) {

    /**
    * @namespace Private methods and properties
    */
    var priv = {

        /**
        * The items stored in the Resource
        * @type Array
        * @private
        */
        items: {},

        /**
        * Formats
        * @param {String} name The key name to find the value for
        */
        GetFormattedItem: function() {
            try {
				var args = arguments[0];
				var formattedtext = priv.items[args[0]];
				//check if there are two arguments in the arguments list
				if (args.length > 1) {
					//retrieve the last token index
					//var lastTokenIndex = args.length - 1;
					for (var token = 0; token < args.length - 1; token++) {
						//iterate through the tokens and replace their placeholders from the original text in order
						formattedtext = formattedtext.replace(new RegExp("\\{" + token + "\\}", "gi"), args[token + 1]);
					}
				}
				return formattedtext;
			}
			catch (exp) {
				return "";
			}

        }
    };

    /**
    * @scope Resource
    */
    return {

        /**
        * Add strings of text to the resource object
        * @param {String} name The key name that will be associated with the supplied value
        * @param {String} value The value associated with the supplied key name
        */
        AddText: function(name, value) {
            priv.items[name] = value;
        },

        /**
        * Get the text value associated with the supplied key name
        * @param {String} name The key name to find the value for
        */
        GetText: function(name) {

			var text = priv.GetFormattedItem(arguments);
            return !(typeof (text) == "undefined" || text === null) ? text : "<span class=\"error\">[" + name + " not in JS resource]</span>";
        },

        /**
        * Get the text value associated with the supplied key name,
        * but formatted for in a cookie, which should never contain
        * html markup.
        * @param {String} name The key name to find the value for
        */
        GetTextForCookie: function(name) {
			var text = priv.GetFormattedItem(arguments);
            return !(typeof (text) == "undefined" || text === null) ? text : "[" + name + " not in JS resource]";
        }
    };
} (jQuery);/*** End of file: generic/common/resource.js ***/
/*** Start of file: generic/common/lightbox.js ***/
/**
 * The lightbox object provides generic 'popup' functionality. The contents of the popup are shown inside a lightbox, on a dark transparent background.
 * The lightbox can either show a static container element that is already present in the document, or load content from an external url, using an Ajax call.
 * Simple caching functionality is also provided so that external content doesn't have to be loaded more than once.
 * @class Lightbox Provides popup, or lightbox, functionality.
 * @constructor
 * @param {Object} configParams The configuration settings for initializing the lightbox
 * @param {Function} callback The callback method to call when the lightbox has finished loading
 */
var Lightbox = function(configParams, callback) {

	/**
	* @namespace Default configuration settings for the lightbox
	*/
	var config = {

		/**
		* String containing the html for creating an element with a loading message (also showing an ajax loader image, etc.)
		* @type String
		*/
		loadingMsg: '<div id="lightboxLoadingMsg" style="position: absolute; background-color: #fff; border: 1px solid #ccc; z-index: 1000; text-align: center;"><img style="display: block; margin: 10px auto;" src="' + Resource.GetText('path_prefix') + '/images/ajax-loader.gif"/>' + Resource.GetText('loading') + '</div>',

		/**
		* The selector string for uniquely selecting the element containing the lightbox loading message
		* @type String
		*/
		loadingMsgId: "#lightboxLoadingMsg",

		/**
		* (Optional) HTML element containing the contents of the lightbox
		* @type HTMLElement
		*/
		container: null,

		/**
		* (Optional) Load data for popup from external URL
		* @type String
		*/
		contentUrl: '',

		/**
		* (Optional) For use when loading data from external URL. When set to true it inserts the data from the URL
		* literally into the container; when false it wraps the data in standard popup markup (<div id="popup"> etc.)
		* @type Boolean
		*/
		literal: true,

		/**
		* (Optional) For use when standard popup markup is used (literal == false). Defines a custom title for the lightbox.
		* @type String
		*/
		title: "",

		/**
		*  (Optional) Max width of the popup element
		* @type Integer
		*/
		width: null,

		/**
		* (Optional) Max height of the popup element
		* @type Integer
		*/
		height: null,

		/**
		* (Optional) Position of sluiten in lightbox
		* @type String
		*/
		locationCloseButton: "right",

		/**
		* (Optional) Position of sluiten in lightbox
		* @type intenger
		*/
		positionCloseButton: 20,

		/**
		* (Optional) Text for the close link of the lightbox, empty for no close link
		* @type String
		*/
		closeText: typeof (Resource) != "undefined" ? Resource.GetText("common_close") : 'Sluiten',

		/**
		* (Optional) Whether to close the Lightbox when the user clicks anywhere outside the lightbox
		* @type Boolean
		*/
		closeOnBlur: true,

		/**
		* (Optional) Define custom styles for the overlay
		* @type String
		*/
		overlayCss: { 'background-color': '#4d4d4d', 'opacity': '0.7' },

		/**
		* (Optional) Default logging object
		* @type Function
		*/
		debuglogger: Log.Debug,

		/**
		* (Optional) The callback function to call after the lightbox has finished loading
		* @type Function
		*/
		callback: function() { },

		/**
		* (Optional) The callback function to call after the lightbox has finished loading
		* @type Function
		*/
		onShowCallback: null,

		/**
		* (Optional) The callback function to call after the lightbox was closed
		* @type Function
		*/
		onCloseCallback: function() { },

		/**
		* (Optional) Sets whether the original container should be cloned or not. Default behavior is cloning is true. This is handy for caching purposes.
		* Sometimes however, when the contents of the lightbox are already in a container inside the document AND the container has some child nodes with
		* an id attribute, this should be set to false. Otherwise having the same id occur multiple times in the same document will cause problems.
		* @type Boolean
		*/
		clone: true,

		/**
		* (Optional) Sets whether the lightbox should act like a hover or overlay.
		* @type String
		*/
		mode: 'overlay',

		/**
		* (Optional) Set to true when the contentUrl contains javascript that needs to be executed after the content is loaded into the lightbox
		* @type Boolean
		*/
		contentUrlHasScript: false,

		/**
		* (Optional) Set to the hover mouse event on which the lightbox is hovering (only for hover mode)
		* @type Boolean
		*/
		hoverEvent: null,

		/**
		* Bind the configuration parameters to the new lightbox object
		* @param {Object} params The configuration parameters to use
		* @param {Function} callback The callback function for use after the lightbox has finished loading
		* @private
		*/
		bind: function(params, callback) {
			if (params) {
				for (var param in params) {
					config[param] = params[param];
				}
			}
			if (typeof (config.onCloseCallback) !== "function") {
				config.onCloseCallback = function() { };
			}
			if (typeof (callback) == "function") {
				config.callback = callback;
			}
			if (typeof (config.onShowCallback) !== "function") {
				config.onShowCallback = function() { };
			}
			//config binding done
			config.init = true;
		},

		/**
		* Determines if the binding of config is done
		* @type Boolean
		* @private
		*/
		init: false
	};

	//bind the configuration
	config.bind(configParams, callback);

	/**
	* @namespace Private methods and variables
	*/
	var priv = {

		/**
		* Whether the lightbox is currently visible
		* @type Boolean
		* @private
		*/
		visible: false,

		/**
		* Whether the lightbox is already initialized
		* @type Boolean
		* @private
		*/
		initialized: false,

		/**
		* Whether the lightbox is currently loading
		* @type Boolean
		* @private
		*/
		loading: false,

		/**
		* Unique identifier that is generated for the lightbox
		* @type Integer
		* @private
		*/
		identifier: null,

		/**
		* The lightbox html element
		* @type HTMLElement
		* @private
		*/
		lightbox: null,

		/**
		* The lightbox header html element
		* @type HTMLElement
		* @private
		*/
		header: null,

		/**
		* Whether the current browser is MS Internet Explorer 6
		* Type Boolean
		* @private
		*/
		msie6: ($.browser.msie && typeof (XMLHttpRequest) == "undefined" && (/MSIE 6\.0/i.test(window.navigator.userAgent)) && !(/MSIE 7\.0/i.test(window.navigator.userAgent)) && !(/MSIE 8\.0/i.test(window.navigator.userAgent))),

		/**
		* The HTML element that is used as a transparent site overlay
		* @type HTMLElement
		* @private
		*/
		siteOverlay: document.createElement("DIV"),

		/**
		* Bind an event handler to the click event of the supplied HTML element, so that the lightbox is closed when this element is clicked.
		* @param {HTMLElement} el The element to bind a close event handler on click to
		* @private
		*/
		bindCloseEventhandler: function(el) {
			$(el).bind("click", function(evt) {
				priv.close();
				//prevent event bubbling
				return false;
			});
		},

		/**
		* Constructor method, initializes the lightbox.
		* @private
		*/
		init: function() {
			//create the unique identifer
			var d = new Date();
			priv.identifier = Math.round((Math.random() * d.getTime())).toString();

			//initialize the lightbox element
			priv.lightbox = document.createElement("DIV");
			$("body").append($(priv.lightbox).attr("id", "lightbox-" + priv.identifier).addClass("lightbox").hide());

			//apply default styles to the lightbox
			$(priv.lightbox).css({ "z-index": 9999, "position": "absolute", "left": 0, "top": 0 });

			//apply the close button to the lightbox
			if (config.closeText && config.closeText.length > 0 && config.mode == 'overlay') {
				config.debuglogger("Lightbox: adding close link");
				priv.header = document.createElement("DIV");
				var closeLink = document.createElement("A");
				$(priv.lightbox).append(
                    $(priv.header).addClass("header")
                );
				if (config.locationCloseButton == "right") {
					$(priv.header).append(
                    $(closeLink)
                        .addClass("remove")
                        .attr("href", "javascript:void(0);")
						.css({ "position": "absolute", "top": 14, "right": config.positionCloseButton, "z-index": 99999 })
                        .html(config.closeText)
                );
				} else {
					if (config.locationCloseButton == "left") {
						$(priv.header).append(
						$(closeLink)
							.addClass("remove")
							.attr("href", "javascript:void(0);")
							.css({ "position": "absolute", "top": 14, "left": config.positionCloseButton, "z-index": 99999 })
							.html(config.closeText)
						);
					}
				}

				//bind the close event to the closeLink
				priv.bindCloseEventhandler($(closeLink));
			}

			//if we do have a valid container for content, append it to the lightbox
			if (config.container) {
				config.debuglogger("LightBox: Container element found, adding to the lightbox");

				// leave the original element intact.
				if (config.clone) {
					config.container = $(config.container).clone().get(0);
					$(config.container).addClass($(config.container).attr('id'));
					$(config.container).removeAttr('id');
				}

				$(priv.lightbox).append($(config.container).show());
				// Only set initialized value to true if we don't have to load content from a url
				if (!config.contentUrl)
					priv.initialized = true;
				// bind close action to close link/button
				priv.bindCloseEventhandler($(priv.lightbox).find('a.pCancel'));
			}

			//initialize the siteOverlay div: add class and append the siteOverlay to the body
			if ($(".site-overlay").length < 1) {
				$("body").append($(priv.siteOverlay).addClass("site-overlay").hide());

				//apply default styles to the overlay
				$(priv.siteOverlay).css({ "top": 0, "left": 0, "z-index": 999, "position": "absolute" });
				//apply the config styles to the overlay
				$(priv.siteOverlay).css(config.overlayCss);
			} else {
				priv.siteOverlay = $(".site-overlay").get(0);
			}

			//determine the click event, for closing the Lightbox on blur
			if (config.closeOnBlur) {
				$(priv.siteOverlay).bind("click",
                    function(evt) {
                    	priv.close();
                    }
                );
			}

			//bind the resize to the window event
			$(window).bind("resize",
                function(evt) {
                	priv.resize();
                }
            ).bind("scroll",
                function(evt) {
                	priv.scroll();
                }
            ).bind("keydown",
                function(evt) {
                	if (evt.keyCode == 27 && config.closeOnBlur == true) {
                		// ESC key pressed; doesn't work in IE for some reason
                		priv.close();
                	}
                }
            );
		},

		/**
		* Loads the content (if required) and calls the show method
		* @private
		*/
		loadAndShow: function() {
			config.debuglogger("LightBox: Showing the lightbox");

			// Hide select boxes in IE and other older browsers, otherwise they shine through the overlay
			if (!jQuery.support.opacity) {
				$('select').not(".lightbox select").css('visibility', 'hidden');
			}

			if (config.mode == 'overlay') {
				$(priv.siteOverlay).show();
			}

			if (!$(config.loadingMsgId).get(0)) {
				$('body').append(config.loadingMsg);
			}

			priv.showLoading();

			//if the content is already initialized simply show the lightbox
			if (priv.initialized) {
				priv.show();
			}
			//otherwise load the content from the config.contentUrl
			else if (config.contentUrl && !priv.loading) {
				config.debuglogger("Lightbox: loading lightbox content from: " + config.contentUrl);
				//set the priv.loading boolean to true, to avoid double loads
				priv.loading = true;
				var container = config.container ? $(config.container) : $(priv.lightbox);
				container.hide();

				// Wrap popup contents in standard markup for the site
				var popupBody = container;
				if (!config.literal) {
					container.empty();
					var closeText = Resource.GetText("common_close");
					container.append("<div id='popup'><div class='shadow'><div class='heading'>" + config.title + "</div><div class='content'></div><div style=\"padding: 10px;\"><strong><a class='remove2' title='" + closeText + "' href='#'>" + closeText + "</a></strong></div></div></div>");
					container.attr('class', 'popup');
					popupBody = container.find('.content');
				}

				if (config.contentUrlHasScript) {
					$.ajax({
						url: config.contentUrl,
						cache: false, // a try to get rid of IE caching of XmlHttpRequest response
						success: function(data) {
							popupBody.html(data);

							//filter out javascript statements and run them individually
							var scriptData = data.replace(/(\r\n|\n|\r)/gm, "");
							var scriptFragment = '<script(.*?)>(.*?)<\/script>';
							var re = new RegExp(scriptFragment, 'gim'), match;

							while ((match = re.exec(scriptData)) != null) {
								eval(match[2]);
							}

							priv.bindCloseEventhandler($(priv.lightbox).find('a.remove2'));
							//set the initialized to true, and the loading back to false
							priv.initialized = true;
							priv.loading = false;
							config.callback();
							//show the lightbox
							priv.show();
						}
					});
				}
				else {
					popupBody.load(config.contentUrl,
                    function() {
                    	// bind close action to possible close links/buttons
                    	priv.bindCloseEventhandler($(priv.lightbox).find('a.remove2'));
                    	//set the initialized to true, and the loading back to false
                    	priv.initialized = true;
                    	priv.loading = false;
                    	config.callback();
                    	//show the lightbox
                    	priv.show();
                    });
				}
			}
			else {
				//nothing to load, check the config!
				config.debuglogger("Lightbox: No content to display in the lightbox, use 'container' or 'contentUrl' config properties to initialize content loading");
			}
		},

		/**
		* Show a loading message in the lightbox
		* @private
		*/
		showLoading: function() {
			config.debuglogger("LightBox: Showing the lightbox");
			config.height = "auto"; // IE7 hack
			priv.positionAndSize(true /*contentChanged*/, $(config.loadingMsgId).get(0));
			$(config.loadingMsgId).show();
			$(priv.lightbox).show();
			config.height = null; // IE7 hack;
		},

		/**
		* Show the lightbox
		* @private
		*/
		show: function() {
			config.debuglogger("LightBox: Showing the lightbox");
			priv.visible = true;
			$(config.loadingMsgId).hide();
			var container = config.container ? $(config.container) : $(priv.lightbox);
			priv.positionAndSize(true /*contentChanged*/);
			container.show();
			$('.dontShowDuringPopup').hide();
			config.onShowCallback();
		},

		/**
		* Close the lightbox
		* @private 
		*/
		close: function() {
			config.debuglogger("LightBox: Closing the lightbox");
			priv.visible = false;
			// Show select boxes in IE again
			if (!jQuery.support.opacity) {
				$('select').not(".lightbox select").css('visibility', 'visible');
			}
			$(priv.lightbox).hide();
			$(priv.siteOverlay).hide();
			$(config.loadingMsgId).hide();

			$('.dontShowDuringPopup').show();

			if (config.mode == 'hover') {
				$(document).unbind('mousemove');
			}

			config.onCloseCallback();
		},

		/**
		* returns the HTML for the lightbox
		* @private
		*/
		getPopupDOM: function() {

		},

		/**
		* Logic for when the user has resized his window while looking at the popup
		* @private
		*/
		resize: function() {
			priv.positionAndSize();
		},

		/**
		* Logic for when the user has scrolled his window while looking at the popup
		* @private
		*/
		scroll: function() {
			priv.positionAndSize();
		},

		/**
		* position the lightbox element in the page
		* @param {Boolean} contentChanged Whether the content has changed (and vertical position needs to be
		* recalculated). Defaults to false.
		* @param {HTMLElement} element (Optional) The element to position and size. If not supplied, the lightbox will be used.
		* @private
		*/
		positionAndSize: function(contentChanged, element) {
			if (typeof (element) == "undefined") {
				element = priv.lightbox;
			}

			//if the lightbox is hidden, there is no need to position or resize
			if (element == priv.lightbox && !priv.visible) {
				return;
			}

			//cannot write debug here since it will initiate a resize of the document when debugging to the document
			//thus generate a call back to itself, and thus creating an infinite loop

			//get the current document and screen sizes
			var docWidth = $(document).width();
			//Heights in FF and IE are different, use the 'html' height in FF and use 'body' in IE (long live the browser standards....?)
			var docHeight = $(document).height();
			var screenWidth = $(window).width();
			var screenHeight = $(window).height();

			//determine the height and width for the overlay (should overlap entire document)
			//get the screenHeight if the screen is higher than the body, otherwise get the body height or the lightbox height,
			//which can be larger than the document height
			var overlayHeight = Math.max(docHeight, screenHeight); //lightbox can potentially extend far below the current document borders
			$(priv.siteOverlay).width(screenWidth).height(overlayHeight);

			// remove width of the lightbox first to correctly determine the width of container
			//$(element).css('width', 'auto');

			//determine the width of the lightbox, try to grab from child element first
			if (config.container && $(config.container).width()) {
				$(element).width($(config.container).width());
			}
			//overrule if config.width is set
			if (config.width) {
				$(element).width(config.width);
			}

			// remove height of the lightbox first to correctly determine the height of container
			$(element).css('height', 'auto');

			//determine the height of the lightbox, try to grab from child element first
			if (config.container && $(config.container).height()) {
				$(element).height($(config.container).height() + $(priv.header).height());
			}
			//overrule if config.height is set
			if (config.height) {
				$(element).height(config.height).css("overflow-y", "hidden");
			}

			var elHeight = null;
			var scrollTop = null;
			if (config.mode == 'hover') {
				$(config.hoverEvent.currentTarget).mousemove(function(e, init) {
					elHeight = Math.min($(element).height(), 600);
					scrollTop = Math.max($("body").scrollTop(), $("html").scrollTop());
					var xPos = init ? init.pageX : e.pageX;
					var yPos = init ? init.pageY : e.pageY;

					if ($(element).height() + yPos + 20 > $("body").height() + scrollTop) {
						$(element).css({ 'left': xPos + 15, 'top': (yPos - $(element).height()) }).height(elHeight);
					}
					else {
						$(element).css({ 'left': xPos + 15, 'top': yPos + 15 }).height(elHeight);
					}
				});
				$(config.hoverEvent.currentTarget).trigger('mousemove', config.hoverEvent);
			}
			if (elHeight == null && scrollTop == null) {
				$(element).css({ 'left': ((screenWidth / 2) - ($(element).width() / 2)) + 'px' });
				if (contentChanged) {
					$(element).css({ 'top': priv.calculateTop(element) + 'px' });
				}
			}
		},

		//determine the position of the Lightbox on the page
		calculateTop: function(element) {
			var screenHeight = $(window).height();
			var elementHeight = $(element).height();
			var windowTop = $(document).scrollTop();

			var top = windowTop;
			if (elementHeight < screenHeight) {
				top = windowTop + (screenHeight - elementHeight) / 2;
			}

			//make sure we have atleast 10px margin on the top of the document
			if (top < 10) {
				top = 10;
			}

			return top;
		}
	};

	priv.init();

	var returnObj = {

		/**
		* Close/hide the lightbox
		* @methodOf Lightbox
		*/
		Close: function() {
			priv.close();
		},

		/**
		* Get the html element of the lightbox
		* @methodOf Lightbox
		*/
		GetHtml: function() {
			return priv.lightbox;
		},

		/**
		* Show the lightbox
		* @methodOf Lightbox
		*/
		Show: function() {
			priv.loadAndShow();
		},

		/**
		* Show the lightbox
		* @methodOf Lightbox
		*/
		UpdateSize: function(contentChanged) {
			priv.positionAndSize(contentChanged);
		}
	};

	return returnObj;
};

/**
 * Object that is used for storing cached lightboxes
 * @memberOf Lightbox
 * @private
 */
Lightbox.Cache = {};

/**
 * Only create a new lightbox if necessary. If a lightbox with the supplied id exists
 * in the cache, return this one.
 * @param {string} id The id with which to store the lightbox
 * @param {Object} options (optional) The options to create the lightbox with. If not supplied,
 * the container with the supplied id will be shown in the lightbox
 * @param {Function} callback (optional) Callback that will be called when the lightbox is loaded
 * @return {Lightbox} The new or already cached lightbox
 * @memberOf Lightbox
 */
Lightbox.CreateCached = function(id, options, callback) {
    var _cache = Lightbox.Cache;

	if (typeof (options) == 'undefined' || !options) {
        options = {
            container: document.getElementById(id)
        };
    }


    if (typeof(_cache[id]) == "undefined" || !_cache[id]) {
        _cache[id] = new Lightbox(options, callback);
        Log.Debug("Storing new lightbox in cache");
    } else {
        Log.Debug("Getting lightbox from cache");
    }

    return _cache[id];
};/*** End of file: generic/common/lightbox.js ***/
/*** Start of file: generic/common/utils.js ***/
/**
 * The Utils object holds all kinds of utility functions that are used throughout the site.
 * @class Utils Object holding all kinds of utility functions and extra functionality for standard classes like Date.
 * @constructor
 * @param {jQuery} $ Reference to the jQuery object
 */
var Utils = function($) {

    /**
    * 
    * @namespace Private methods and properties
    */
    var priv = {

        /**
        * Extend the JavaScript Date object with several extension methods.
        * @private
        */
        setDateExtensions: function() {

            /**
            * An Array of day names starting with Sunday.
            * 
            * @example dayNames[0]
            * @result 'Sunday'
            *
            * @name dayNames
            * @type Array
            * @memberOf Date
            */
            Date.dayNames = [Resource.GetText('date_days_long')[0], Resource.GetText('date_days_long')[1], Resource.GetText('date_days_long')[2], Resource.GetText('date_days_long')[3], Resource.GetText('date_days_long')[4], Resource.GetText('date_days_long')[5], Resource.GetText('date_days_long')[6]];

            /**
            * An Array of abbreviated day names starting with Sun.
            * 
            * @example abbrDayNames[0]
            * @result 'Sun'
            *
            * @name abbrDayNames
            * @type Array
            * @memberOf Date
            */
            Date.abbrDayNames = [Resource.GetText('date_days_short')[0], Resource.GetText('date_days_short')[1], Resource.GetText('date_days_short')[2], Resource.GetText('date_days_short')[3], Resource.GetText('date_days_short')[4], Resource.GetText('date_days_short')[5], Resource.GetText('date_days_short')[6]];

            /**
            * An Array of month names starting with Janurary.
            * 
            * @example monthNames[0]
            * @result 'January'
            *
            * @name monthNames
            * @type Array
            * @memberOf Date
            */
            Date.monthNames = [Resource.GetText('date_months_long')[0], Resource.GetText('date_months_long')[1], Resource.GetText('date_months_long')[2], Resource.GetText('date_months_long')[3], Resource.GetText('date_months_long')[4], Resource.GetText('date_months_long')[5], Resource.GetText('date_months_long')[6], Resource.GetText('date_months_long')[7], Resource.GetText('date_months_long')[8], Resource.GetText('date_months_long')[9], Resource.GetText('date_months_long')[10], Resource.GetText('date_months_long')[11]];

            /**
            * An Array of abbreviated month names starting with Jan.
            * 
            * @example abbrMonthNames[0]
            * @result 'Jan'
            *
            * @name abbrMonthNames
            * @type Array
            * @memberOf Date
            */
            Date.abbrMonthNames = [Resource.GetText('date_months_short')[0], Resource.GetText('date_months_short')[1], Resource.GetText('date_months_short')[2], Resource.GetText('date_months_short')[3], Resource.GetText('date_months_short')[4], Resource.GetText('date_months_short')[5], Resource.GetText('date_months_short')[6], Resource.GetText('date_months_short')[7], Resource.GetText('date_months_short')[8], Resource.GetText('date_months_short')[9], Resource.GetText('date_months_short')[10], Resource.GetText('date_months_short')[11]];

            /**
            * The first day of the week for this locale.
            *
            * @name firstDayOfWeek
            * @type Number
            * @memberOf Date
            */
            Date.firstDayOfWeek = 1;

            /**
            * The format that string dates should be represented as (e.g. 'dd/mm/yyyy' for UK, 'mm/dd/yyyy' for US, 'yyyy-mm-dd' for Unicode etc).
            *
            * @name format
            * @type String
            * @memberOf Date
            */
            Date.format = 'dd/mm/yyyy';
            //Date.format = 'mm/dd/yyyy';
            //Date.format = 'yyyy-mm-dd';
            //Date.format = 'dd mmm yy';

            (function() {

                /**
                * Adds a given method under the given name 
                * to the Date prototype if it doesn't
                * currently exist.
                * @memberOf Date
                * @private
                */
                function add(name, method) {
                    if (!Date.prototype[name]) {
                        Date.prototype[name] = method;
                    }
                }

                /**
                * Checks if the year is a leap year.
                *
                * @example var dtm = new Date("01/12/2008");
                * dtm.isLeapYear();
                * @result true
                *
                * @name isLeapYear
                * @type Boolean
                * @memberOf Date
                */
                add("isLeapYear", function() {
                    var y = this.getFullYear();
                    return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
                });

                /**
                * Checks if the day is a weekend day (Sat or Sun).
                *
                * @example var dtm = new Date("01/12/2008");
                * dtm.isWeekend();
                * @result false
                *
                * @name isWeekend
                * @type Boolean
                * @memberOf Date
                */
                add("isWeekend", function() {
                    return this.getDay() == 0 || this.getDay() == 6;
                });

                /**
                * Check if the day is a day of the week (Mon-Fri)
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.isWeekDay();
                * @result false
                * 
                * @name isWeekDay
                * @type Boolean
                * @memberOf Date
                */
                add("isWeekDay", function() {
                    return !this.isWeekend();
                });

                /**
                * Gets the number of days in the month.
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.getDaysInMonth();
                * @result 31
                * 
                * @name getDaysInMonth
                * @type Number
                * @memberOf Date
                */
                add("getDaysInMonth", function() {
                    return [31, (this.isLeapYear() ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][this.getMonth()];
                });

                /**
                * Gets the name of the day.
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.getDayName();
                * @result 'Saturday'
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.getDayName(true);
                * @result 'Sat'
                * 
                * @param abbreviated Boolean When set to true the name will be abbreviated.
                * @name getDayName
                * @type String
                * @memberOf Date
                */
                add("getDayName", function(abbreviated) {
                    return abbreviated ? Date.abbrDayNames[this.getDay()] : Date.dayNames[this.getDay()];
                });

                /**
                * Gets the name of the month.
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.getMonthName();
                * @result 'January'
                *
                * @example var dtm = new Date("01/12/2008");
                * dtm.getMonthName(true);
                * @result 'Jan'
                * 
                * @param abbreviated Boolean When set to true the name will be abbreviated.
                * @name getMonthName
                * @type String
                * @memberOf Date
                */
                add("getMonthName", function(abbreviated) {
                    return abbreviated ? Date.abbrMonthNames[this.getMonth()] : Date.monthNames[this.getMonth()];
                });

                /**
                * Get the number of the day of the year.
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.getDayOfYear();
                * @result 11
                * 
                * @name getDayOfYear
                * @type Number
                * @memberOf Date
                */
                add("getDayOfYear", function() {
                    var tmpdtm = new Date("1/1/" + this.getFullYear());
                    return Math.floor((this.getTime() - tmpdtm.getTime()) / 86400000);
                });

                /**
                * Get the number of the week of the year.
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.getWeekOfYear();
                * @result 2
                * 
                * @name getWeekOfYear
                * @type Number
                * @memberOf Date
                */
                add("getWeekOfYear", function() {
                    return Math.ceil(this.getDayOfYear() / 7);
                });

                /**
                * Set the day of the year.
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.setDayOfYear(1);
                * dtm.toString();
                * @result 'Tue Jan 01 2008 00:00:00'
                * 
                * @name setDayOfYear
                * @type Date
                * @memberOf Date
                */
                add("setDayOfYear", function(day) {
                    this.setMonth(0);
                    this.setDate(day);
                    return this;
                });

                /**
                * Add a number of years to the date object.
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.addYears(1);
                * dtm.toString();
                * @result 'Mon Jan 12 2009 00:00:00'
                * 
                * @name addYears
                * @type Date
                * @memberOf Date
                */
                add("addYears", function(num) {
                    this.setFullYear(this.getFullYear() + num);
                    return this;
                });

                /**
                * Add a number of months to the date object.
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.addMonths(1);
                * dtm.toString();
                * @result 'Tue Feb 12 2008 00:00:00'
                * 
                * @name addMonths
                * @type Date
                * @memberOf Date
                */
                add("addMonths", function(num) {
                    var tmpdtm = this.getDate();

                    this.setMonth(this.getMonth() + num);

                    if (tmpdtm > this.getDate())
                        this.addDays(-this.getDate());

                    return this;
                });

                /**
                * Add a number of days to the date object.
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.addDays(1);
                * dtm.toString();
                * @result 'Sun Jan 13 2008 00:00:00'
                * 
                * @name addDays
                * @type Date
                * @memberOf Date
                */
                add("addDays", function(num) {
                    this.setDate(this.getDate() + num);
                    return this;
                });

                /**
                * Add a number of hours to the date object.
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.addHours(24);
                * dtm.toString();
                * @result 'Sun Jan 13 2008 00:00:00'
                * 
                * @name addHours
                * @type Date
                * @memberOf Date
                */
                add("addHours", function(num) {
                    this.setHours(this.getHours() + num);
                    return this;
                });

                /**
                * Add a number of minutes to the date object.
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.addMinutes(60);
                * dtm.toString();
                * @result 'Sat Jan 12 2008 01:00:00'
                * 
                * @name addMinutes
                * @type Date
                * @memberOf Date
                */
                add("addMinutes", function(num) {
                    this.setMinutes(this.getMinutes() + num);
                    return this;
                });

                /**
                * Add a number of seconds to the date object.
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.addSeconds(60);
                * dtm.toString();
                * @result 'Sat Jan 12 2008 00:01:00'
                * 
                * @name addSeconds
                * @type Date
                * @memberOf Date
                */
                add("addSeconds", function(num) {
                    this.setSeconds(this.getSeconds() + num);
                    return this;
                });

                /**
                * Sets the time component of this Date to zero for cleaner, easier comparison of dates where time is not relevant.
                * 
                * @example var dtm = new Date();
                * dtm.zeroTime();
                * dtm.toString();
                * @result 'Sat Jan 12 2008 00:01:00'
                * 
                * @name zeroTime
                * @type Date
                * @memberOf Date
                */
                add("zeroTime", function() {
                    this.setMilliseconds(0);
                    this.setSeconds(0);
                    this.setMinutes(0);
                    this.setHours(0);
                    return this;
                });

                /**
                * Returns a string representation of the date object according to Date.format.
                * (Date.toString may be used in other places so I purposefully didn't overwrite it)
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.asString();
                * @result '12/01/2008' // (where Date.format == 'dd/mm/yyyy'
                * 
                * @name asString
                * @type Date
                * @memberOf Date
                */
                add("asString", function() {
                    var r = Date.format;
                    return r
                        .split('yyyy').join(this.getFullYear())
                        .split('yy').join(this.getYear())
                        .split('mmm').join(this.getMonthName(true))
                        .split('mm').join(_zeroPad(this.getMonth() + 1))
                        .split('dd').join(_zeroPad(this.getDate()));
                });

                /**
                * Returns a string representation of the date object according in a timestamp format (year, month, day without a separator).
                * 
                * @example var dtm = new Date("01/12/2008");
                * dtm.asString2();
                * @result '20080112'
                * 
                * @name asString2
                * @type Date
                * @memberOf Date
                */
                add("asString2", function() {
                    var returnString = this.getFullYear();
                    if ((this.getMonth() + 1) < 10) {
                        returnString += '0' + (this.getMonth() + 1);
                    } else {
                        returnString += '' + (this.getMonth() + 1);
                    }
                    if (this.getDate() < 10) {
                        returnString += '0' + this.getDate();
                    } else {
                        returnString += '' + this.getDate();
                    }

                    return returnString;
                });

                /**
                * Returns a new date object created from the passed String according to Date.format or false if the attempt to do this results in an invalid date object
                * (We can't simple use Date.parse as it's not aware of locale and I chose not to overwrite it incase it's functionality is being relied on elsewhere)
                *
                * @example var dtm = Date.fromString("12/01/2008");
                * dtm.toString();
                * @result 'Sat Jan 12 2008 00:00:00' // (where Date.format == 'dd/mm/yyyy'
                * 
                * @name fromString
                * @type Date
                * @memberOf Date
                */
                Date.fromString = function(s) {
                    var f = Date.format;
                    var d = new Date('01/01/1977');
                    var iY = f.indexOf('yyyy');
                    if (iY > -1) {
                        d.setFullYear(Number(s.substr(iY, 4)));
                    } else {
                        // TODO - this doesn't work very well - are there any rules for what is meant by a two digit year?
                        d.setYear(Number(s.substr(f.indexOf('yy'), 2)));
                    }
                    var iM = f.indexOf('mmm');
                    if (iM > -1) {
                        var mStr = s.substr(iM, 3);
                        for (var i = 0; i < Date.abbrMonthNames.length; i++) {
                            if (Date.abbrMonthNames[i] == mStr) break;
                        }
                        d.setMonth(i);
                    } else {
                        d.setMonth(Number(s.substr(f.indexOf('mm'), 2)) - 1);
                    }
                    d.setDate(Number(s.substr(f.indexOf('dd'), 2)));
                    if (isNaN(d.getTime())) {
                        return false;
                    }
                    return d;
                };

                /**
                * Utility method, only used in this anonymous object. Hidden from outside
                */
                var _zeroPad = function(num) {
                    var s = '0' + num;
                    return s.substring(s.length - 2);
                    //return ('0'+num).substring(-2); // doesn't work on IE :(
                };
            })();
        },

        /**
        * Extend the JavaScript String object with several extension methods.
        * @private
        */
        setStringExtensions: function() {

            /**
            * Get a presentation of the string with all html tags removed. Note that the original string is left unchanged.
            * @return {String} The string with all tags removed
            * @memberOf String
            */
            String.prototype.stripTags = function() { return this.replace(/<(.|\n)*?>/g, ""); };
            String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); };
            String.format = function() {
                if (arguments.length == 0)
                    return null;

                var str = arguments[0];
                for (var i = 1; i < arguments.length; i++) {
                    var re = new RegExp('\\{' + (i - 1) + '\\}', 'gm');
                    str = str.replace(re, arguments[i]);
                }

                return str;
            };

        },

        /**
        * Checks if the current browser has cookies enabled. Thus trying to create and read a cookie at client side.
        * @private
        */
        checkCookiesEnabled: function() {
            var result = true;
            var cookieId = 'test_cookie';

            $.cookie(cookieId, true);
            result = $.cookie(cookieId);

            if (result) $.cookie(cookieId, null);

            return result;
        }
    };

    /**
    * @scope Utils
    */
    return {

        /**
        * Open the page that is referred by the supplied anchor element in a new window.
        * @param {HTMLElement} anchor An anchor element, whose 'href' attribute is used to load another page in a new window. If it
        * contains a 'target' attribute, this is used as the name of the new window.
        * @param {Integer} width The width of the new window
        * @param {Integer} height The height of the new window
        * @param {Integer} top The top position of the new window
        * @param {Integer} left The left position of the new window
        * @return {Window} Reference to the new window
        */
        newWindowPosition: function(anchor, width, height, top, left) {
            var settings = "width=" + width +
                        ",height=" + height +
                        ",top=" + top +
                        ",left=" + left +
                        ",scrollbars=yes,location=no,directories=no,status=no,menubar=no,toolbar=no,resizable=yes";

            var $anchor = $(anchor);
            var target = $anchor.attr('target') || "newWindow";
            var win = window.open($anchor.attr('href'), target, settings);

            win.focus();

            return win;
        },

        /**
        * Open the page that is referred by the supplied anchor element in a new window.
        * @param {HTMLElement} anchor An anchor element, whose 'href' attribute is used to load another page in a new window. If it
        * contains a 'target' attribute, this is used as the name of the new window.
        * @param {Integer} width The width of the new window
        * @param {Integer} height The height of the new window
        * @return {Window} Reference to the new window
        */
        newWindow: function(anchor, width, height) {
            var left = (screen.width) ? (screen.width - width) / 2 : 100;
            var top = (screen.height) ? (screen.height - height) / 2 : 100;

            return Utils.newWindowPosition(anchor, width, height, top, left);
        },

        printRoute: function(accoId) {
            var DocumentContainer = $('#googleDirections');
            var WindowObject = window.open('', "PrintRoute", "width=740,height=325,top=200,left=250,toolbars=no,scrollbars=yes,status=no,resizable=yes");
            WindowObject.document.writeln(DocumentContainer.html());
            WindowObject.document.close();
            WindowObject.focus();
            WindowObject.print();
            WindowObject.close();
        },

        checkCookiesEnabled: function() {
            return priv.checkCookiesEnabled();
        },

        /**
        * Use this to extend base classes with new functionality
        */
        OnReady: function() {
            priv.setDateExtensions();
            priv.setStringExtensions();
        }
    };
} (jQuery);/*** End of file: generic/common/utils.js ***/
/*** Start of file: generic/common/flash.js ***/
/**
* The Flash object is now only used to check if the Flash plugin is installed and has the right version.
* If no Flash plugin is installed or an old version is detected the Flash object shows an image that links to an url.
* @class Flash Object shows an image when Flash plugin is not installed or the wrong version is detected
* @constructor
 * @param {Object} configParams The configuration settings for initializing the flash object
*/
var Flash = function(configParams) {

    /**
    * Configuration object for the validator. Can be customized through the configParams constructor parameter.
    * @namespace Configuration object for the banner pool; contains default settings.
    */
    var config = {

        /**
        * The HTML element that contains the flash object
        * @type HTMLElement
        */
        container: null,

        /**
        * Minimal Flash plugin version
        * @type String
        */
        version: '6,0,0',

        /**
        * Url of the replacing image
        * @type String
        */
        imageurl: Resource.GetText('path_prefix') + '/images/no-image.jpg',

        /**
        * Url of the link
        * @type String
        */
        url: 'http://www.adobe.com/go/getflashplayer',

        /**
        * Default logging object
        * @type Function
        */
        debuglogger: Log.Debug,

        /**
        * For internal use. Cycle through the configuration parameters and overwrite defaults if necessary.
        * @param Object params The new configuration parameters.
        * @type Function
        * @private
        */
        bind: function(params) {
            if (params) {
                for (param in params) {
                    eval("config." + param + " = params." + param);
                }
            }

            //config binding done
            config.init = true;
        },

        /**
        * For internal use only. Determines if the binding of the config is done.
        * @type Boolean
        * @private
        */
        init: false
    };

    //bind the configuration
    config.bind(configParams);

    /**
    * @namespace Private methods and variables
    */
    var priv = {
        /**
        * Initialize the flash object
        * @private
        */
        init: function() {
            //test whether we actually have a valid container element, that actually contains items
            if (!config.container) {
                config.debuglogger("Flash: No container element.");
                return;
            }

            //test if flash plugin not installed or wrong version
            if (!priv.hasflash()) {
                var msg = '<a href="' + config.url + '" target="_blank"><img src="' + config.imageurl + '" /></a>';
                $(config.container).html(msg);
            }
        },

        hasflash: function() {
            var pv = priv.playerversion().match(/\d+/g);
            var rv = String([arguments[0], arguments[1], arguments[2]]).match(/\d+/g) || String(config.version).match(/\d+/g);
            for (var i = 0; i < 3; i++) {
                pv[i] = parseInt(pv[i] || 0);
                rv[i] = parseInt(rv[i] || 0);
                // player is less than required
                if (pv[i] < rv[i]) return false;
                // player is greater than required
                if (pv[i] > rv[i]) return true;
            }
            // major version, minor version and revision match exactly
            return true;
        },

        playerversion: function() {
            // ie
            try {
                try {
                    // avoid fp6 minor version lookup issues
                    // see: http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
                    var axo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.6');
                    try { axo.AllowScriptAccess = 'always'; }
                    catch (e) { return '6,0,0'; }
                } catch (e) { }
                return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
                // other browsers
            } catch (e) {
                try {
                    if (navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin) {
                        return (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1];
                    }
                } catch (e) { }
            }
            return '0,0,0';
        }
    };

    priv.init();
};/*** End of file: generic/common/flash.js ***/
/*** Start of file: generic/common/analytics.js ***/
/**
 * Utility class that creates a event tracker object for Google Analytics. This can be used to track events for submitted # of people, playing of videos and downloading of pdfs.
 * Note: this class uses the async mode of caling methods on GA trackers so ga.js can be loaded async;
 * Note: a variable _gaq has to be declared before this class is used
 * @class Google Analytics Event Tracker Object providing tracking functionality for events in website
 * @constructor
 */

var Analytics = function($) {

    /**
     * @namespace Private methods and properties
     */
    var priv = {

        /**
        * Enable/disable tracking
        * @type boolean
        * @private
        */
		trackingEnabled: true,

        /**
        * The category of the trackEvent
        * @type string
        * @private
        */
        category: null,

        /**
        * The action of the trackEvent
        * @type string
        * @private
        */
        action: null,

        /**
        * The optional_label of the trackEvent
        * @type string
        * @private
        */
        optional_label: null,

        /**
        * The optional_value of the trackEvent
        * @type string
        * @private
        */
        optional_value: null,

        /**
        * The virtual pageview url
        * @type string
        * @private
        */
        pageView: null,

        /**
        * The link url
        * @type string
        * @private
        */
        link: null,
        /**
        * The id of the player that is being viewed
        * @type string
        * @private
        */
        playeralreadyclicked: null,

        /**
        * Start the tracking of event
        * @private
         */
		trackEvent: function() {

            if (priv.trackingEnabled) {
                try {
                    if (priv.optional_value != null) {                    	
	                    _gaq.push(['pageTracker._trackEvent', priv.category, priv.action, priv.optional_label, priv.optional_value]);	                    
	                    _gaq.push(['rollupTracker._trackEvent', priv.category, priv.action, priv.optional_label, priv.optional_value]); 
						Log.Debug("Google tracking: called async _trackEvent('" + priv.category + "', '" + priv.action + "', '" + priv.optional_label + "', '" + priv.optional_value + "')");
	                    return false;
                    }
                    else {                    	                    	
                    	_gaq.push(['pageTracker._trackEvent', priv.category, priv.action, priv.optional_label]);                    	
	                    _gaq.push(['rollupTracker._trackEvent', priv.category, priv.action, priv.optional_label]);
						Log.Debug("Google tracking: called async _trackEvent('" + priv.category + "', '" + priv.action + "', '" + priv.optional_label + "')");
	                    return false;
                    }

                }
				catch (exp) { Log.Debug("google tracking failed, " + exp.toString()) };
            }
            else {
                Log.Debug("google tracking disabled");
			}
        },

        /**
        * Start the tracking of virtual pageview
        * @private
		*/
		trackPageview: function() {			
			_gaq.push(['pageTracker._trackPageview', priv.pageView]);			
            _gaq.push(['rollupTracker._trackPageview', priv.pageView]);
        },

		trackTransaction: function() {
			priv.addTransaction();
			priv.addItem();
			priv.track();
		},

		addTransaction: function() {
			_gaq.push(['pageTracker._addTrans',
					priv.orderID,
					priv.storeName,
					priv.total,
					priv.tax,
					priv.shipping,
					priv.city,
					priv.postalCode,
					priv.country]);

			_gaq.push(['rollupTracker._addTrans',
					priv.orderID,
					priv.storeName,
					priv.total,
					priv.tax,
					priv.shipping,
					priv.city,
					priv.postalCode,
					priv.country]);
		},
		addItem: function() {
			_gaq.push(['pageTracker._addItem',
					priv.orderID,
					priv.hotelName,
					priv.cityDestination,
					priv.countryDestination,
					priv.price,
					priv.numberPersons]);

			_gaq.push(['rollupTracker._addItem',
				priv.orderID,
				priv.hotelName,
				priv.cityDestination,
				priv.countryDestination,
				priv.price,
				priv.numberPersons]);
		},

		track: function() {			
			_gaq.push(['pageTracker._trackTrans']);			
			_gaq.push(['rollupTracker._trackTrans']);
		},

        /**
        * Start the tracking of virtual pageview
        * @private
		*/
		trackLink: function() {            
            _gaq.push(['pageTracker._link', priv.link]);
            return false;            
            _gaq.push(['rollupTracker._link', priv.link]);
            return false;
        }
    };

    /**
     * @scope EventTracker
	*/
    return {

        /**
         * Turn 'eventracking' mode on or off
         * @param {Boolean} value Can be true or false, 0 or 1, to turn event tracking on or off
         */
		SetTracking: function(value) {
            priv.trackingEnabled = value;
        },

        /**
         * trackEvent submitted # of people
         */
		TrackOccupancy: function() {
            var occupancy = Occupancy.getOccupancy();
            var a = Occupancy.getNrAdults();
            var c = Occupancy.getNrChildren();
            var b = Occupancy.getNrBabies();
            var partycomposition = "";
            if (a > 0)
            {
				partycomposition = a + "a";
				if (c > 0)
				{
					partycomposition += " + " + c + "c";
				}
				if (b > 0)
				{
					partycomposition += " + " + b + "b";
				}
            }
            priv.category = "party composition";
            priv.action = "saved";
            priv.optional_label = partycomposition;
            //priv.optional_value = occupancy;
            priv.trackEvent();
        },

        /**
		* trackEvent submitted # of people
		*/
		TrackOccupancyReservation: function() {
			var occupancy = Occupancy.getOccupancy();
			priv.category = "reisgezelschap";
			priv.action = "submit";
			priv.optional_label = occupancy;
			priv.optional_value = occupancy;
            priv.trackEvent();
        },
        /**
         * trackEvent video player
		*/
		TrackPlayer: function(action, label) {
				priv.category = "video";
			priv.action = action;
			priv.optional_label = label;
			priv.trackEvent();
        },

        /**
         * trackEvent pdf download
		*/
		TrackDownload: function(value) {
            priv.category = "downloads";
            priv.action = "pdf";
			priv.optional_label = value;
			priv.trackEvent();
        },

        /**
		* track virtual pageview with or without parameter
		*/
		TrackPageview: function(value) {
			if (typeof(value) != "undefined")
			{
            priv.pageView = value;
			priv.trackPageview(priv.pageView);
			}
			else
			{
            priv.trackPageview();
			}
		},

        /**
		* track the confirmation transaction
		*/
		TrackTransaction: function(orderID, storeName, total, tax, shipping, city, postalCode, country, hotelName, cityDestination, countryDestination, price, numberPersons) {

			priv.orderID = orderID;
			priv.storeName = storeName;
			priv.total = total;
			priv.tax = tax;
			priv.shipping = shipping;
			priv.city = city;
			priv.postalCode = postalCode;
			priv.country = country;
			priv.hotelName = hotelName;
			priv.cityDestination = cityDestination;
			priv.countryDestination = countryDestination;
			priv.price = price;
			priv.numberPersons = numberPersons;

			priv.trackTransaction();
		},

		/**
         * track link
		*/
		TrackLink: function(value) {
            priv.link = value;
            priv.trackLink();
		},

		/**
         * trackEvent custom category/action
		*/
        TrackEvent   : function(category, action, value){
            priv.category = category;
            priv.action = action;
            priv.optional_label = value;  
            priv.trackEvent(); 
        },

		/**
         * trackEvent custom category/action
		*/
        TrackEvent   : function(category, action, label, value){
            priv.category = category;
            priv.action = action;
            priv.optional_label = label;
            priv.optional_value = value;
            priv.trackEvent(); 
        }

    };
} (jQuery);

/**
* Functions needed for tracking youtube movies
*/

/**
* Overwrite buggy global __flash__removeCallback generated by flash player, 
* after flash player is completely loaded to be sure
 */
function fixFlashRemoveCallback() {
    if (typeof(__flash__removeCallback) != "undefined" && __flash__removeCallback) {
        __flash__removeCallback = function(instance, name) {
            if (instance) {
                instance[name] = null;
            }
        };
    }
}
var playedOnce = false;
/**
* Youtube player extension point
* http://code.google.com/apis/youtube/js_api_reference.html
*/
function onYouTubePlayerReady(playerid) {
	fixFlashRemoveCallback();
	var player = document.getElementById('trackFlashVideo');
	player.addEventListener('onStateChange', 'youtubeEvent', false);
}
function youtubeEvent(state) {
	var player = document.getElementById('trackFlashVideo');
	var nameplayer = player.getAttribute("src");
	var querystring = nameplayer.indexOf('?');
	if (querystring != -1)
	{
		nameplayer = nameplayer.replace(nameplayer.substr(querystring), '');
	}
	else 
	{
		querystring = nameplayer.indexOf('&')
		if (querystring != -1)
		{
			nameplayer = nameplayer.replace(nameplayer.substr(querystring), '');
		}
	}
	if (state == 1) {
		if (!playedOnce) {
			playedOnce = true;
			Analytics.TrackPlayer('play',nameplayer);
		}
		return;
	}
	if (state == 0) {
		Analytics.TrackPlayer('ended',nameplayer);
		return;
	}
	if (state == 2) {
		Analytics.TrackPlayer('pause',nameplayer);
		return;
	}
}/*** End of file: generic/common/analytics.js ***/
/*** Start of file: generic/common/image-preloader.js ***/
/**
 * ImagePreloader object, preloads images provided in an array and calls back when done
 * @class ImagePreloader preloads images provided in an array and calls back when done
 * @constructor
 * @param {Array} images array of the images that require preloading
 * @param {Function} callback The callback method to call after all images have succeeded in loading
 */ 
var ImagePreloader = function(images, callback){
	var images = images;
	var priv = {
		totalCount : images.length,
		completeCount : 0,
		timer : null,
		
		init : function(){
			priv.timer = new Timer();
			//loop through the countries
			$(images).each(
				function(index){					
					var tmpImage = new Image();
					tmpImage.src = this;
					
					//when using the back-button IE has the images loaded already, the onload will not be triggered
					if(tmpImage.complete == true){
						Log.Debug("Preloader got image from cache " + tmpImage.src);
						priv.imgComplete(tmpImage.src, "cached");
						return;
					}
					$(tmpImage).bind("error", 
						function(){
							Log.Debug("Preloader failed to load image " + this.src);
							priv.imgComplete(tmpImage.src, "error");
						}
					);
					$(tmpImage).load(
						function(){
							Log.Debug("Preloader completed image " + this.src);
							priv.imgComplete(tmpImage.src, "success");
						}
					);
				}
			);
		},
				
		imgComplete : function(src, status){
			priv.completeCount++;
			
			//if all images have been completed, exit calling the callback function
			if(priv.completeCount >= priv.totalCount){
				Log.Debug("Preloader completed all images in " + priv.timer.Stop() + "ms; making callback");
				if(typeof(callback) == "function"){
					callback();
				}
			}
		}
	};
	priv.init();
		
	return {
		
	};	
};/*** End of file: generic/common/image-preloader.js ***/
/*** Start of file: generic/sundio/participant.js ***/
/**
 * Simple object used in booking, to hold information about a particular participant.
 * @class Participant Holds information about a participant
 * @constructor
 * @param {jQuery} $ Reference to the jQuery object
 */
 function Participant($){
     
    /** @scope Participant */
    return {

        /**
         * The ID of the participant
         * @type String
         */
        volgnr : '',
        
        /**
         * The type of participant (child, baby, adult)
         * @type String
         */
        type : '',

        /**
         * The title of the participant
         * @type String
         */
        aanhef : '',
        
        /**
         * The participant's first name
         * @type String
         */
        voornaam : '',

        /**
         * The participant's middle name
         * @type String
         */
        tussenvoegsel : '',

        /**
         * The participant's last name
         * @type String
         */
        achternaam : '',

        /**
         * The participant's birthdate
         * @type Date
         */
        geboortedatum : null
    };
}/*** End of file: generic/sundio/participant.js ***/
/*** Start of file: generic/sundio/occupancy.js ***/
/**
 * Occupancy object, provides functionality for the user to choose / edit his group of travelers and saving and reading this information to/from a cookie.
 * @class Class for travelers / occupancy
 * @constructor
 * @param {jQuery} $ Reference to the jQuery object
 */
var Occupancy = function($) {

	var config = {
		width: 305,
		filterSearch: 1,
		autorefresh: true,

		bind: function(configParams) {
			$.extend(config, configParams);
			priv.filterSearch = config.filterSearch;
			priv.autorefresh = config.autorefresh;
		}
	};

	/** @namespace Private variables and methods */
	var priv = {

		/**
		* Name of the cookie
		* @type String
		* @private
		*/
		cookieName: 'occupancy',

		/**
		* When the cookie expires (in days)
		* @type Integer
		* @private
		*/
		cookieExpires: 30,

		/**
		* Integer used as a boolean, can be 0 or 1, determining whether or not to filter
		* @type Integer
		* @private
		*/
		filterSearch: config.filterSearch,

		/**
		* The number of adults in the group
		* @type Integer
		* @private
		*/
		nrAdults: -1,

		/**
		* The number of children in the group
		* @type Integer
		* @private
		*/
		nrChildren: -1,

		/**
		* The number of babies in the group
		* @type Integer
		* @private
		*/
		nrBabies: -1,

		/**
		* The date that cookie was changed
		* @private
		*/
		cookieDate: null,

		/**
		* The adult of the travelers group
		* @type Array
		* @private
		*/
		arrAdults: null,

		/**
		* The children of the travelers group
		* @type Array
		* @private
		*/
		arrChildren: null,

		/**
		* The babies of the travelers group
		* @type Array
		* @private
		*/
		arrBabies: null,

		/**
		* Flag specifying if reminder about selected travelers should be shown
		* @private
		*/
		showReminder: null,

		/**
		* For internal use. Whether the Occupancy object is already initialized or not
		* @type Boolean
		* @private
		*/
		initialized: false,

		/**
		* The popup or lightbox object in which to show the travelers
		* @type Lightbox
		* @private
		*/
		popup: null,

		autorefresh: true,

		/** 
		* Get the occupancy cookie name
		* @return {String} The name of the occupancy cookie
		* @private
		*/
		getCookieName: function() {
			return Resource.GetTextForCookie('cookie-prefix') + priv.cookieName;
		},

		/**
		* Check birthdays and show a popup
		* @private
		*/
		birthDaysCheck: function() {
			if (priv.nrChildren > 0 || priv.nrBabies > 0) {
				var curDate = new Date();
				var babyMaxYear = curDate.getFullYear();
				var babyMinYear = curDate.getFullYear() - 2;
				var childMaxYear = curDate.getFullYear() - 2;
				var childMinYear = curDate.getFullYear() - 17;
				var selected = ' selected="selected"';

				var dayOptions = '';
				for (var dayIdx = 1; dayIdx <= 31; dayIdx++) {
					dayOptions += '<option';
					if (dayIdx == 20) {
						dayOptions += selected;
					}
					dayOptions += '>' + dayIdx + '</option>';
				}
				var monthOptions = '';
				for (var monthIdx = 0; monthIdx < 12; monthIdx++) {
					monthOptions += '<option';
					if (monthIdx == 2) {
						monthOptions += selected;
					}
					monthOptions += '>' + Resource.GetText('date_months_long')[monthIdx] + '</option>';
				}
				var childYearOptions = '';
				for (var i = childMinYear; i <= childMaxYear; i++) {
					childYearOptions += '<option';
					if (i == (parseInt((childMaxYear - childMinYear) / 2) + childMinYear)) {
						childYearOptions += selected;
					}
					childYearOptions += '>' + i + '</option>';
				}
				var babyYearOptions = '';
				for (var j = babyMinYear; j <= babyMaxYear; j++) {
					babyYearOptions += '<option';
					if (j == (((babyMaxYear - babyMinYear) / 2) + babyMinYear)) {
						babyYearOptions += selected;
					}
					babyYearOptions += '>' + j + '</option>';
				}

				// add children date of birth selections
				if (priv.nrChildren > 0) {
					if ($('#children').html() == '') {
						$('#children').html('<span>' + Resource.GetText('birthdate_children') + '</span><br/>');
					}
				} else {
					$('#children').html('');
				}
				priv.buildBirthDayDropDowns('#children', 'childrow', priv.nrChildren, dayOptions, monthOptions, childYearOptions);

				//add babies day of birth selections
				if (priv.nrBabies > 0) {
					if ($('#babies').html() == '') {
						$('#babies').html('<span>' + Resource.GetText('birthdate_babies') + '</span><br/>');
					}
				} else {
					$('#babies').html('');
				}
				priv.buildBirthDayDropDowns('#babies', 'babyrow', priv.nrBabies, dayOptions, monthOptions, babyYearOptions);

				$('#birthdays').show();
			} else {
				$('#birthdays #children').html('');
				$('#birthdays #babies').html('');
				$('#birthdays').hide();
			}
		},

		/**
		* Check the supplied date for validity
		* @param {Integer} year The year
		* @param {Integer} month The month
		* @param {Integer} day The day
		* @private
		*/
		isDate: function(year, month, day) {
			// set number of days in a month
			var daysInMonth = [];
			for (var i = 1; i <= 12; i++) {
				daysInMonth[i] = 31;
				if (i == 4 || i == 6 || i == 9 || i == 11) { daysInMonth[i] = 30; }
				if (i == 2) { daysInMonth[i] = 29; }
			}
			// February has 29 days in any year evenly divisible by four,
			// EXCEPT for centurial years which are not also divisible by 400.
			var daysInFebruary = (((year % 4 == 0) && ((!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28);
			// check if date is valid
			if (((month + 1) == 2 && day > daysInFebruary) || day > daysInMonth[month + 1]) {
				return false;
			}
			return true;
		},

		/**
		* Check whether the birthdays chosen in the dropdowns are correct (children shouldn't be older than a certain age, etc.)
		* @private
		*/
		checkBirthDaysCorrect: function() {
			var hasInvalidDate = false;
			$('#birthdays #children .childrow').each(function(i) {
				var invalidItemDate = false;
				var day = $('#day', this).val();
				var month = $('#month', this).get(0).selectedIndex;
				var year = $('#year', this).val();

				if (!priv.isDate(year, month, day)) {
					$('#birthdays #children .rowerror:eq(' + i + ')').text(Resource.GetText('fill_correct_date'));
					invalidItemDate = true;
				}

				var inputDate = new Date(year, month, day);

				var today = new Date();
				var minDate = new Date(today.getFullYear() - 17, today.getMonth(), today.getDate());
				var maxDate = new Date(today.getFullYear() - 2, today.getMonth(), today.getDate());
				if (inputDate < minDate || inputDate > maxDate) {
					var dateBegin = minDate.getDate() + ' ' + Resource.GetText('date_months_short')[minDate.getMonth()] + ' ' + minDate.getFullYear();
					var dateEnd = maxDate.getDate() + ' ' + Resource.GetText('date_months_short')[maxDate.getMonth()] + ' ' + maxDate.getFullYear();
					var message = Resource.GetText('date_between', dateBegin, dateEnd);
					$('#birthdays #children .rowerror:eq(' + i + ')').text(message);
					invalidItemDate = true;
				}

				if (!invalidItemDate) {
					$('#birthdays #children .rowerror:eq(' + i + ')').text('');
				} else {
					hasInvalidDate = invalidItemDate;
				}
			});

			$('#birthdays #babies .babyrow').each(function(i) {
				var invalidItemDate = false;
				var day = $('#day', this).val();
				var month = $('#month', this).get(0).selectedIndex;
				var year = $('#year', this).val();

				if (!priv.isDate(year, month, day)) {
					$('#birthdays #babies .rowerror:eq(' + i + ')').text(Resource.GetText('fill_correct_date'));
					invalidItemDate = true;
				}

				var inputDate = new Date(year, month, day);

				var today = new Date();
				var minDate = new Date(today.getFullYear() - 2, today.getMonth(), today.getDate());
				var maxDate = today;
				if (inputDate < minDate || inputDate > maxDate) {
					var dateBegin = minDate.getDate() + ' ' + Resource.GetText('date_months_short')[minDate.getMonth()] + ' ' + minDate.getFullYear();
					var dateEnd = maxDate.getDate() + ' ' + Resource.GetText('date_months_short')[maxDate.getMonth()] + ' ' + maxDate.getFullYear();
					var message = Resource.GetText('date_between', dateBegin, dateEnd);
					$('#birthdays #babies .rowerror:eq(' + i + ')').text(message);
					invalidItemDate = true;
				}

				if (!invalidItemDate) {
					$('#birthdays #babies .rowerror:eq(' + i + ')').text('');
				} else {
					hasInvalidDate = invalidItemDate;
				}
			});

			return !hasInvalidDate;
		},

		/**
		* Build the birthday dropdowns to show in the travelers popup
		* @param {Object} holderId
		* @param {Object} rowClass
		* @param {Object} nrOfType
		* @param {Object} dayOptions
		* @param {Object} monthOptions
		* @param {Object} yearOptions
		* @private
		*/
		buildBirthDayDropDowns: function(holderId, rowClass, nrOfType, dayOptions, monthOptions, yearOptions) {
			//add day of birth selections
			var alreadyAdded = $('#birthdays ' + holderId + ' .' + rowClass).length;
			// less children selected than before, remove the children that are above the limit
			if (alreadyAdded > nrOfType) {
				for (var i = (alreadyAdded - 1); i >= nrOfType; i--) {
					$('#birthdays ' + holderId + ' .' + rowClass + ':eq(' + i + ')').remove();
					if (nrOfType > 1 && i == nrOfType) {
						$('#birthdays ' + holderId + ' .' + rowClass + ':eq(' + (i - 1) + ')').removeClass('middle');
						$('#birthdays ' + holderId + ' .' + rowClass + ':eq(' + (i - 1) + ')').addClass('last');
					}
				}
			} else { // there are more children selected than before, add the extra children
				var className = 'first';
				for (var j = 0; j < nrOfType; j++) {
					if (j == (nrOfType - 1)) {
						className = 'last';
					} else if (j > 0) {
						className = 'middle';
					}

					if (j < alreadyAdded) {
						$('#birthdays ' + holderId + ' .' + rowClass + ':eq(' + j + ')').removeClass('last');
						$('#birthdays ' + holderId + ' .' + rowClass + ':eq(' + j + ')').addClass(className);
					} else {
						var row = '<div class="' + rowClass + ' ' + className + '">' +
                                        (j + 1) + ') ' +
                                        '<select id="day">' +
                                            dayOptions +
                                        '</select> ' +
                                        '<select id="month">' +
                                            monthOptions +
                                        '</select> ' +
                                        '<select id="year">' +
                                            yearOptions +
                                        '</select>' +
                                    '</div>';

						$('#birthdays ' + holderId).append(row + '<div class="rowerror"></div>');
					}
				}
			}
		},

		/**
		* Bind all popup events for controls in the travelers / occupancy popup
		* @private
		*/
		bindPopupEvents: function() {
			if (!priv.initialized) {
				$('#birthdays #children').html('');
				$('#birthdays #babies').html('');

				priv.loadCookie();

				$('#nr-adults').val(priv.nrAdults);
				$('#nr-children').val(priv.nrChildren);
				$('#nr-babies').val(priv.nrBabies);

				if (priv.filterSearch == 0) {
					$('#chkFilter').removeAttr('checked');
				} else {
					$('#chkFilter').attr('checked', 'checked');
				}

				priv.birthDaysCheck();

				$('#birthdays #children .childrow').each(function(i) {
					$('#day', this).val(priv.arrChildren[i].geboortedatum.getDate());
					$('#month', this).get(0).selectedIndex = priv.arrChildren[i].geboortedatum.getMonth();
					$('#year', this).val(priv.arrChildren[i].geboortedatum.getFullYear());

				});
				$('#birthdays #babies .babyrow').each(function(i) {
					$('#day', this).val(priv.arrBabies[i].geboortedatum.getDate());
					$('#month', this).get(0).selectedIndex = priv.arrBabies[i].geboortedatum.getMonth();
					$('#year', this).val(priv.arrBabies[i].geboortedatum.getFullYear());
				});

				$('#nr-adults').bind("change", function() {
					Occupancy.changeNrAdults();
				});

				$('#nr-children').bind("change", function() {
					var newValue = parseInt($('#nr-children').val());
					if (newValue == 0) {
						priv.arrChildren = [];
					} else {
						if (newValue < priv.nrChildren) {
							priv.arrChildren = priv.arrChildren.slice(0, newValue);
						} else if (newValue > priv.nrChildren) {
							for (var i = priv.nrChildren; i < newValue; i++) {
								var addPart = new Participant();
								addPart.type = 'Child';
								priv.arrChildren[i] = addPart;
							}
						}
					}

					priv.nrChildren = newValue;
					priv.birthDaysCheck();

					priv.updatePopupSize();
				});

				$('#nr-babies').bind("change", function() {
					var newValue = parseInt($('#nr-babies').val());
					if (newValue == 0) {
						priv.arrBabies = [];
					} else {
						if (newValue < priv.nrBabies) {
							priv.arrBabies = priv.arrBabies.slice(0, newValue);
						} else if (newValue > priv.nrBabies) {
							for (var i = priv.nrBabies; i < newValue; i++) {
								var addPart = new Participant();
								addPart.type = 'Baby';
								priv.arrBabies[i] = addPart;
							}
						}
					}

					priv.nrBabies = newValue;
					priv.birthDaysCheck();

					priv.updatePopupSize();
				});

				$('#chkFilter').bind("click", function() {
					priv.filterSearch = this.checked ? 1 : 0;
				});

				// Somehow in IE the dropdownlists are hidden so show them here
				$('#nr-adults').show();
				$('#nr-children').show();
				$('#nr-babies').show();

				priv.initialized = true;

				priv.updatePopupSize();
			}
		},

		showExtraNote: function() {
			if (priv.nrAdults >= 5) {
				$('#pTravelers .nroccs .extranote').show();
			}
			else {
				$('#pTravelers .nroccs .extranote').hide();
			}
		},

		/**
		* Updates the occupancy popup size according to the new content
		* @private
		*/
		updatePopupSize: function() {
			if (priv.popup != null && typeof (priv.popup) != "undefined") {
				priv.popup.UpdateSize();
			}
		},

		/**
		* Load the travelers information from a cookie
		* @private
		*/
		loadCookie: function() {
			priv.filterSearch = config.filterSearch;
			priv.nrAdults = 0;
			priv.nrChildren = 0;
			priv.nrBabies = 0;
			priv.arrAdults = [];
			priv.arrChildren = [];
			priv.arrBabies = [];

			var cookieStr = $.cookie(priv.getCookieName());
			if (!(cookieStr == null || cookieStr == '' || cookieStr.indexOf('<OCCUPANCY') == -1)) {
				try {
					var xmlDoc = null;
					if (window.ActiveXObject) {
						// code for IE
						xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
						xmlDoc.async = "false";
						xmlDoc.loadXML(cookieStr);
					}
					else {
						// code for Mozilla, Firefox, Opera, etc.
						var parser = new DOMParser();
						xmlDoc = parser.parseFromString(cookieStr, "text/xml");
					}
					var root = xmlDoc.documentElement;

					// set values from cookie; keep defaults if the values are unreadable
					var searchSetting = parseInt(root.getAttribute("USEFORSEARCH"));
					if (searchSetting === 0 || searchSetting === 1) {
						priv.filterSearch = searchSetting;
					}
					priv.nrAdults = parseInt(root.getAttribute("ADULTS")) || priv.nrAdults;
					priv.nrChildren = parseInt(root.getAttribute("CHILDS")) || priv.nrChildren;
					priv.nrBabies = parseInt(root.getAttribute("BABYS")) || priv.nrBabies;

					priv.cookieDate = new Date(root.getAttribute("TIMESTAMP"));

					// set date arrays
					var xmlParticipants = xmlDoc.documentElement.getElementsByTagName("PART");
					var adultCount = 0;
					var childCount = 0;
					var babyCount = 0;
					for (var i = 0; i < xmlParticipants.length; i++) {
						var addParticipant = new Participant();
						addParticipant.volgnr = xmlParticipants[i].getAttribute("VOLGNR");
						addParticipant.type = xmlParticipants[i].getAttribute("TYPE");
						addParticipant.aanhef = xmlParticipants[i].getAttribute("AANHEF");
						addParticipant.voornaam = xmlParticipants[i].getAttribute("VOORNAAM");
						addParticipant.tussenvoegsel = xmlParticipants[i].getAttribute("TUSSENVOEGSEL");
						addParticipant.achternaam = xmlParticipants[i].getAttribute("ACHTERNAAM");
						var birthDate = xmlParticipants[i].getAttribute("GEBOORTEDATUM");

						//catch some data errors:
						//remove dates that contain '0:00:00'
						if (birthDate.indexOf(':') != -1) {
							birthDate = null;
						}
						if (birthDate != null && birthDate != '') {
							//replace the '/' with '-', since we are now out of sync with booking steps logic
							birthDate = birthDate.replace(/\//g, '-');
							var spltbirthDate = birthDate.split('-');
							var date = new Date();
							date.setFullYear(spltbirthDate[2], parseInt(spltbirthDate[1]) - 1, spltbirthDate[0]);
							addParticipant.geboortedatum = date;
							Log.Debug(addParticipant.type + ":" + date.toString());
						}

						if (addParticipant.type == 'A' || addParticipant.type == 'Adult') {
							priv.arrAdults[adultCount] = addParticipant;
							adultCount++;
						} else if (addParticipant.type == 'C' || addParticipant.type == 'Child') {
							priv.arrChildren[childCount] = addParticipant;
							childCount++;
						} else if (addParticipant.type == 'B' || addParticipant.type == 'Baby') {
							priv.arrBabies[babyCount] = addParticipant;
							babyCount++;
						}

					}
				} catch (err) {
					Log.Debug(err);
				}
				if (priv.showReminder) {
					priv.remind();
				}
				return;
			}

			priv.deleteCookie();
		},

		/**
		* Get an array of localized strings describing the travelers
		* @private
		*/
		getOccupancyLines: function() {
			var occupancy = [];
			if (priv.nrAdults >= 1) {
				occupancy.push(priv.nrAdults + ' ' + (priv.nrAdults == 1 ? Resource.GetText('travelers_adult') : Resource.GetText('travelers_adults')));
			}
			if (priv.nrChildren >= 1) {
				occupancy.push(priv.nrChildren + ' ' + (priv.nrChildren == 1 ? Resource.GetText('travelers_child') : Resource.GetText('travelers_children')));
			}
			if (priv.nrBabies >= 1) {
				occupancy.push(priv.nrBabies + ' ' + (priv.nrBabies == 1 ? Resource.GetText('travelers_baby') : Resource.GetText('travelers_babies')));
			}
			return occupancy;
		},

		/**
		* Show reminder about selected travelers 
		* @private
		*/
		remind: function() {
			//show alert if occupancy is used
			$('a').click(function() {
				var now = new Date();
				var minutes = (now.getTime() - priv.cookieDate.getTime()) / (1000 * 60);
				if (minutes >= 2 &&
                    (window.location.href.indexOf(Resource.GetText('searchpage')) > -1 ||
                    window.location.href.indexOf(Resource.GetText('offerspage')) > -1)) {
					var occupancy = priv.getOccupancyLines();
					alert(Resource.GetText('SAME_OCCUPANCY_REMINDER') + '\n\n' + occupancy.join('\n'));
					priv.cookieDate = now;
					priv.saveCookie();
				}
			});
		},

		/**
		* Save the travelers information from the popup to a cookie
		* @private
		*/
		saveCookie: function() {
			// Add the birthdays of the children and babies
			$('#birthdays #children .childrow').each(function(i) {
				priv.addBirthdate(i, priv.arrChildren, this);
			});
			$('#birthdays #babies .babyrow').each(function(i) {
				priv.addBirthdate(i, priv.arrBabies, this);
			});

			// build the cookie string
			var cookieStr = '<OCCUPANCY PARTICIPANTS="' + Occupancy.getOccupancy() +
                            '" ADULTS="' + priv.nrAdults +
                            '" CHILDS="' + priv.nrChildren +
                            '" BABYS="' + priv.nrBabies +
                            '" USEFORSEARCH="' + priv.filterSearch +
                            '" TIMESTAMP="' + new Date() +
                            '">';
			cookieStr += priv.buildCookieString([priv.arrAdults, priv.arrChildren, priv.arrBabies]);
			cookieStr += '</OCCUPANCY>';

			// save the cookie
			$.cookie(priv.getCookieName(), cookieStr, { expires: priv.cookieExpires, path: '/' });
		},

		/**
		* Add the birthdate found in the supplied html element to the array, at the supplied index.
		* @param {Integer} index The index of the current element in the array
		* @param {Array} array The array to add teh birthdate to
		* @param {HTML Element} el The html element from which to get the birthdate
		* @private
		*/
		addBirthdate: function(index, array, el) {
			var newDate = new Date();
			newDate.setFullYear($('#year', el).val(), $('#month', el).get(0).selectedIndex, $('#day', el).val());

			if (array === priv.arrChildren) {
				Log.Debug('1) ' + index + ' - ' + newDate);
			}

			array[index].geboortedatum = newDate;

			if (array === priv.arrChildren) {
				Log.Debug('2) ' + index + ' - ' + array[index].geboortedatum);
			}
		},

		/**
		* For each of the arrays found in the supplied array object, read all of its Participant elements and convert them to a string
		* @param {Array} arrays An array of arrays
		* @return {String} The cookie string that was built
		* @private
		*/
		buildCookieString: function(arrays) {
			var str = "";
			for (var i = 0; i < arrays.length; i++) {
				// For each array, cycle through its elements and build the cookie string
				var arr = arrays[i];
				for (var j = 0; j < arr.length; j++) {
					var current = arr[j];
					if (arr == priv.arrChildren) {
						Log.Debug('3) ' + i + ' - ' + current.geboortedatum);
					}
					str += priv.participantToString(current, arr);
				}
			}
			return str;
		},

		/** 
		* Build a string from the supplied participant, which is included in the supplied array
		* @param {Participant} part The participant to build a cookie string from
		* @param {Array} array The array in which the participant is included
		* @return {String} The cookie string
		* @private
		*/
		participantToString: function(part, array) {
			var birthDate = '';
			if (typeof (part.geboortedatum) != "undefined" && part.geboortedatum != null) {
				var curDate = part.geboortedatum;
				birthDate = curDate.getDate() + '-' + (curDate.getMonth() + 1) + '-' + curDate.getFullYear();
			} else if (array === priv.arrAdults) {
				//little hack for the bookingsteps for adults
				birthDate = '0:00:00';
			}
			return '<PART VOLGNR="' + part.volgnr + '" TYPE="' + part.type + '" AANHEF="' + part.aanhef + '" VOORNAAM="' + part.voornaam + '" TUSSENVOEGSEL="' + part.tussenvoegsel + '" ACHTERNAAM="' + part.achternaam + '" GEBOORTEDATUM="' + birthDate + '" />';
		},

		/**
		* Delete the occupancy cookie
		* @private
		*/
		deleteCookie: function() {
			$.cookie(priv.getCookieName(), '', { expires: -1, path: '/' });
		},

		/**		
		* Handler responsible for the reloading of the content. It makes use of the Locations object defined inside jiba.locations.js.
		*/
		reloadHandler: function() {

			if (Locations && Locations.reload) {
				Locations.reload();
			}
		},

		/**
		* Creates the link responsible for opening the party composition modal block.
		*/
		createPartyCompositionContent: function() {
			// the reload handler is called after the button that saves the party composition is clicked.
			$('#travelersDiv').html(Occupancy.getStrOccupancy(priv.reloadHandler));
		}
	};

	/** @scope Occupancy */
	return {

		/**
		* Show popup with travelers
		*/
		showTravelersPopup: function(onCloseCallback) {
			priv.initialized = false;
			priv.popup = new Lightbox({
				container: document.getElementById('pTravelers'),
				width: config.width + 'px',
				clone: false,
				onCloseCallback: onCloseCallback
			});
			priv.popup.Show();
			priv.bindPopupEvents();
			priv.showExtraNote();
		},

		/**
		* Get an array of localized strings describing the travelers
		*/
		getOccupancyLines: function() {
			return priv.getOccupancyLines();
		},


		/**
		* Bind the popup events to controls in the occupancy popup
		*/
		bindTravelerSelectors: function() {
			priv.bindPopupEvents();
		},

		/**
		* Enable showing reminder about travelers
		*/
		enableReminder: function() {
			priv.showReminder = true;
		},

		/**
		* Get the number of adults in the group
		* @returns {Integer} The number of adults
		*/
		getNrAdults: function() {
			return parseInt(priv.nrAdults);
		},

		/**
		* Get the number of children in the group
		* @returns {Integer} The number of children
		*/
		getNrChildren: function() {
			return parseInt(priv.nrChildren);
		},

		/**
		* Get the number of babies in the group
		* @returns {Integer} The number of babies
		*/
		getNrBabies: function() {
			return parseInt(priv.nrBabies);
		},

		/**
		* Get the occupancy total: the sum of the number of adults and the number of children
		* @return {Integer} The total occupancy
		*/
		getOccupancy: function() {
			return parseInt(priv.nrAdults) + parseInt(priv.nrChildren);
		},

		/**
		* Get the occupancy markup
		*/
		getStrOccupancy: function() {
			var TRAVELERS = Resource.GetText('travelers');
			var CHANGE = Resource.GetText('travelers_change');
			var SELECT = Resource.GetText('travelers_select');

			var strOccupancy = TRAVELERS + ' (<a href="javascript:Occupancy.showTravelersPopup()" class="drilllink">';

			var occupancyLines = priv.getOccupancyLines();
			if (occupancyLines.length >= 1) {
				strOccupancy += CHANGE + '</a>)<br/>';
				strOccupancy += '<ul class="usp-texts"><li>' + occupancyLines.join('</li><li>') + '</li></ul>';
				return strOccupancy;
			}

			return strOccupancy + SELECT + '</a>)';
		},

		getOccupancyLines: function() {
			return priv.getOccupancyLines();
		},

		/**
		* Set default cookie with two adults - for now only used on Vaya
		*/
		setDefaultCookie: function() {
			// set cookie to default of 2 adults
			priv.filterSearch = config.filterSearch;
			priv.nrAdults = 2;
			priv.nrChildren = 0;
			priv.nrBabies = 0;
			priv.arrAdults = new Array();
			priv.arrChildren = new Array();
			priv.arrBabies = new Array();

			var addParticipant1 = new Participant();
			var addParticipant2 = new Participant();
			addParticipant1.type = 'Adult';
			addParticipant2.type = 'Adult';
			addParticipant1.geboortedatum = null;
			addParticipant2.geboortedatum = null;

			priv.arrAdults[0] = addParticipant1;
			priv.arrAdults[1] = addParticipant2;

			priv.saveCookie();
		},

		removeFilterSearch: function() {
			priv.filterSearch = 0;
			priv.saveCookie();
		},

		/**
		* Save the travelers and update the travelers / occupancy info div.
		*/
		saveTravelers: function(blockPageRefresh) {
			// check if the birthdays are correct
			if (!priv.checkBirthDaysCorrect()) {
				// stop if the birthdays are incorrect
				return false;
			} else {
				// delete cookie if there are no occupants. else save the cookie
				if (Occupancy.getOccupancy() == 0) {
					priv.deleteCookie();
				} else {
					priv.saveCookie();
				}
				// show the new travelers information in the div
				$('#travelersDiv').html(Occupancy.getStrOccupancy());
				if (priv.popup != null) priv.popup.Close();

				// do google analytics eventtracking
				//check if there's an instance of a Analytics JS object in memory
				if (typeof Analytics != 'undefined') {
					Analytics.TrackOccupancy();
				}

				if (priv.autorefresh) {
					if (($('#refeshOnOccupancyChange').length && $('#refeshOnOccupancyChange').val() == '1') ||
						Resource.GetText('issearchpage') == 'true' ||
						Resource.GetText('isofferspage') == 'true' ||
						location.href.indexOf('view=prices') != -1) {
						if (location.href.indexOf('#') != -1) {
							location.href = location.href.substring(0, location.href.indexOf('#'));
						} else {
							location.href = location.href;
						}
					}
					else if ($('#nr1').length || $('#searchbar').length) {
						return;
					}
					else {
						if (blockPageRefresh) {
							return;
						} else {
							// refresh page to apply new filter
							if (location.href.indexOf('#') != -1) {
								location.href = location.href.substring(0, location.href.indexOf('#'));
							} else {
								location.href = location.href;
							}
						}
					}
				}
			}
		},

		/**
		* Enables/disables the autorefresh function
		*/
		enableAutoRefresh: function() {
			priv.autorefresh = true;
		},

		disableAutoRefresh: function() {
			priv.autorefresh = false;
		},


		/**
		* Reset occupancy to specified total amount of travelers. 
		* In the absence of additional information, all of them will be adults. 
		*/
		saveTotalTravelers: function(total) {
			priv.nrAdults = total;
			priv.nrChildren = 0;
			priv.nrBabies = 0;
			priv.arrAdults = new Array();
			priv.arrChildren = new Array();
			priv.arrBabies = new Array();

			for (var i = 0; i < total; i++) {
				var addParticipant = new Participant();
				addParticipant.type = 'Adult';
				addParticipant.geboortedatum = null;
				priv.arrAdults.push(addParticipant);
			}

			Occupancy.saveTravelers();
		},

		/**
		* Remove the travelers settings and reload the page.
		*/
		removeTravelers: function() {
			// remove cookie
			priv.deleteCookie();
			// reload page
			location.href = location.href;
		},

		/**
		* Save the occupancy, the same as saveTravelers(), except this is used by the lastminute wizard.
		* Here the traveler selection boxes are shown on the page itself and not in the lightbox
		*/
		lmtop10_saveTravelers: function() {
			var wizardValid = true;

			//check if there's an instance of a VakantieWizard JS object in memory
			if (typeof VakantieWizard != 'undefined') {
				//if so, check the chosen occupancy is ok to continue the wizard
				wizardValid = VakantieWizard.checkOccupancy(priv.nrAdults);
			}

			if (wizardValid) {
				// check if the birthdays are correct
				if (!priv.checkBirthDaysCorrect()) {
					// stop if the birthdays are incorrect
					return false;
				} else {
					// delete cookie if there are no occupants. else save the cookie
					if (Occupancy.getOccupancy() == 0) {
						priv.deleteCookie();
					} else {
						priv.saveCookie();
					}

					//call server side logic to process occupancy in the vakantiewizard
					VakantieWizard.setAnswer(0);
				}
			}
		},

		changeNrAdults: function() {
			var newValue = parseInt($('#nr-adults').val());
			if (newValue == 0) {
				priv.arrAdults = new Array();
			} else {
				if (newValue < priv.nrAdults) {
					priv.arrAdults = priv.arrAdults.slice(0, newValue);
				} else if (newValue > priv.nrAdults) {
					for (var i = priv.nrAdults; i < newValue; i++) {
						var addPart = new Participant();
						addPart.type = 'Adult';
						priv.arrAdults[i] = addPart;
					}
				}
			}

			priv.nrAdults = newValue;

			priv.showExtraNote();

			priv.updatePopupSize();
		},

		/**
		* 
		*/
		reloadHandler: function() {

			priv.reloadHandler();
		},

		/**
		* Creates the link responsible for opening the party composition block.
		*/
		createPartyCompositionContent: function() {

			priv.createPartyCompositionContent();
		},

		deleteCookie: function() {
			priv.deleteCookie();
		},
		/**
		* Called on $(document).ready() to initialize the occupancy object
		* @param {boolean} blockPageRefresh If set to true, it will block the reloading of the page.
		* @param {function} callbackHandler A handler called after the function executes.
		*/
		OnReady: function(configParams, blockPageRefresh, callbackHandler) {
			config.bind(configParams);

			if ($('#occWitdh').val() != undefined) {
				config.bind({ width: $('#occWitdh').val() });
			}


			// load the travelers data from cookie
			priv.loadCookie();

			// Bind click event to the 'opslaan' button
			$('#pTravelers .main input[type=button]').bind('click', function() {
				Occupancy.saveTravelers(blockPageRefresh);

				if (typeof callbackHandler === 'function') {
					callbackHandler();
				}
			});

			// show the travelers information in the div
			priv.createPartyCompositionContent();
		}
	};
} (jQuery);
/*** End of file: generic/sundio/occupancy.js ***/
/*** Start of file: generic/sundio/personalitems.js ***/
/**
 * @class personal items
 */
var PersonalItems = function($){

    /** @namespace Private methods and variables */
    var priv = {

        /**
         * @type Array
         * @private
         */
        lists   : [],
        
        /**
         * Indication to use the profile instead of cookies
         * @type Bool
         * @private
         */
        useProfile : false,
        
        /**
         * Url to http handler to use when storing and retrieving values for the profile
         * @type String
         * @private
         */
        profileHandlerUrl : '',
        
        /**
         * @type String
         * @private
         */
        myPersonalItems : "#my-personal-items",
        
        /**
         * Number of days that cookie remains valid
         * @type Integer
         * @private
         */
        cookieExpires	: 365,

        /**
         * Avoids cookie getting bigger than 4kB, 185 is a safe number
         * @type Integer
         * @private
         */
        maxCookieItems	: 50,
        
        /**
         * object that contains cookie item information
         * @param {Integer} id, identifier for object
         * @param {Number} date, milliseconds since 1 1 1970
         * @private
         */
        cookieItem	: function(id, date){
            this.id		= id;
            this.date	= date;
        },
        
        /**
         * Saves the cookieItems to the cookie 
         * @param {String} cookieName, the name for the cookie
         * @private
         */
        saveCookieItems	: function(cookieName){
            //first make sure we have the requested list
            if (!priv.lists[cookieName]) {
                Log.Debug("PersonalItems: trying to save to cookie '" + cookieName + "', no such list exists");
                return false;
            }
            var cookieStr = "";
            
            //make sure we do not exceed the priv.maxCookieItems
            priv.lists[cookieName] = priv.checkMaxCookieItems(priv.lists[cookieName]);
                        
            //make sorting by Id before adding to cookie
            //priv.lists[cookieName].sort(priv.sortCookieItemsById);
            
            //create string for cookie, in format: ID1_millisecs1,ID2_millisecs2, .....
            for (var i = 0; i < priv.lists[cookieName].length; i++) {
                //make sure we are not inserting corrupted items
                if(!isNaN(parseInt(priv.lists[cookieName][i].id)) && priv.lists[cookieName][i].date){
                    cookieStr += priv.lists[cookieName][i].id + "_" + priv.lists[cookieName][i].date + ",";
                }
            }
            
            $.cookie(Resource.GetTextForCookie('cookie-prefix') + "" + cookieName, cookieStr, { expires: priv.cookieExpires, path: '/' });
            
            return true;
        },
        
        /**
         * loads the cookieItems from the given cookie
         * @param {String} cookieName, the name of the cookie to get
         * @return {Object} The cookie item
         * @private
         */
        loadCookieItems	: function(cookieName){			
            //check wether we had already loaded this array, if so return that array
            if(priv.lists[cookieName] && priv.lists[cookieName].length > 0){
                return priv.lists[cookieName];
            }
            
            priv.lists[cookieName] = new Array();
            //fill temp array
            //get the favoritesCookie
            //markup like accoId1_timemillisecs1,accoId2_timemillisecs2,
            
            var cookieStr = $.cookie(Resource.GetText('cookie-prefix') + "" + cookieName);
        
            Log.Debug("PersonalItems: " + cookieName + ":\n" + cookieStr);
                        
            if(cookieStr && cookieStr.length > 1){
                //cookie exists and contains data
                var cookieArr = cookieStr.split(",");
                //strip last item (always emtpy because of trailing ",")
                cookieArr.length = cookieArr.length - 1;
                
                //get push the cookie into the items array
                for(var i=0; i<cookieArr.length; i++){
                    var thisItem = cookieArr[i].split("_");
                    priv.lists[cookieName].push(new priv.cookieItem(thisItem[0], thisItem[1]));
                }
                priv.lists[cookieName].sort(priv.sortCookieItemsById);
            }
            
            return priv.lists[cookieName];
        },
        
        /**
         * loads the personal items from the user profile
         * @param {String} cookieName, the name of the prifile id to get
         * @return {Object} The profile items
         * @private
         */
        loadProfileItems : function(cookieName){
			//check wether we had already loaded this array, if so return that array
            if(priv.lists[cookieName] && priv.lists[cookieName].length > 0){
                return priv.lists[cookieName];
            }
            
            $.ajax({
				async: false,
				url: priv.profileHandlerUrl,
				data: { 'action': 'get', 'type': cookieName },
				//data: "action=get&type=" + cookieName,
				cache: false,
				success: function(data) {	
					priv.lists[cookieName] = new Array();
					for(var i=0; i<data.length; i++){
						var thisItem = data[i];
						priv.lists[cookieName].push(new priv.cookieItem(thisItem.DataId, priv.getDateForCookie()));
					}
					priv.lists[cookieName].sort(priv.sortCookieItemsById);
					
					Log.Debug("PersonalItems (profile): Loaded " + data.length + " items from list '" + cookieName + "'");
				},
				error: function(result) {
					Log.Debug("PersonalItems (profile): failed to load items from list '" + cookieName + "'");
				}
			});
			
			return priv.lists[cookieName];
        },
                
        /**
         * Custom sort function used to sort arrays of cookieItem objects by id
         * @private
         */
        sortCookieItemsById	: function(a, b){
            var returnValue = 0;
            try {
                returnValue = (a.id - b.id);
            }
            catch(err){
                Log.Debug("PersonalItems: Error sortCookieItemsById:\n" + err);
            }
            return (isNaN(returnValue) ? 0 : returnValue);
        },
        
        /**
         * Custom sort function used to sort arrays of cookieItem objects by id
         * @private
         */
        sortCookieItemsByDate	: function(a, b){
            returnValue = 0;
            try {
                returnValue = (b.date - a.date);
            }
            catch(err){
                Log.Debug("PersonalItems: Error: sortCookieItemsByDate:\n" + err);
            }
            return returnValue;
        },
        
        /**
         * returns string: formated to the timestamp for the cookie
         * @param {Object} date (optional)
         * @private
         */
        getDateForCookie	: function (date) {
            var currDate = new Date();
            
            if (typeof(date) != "undefined" && date != null) {
                currDate = date;
            }
            
            return Date.parse(currDate);
        },
        
        /**
         * returns Date object with date from string
         * @param {String} cookieDate
         * @private
         */
        getDateFromCookie	: function(cookieDate){						
            var returnDate = new Date();
            returnDate.setTime(cookieDate);
            
            Log.Debug("PersonalItems: " + returnDate.toString());
            return returnDate;
        },
        
        /**
         * Checks that we not exceed the priv.maxCookieItems
         * if priv.maxCookieItems is exceeded, strips oldest items, and returns newest
         * @param {Array} cookieItems, the array with cookieItem objects to test
         * @return array with correct amount of cookieItems
         * @private
         */
        checkMaxCookieItems	: function(cookieItems){
            //if the array is bigger than defined maximum, strip oldest items
            if(cookieItems.length > priv.maxCookieItems){
                Log.Debug("PersonalItems: Stripping oldest cookieItems from array");
                //sort by date, strip the oldest items
                cookieItems.sort(priv.sortCookieItemsByDate);
                cookieItems.length = priv.maxCookieItems;
            }
                        
            return cookieItems;
        },
        
        /**
         * Merges all current values in the cookie to the profile. Values in the cookie
         * will be removed after merging.
         * @private
         */
        mergeCookieWithProfile : function(){
			for(cookieName in priv.lists){
				var cookieContent = $.cookie(Resource.GetText('cookie-prefix') + "" + cookieName);
				if (cookieContent){				
					// Force refresh from cookie
					priv.lists[cookieName].length = 0;
					priv.loadCookieItems(cookieName);
					
					// Add items from cookie to profile				
					$(priv.lists[cookieName]).each(function(index) {
							PersonalItems.Add(cookieName, this.id);
						}
					);
					
					// Remove cookie values
					priv.lists[cookieName].length = 0;
					priv.saveCookieItems(cookieName);
					
					// Reload from profile				
					PersonalItems.Load(cookieName);
				}
			}			
		}
    };
    
    /**
     * @scope PersonalItems
     */
    return {

        /**
         * loads the cookieItems from the given cookie
         * @param {String} cookieName, the name of the cookie to get
         * @return {Object} The cookie item
         */
        Load : function(cookieName){
            if (priv.useProfile) {
				return priv.loadProfileItems(cookieName);
			}
            else {
				return priv.loadCookieItems(cookieName);
			}
        },
        
        /**
         * Adds or updates the current array with the Id and Current Date stamp
         * and saves the cookie after updating
         * @param {String} cookieName, the name of the list to store
         * @param {Integer} matchId, the id of the item to store
         */
        Add : function(cookieName, matchId){
            var timer = new Timer();
            //check wether we already had this list
			if(!priv.lists[cookieName]){
				//create the list
				priv.lists[cookieName] = new Array();
			}
                        
			//check wether we already had this item
			//if found in the array, only update the date field
			var exists = false;
			for(var i=0; i<priv.lists[cookieName].length; i++){
				if(priv.lists[cookieName][i].id == matchId){
					priv.lists[cookieName][i].date = priv.getDateForCookie();
					exists = true;
					Log.Debug("PersonalItems(cache): updating item '" + matchId + "' in list '" + cookieName + "'");
					break;
				}	
			}
            
			//if the item was not found in the array, insert new item
			if(!exists){
				priv.lists[cookieName].push(new priv.cookieItem(matchId, priv.getDateForCookie()));
				Log.Debug("PersonalItems(cache): add new item '" + matchId + "' in list '" + cookieName + "'");
			}
			
            if (priv.useProfile) {
				$.ajax({
					url: priv.profileHandlerUrl,
					data: { 'action': 'insert', 'data-id': matchId, 'type': cookieName },
					//data: "action=insert&data-id=" + matchId + "&type=" + cookieName,
					cache: false,
					success: function(result) {
						Log.Debug("PersonalItems(profile): add new item '" + matchId + "' in list '" + cookieName + "'");
					},
					error: function(result) {
						Log.Debug("PersonalItems(profile): failed to add new item '" + matchId + "' in list '" + cookieName + "'");
					}
				}); 
            }
            else {
				priv.saveCookieItems(cookieName);
            }
            Log.Debug("PersonalItems: saving value took: " + timer.Stop() + " ms");
        },
        
        /**
         * Removes an item from the given list and saves the cookie
         * and saves the cookie after updating
         * @param {String} cookieName, the name of the list from which to remove
         * @param {Integer} matchId, the id of the item to remove
         */
        Remove  : function(cookieName, matchId){
			// Remove element from user profile
			if (priv.useProfile) {
				$.ajax({
					url: priv.profileHandlerUrl,
					data: { 'action': 'delete', 'data-id': matchId, 'type': cookieName },
					cache: false,
					success: function(result) {
						Log.Debug("PersonalItems (profile): removed item '" + matchId + "' from list '" + cookieName + "'");
					},
					error: function(result) {
						Log.Debug("PersonalItems (profile): failed to removed item '" + matchId + "' from list '" + cookieName + "'");
					}
				});
			}
			//always remove element from cookie as well
			//get the correct array index, and remove
			for(i=0; i<priv.lists[cookieName].length; i++){
				if(priv.lists[cookieName][i].id == matchId){
					priv.lists[cookieName].splice(i, 1);
					Log.Debug("PersonalItems: removed item '" + matchId + "' from list '" + cookieName + "'");
					priv.saveCookieItems(cookieName);
					break;
				}
			}			
        },
        
        /**
         * Removes the cookie for the given name
         * @param {String} cookieName, the name of the list from which to remove
         */
        RemoveAll  : function(cookieName){
			if (priv.useProfile) {
				$.ajax({
					url: priv.profileHandlerUrl,
					data: { 'action': 'clear', 'type': cookieName },
					cache: false,
					success: function(result) {
						Log.Debug("PersonalItems(profile): removed all from list '" + cookieName + "'");
					},
					error: function(result) {
						Log.Debug("PersonalItems(profile): failed to removed all from list '" + cookieName + "'");
					}
				});
			}
            //remove cookie
            priv.lists[cookieName].length = 0;
            Log.Debug("PersonalItems: removed all from list '" + cookieName + "'");
            priv.saveCookieItems(cookieName);
        },
        
        /**
         * Tests wether a certain item exists in the given array
         * @param {String} cookieName, the name of the list to search
         * @param {Integer} matchId, the id of the item to find
         * returns {Boolean} True if the id exists in the array
         */
        Contains  : function(cookieName, matchId){
            //make sure the array has been loaded
            this.Load(cookieName);
            
            //check if the id exists in the array
            for(i=0; i<priv.lists[cookieName].length; i++){
                if(priv.lists[cookieName][i].id == matchId){
                    //if found, return true
                    return true;
                }
            }
            //not found, return false
            return false;
        },
        
        /**
         * returns Date object with date from string
         * @param {String} cookieDate The cookie date string
         * @return {Date} The date
         */
        GetDate : function(cookieDate){
            return priv.getDateFromCookie(cookieDate);
        },
        
        /**
		* Gets the amount of items for the given cookieName
		*/
		GetItemCount : function(cookieName){
			if(priv.lists[cookieName]){
				return priv.lists[cookieName].length;
			}
			
			return 0;
		},
		
		/**
		* Switch to use the profile instead of cookies
		*/
		UseProfile : function(handlerUrl){
			if(priv.useProfile == false) {
				priv.useProfile = true;
				priv.profileHandlerUrl = Resource.GetText('path_prefix') + handlerUrl;
				priv.mergeCookieWithProfile();
			}
		},
		
		/**
		* Switch to use cookies instead of the profile
		*/
		UseCookies : function(){
			if(priv.useProfile == true) {			
				priv.useProfile = false;
				for(cookieName in priv.lists){  
					priv.lists[cookieName].length = 0;
					priv.loadCookieItems(cookieName);
				}
			}			
		},
        
        /**
         * Shows the links for the personal items, and (re)calculates the counters
         */
        ShowItemLinks : function(){
            for(cookieName in priv.lists){                
                var $item = $("#my-" + cookieName.toLowerCase() + "-items");
                var counterIdentifier = "my-" + cookieName.toLowerCase() + "-count";
                // Allow counters to be marked with id or css class
                var $counter = $("#" + counterIdentifier + ",." + counterIdentifier);
                
                if($item.attr("id") && priv.lists[cookieName].length > 0){
                    Log.Debug("PersonalItems: showing personal link: " + $item.attr("id") + " with count: " + priv.lists[cookieName].length);
                    
                    $counter.html("(" + priv.lists[cookieName].length + ")").css("visibility", "visible").removeClass("inactive");
                    $item.removeClass("inactive");
                    $item.unbind('click');
                                        
                    //if the item has visibility:hidden style, show, and set bindings
                    if($item.css("visibility") == "hidden"){
                        if($item.attr('class') == 'drillsel'){
                            $item.css("visibility", "visible").bind("click", 
                                function(){
                                    document.location.href = Resource.GetText('path_prefix') + "/_search/search.aspx?N=0";
                                    return false;
                                }
                            );
                        } else {
                            $item.css("visibility", "visible").bind("click", 
                                function(){
                                    //to make the redirect: 
                                    //strip current querystring (if any)
                                    //var newUrl = document.location.href.substring(0, document.location.href.indexOf("?"));
                                    
                                    cookieName = this.id.substring(this.id.indexOf("-") + 1, this.id.lastIndexOf("-"));
                                    //add favorites parameter
                                    document.location.href = Resource.GetText('path_prefix') + "/_search/search.aspx?N=0&personal=" + cookieName;
                                    return false;
                                }
                            );
                        }
                    }
                }
                else {
                    //hide the links if array is emtpy
                    //$item.css("visibility", "hidden");
                    //$counter.css("visibility", "hidden");
                    
                    //show the links, even when the count is 0
                    //but do not make them active
                    $item.css("visibility", "visible").addClass("inactive");
                    $counter.html("(0)").css("visibility", "visible").addClass("inactive");
                    $item.click(function() { return false; });
                }
            }
        }
    };
}(jQuery);

/*** End of file: generic/sundio/personalitems.js ***/
/*** Start of file: generic/sundio/direct-to-control.js ***/
/**
 * Class is highly dependent on specific HTML structure (select with nested options)
 * @class DirectTo Used to create a dropdown with several options to see results for a selected destination
 * @constructor
 * @param {Object} configParams The configuration settings for initializing the direct-to control
 */
var DirectTo = function(configParams){
    
    /** @namespace Default configuration settings for the direct-to control */
    var config = {
        
        /**
         * html element that contains the select tag
         * @type HTMLElement
         */
        container : null,

        /**
         * Array of possible document names of the search page
         * @type Array
         */
        searchpagePath : ["zoeken.aspx"],

        /**
         * Array of possible document names of the offers page
         * @type Array
         */
        offerspagePath : ["lastminutes.aspx"],

        /**
         * Default logging object, used to log debug messages
         * @type Function
         */
        debuglogger : Log.Debug,
                
        /**
         * For internal use. Bind the configuration parameters supplied to the constructor to the direct-to control's configuration
         * @param {Object} params The configuration parameters from the constructor
         * @private
         */
        bind : function(params){
            if(params){
                for(param in params){
                    config[param] = params[param];
                }
            }
            //config binding done
            config.init = true;
        },

        /**
         * For internal use. Determines if the binding of config is done
         * @type Boolean
         * @private
         */
        init : false
    }; 
    
    //bind the configuration
    config.bind(configParams);
    
    //enum definitions
    var enums = {
        searchtype : {'search' : 'enum_search', 'offers' : 'enum_offers'}
    };
    
    /** @namespace Private methods and variables */
    var priv = {

        /**
         * Determines the current type of search
         * @type String
         * @private
         */
        searchtype : enums.searchtype.search,

        /**
         * Navigation of the currently selected item (to be set in navigation)
         * @type String
         * @private
         */
        navigationValue : '0',
        
        /**
         * Constructor; initialize the direct-to control
         * @private
         */
        init : function(){
            //test whether we actually have a valid container element, that actually contains items
            if(!config.container){
                config.debuglogger("DirectTo: No container element found.");
                return;
            }
            
            //determine the current searchtype
            if(priv.isInPagePath(config.offerspagePath)){
                priv.searchtype = enums.searchtype.offers;
            }
            config.debuglogger("DirectTo: Current search type is: " + priv.searchtype);
            
            //now bind the events to the object
            $(config.container).bind("change", 
                function(evt){
                    priv.navigate();
                }
            );
            
            // Select an initial value
            priv.selectDirectTo();
        },
        
        /**
         * Logic to make a selection based on the breadcrumbs
         * @private
         */
        selectDirectTo : function(){
            var destLength = $('.result-properties td.breadcrumb a').length;
            if(destLength){
                var destinationName = $('.result-properties td.breadcrumb span').get(0).innerHTML;
                var breadLength = $('.result-properties td.breadcrumb a').length;
                if(breadLength == 1){
                    $(config.container).find("option[class='c']:contains('"+destinationName+"')").attr('selected', 'selected');
                } else if (breadLength == 2){
                    $(config.container).find("option[class='r']:contains('"+destinationName+"')").attr('selected', 'selected');
                } else {
                    $(config.container).find("option:contains('"+destinationName+"')").attr('selected', 'selected');
                }
            }
        },
        
        /**
         * Logic to navigate to the new page
         * @private
         */
        navigate : function(){
            //let them know we have been triggered
            config.debuglogger("DirectTo: navigate method called and executing.");
            
            //get the newly selected navigation value
            priv.navigationValue = $(config.container).val();
            
            //if the newly selected navigationValue is not valid, exit the method
            if(!priv.navigationValue || priv.navigationValue == '-1'){
                return;
            }
            
            //if on search/offers page test availability with current Endeca navigation when navigating to a new location
            priv.checkAvailability();
            
            //navigate to new location with the new navigation value
            //if we are on the offers page, stay here
            if(priv.searchtype == enums.searchtype.offers){
                config.debuglogger("DirectTo: Navigating to offers page with navigation value: " + priv.navigationValue);
                location.href = priv.getLocationPath(config.offerspagePath[0]);
            }
            else {
                //default go to the searchpage
                config.debuglogger("DirectTo: Navigating to offers search with navigation value: " + priv.navigationValue);
                location.href = priv.getLocationPath(config.searchpagePath[0]);
            }
        },
        
        
        /**
         * Tests the availability for the newly selected navigation value when the location is altered 
         * @private
         */
        checkAvailability : function(){
            //if we are not on the offers or search page, checking is not required, so simply exit the method.
            if(priv.searchtype != enums.searchtype.offers && !priv.isInPagePath(config.searchpagePath)){
                return;
            }
            
            config.debuglogger("DirectTo: Checking availability for new selected navigation");
            
            //if required the location id is provided in the options of the container, get the selected value
            var locationId = $(config.container).find(":selected").attr("rel");
            
            //if the locationId is not valid, checking is not required, exit the method
            if(!locationId){
                return;
            }
            
            config.debuglogger("DirectTo: Currently selected location is: " + locationId);
            
            //TODO make the ajax request to the backend for the availability check
            
        },
        
        /**
         * Returns a path based on the documentPath supplied, that represents the search location and navigation values
         * @param {String} documentPath The path to the current document
         * @private
         */
        getLocationPath : function(documentPath){
            config.debuglogger("DirectTo: Navigating to offers search with navigation value: " + priv.navigationValue);
            return Resource.GetText("path_prefix") + "/" + documentPath + "?N=" + priv.navigationValue;
        },
        
        /**
         * Tests if the given path (array) exists in the location.href
         * @param {Array} pagePath By the config provided search or offerspagePath
         * @private
         */
        isInPagePath : function(pagePath){
            //find the offerspagePath in the current location
            var tmppageArray = $.grep(pagePath, 
                function(a){
                    if(location.href.indexOf(a) != -1){
                        return a;
                    }
                }
            );
            //if the tmppageArray has at least one value return true, otherwise false
            return tmppageArray.length > 0;
        }
    };
    
    priv.init();
};

/*** End of file: generic/sundio/direct-to-control.js ***/
/*** Start of file: generic/sundio/user-opinion.js ***/
/**
 * Wraps around a supplied jQuery element and binds an onclick function: if the element is clicked, a lightbox is loaded
 * with the lightboxContent defined in the options object, which allows the user to give his opinion about the site.
 * @class UserOpinion Provides functionality to let a user give his opinion about the site
 * @constructor
 * @param {Object} options The options for the useropinion object
 */
function UserOpinion(options) {
    
    /** @namespace Configuration settings  */
    var config = {

        /**
         * Whether the UserOpinion object has been initialized
         * @type Boolean
         */
        init: false,

        /**
         *
         * @type String
         */
        handler: "",

        /**
         * 
         * @type String
         */
        popupContent: "",

        /**
         *
         * @type String
         */
        id: "userOpinion",

        /**
         *
         * @type String
         */
        width: "643px",
        
        /**
         * For internal use. Binds configuration parameters supplied to the useropinion object's constructor.
         * @param {Object} params
         * @private
         */
        bind : function(params){
            if(params){
                for(param in params){
                    config[param] = params[param];
                }
            }
            //config binding done
            config.init = true;
        }
    };
    
    /** @namespace Private methods and variables */
    var priv = {
        lightbox: null,
        /**
         * Set to true while processing the form, prevents double submitting when a user double-clicks the submit button
         * @type Boolean
         * @private
         */
        sendReactionClicked: false,

        /**
         * Initialize the UserOpinion object
         * @private
         */
        init: function() {
            $('body').append("<div id='ribbon-tag'><div class='img-1'></div><div class='img-2'></div><div class='img-3'></div><div class='img-4'></div><div class='img-5'></div></div>");
            $("#ribbon-tag div").bind('click', function() {
                if ($("#" + config.id).length < 1) {
                    $('body').append("<div id=\"" + config.id + "\"></div>");
                }

                priv.lightbox = Lightbox.CreateCached(config.id, {
                    container: document.getElementById(config.id),
                    contentUrl: config.popupContent,
                    width: config.width
                }, function () {
                    $(priv.lightbox.GetHtml()).find('input[type=button]').bind('click', priv.sendReaction);
                });

                priv.lightbox.Show();
            });
        },

        /**
         * Send the user opinion to the server using an ajax call.
         * @private
         */
        sendReaction: function() {
            if (!priv.sendReactionClicked) { // make sure the email isn't sent multiple times
                priv.sendReactionClicked = true;

                // input values
                var message = $('#reaction-txtMessage').val();
                var fromName = $('#reaction-txtFromName').val();
                var fromEmail = $('#reaction-txtFromEmail').val();

                var reg = new RegExp("^[A-Za-z0-9._%-]+@(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,8}$");

                if (fromEmail == '' || !reg.test(fromEmail)) {
	                priv.showSendReactionError(Resource.GetText('useropinion_email_error'));
	            }
	            else {
	                $.ajax({
		                type: "POST",
		                url: config.handler,
			            data: 'message=' + message + '&fromName=' + fromName + '&fromEmail=' + fromEmail,
			            async: true,
                        success: priv.successSendReaction,
                        error: priv.errorSendReaction
		            });
	            }
	        }
        },

        /**
         * Called after a successful submit of the user opinion to the server 
         * @param {Object} result The result of the ajax call
         * @private
         */
        successSendReaction: function(result) {
	        // reset input boxes
            $('#reaction-txtMessage').val('');
            $('#reaction-txtFromName').val('');
            $('#reaction-txtFromEmail').val('');
	        $('#sendReactionContent').hide();
	        $('#sendReactionMessage').show();

	        priv.sendReactionClicked = false;
	    },

        /**
         * Called after an error occurred during the submit of the user opinion to the server 
         * @param {Object} result The result of the ajax call
         * @private
         */
        errorSendReaction: function(result) {
	        priv.showSendReactionError(Resource.GetText("error_common"));
	        priv.sendReactionClicked = false;
        },

        /**
         * Called when an error has occurred while submitting the user opinion; shows an error message  
         * @param {String} errorMsg The error message to show
         * @private
         */
        showSendReactionError: function(errorMsg) {
	        $('#sendreaction-errormsg').show();
	        $('#sendreaction-errormsg').html(errorMsg);
	        priv.sendReactionClicked = false;
            priv.lightbox.UpdateSize();
        }
    };
    
    config.bind(options);
    priv.init();
}/*** End of file: generic/sundio/user-opinion.js ***/
/*** Start of file: generic/sundio/generic-popup.js ***/
/**
 * This object contains common behaviors. All generic functions that can be used on controls are placed here.
 * 
 *
 */
 var GenericPopup = function($) {

    /**
    * @namespace Private methods and properties
    */
    var priv = {

        
    };

    /**
    * @scope Behaviour
    */
    return {

        /**
        * Allows to set a unique radio button into a set of radiobuttons. 
        * The behavior of radio group does not work if the name of the set is not exacly the same 
        * This function forces the behavior.
        * @param {String} nameOfGroup The name that associates the radio butttons
        * @param {String} current The element itself
        */
        open_popup : function(pagina, w, h)  {
	        var parameters = "width=" + w + ", height=" + h + ", left=100, top=50, toolbar=0, location=0, directories=0, status=0, menubar=0, scrollbars=1, resizable=1";
	        var winpopup = window.top.winpopup;
			
	        window.top.winpopup = window.open(pagina, '_blank', parameters);
	        window.top.winpopup.focus()
        }
    };
} (jQuery);/*** End of file: generic/sundio/generic-popup.js ***/

