
/*
* jQuery JavaScript Library v1.3.2
* http://jquery.com/
*
* Copyright (c) 2009 John Resig
* Dual licensed under the MIT and GPL licenses.
* http://docs.jquery.com/License
*
* Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
* Revision: 6246
*/
(function() {
    var l = this, g, y = l.jQuery, p = l.$, o = l.jQuery = l.$ = function(E, F) { return new o.fn.init(E, F) }, D = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/, f = /^.[^:#\[\.,]*$/; o.fn = o.prototype = { init: function(E, H) { E = E || document; if (E.nodeType) { this[0] = E; this.length = 1; this.context = E; return this } if (typeof E === "string") { var G = D.exec(E); if (G && (G[1] || !H)) { if (G[1]) { E = o.clean([G[1]], H) } else { var I = document.getElementById(G[3]); if (I && I.id != G[3]) { return o().find(E) } var F = o(I || []); F.context = document; F.selector = E; return F } } else { return o(H).find(E) } } else { if (o.isFunction(E)) { return o(document).ready(E) } } if (E.selector && E.context) { this.selector = E.selector; this.context = E.context } return this.setArray(o.isArray(E) ? E : o.makeArray(E)) }, selector: "", jquery: "1.3.2", size: function() { return this.length }, get: function(E) { return E === g ? Array.prototype.slice.call(this) : this[E] }, pushStack: function(F, H, E) { var G = o(F); G.prevObject = this; G.context = this.context; if (H === "find") { G.selector = this.selector + (this.selector ? " " : "") + E } else { if (H) { G.selector = this.selector + "." + H + "(" + E + ")" } } return G }, setArray: function(E) { this.length = 0; Array.prototype.push.apply(this, E); return this }, each: function(F, E) { return o.each(this, F, E) }, index: function(E) { return o.inArray(E && E.jquery ? E[0] : E, this) }, attr: function(F, H, G) { var E = F; if (typeof F === "string") { if (H === g) { return this[0] && o[G || "attr"](this[0], F) } else { E = {}; E[F] = H } } return this.each(function(I) { for (F in E) { o.attr(G ? this.style : this, F, o.prop(this, E[F], G, I, F)) } }) }, css: function(E, F) { if ((E == "width" || E == "height") && parseFloat(F) < 0) { F = g } return this.attr(E, F, "curCSS") }, text: function(F) { if (typeof F !== "object" && F != null) { return this.empty().append((this[0] && this[0].ownerDocument || document).createTextNode(F)) } var E = ""; o.each(F || this, function() { o.each(this.childNodes, function() { if (this.nodeType != 8) { E += this.nodeType != 1 ? this.nodeValue : o.fn.text([this]) } }) }); return E }, wrapAll: function(E) { if (this[0]) { var F = o(E, this[0].ownerDocument).clone(); if (this[0].parentNode) { F.insertBefore(this[0]) } F.map(function() { var G = this; while (G.firstChild) { G = G.firstChild } return G }).append(this) } return this }, wrapInner: function(E) { return this.each(function() { o(this).contents().wrapAll(E) }) }, wrap: function(E) { return this.each(function() { o(this).wrapAll(E) }) }, append: function() { return this.domManip(arguments, true, function(E) { if (this.nodeType == 1) { this.appendChild(E) } }) }, prepend: function() { return this.domManip(arguments, true, function(E) { if (this.nodeType == 1) { this.insertBefore(E, this.firstChild) } }) }, before: function() { return this.domManip(arguments, false, function(E) { this.parentNode.insertBefore(E, this) }) }, after: function() { return this.domManip(arguments, false, function(E) { this.parentNode.insertBefore(E, this.nextSibling) }) }, end: function() { return this.prevObject || o([]) }, push: [].push, sort: [].sort, splice: [].splice, find: function(E) { if (this.length === 1) { var F = this.pushStack([], "find", E); F.length = 0; o.find(E, this[0], F); return F } else { return this.pushStack(o.unique(o.map(this, function(G) { return o.find(E, G) })), "find", E) } }, clone: function(G) { var E = this.map(function() { if (!o.support.noCloneEvent && !o.isXMLDoc(this)) { var I = this.outerHTML; if (!I) { var J = this.ownerDocument.createElement("div"); J.appendChild(this.cloneNode(true)); I = J.innerHTML } return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0] } else { return this.cloneNode(true) } }); if (G === true) { var H = this.find("*").andSelf(), F = 0; E.find("*").andSelf().each(function() { if (this.nodeName !== H[F].nodeName) { return } var I = o.data(H[F], "events"); for (var K in I) { for (var J in I[K]) { o.event.add(this, K, I[K][J], I[K][J].data) } } F++ }) } return E }, filter: function(E) { return this.pushStack(o.isFunction(E) && o.grep(this, function(G, F) { return E.call(G, F) }) || o.multiFilter(E, o.grep(this, function(F) { return F.nodeType === 1 })), "filter", E) }, closest: function(E) { var G = o.expr.match.POS.test(E) ? o(E) : null, F = 0; return this.map(function() { var H = this; while (H && H.ownerDocument) { if (G ? G.index(H) > -1 : o(H).is(E)) { o.data(H, "closest", F); return H } H = H.parentNode; F++ } }) }, not: function(E) { if (typeof E === "string") { if (f.test(E)) { return this.pushStack(o.multiFilter(E, this, true), "not", E) } else { E = o.multiFilter(E, this) } } var F = E.length && E[E.length - 1] !== g && !E.nodeType; return this.filter(function() { return F ? o.inArray(this, E) < 0 : this != E }) }, add: function(E) { return this.pushStack(o.unique(o.merge(this.get(), typeof E === "string" ? o(E) : o.makeArray(E)))) }, is: function(E) { return !!E && o.multiFilter(E, this).length > 0 }, hasClass: function(E) { return !!E && this.is("." + E) }, val: function(K) { if (K === g) { var E = this[0]; if (E) { if (o.nodeName(E, "option")) { return (E.attributes.value || {}).specified ? E.value : E.text } if (o.nodeName(E, "select")) { var I = E.selectedIndex, L = [], M = E.options, H = E.type == "select-one"; if (I < 0) { return null } for (var F = H ? I : 0, J = H ? I + 1 : M.length; F < J; F++) { var G = M[F]; if (G.selected) { K = o(G).val(); if (H) { return K } L.push(K) } } return L } return (E.value || "").replace(/\r/g, "") } return g } if (typeof K === "number") { K += "" } return this.each(function() { if (this.nodeType != 1) { return } if (o.isArray(K) && /radio|checkbox/.test(this.type)) { this.checked = (o.inArray(this.value, K) >= 0 || o.inArray(this.name, K) >= 0) } else { if (o.nodeName(this, "select")) { var N = o.makeArray(K); o("option", this).each(function() { this.selected = (o.inArray(this.value, N) >= 0 || o.inArray(this.text, N) >= 0) }); if (!N.length) { this.selectedIndex = -1 } } else { this.value = K } } }) }, html: function(E) { return E === g ? (this[0] ? this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") : null) : this.empty().append(E) }, replaceWith: function(E) { return this.after(E).remove() }, eq: function(E) { return this.slice(E, +E + 1) }, slice: function() { return this.pushStack(Array.prototype.slice.apply(this, arguments), "slice", Array.prototype.slice.call(arguments).join(",")) }, map: function(E) { return this.pushStack(o.map(this, function(G, F) { return E.call(G, F, G) })) }, andSelf: function() { return this.add(this.prevObject) }, domManip: function(J, M, L) { if (this[0]) { var I = (this[0].ownerDocument || this[0]).createDocumentFragment(), F = o.clean(J, (this[0].ownerDocument || this[0]), I), H = I.firstChild; if (H) { for (var G = 0, E = this.length; G < E; G++) { L.call(K(this[G], H), this.length > 1 || G > 0 ? I.cloneNode(true) : I) } } if (F) { o.each(F, z) } } return this; function K(N, O) { return M && o.nodeName(N, "table") && o.nodeName(O, "tr") ? (N.getElementsByTagName("tbody")[0] || N.appendChild(N.ownerDocument.createElement("tbody"))) : N } } }; o.fn.init.prototype = o.fn; function z(E, F) { if (F.src) { o.ajax({ url: F.src, async: false, dataType: "script" }) } else { o.globalEval(F.text || F.textContent || F.innerHTML || "") } if (F.parentNode) { F.parentNode.removeChild(F) } } function e() { return +new Date } o.extend = o.fn.extend = function() { var J = arguments[0] || {}, H = 1, I = arguments.length, E = false, G; if (typeof J === "boolean") { E = J; J = arguments[1] || {}; H = 2 } if (typeof J !== "object" && !o.isFunction(J)) { J = {} } if (I == H) { J = this; --H } for (; H < I; H++) { if ((G = arguments[H]) != null) { for (var F in G) { var K = J[F], L = G[F]; if (J === L) { continue } if (E && L && typeof L === "object" && !L.nodeType) { J[F] = o.extend(E, K || (L.length != null ? [] : {}), L) } else { if (L !== g) { J[F] = L } } } } } return J }; var b = /z-?index|font-?weight|opacity|zoom|line-?height/i, q = document.defaultView || {}, s = Object.prototype.toString; o.extend({ noConflict: function(E) { l.$ = p; if (E) { l.jQuery = y } return o }, isFunction: function(E) { return s.call(E) === "[object Function]" }, isArray: function(E) { return s.call(E) === "[object Array]" }, isXMLDoc: function(E) { return E.nodeType === 9 && E.documentElement.nodeName !== "HTML" || !!E.ownerDocument && o.isXMLDoc(E.ownerDocument) }, globalEval: function(G) { if (G && /\S/.test(G)) { var F = document.getElementsByTagName("head")[0] || document.documentElement, E = document.createElement("script"); E.type = "text/javascript"; if (o.support.scriptEval) { E.appendChild(document.createTextNode(G)) } else { E.text = G } F.insertBefore(E, F.firstChild); F.removeChild(E) } }, nodeName: function(F, E) { return F.nodeName && F.nodeName.toUpperCase() == E.toUpperCase() }, each: function(G, K, F) { var E, H = 0, I = G.length; if (F) { if (I === g) { for (E in G) { if (K.apply(G[E], F) === false) { break } } } else { for (; H < I; ) { if (K.apply(G[H++], F) === false) { break } } } } else { if (I === g) { for (E in G) { if (K.call(G[E], E, G[E]) === false) { break } } } else { for (var J = G[0]; H < I && K.call(J, H, J) !== false; J = G[++H]) { } } } return G }, prop: function(H, I, G, F, E) { if (o.isFunction(I)) { I = I.call(H, F) } return typeof I === "number" && G == "curCSS" && !b.test(E) ? I + "px" : I }, className: { add: function(E, F) { o.each((F || "").split(/\s+/), function(G, H) { if (E.nodeType == 1 && !o.className.has(E.className, H)) { E.className += (E.className ? " " : "") + H } }) }, remove: function(E, F) { if (E.nodeType == 1) { E.className = F !== g ? o.grep(E.className.split(/\s+/), function(G) { return !o.className.has(F, G) }).join(" ") : "" } }, has: function(F, E) { return F && o.inArray(E, (F.className || F).toString().split(/\s+/)) > -1 } }, swap: function(H, G, I) { var E = {}; for (var F in G) { E[F] = H.style[F]; H.style[F] = G[F] } I.call(H); for (var F in G) { H.style[F] = E[F] } }, css: function(H, F, J, E) { if (F == "width" || F == "height") { var L, G = { position: "absolute", visibility: "hidden", display: "block" }, K = F == "width" ? ["Left", "Right"] : ["Top", "Bottom"]; function I() { L = F == "width" ? H.offsetWidth : H.offsetHeight; if (E === "border") { return } o.each(K, function() { if (!E) { L -= parseFloat(o.curCSS(H, "padding" + this, true)) || 0 } if (E === "margin") { L += parseFloat(o.curCSS(H, "margin" + this, true)) || 0 } else { L -= parseFloat(o.curCSS(H, "border" + this + "Width", true)) || 0 } }) } if (H.offsetWidth !== 0) { I() } else { o.swap(H, G, I) } return Math.max(0, Math.round(L)) } return o.curCSS(H, F, J) }, curCSS: function(I, F, G) { var L, E = I.style; if (F == "opacity" && !o.support.opacity) { L = o.attr(E, "opacity"); return L == "" ? "1" : L } if (F.match(/float/i)) { F = w } if (!G && E && E[F]) { L = E[F] } else { if (q.getComputedStyle) { if (F.match(/float/i)) { F = "float" } F = F.replace(/([A-Z])/g, "-$1").toLowerCase(); var M = q.getComputedStyle(I, null); if (M) { L = M.getPropertyValue(F) } if (F == "opacity" && L == "") { L = "1" } } else { if (I.currentStyle) { var J = F.replace(/\-(\w)/g, function(N, O) { return O.toUpperCase() }); L = I.currentStyle[F] || I.currentStyle[J]; if (!/^\d+(px)?$/i.test(L) && /^\d/.test(L)) { var H = E.left, K = I.runtimeStyle.left; I.runtimeStyle.left = I.currentStyle.left; E.left = L || 0; L = E.pixelLeft + "px"; E.left = H; I.runtimeStyle.left = K } } } } return L }, clean: function(F, K, I) { K = K || document; if (typeof K.createElement === "undefined") { K = K.ownerDocument || K[0] && K[0].ownerDocument || document } if (!I && F.length === 1 && typeof F[0] === "string") { var H = /^<(\w+)\s*\/?>$/.exec(F[0]); if (H) { return [K.createElement(H[1])] } } var G = [], E = [], L = K.createElement("div"); o.each(F, function(P, S) { if (typeof S === "number") { S += "" } if (!S) { return } if (typeof S === "string") { S = S.replace(/(<(\w+)[^>]*?)\/>/g, function(U, V, T) { return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? U : V + "></" + T + ">" }); var O = S.replace(/^\s+/, "").substring(0, 10).toLowerCase(); var Q = !O.indexOf("<opt") && [1, "<select multiple='multiple'>", "</select>"] || !O.indexOf("<leg") && [1, "<fieldset>", "</fieldset>"] || O.match(/^<(thead|tbody|tfoot|colg|cap)/) && [1, "<table>", "</table>"] || !O.indexOf("<tr") && [2, "<table><tbody>", "</tbody></table>"] || (!O.indexOf("<td") || !O.indexOf("<th")) && [3, "<table><tbody><tr>", "</tr></tbody></table>"] || !O.indexOf("<col") && [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"] || !o.support.htmlSerialize && [1, "div<div>", "</div>"] || [0, "", ""]; L.innerHTML = Q[1] + S + Q[2]; while (Q[0]--) { L = L.lastChild } if (!o.support.tbody) { var R = /<tbody/i.test(S), N = !O.indexOf("<table") && !R ? L.firstChild && L.firstChild.childNodes : Q[1] == "<table>" && !R ? L.childNodes : []; for (var M = N.length - 1; M >= 0; --M) { if (o.nodeName(N[M], "tbody") && !N[M].childNodes.length) { N[M].parentNode.removeChild(N[M]) } } } if (!o.support.leadingWhitespace && /^\s/.test(S)) { L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]), L.firstChild) } S = o.makeArray(L.childNodes) } if (S.nodeType) { G.push(S) } else { G = o.merge(G, S) } }); if (I) { for (var J = 0; G[J]; J++) { if (o.nodeName(G[J], "script") && (!G[J].type || G[J].type.toLowerCase() === "text/javascript")) { E.push(G[J].parentNode ? G[J].parentNode.removeChild(G[J]) : G[J]) } else { if (G[J].nodeType === 1) { G.splice.apply(G, [J + 1, 0].concat(o.makeArray(G[J].getElementsByTagName("script")))) } I.appendChild(G[J]) } } return E } return G }, attr: function(J, G, K) { if (!J || J.nodeType == 3 || J.nodeType == 8) { return g } var H = !o.isXMLDoc(J), L = K !== g; G = H && o.props[G] || G; if (J.tagName) { var F = /href|src|style/.test(G); if (G == "selected" && J.parentNode) { J.parentNode.selectedIndex } if (G in J && H && !F) { if (L) { if (G == "type" && o.nodeName(J, "input") && J.parentNode) { throw "type property can't be changed" } J[G] = K } if (o.nodeName(J, "form") && J.getAttributeNode(G)) { return J.getAttributeNode(G).nodeValue } if (G == "tabIndex") { var I = J.getAttributeNode("tabIndex"); return I && I.specified ? I.value : J.nodeName.match(/(button|input|object|select|textarea)/i) ? 0 : J.nodeName.match(/^(a|area)$/i) && J.href ? 0 : g } return J[G] } if (!o.support.style && H && G == "style") { return o.attr(J.style, "cssText", K) } if (L) { J.setAttribute(G, "" + K) } var E = !o.support.hrefNormalized && H && F ? J.getAttribute(G, 2) : J.getAttribute(G); return E === null ? g : E } if (!o.support.opacity && G == "opacity") { if (L) { J.zoom = 1; J.filter = (J.filter || "").replace(/alpha\([^)]*\)/, "") + (parseInt(K) + "" == "NaN" ? "" : "alpha(opacity=" + K * 100 + ")") } return J.filter && J.filter.indexOf("opacity=") >= 0 ? (parseFloat(J.filter.match(/opacity=([^)]*)/)[1]) / 100) + "" : "" } G = G.replace(/-([a-z])/ig, function(M, N) { return N.toUpperCase() }); if (L) { J[G] = K } return J[G] }, trim: function(E) { return (E || "").replace(/^\s+|\s+$/g, "") }, makeArray: function(G) { var E = []; if (G != null) { var F = G.length; if (F == null || typeof G === "string" || o.isFunction(G) || G.setInterval) { E[0] = G } else { while (F) { E[--F] = G[F] } } } return E }, inArray: function(G, H) { for (var E = 0, F = H.length; E < F; E++) { if (H[E] === G) { return E } } return -1 }, merge: function(H, E) { var F = 0, G, I = H.length; if (!o.support.getAll) { while ((G = E[F++]) != null) { if (G.nodeType != 8) { H[I++] = G } } } else { while ((G = E[F++]) != null) { H[I++] = G } } return H }, unique: function(K) { var F = [], E = {}; try { for (var G = 0, H = K.length; G < H; G++) { var J = o.data(K[G]); if (!E[J]) { E[J] = true; F.push(K[G]) } } } catch (I) { F = K } return F }, grep: function(F, J, E) { var G = []; for (var H = 0, I = F.length; H < I; H++) { if (!E != !J(F[H], H)) { G.push(F[H]) } } return G }, map: function(E, J) { var F = []; for (var G = 0, H = E.length; G < H; G++) { var I = J(E[G], G); if (I != null) { F[F.length] = I } } return F.concat.apply([], F) } }); var C = navigator.userAgent.toLowerCase(); o.browser = { version: (C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [0, "0"])[1], safari: /webkit/.test(C), opera: /opera/.test(C), msie: /msie/.test(C) && !/opera/.test(C), mozilla: /mozilla/.test(C) && !/(compatible|webkit)/.test(C) }; o.each({ parent: function(E) { return E.parentNode }, parents: function(E) { return o.dir(E, "parentNode") }, next: function(E) { return o.nth(E, 2, "nextSibling") }, prev: function(E) { return o.nth(E, 2, "previousSibling") }, nextAll: function(E) { return o.dir(E, "nextSibling") }, prevAll: function(E) { return o.dir(E, "previousSibling") }, siblings: function(E) { return o.sibling(E.parentNode.firstChild, E) }, children: function(E) { return o.sibling(E.firstChild) }, contents: function(E) { return o.nodeName(E, "iframe") ? E.contentDocument || E.contentWindow.document : o.makeArray(E.childNodes) } }, function(E, F) { o.fn[E] = function(G) { var H = o.map(this, F); if (G && typeof G == "string") { H = o.multiFilter(G, H) } return this.pushStack(o.unique(H), E, G) } }); o.each({ appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function(E, F) { o.fn[E] = function(G) { var J = [], L = o(G); for (var K = 0, H = L.length; K < H; K++) { var I = (K > 0 ? this.clone(true) : this).get(); o.fn[F].apply(o(L[K]), I); J = J.concat(I) } return this.pushStack(J, E, G) } }); o.each({ removeAttr: function(E) { o.attr(this, E, ""); if (this.nodeType == 1) { this.removeAttribute(E) } }, addClass: function(E) { o.className.add(this, E) }, removeClass: function(E) { o.className.remove(this, E) }, toggleClass: function(F, E) { if (typeof E !== "boolean") { E = !o.className.has(this, F) } o.className[E ? "add" : "remove"](this, F) }, remove: function(E) { if (!E || o.filter(E, [this]).length) { o("*", this).add([this]).each(function() { o.event.remove(this); o.removeData(this) }); if (this.parentNode) { this.parentNode.removeChild(this) } } }, empty: function() { o(this).children().remove(); while (this.firstChild) { this.removeChild(this.firstChild) } } }, function(E, F) { o.fn[E] = function() { return this.each(F, arguments) } }); function j(E, F) { return E[0] && parseInt(o.curCSS(E[0], F, true), 10) || 0 } var h = "jQuery" + e(), v = 0, A = {}; o.extend({ cache: {}, data: function(F, E, G) { F = F == l ? A : F; var H = F[h]; if (!H) { H = F[h] = ++v } if (E && !o.cache[H]) { o.cache[H] = {} } if (G !== g) { o.cache[H][E] = G } return E ? o.cache[H][E] : H }, removeData: function(F, E) { F = F == l ? A : F; var H = F[h]; if (E) { if (o.cache[H]) { delete o.cache[H][E]; E = ""; for (E in o.cache[H]) { break } if (!E) { o.removeData(F) } } } else { try { delete F[h] } catch (G) { if (F.removeAttribute) { F.removeAttribute(h) } } delete o.cache[H] } }, queue: function(F, E, H) { if (F) { E = (E || "fx") + "queue"; var G = o.data(F, E); if (!G || o.isArray(H)) { G = o.data(F, E, o.makeArray(H)) } else { if (H) { G.push(H) } } } return G }, dequeue: function(H, G) { var E = o.queue(H, G), F = E.shift(); if (!G || G === "fx") { F = E[0] } if (F !== g) { F.call(H) } } }); o.fn.extend({ data: function(E, G) { var H = E.split("."); H[1] = H[1] ? "." + H[1] : ""; if (G === g) { var F = this.triggerHandler("getData" + H[1] + "!", [H[0]]); if (F === g && this.length) { F = o.data(this[0], E) } return F === g && H[1] ? this.data(H[0]) : F } else { return this.trigger("setData" + H[1] + "!", [H[0], G]).each(function() { o.data(this, E, G) }) } }, removeData: function(E) { return this.each(function() { o.removeData(this, E) }) }, queue: function(E, F) { if (typeof E !== "string") { F = E; E = "fx" } if (F === g) { return o.queue(this[0], E) } return this.each(function() { var G = o.queue(this, E, F); if (E == "fx" && G.length == 1) { G[0].call(this) } }) }, dequeue: function(E) { return this.each(function() { o.dequeue(this, E) }) } });
    /*
    * Sizzle CSS Selector Engine - v0.9.3
    *  Copyright 2009, The Dojo Foundation
    *  Released under the MIT, BSD, and GPL Licenses.
    *  More information: http://sizzlejs.com/
    */
    (function() { var R = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g, L = 0, H = Object.prototype.toString; var F = function(Y, U, ab, ac) { ab = ab || []; U = U || document; if (U.nodeType !== 1 && U.nodeType !== 9) { return [] } if (!Y || typeof Y !== "string") { return ab } var Z = [], W, af, ai, T, ad, V, X = true; R.lastIndex = 0; while ((W = R.exec(Y)) !== null) { Z.push(W[1]); if (W[2]) { V = RegExp.rightContext; break } } if (Z.length > 1 && M.exec(Y)) { if (Z.length === 2 && I.relative[Z[0]]) { af = J(Z[0] + Z[1], U) } else { af = I.relative[Z[0]] ? [U] : F(Z.shift(), U); while (Z.length) { Y = Z.shift(); if (I.relative[Y]) { Y += Z.shift() } af = J(Y, af) } } } else { var ae = ac ? { expr: Z.pop(), set: E(ac)} : F.find(Z.pop(), Z.length === 1 && U.parentNode ? U.parentNode : U, Q(U)); af = F.filter(ae.expr, ae.set); if (Z.length > 0) { ai = E(af) } else { X = false } while (Z.length) { var ah = Z.pop(), ag = ah; if (!I.relative[ah]) { ah = "" } else { ag = Z.pop() } if (ag == null) { ag = U } I.relative[ah](ai, ag, Q(U)) } } if (!ai) { ai = af } if (!ai) { throw "Syntax error, unrecognized expression: " + (ah || Y) } if (H.call(ai) === "[object Array]") { if (!X) { ab.push.apply(ab, ai) } else { if (U.nodeType === 1) { for (var aa = 0; ai[aa] != null; aa++) { if (ai[aa] && (ai[aa] === true || ai[aa].nodeType === 1 && K(U, ai[aa]))) { ab.push(af[aa]) } } } else { for (var aa = 0; ai[aa] != null; aa++) { if (ai[aa] && ai[aa].nodeType === 1) { ab.push(af[aa]) } } } } } else { E(ai, ab) } if (V) { F(V, U, ab, ac); if (G) { hasDuplicate = false; ab.sort(G); if (hasDuplicate) { for (var aa = 1; aa < ab.length; aa++) { if (ab[aa] === ab[aa - 1]) { ab.splice(aa--, 1) } } } } } return ab }; F.matches = function(T, U) { return F(T, null, null, U) }; F.find = function(aa, T, ab) { var Z, X; if (!aa) { return [] } for (var W = 0, V = I.order.length; W < V; W++) { var Y = I.order[W], X; if ((X = I.match[Y].exec(aa))) { var U = RegExp.leftContext; if (U.substr(U.length - 1) !== "\\") { X[1] = (X[1] || "").replace(/\\/g, ""); Z = I.find[Y](X, T, ab); if (Z != null) { aa = aa.replace(I.match[Y], ""); break } } } } if (!Z) { Z = T.getElementsByTagName("*") } return { set: Z, expr: aa} }; F.filter = function(ad, ac, ag, W) { var V = ad, ai = [], aa = ac, Y, T, Z = ac && ac[0] && Q(ac[0]); while (ad && ac.length) { for (var ab in I.filter) { if ((Y = I.match[ab].exec(ad)) != null) { var U = I.filter[ab], ah, af; T = false; if (aa == ai) { ai = [] } if (I.preFilter[ab]) { Y = I.preFilter[ab](Y, aa, ag, ai, W, Z); if (!Y) { T = ah = true } else { if (Y === true) { continue } } } if (Y) { for (var X = 0; (af = aa[X]) != null; X++) { if (af) { ah = U(af, Y, X, aa); var ae = W ^ !!ah; if (ag && ah != null) { if (ae) { T = true } else { aa[X] = false } } else { if (ae) { ai.push(af); T = true } } } } } if (ah !== g) { if (!ag) { aa = ai } ad = ad.replace(I.match[ab], ""); if (!T) { return [] } break } } } if (ad == V) { if (T == null) { throw "Syntax error, unrecognized expression: " + ad } else { break } } V = ad } return aa }; var I = F.selectors = { order: ["ID", "NAME", "TAG"], match: { ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/, CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/, NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/, ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/, CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/ }, attrMap: { "class": "className", "for": "htmlFor" }, attrHandle: { href: function(T) { return T.getAttribute("href") } }, relative: { "+": function(aa, T, Z) { var X = typeof T === "string", ab = X && !/\W/.test(T), Y = X && !ab; if (ab && !Z) { T = T.toUpperCase() } for (var W = 0, V = aa.length, U; W < V; W++) { if ((U = aa[W])) { while ((U = U.previousSibling) && U.nodeType !== 1) { } aa[W] = Y || U && U.nodeName === T ? U || false : U === T } } if (Y) { F.filter(T, aa, true) } }, ">": function(Z, U, aa) { var X = typeof U === "string"; if (X && !/\W/.test(U)) { U = aa ? U : U.toUpperCase(); for (var V = 0, T = Z.length; V < T; V++) { var Y = Z[V]; if (Y) { var W = Y.parentNode; Z[V] = W.nodeName === U ? W : false } } } else { for (var V = 0, T = Z.length; V < T; V++) { var Y = Z[V]; if (Y) { Z[V] = X ? Y.parentNode : Y.parentNode === U } } if (X) { F.filter(U, Z, true) } } }, "": function(W, U, Y) { var V = L++, T = S; if (!U.match(/\W/)) { var X = U = Y ? U : U.toUpperCase(); T = P } T("parentNode", U, V, W, X, Y) }, "~": function(W, U, Y) { var V = L++, T = S; if (typeof U === "string" && !U.match(/\W/)) { var X = U = Y ? U : U.toUpperCase(); T = P } T("previousSibling", U, V, W, X, Y) } }, find: { ID: function(U, V, W) { if (typeof V.getElementById !== "undefined" && !W) { var T = V.getElementById(U[1]); return T ? [T] : [] } }, NAME: function(V, Y, Z) { if (typeof Y.getElementsByName !== "undefined") { var U = [], X = Y.getElementsByName(V[1]); for (var W = 0, T = X.length; W < T; W++) { if (X[W].getAttribute("name") === V[1]) { U.push(X[W]) } } return U.length === 0 ? null : U } }, TAG: function(T, U) { return U.getElementsByTagName(T[1]) } }, preFilter: { CLASS: function(W, U, V, T, Z, aa) { W = " " + W[1].replace(/\\/g, "") + " "; if (aa) { return W } for (var X = 0, Y; (Y = U[X]) != null; X++) { if (Y) { if (Z ^ (Y.className && (" " + Y.className + " ").indexOf(W) >= 0)) { if (!V) { T.push(Y) } } else { if (V) { U[X] = false } } } } return false }, ID: function(T) { return T[1].replace(/\\/g, "") }, TAG: function(U, T) { for (var V = 0; T[V] === false; V++) { } return T[V] && Q(T[V]) ? U[1] : U[1].toUpperCase() }, CHILD: function(T) { if (T[1] == "nth") { var U = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2] == "even" && "2n" || T[2] == "odd" && "2n+1" || !/\D/.test(T[2]) && "0n+" + T[2] || T[2]); T[2] = (U[1] + (U[2] || 1)) - 0; T[3] = U[3] - 0 } T[0] = L++; return T }, ATTR: function(X, U, V, T, Y, Z) { var W = X[1].replace(/\\/g, ""); if (!Z && I.attrMap[W]) { X[1] = I.attrMap[W] } if (X[2] === "~=") { X[4] = " " + X[4] + " " } return X }, PSEUDO: function(X, U, V, T, Y) { if (X[1] === "not") { if (X[3].match(R).length > 1 || /^\w/.test(X[3])) { X[3] = F(X[3], null, null, U) } else { var W = F.filter(X[3], U, V, true ^ Y); if (!V) { T.push.apply(T, W) } return false } } else { if (I.match.POS.test(X[0]) || I.match.CHILD.test(X[0])) { return true } } return X }, POS: function(T) { T.unshift(true); return T } }, filters: { enabled: function(T) { return T.disabled === false && T.type !== "hidden" }, disabled: function(T) { return T.disabled === true }, checked: function(T) { return T.checked === true }, selected: function(T) { T.parentNode.selectedIndex; return T.selected === true }, parent: function(T) { return !!T.firstChild }, empty: function(T) { return !T.firstChild }, has: function(V, U, T) { return !!F(T[3], V).length }, header: function(T) { return /h\d/i.test(T.nodeName) }, text: function(T) { return "text" === T.type }, radio: function(T) { return "radio" === T.type }, checkbox: function(T) { return "checkbox" === T.type }, file: function(T) { return "file" === T.type }, password: function(T) { return "password" === T.type }, submit: function(T) { return "submit" === T.type }, image: function(T) { return "image" === T.type }, reset: function(T) { return "reset" === T.type }, button: function(T) { return "button" === T.type || T.nodeName.toUpperCase() === "BUTTON" }, input: function(T) { return /input|select|textarea|button/i.test(T.nodeName) } }, setFilters: { first: function(U, T) { return T === 0 }, last: function(V, U, T, W) { return U === W.length - 1 }, even: function(U, T) { return T % 2 === 0 }, odd: function(U, T) { return T % 2 === 1 }, lt: function(V, U, T) { return U < T[3] - 0 }, gt: function(V, U, T) { return U > T[3] - 0 }, nth: function(V, U, T) { return T[3] - 0 == U }, eq: function(V, U, T) { return T[3] - 0 == U } }, filter: { PSEUDO: function(Z, V, W, aa) { var U = V[1], X = I.filters[U]; if (X) { return X(Z, W, V, aa) } else { if (U === "contains") { return (Z.textContent || Z.innerText || "").indexOf(V[3]) >= 0 } else { if (U === "not") { var Y = V[3]; for (var W = 0, T = Y.length; W < T; W++) { if (Y[W] === Z) { return false } } return true } } } }, CHILD: function(T, W) { var Z = W[1], U = T; switch (Z) { case "only": case "first": while (U = U.previousSibling) { if (U.nodeType === 1) { return false } } if (Z == "first") { return true } U = T; case "last": while (U = U.nextSibling) { if (U.nodeType === 1) { return false } } return true; case "nth": var V = W[2], ac = W[3]; if (V == 1 && ac == 0) { return true } var Y = W[0], ab = T.parentNode; if (ab && (ab.sizcache !== Y || !T.nodeIndex)) { var X = 0; for (U = ab.firstChild; U; U = U.nextSibling) { if (U.nodeType === 1) { U.nodeIndex = ++X } } ab.sizcache = Y } var aa = T.nodeIndex - ac; if (V == 0) { return aa == 0 } else { return (aa % V == 0 && aa / V >= 0) } } }, ID: function(U, T) { return U.nodeType === 1 && U.getAttribute("id") === T }, TAG: function(U, T) { return (T === "*" && U.nodeType === 1) || U.nodeName === T }, CLASS: function(U, T) { return (" " + (U.className || U.getAttribute("class")) + " ").indexOf(T) > -1 }, ATTR: function(Y, W) { var V = W[1], T = I.attrHandle[V] ? I.attrHandle[V](Y) : Y[V] != null ? Y[V] : Y.getAttribute(V), Z = T + "", X = W[2], U = W[4]; return T == null ? X === "!=" : X === "=" ? Z === U : X === "*=" ? Z.indexOf(U) >= 0 : X === "~=" ? (" " + Z + " ").indexOf(U) >= 0 : !U ? Z && T !== false : X === "!=" ? Z != U : X === "^=" ? Z.indexOf(U) === 0 : X === "$=" ? Z.substr(Z.length - U.length) === U : X === "|=" ? Z === U || Z.substr(0, U.length + 1) === U + "-" : false }, POS: function(X, U, V, Y) { var T = U[2], W = I.setFilters[T]; if (W) { return W(X, V, U, Y) } } } }; var M = I.match.POS; for (var O in I.match) { I.match[O] = RegExp(I.match[O].source + /(?![^\[]*\])(?![^\(]*\))/.source) } var E = function(U, T) { U = Array.prototype.slice.call(U); if (T) { T.push.apply(T, U); return T } return U }; try { Array.prototype.slice.call(document.documentElement.childNodes) } catch (N) { E = function(X, W) { var U = W || []; if (H.call(X) === "[object Array]") { Array.prototype.push.apply(U, X) } else { if (typeof X.length === "number") { for (var V = 0, T = X.length; V < T; V++) { U.push(X[V]) } } else { for (var V = 0; X[V]; V++) { U.push(X[V]) } } } return U } } var G; if (document.documentElement.compareDocumentPosition) { G = function(U, T) { var V = U.compareDocumentPosition(T) & 4 ? -1 : U === T ? 0 : 1; if (V === 0) { hasDuplicate = true } return V } } else { if ("sourceIndex" in document.documentElement) { G = function(U, T) { var V = U.sourceIndex - T.sourceIndex; if (V === 0) { hasDuplicate = true } return V } } else { if (document.createRange) { G = function(W, U) { var V = W.ownerDocument.createRange(), T = U.ownerDocument.createRange(); V.selectNode(W); V.collapse(true); T.selectNode(U); T.collapse(true); var X = V.compareBoundaryPoints(Range.START_TO_END, T); if (X === 0) { hasDuplicate = true } return X } } } } (function() { var U = document.createElement("form"), V = "script" + (new Date).getTime(); U.innerHTML = "<input name='" + V + "'/>"; var T = document.documentElement; T.insertBefore(U, T.firstChild); if (!!document.getElementById(V)) { I.find.ID = function(X, Y, Z) { if (typeof Y.getElementById !== "undefined" && !Z) { var W = Y.getElementById(X[1]); return W ? W.id === X[1] || typeof W.getAttributeNode !== "undefined" && W.getAttributeNode("id").nodeValue === X[1] ? [W] : g : [] } }; I.filter.ID = function(Y, W) { var X = typeof Y.getAttributeNode !== "undefined" && Y.getAttributeNode("id"); return Y.nodeType === 1 && X && X.nodeValue === W } } T.removeChild(U) })(); (function() { var T = document.createElement("div"); T.appendChild(document.createComment("")); if (T.getElementsByTagName("*").length > 0) { I.find.TAG = function(U, Y) { var X = Y.getElementsByTagName(U[1]); if (U[1] === "*") { var W = []; for (var V = 0; X[V]; V++) { if (X[V].nodeType === 1) { W.push(X[V]) } } X = W } return X } } T.innerHTML = "<a href='#'></a>"; if (T.firstChild && typeof T.firstChild.getAttribute !== "undefined" && T.firstChild.getAttribute("href") !== "#") { I.attrHandle.href = function(U) { return U.getAttribute("href", 2) } } })(); if (document.querySelectorAll) { (function() { var T = F, U = document.createElement("div"); U.innerHTML = "<p class='TEST'></p>"; if (U.querySelectorAll && U.querySelectorAll(".TEST").length === 0) { return } F = function(Y, X, V, W) { X = X || document; if (!W && X.nodeType === 9 && !Q(X)) { try { return E(X.querySelectorAll(Y), V) } catch (Z) { } } return T(Y, X, V, W) }; F.find = T.find; F.filter = T.filter; F.selectors = T.selectors; F.matches = T.matches })() } if (document.getElementsByClassName && document.documentElement.getElementsByClassName) { (function() { var T = document.createElement("div"); T.innerHTML = "<div class='test e'></div><div class='test'></div>"; if (T.getElementsByClassName("e").length === 0) { return } T.lastChild.className = "e"; if (T.getElementsByClassName("e").length === 1) { return } I.order.splice(1, 0, "CLASS"); I.find.CLASS = function(U, V, W) { if (typeof V.getElementsByClassName !== "undefined" && !W) { return V.getElementsByClassName(U[1]) } } })() } function P(U, Z, Y, ad, aa, ac) { var ab = U == "previousSibling" && !ac; for (var W = 0, V = ad.length; W < V; W++) { var T = ad[W]; if (T) { if (ab && T.nodeType === 1) { T.sizcache = Y; T.sizset = W } T = T[U]; var X = false; while (T) { if (T.sizcache === Y) { X = ad[T.sizset]; break } if (T.nodeType === 1 && !ac) { T.sizcache = Y; T.sizset = W } if (T.nodeName === Z) { X = T; break } T = T[U] } ad[W] = X } } } function S(U, Z, Y, ad, aa, ac) { var ab = U == "previousSibling" && !ac; for (var W = 0, V = ad.length; W < V; W++) { var T = ad[W]; if (T) { if (ab && T.nodeType === 1) { T.sizcache = Y; T.sizset = W } T = T[U]; var X = false; while (T) { if (T.sizcache === Y) { X = ad[T.sizset]; break } if (T.nodeType === 1) { if (!ac) { T.sizcache = Y; T.sizset = W } if (typeof Z !== "string") { if (T === Z) { X = true; break } } else { if (F.filter(Z, [T]).length > 0) { X = T; break } } } T = T[U] } ad[W] = X } } } var K = document.compareDocumentPosition ? function(U, T) { return U.compareDocumentPosition(T) & 16 } : function(U, T) { return U !== T && (U.contains ? U.contains(T) : true) }; var Q = function(T) { return T.nodeType === 9 && T.documentElement.nodeName !== "HTML" || !!T.ownerDocument && Q(T.ownerDocument) }; var J = function(T, aa) { var W = [], X = "", Y, V = aa.nodeType ? [aa] : aa; while ((Y = I.match.PSEUDO.exec(T))) { X += Y[0]; T = T.replace(I.match.PSEUDO, "") } T = I.relative[T] ? T + "*" : T; for (var Z = 0, U = V.length; Z < U; Z++) { F(T, V[Z], W) } return F.filter(X, W) }; o.find = F; o.filter = F.filter; o.expr = F.selectors; o.expr[":"] = o.expr.filters; F.selectors.filters.hidden = function(T) { return T.offsetWidth === 0 || T.offsetHeight === 0 }; F.selectors.filters.visible = function(T) { return T.offsetWidth > 0 || T.offsetHeight > 0 }; F.selectors.filters.animated = function(T) { return o.grep(o.timers, function(U) { return T === U.elem }).length }; o.multiFilter = function(V, T, U) { if (U) { V = ":not(" + V + ")" } return F.matches(V, T) }; o.dir = function(V, U) { var T = [], W = V[U]; while (W && W != document) { if (W.nodeType == 1) { T.push(W) } W = W[U] } return T }; o.nth = function(X, T, V, W) { T = T || 1; var U = 0; for (; X; X = X[V]) { if (X.nodeType == 1 && ++U == T) { break } } return X }; o.sibling = function(V, U) { var T = []; for (; V; V = V.nextSibling) { if (V.nodeType == 1 && V != U) { T.push(V) } } return T }; return; l.Sizzle = F })(); o.event = { add: function(I, F, H, K) { if (I.nodeType == 3 || I.nodeType == 8) { return } if (I.setInterval && I != l) { I = l } if (!H.guid) { H.guid = this.guid++ } if (K !== g) { var G = H; H = this.proxy(G); H.data = K } var E = o.data(I, "events") || o.data(I, "events", {}), J = o.data(I, "handle") || o.data(I, "handle", function() { return typeof o !== "undefined" && !o.event.triggered ? o.event.handle.apply(arguments.callee.elem, arguments) : g }); J.elem = I; o.each(F.split(/\s+/), function(M, N) { var O = N.split("."); N = O.shift(); H.type = O.slice().sort().join("."); var L = E[N]; if (o.event.specialAll[N]) { o.event.specialAll[N].setup.call(I, K, O) } if (!L) { L = E[N] = {}; if (!o.event.special[N] || o.event.special[N].setup.call(I, K, O) === false) { if (I.addEventListener) { I.addEventListener(N, J, false) } else { if (I.attachEvent) { I.attachEvent("on" + N, J) } } } } L[H.guid] = H; o.event.global[N] = true }); I = null }, guid: 1, global: {}, remove: function(K, H, J) { if (K.nodeType == 3 || K.nodeType == 8) { return } var G = o.data(K, "events"), F, E; if (G) { if (H === g || (typeof H === "string" && H.charAt(0) == ".")) { for (var I in G) { this.remove(K, I + (H || "")) } } else { if (H.type) { J = H.handler; H = H.type } o.each(H.split(/\s+/), function(M, O) { var Q = O.split("."); O = Q.shift(); var N = RegExp("(^|\\.)" + Q.slice().sort().join(".*\\.") + "(\\.|$)"); if (G[O]) { if (J) { delete G[O][J.guid] } else { for (var P in G[O]) { if (N.test(G[O][P].type)) { delete G[O][P] } } } if (o.event.specialAll[O]) { o.event.specialAll[O].teardown.call(K, Q) } for (F in G[O]) { break } if (!F) { if (!o.event.special[O] || o.event.special[O].teardown.call(K, Q) === false) { if (K.removeEventListener) { K.removeEventListener(O, o.data(K, "handle"), false) } else { if (K.detachEvent) { K.detachEvent("on" + O, o.data(K, "handle")) } } } F = null; delete G[O] } } }) } for (F in G) { break } if (!F) { var L = o.data(K, "handle"); if (L) { L.elem = null } o.removeData(K, "events"); o.removeData(K, "handle") } } }, trigger: function(I, K, H, E) { var G = I.type || I; if (!E) { I = typeof I === "object" ? I[h] ? I : o.extend(o.Event(G), I) : o.Event(G); if (G.indexOf("!") >= 0) { I.type = G = G.slice(0, -1); I.exclusive = true } if (!H) { I.stopPropagation(); if (this.global[G]) { o.each(o.cache, function() { if (this.events && this.events[G]) { o.event.trigger(I, K, this.handle.elem) } }) } } if (!H || H.nodeType == 3 || H.nodeType == 8) { return g } I.result = g; I.target = H; K = o.makeArray(K); K.unshift(I) } I.currentTarget = H; var J = o.data(H, "handle"); if (J) { J.apply(H, K) } if ((!H[G] || (o.nodeName(H, "a") && G == "click")) && H["on" + G] && H["on" + G].apply(H, K) === false) { I.result = false } if (!E && H[G] && !I.isDefaultPrevented() && !(o.nodeName(H, "a") && G == "click")) { this.triggered = true; try { H[G]() } catch (L) { } } this.triggered = false; if (!I.isPropagationStopped()) { var F = H.parentNode || H.ownerDocument; if (F) { o.event.trigger(I, K, F, true) } } }, handle: function(K) { var J, E; K = arguments[0] = o.event.fix(K || l.event); K.currentTarget = this; var L = K.type.split("."); K.type = L.shift(); J = !L.length && !K.exclusive; var I = RegExp("(^|\\.)" + L.slice().sort().join(".*\\.") + "(\\.|$)"); E = (o.data(this, "events") || {})[K.type]; for (var G in E) { var H = E[G]; if (J || I.test(H.type)) { K.handler = H; K.data = H.data; var F = H.apply(this, arguments); if (F !== g) { K.result = F; if (F === false) { K.preventDefault(); K.stopPropagation() } } if (K.isImmediatePropagationStopped()) { break } } } }, props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), fix: function(H) { if (H[h]) { return H } var F = H; H = o.Event(F); for (var G = this.props.length, J; G; ) { J = this.props[--G]; H[J] = F[J] } if (!H.target) { H.target = H.srcElement || document } if (H.target.nodeType == 3) { H.target = H.target.parentNode } if (!H.relatedTarget && H.fromElement) { H.relatedTarget = H.fromElement == H.target ? H.toElement : H.fromElement } if (H.pageX == null && H.clientX != null) { var I = document.documentElement, E = document.body; H.pageX = H.clientX + (I && I.scrollLeft || E && E.scrollLeft || 0) - (I.clientLeft || 0); H.pageY = H.clientY + (I && I.scrollTop || E && E.scrollTop || 0) - (I.clientTop || 0) } if (!H.which && ((H.charCode || H.charCode === 0) ? H.charCode : H.keyCode)) { H.which = H.charCode || H.keyCode } if (!H.metaKey && H.ctrlKey) { H.metaKey = H.ctrlKey } if (!H.which && H.button) { H.which = (H.button & 1 ? 1 : (H.button & 2 ? 3 : (H.button & 4 ? 2 : 0))) } return H }, proxy: function(F, E) { E = E || function() { return F.apply(this, arguments) }; E.guid = F.guid = F.guid || E.guid || this.guid++; return E }, special: { ready: { setup: B, teardown: function() { } } }, specialAll: { live: { setup: function(E, F) { o.event.add(this, F[0], c) }, teardown: function(G) { if (G.length) { var E = 0, F = RegExp("(^|\\.)" + G[0] + "(\\.|$)"); o.each((o.data(this, "events").live || {}), function() { if (F.test(this.type)) { E++ } }); if (E < 1) { o.event.remove(this, G[0], c) } } } }} }; o.Event = function(E) { if (!this.preventDefault) { return new o.Event(E) } if (E && E.type) { this.originalEvent = E; this.type = E.type } else { this.type = E } this.timeStamp = e(); this[h] = true }; function k() { return false } function u() { return true } o.Event.prototype = { preventDefault: function() { this.isDefaultPrevented = u; var E = this.originalEvent; if (!E) { return } if (E.preventDefault) { E.preventDefault() } E.returnValue = false }, stopPropagation: function() { this.isPropagationStopped = u; var E = this.originalEvent; if (!E) { return } if (E.stopPropagation) { E.stopPropagation() } E.cancelBubble = true }, stopImmediatePropagation: function() { this.isImmediatePropagationStopped = u; this.stopPropagation() }, isDefaultPrevented: k, isPropagationStopped: k, isImmediatePropagationStopped: k }; var a = function(F) { var E = F.relatedTarget; while (E && E != this) { try { E = E.parentNode } catch (G) { E = this } } if (E != this) { F.type = F.data; o.event.handle.apply(this, arguments) } }; o.each({ mouseover: "mouseenter", mouseout: "mouseleave" }, function(F, E) { o.event.special[E] = { setup: function() { o.event.add(this, F, a, E) }, teardown: function() { o.event.remove(this, F, a) } } }); o.fn.extend({ bind: function(F, G, E) { return F == "unload" ? this.one(F, G, E) : this.each(function() { o.event.add(this, F, E || G, E && G) }) }, one: function(G, H, F) { var E = o.event.proxy(F || H, function(I) { o(this).unbind(I, E); return (F || H).apply(this, arguments) }); return this.each(function() { o.event.add(this, G, E, F && H) }) }, unbind: function(F, E) { return this.each(function() { o.event.remove(this, F, E) }) }, trigger: function(E, F) { return this.each(function() { o.event.trigger(E, F, this) }) }, triggerHandler: function(E, G) { if (this[0]) { var F = o.Event(E); F.preventDefault(); F.stopPropagation(); o.event.trigger(F, G, this[0]); return F.result } }, toggle: function(G) { var E = arguments, F = 1; while (F < E.length) { o.event.proxy(G, E[F++]) } return this.click(o.event.proxy(G, function(H) { this.lastToggle = (this.lastToggle || 0) % F; H.preventDefault(); return E[this.lastToggle++].apply(this, arguments) || false })) }, hover: function(E, F) { return this.mouseenter(E).mouseleave(F) }, ready: function(E) { B(); if (o.isReady) { E.call(document, o) } else { o.readyList.push(E) } return this }, live: function(G, F) { var E = o.event.proxy(F); E.guid += this.selector + G; o(document).bind(i(G, this.selector), this.selector, E); return this }, die: function(F, E) { o(document).unbind(i(F, this.selector), E ? { guid: E.guid + this.selector + F} : null); return this } }); function c(H) { var E = RegExp("(^|\\.)" + H.type + "(\\.|$)"), G = true, F = []; o.each(o.data(this, "events").live || [], function(I, J) { if (E.test(J.type)) { var K = o(H.target).closest(J.data)[0]; if (K) { F.push({ elem: K, fn: J }) } } }); F.sort(function(J, I) { return o.data(J.elem, "closest") - o.data(I.elem, "closest") }); o.each(F, function() { if (this.fn.call(this.elem, H, this.fn.data) === false) { return (G = false) } }); return G } function i(F, E) { return ["live", F, E.replace(/\./g, "`").replace(/ /g, "|")].join(".") } o.extend({ isReady: false, readyList: [], ready: function() { if (!o.isReady) { o.isReady = true; if (o.readyList) { o.each(o.readyList, function() { this.call(document, o) }); o.readyList = null } o(document).triggerHandler("ready") } } }); var x = false; function B() { if (x) { return } x = true; if (document.addEventListener) { document.addEventListener("DOMContentLoaded", function() { document.removeEventListener("DOMContentLoaded", arguments.callee, false); o.ready() }, false) } else { if (document.attachEvent) { document.attachEvent("onreadystatechange", function() { if (document.readyState === "complete") { document.detachEvent("onreadystatechange", arguments.callee); o.ready() } }); if (document.documentElement.doScroll && l == l.top) { (function() { if (o.isReady) { return } try { document.documentElement.doScroll("left") } catch (E) { setTimeout(arguments.callee, 0); return } o.ready() })() } } } o.event.add(l, "load", o.ready) } o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","), function(F, E) { o.fn[E] = function(G) { return G ? this.bind(E, G) : this.trigger(E) } }); o(l).bind("unload", function() { for (var E in o.cache) { if (E != 1 && o.cache[E].handle) { o.event.remove(o.cache[E].handle.elem) } } }); (function() { o.support = {}; var F = document.documentElement, G = document.createElement("script"), K = document.createElement("div"), J = "script" + (new Date).getTime(); K.style.display = "none"; K.innerHTML = '   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>'; var H = K.getElementsByTagName("*"), E = K.getElementsByTagName("a")[0]; if (!H || !H.length || !E) { return } o.support = { leadingWhitespace: K.firstChild.nodeType == 3, tbody: !K.getElementsByTagName("tbody").length, objectAll: !!K.getElementsByTagName("object")[0].getElementsByTagName("*").length, htmlSerialize: !!K.getElementsByTagName("link").length, style: /red/.test(E.getAttribute("style")), hrefNormalized: E.getAttribute("href") === "/a", opacity: E.style.opacity === "0.5", cssFloat: !!E.style.cssFloat, scriptEval: false, noCloneEvent: true, boxModel: null }; G.type = "text/javascript"; try { G.appendChild(document.createTextNode("window." + J + "=1;")) } catch (I) { } F.insertBefore(G, F.firstChild); if (l[J]) { o.support.scriptEval = true; delete l[J] } F.removeChild(G); if (K.attachEvent && K.fireEvent) { K.attachEvent("onclick", function() { o.support.noCloneEvent = false; K.detachEvent("onclick", arguments.callee) }); K.cloneNode(true).fireEvent("onclick") } o(function() { var L = document.createElement("div"); L.style.width = L.style.paddingLeft = "1px"; document.body.appendChild(L); o.boxModel = o.support.boxModel = L.offsetWidth === 2; document.body.removeChild(L).style.display = "none" }) })(); var w = o.support.cssFloat ? "cssFloat" : "styleFloat"; o.props = { "for": "htmlFor", "class": "className", "float": w, cssFloat: w, styleFloat: w, readonly: "readOnly", maxlength: "maxLength", cellspacing: "cellSpacing", rowspan: "rowSpan", tabindex: "tabIndex" }; o.fn.extend({ _load: o.fn.load, load: function(G, J, K) { if (typeof G !== "string") { return this._load(G) } var I = G.indexOf(" "); if (I >= 0) { var E = G.slice(I, G.length); G = G.slice(0, I) } var H = "GET"; if (J) { if (o.isFunction(J)) { K = J; J = null } else { if (typeof J === "object") { J = o.param(J); H = "POST" } } } var F = this; o.ajax({ url: G, type: H, dataType: "html", data: J, complete: function(M, L) { if (L == "success" || L == "notmodified") { F.html(E ? o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g, "")).find(E) : M.responseText) } if (K) { F.each(K, [M.responseText, L, M]) } } }); return this }, serialize: function() { return o.param(this.serializeArray()) }, serializeArray: function() { return this.map(function() { return this.elements ? o.makeArray(this.elements) : this }).filter(function() { return this.name && !this.disabled && (this.checked || /select|textarea/i.test(this.nodeName) || /text|hidden|password|search/i.test(this.type)) }).map(function(E, F) { var G = o(this).val(); return G == null ? null : o.isArray(G) ? o.map(G, function(I, H) { return { name: F.name, value: I} }) : { name: F.name, value: G} }).get() } }); o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(E, F) { o.fn[F] = function(G) { return this.bind(F, G) } }); var r = e(); o.extend({ get: function(E, G, H, F) { if (o.isFunction(G)) { H = G; G = null } return o.ajax({ type: "GET", url: E, data: G, success: H, dataType: F }) }, getScript: function(E, F) { return o.get(E, null, F, "script") }, getJSON: function(E, F, G) { return o.get(E, F, G, "json") }, post: function(E, G, H, F) { if (o.isFunction(G)) { H = G; G = {} } return o.ajax({ type: "POST", url: E, data: G, success: H, dataType: F }) }, ajaxSetup: function(E) { o.extend(o.ajaxSettings, E) }, ajaxSettings: { url: location.href, global: true, type: "GET", contentType: "application/x-www-form-urlencoded", processData: true, async: true, xhr: function() { return l.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest() }, accepts: { xml: "application/xml, text/xml", html: "text/html", script: "text/javascript, application/javascript", json: "application/json, text/javascript", text: "text/plain", _default: "*/*"} }, lastModified: {}, ajax: function(M) { M = o.extend(true, M, o.extend(true, {}, o.ajaxSettings, M)); var W, F = /=\?(&|$)/g, R, V, G = M.type.toUpperCase(); if (M.data && M.processData && typeof M.data !== "string") { M.data = o.param(M.data) } if (M.dataType == "jsonp") { if (G == "GET") { if (!M.url.match(F)) { M.url += (M.url.match(/\?/) ? "&" : "?") + (M.jsonp || "callback") + "=?" } } else { if (!M.data || !M.data.match(F)) { M.data = (M.data ? M.data + "&" : "") + (M.jsonp || "callback") + "=?" } } M.dataType = "json" } if (M.dataType == "json" && (M.data && M.data.match(F) || M.url.match(F))) { W = "jsonp" + r++; if (M.data) { M.data = (M.data + "").replace(F, "=" + W + "$1") } M.url = M.url.replace(F, "=" + W + "$1"); M.dataType = "script"; l[W] = function(X) { V = X; I(); L(); l[W] = g; try { delete l[W] } catch (Y) { } if (H) { H.removeChild(T) } } } if (M.dataType == "script" && M.cache == null) { M.cache = false } if (M.cache === false && G == "GET") { var E = e(); var U = M.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + E + "$2"); M.url = U + ((U == M.url) ? (M.url.match(/\?/) ? "&" : "?") + "_=" + E : "") } if (M.data && G == "GET") { M.url += (M.url.match(/\?/) ? "&" : "?") + M.data; M.data = null } if (M.global && !o.active++) { o.event.trigger("ajaxStart") } var Q = /^(\w+:)?\/\/([^\/?#]+)/.exec(M.url); if (M.dataType == "script" && G == "GET" && Q && (Q[1] && Q[1] != location.protocol || Q[2] != location.host)) { var H = document.getElementsByTagName("head")[0]; var T = document.createElement("script"); T.src = M.url; if (M.scriptCharset) { T.charset = M.scriptCharset } if (!W) { var O = false; T.onload = T.onreadystatechange = function() { if (!O && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) { O = true; I(); L(); T.onload = T.onreadystatechange = null; H.removeChild(T) } } } H.appendChild(T); return g } var K = false; var J = M.xhr(); if (M.username) { J.open(G, M.url, M.async, M.username, M.password) } else { J.open(G, M.url, M.async) } try { if (M.data) { J.setRequestHeader("Content-Type", M.contentType) } if (M.ifModified) { J.setRequestHeader("If-Modified-Since", o.lastModified[M.url] || "Thu, 01 Jan 1970 00:00:00 GMT") } J.setRequestHeader("X-Requested-With", "XMLHttpRequest"); J.setRequestHeader("Accept", M.dataType && M.accepts[M.dataType] ? M.accepts[M.dataType] + ", */*" : M.accepts._default) } catch (S) { } if (M.beforeSend && M.beforeSend(J, M) === false) { if (M.global && ! --o.active) { o.event.trigger("ajaxStop") } J.abort(); return false } if (M.global) { o.event.trigger("ajaxSend", [J, M]) } var N = function(X) { if (J.readyState == 0) { if (P) { clearInterval(P); P = null; if (M.global && ! --o.active) { o.event.trigger("ajaxStop") } } } else { if (!K && J && (J.readyState == 4 || X == "timeout")) { K = true; if (P) { clearInterval(P); P = null } R = X == "timeout" ? "timeout" : !o.httpSuccess(J) ? "error" : M.ifModified && o.httpNotModified(J, M.url) ? "notmodified" : "success"; if (R == "success") { try { V = o.httpData(J, M.dataType, M) } catch (Z) { R = "parsererror" } } if (R == "success") { var Y; try { Y = J.getResponseHeader("Last-Modified") } catch (Z) { } if (M.ifModified && Y) { o.lastModified[M.url] = Y } if (!W) { I() } } else { o.handleError(M, J, R) } L(); if (X) { J.abort() } if (M.async) { J = null } } } }; if (M.async) { var P = setInterval(N, 13); if (M.timeout > 0) { setTimeout(function() { if (J && !K) { N("timeout") } }, M.timeout) } } try { J.send(M.data) } catch (S) { o.handleError(M, J, null, S) } if (!M.async) { N() } function I() { if (M.success) { M.success(V, R) } if (M.global) { o.event.trigger("ajaxSuccess", [J, M]) } } function L() { if (M.complete) { M.complete(J, R) } if (M.global) { o.event.trigger("ajaxComplete", [J, M]) } if (M.global && ! --o.active) { o.event.trigger("ajaxStop") } } return J }, handleError: function(F, H, E, G) { if (F.error) { F.error(H, E, G) } if (F.global) { o.event.trigger("ajaxError", [H, F, G]) } }, active: 0, httpSuccess: function(F) { try { return !F.status && location.protocol == "file:" || (F.status >= 200 && F.status < 300) || F.status == 304 || F.status == 1223 } catch (E) { } return false }, httpNotModified: function(G, E) { try { var H = G.getResponseHeader("Last-Modified"); return G.status == 304 || H == o.lastModified[E] } catch (F) { } return false }, httpData: function(J, H, G) { var F = J.getResponseHeader("content-type"), E = H == "xml" || !H && F && F.indexOf("xml") >= 0, I = E ? J.responseXML : J.responseText; if (E && I.documentElement.tagName == "parsererror") { throw "parsererror" } if (G && G.dataFilter) { I = G.dataFilter(I, H) } if (typeof I === "string") { if (H == "script") { o.globalEval(I) } if (H == "json") { I = l["eval"]("(" + I + ")") } } return I }, param: function(E) { var G = []; function H(I, J) { G[G.length] = encodeURIComponent(I) + "=" + encodeURIComponent(J) } if (o.isArray(E) || E.jquery) { o.each(E, function() { H(this.name, this.value) }) } else { for (var F in E) { if (o.isArray(E[F])) { o.each(E[F], function() { H(F, this) }) } else { H(F, o.isFunction(E[F]) ? E[F]() : E[F]) } } } return G.join("&").replace(/%20/g, "+") } }); var m = {}, n, d = [["height", "marginTop", "marginBottom", "paddingTop", "paddingBottom"], ["width", "marginLeft", "marginRight", "paddingLeft", "paddingRight"], ["opacity"]]; function t(F, E) { var G = {}; o.each(d.concat.apply([], d.slice(0, E)), function() { G[this] = F }); return G } o.fn.extend({ show: function(J, L) { if (J) { return this.animate(t("show", 3), J, L) } else { for (var H = 0, F = this.length; H < F; H++) { var E = o.data(this[H], "olddisplay"); this[H].style.display = E || ""; if (o.css(this[H], "display") === "none") { var G = this[H].tagName, K; if (m[G]) { K = m[G] } else { var I = o("<" + G + " />").appendTo("body"); K = I.css("display"); if (K === "none") { K = "block" } I.remove(); m[G] = K } o.data(this[H], "olddisplay", K) } } for (var H = 0, F = this.length; H < F; H++) { this[H].style.display = o.data(this[H], "olddisplay") || "" } return this } }, hide: function(H, I) { if (H) { return this.animate(t("hide", 3), H, I) } else { for (var G = 0, F = this.length; G < F; G++) { var E = o.data(this[G], "olddisplay"); if (!E && E !== "none") { o.data(this[G], "olddisplay", o.css(this[G], "display")) } } for (var G = 0, F = this.length; G < F; G++) { this[G].style.display = "none" } return this } }, _toggle: o.fn.toggle, toggle: function(G, F) { var E = typeof G === "boolean"; return o.isFunction(G) && o.isFunction(F) ? this._toggle.apply(this, arguments) : G == null || E ? this.each(function() { var H = E ? G : o(this).is(":hidden"); o(this)[H ? "show" : "hide"]() }) : this.animate(t("toggle", 3), G, F) }, fadeTo: function(E, G, F) { return this.animate({ opacity: G }, E, F) }, animate: function(I, F, H, G) { var E = o.speed(F, H, G); return this[E.queue === false ? "each" : "queue"](function() { var K = o.extend({}, E), M, L = this.nodeType == 1 && o(this).is(":hidden"), J = this; for (M in I) { if (I[M] == "hide" && L || I[M] == "show" && !L) { return K.complete.call(this) } if ((M == "height" || M == "width") && this.style) { K.display = o.css(this, "display"); K.overflow = this.style.overflow } } if (K.overflow != null) { this.style.overflow = "hidden" } K.curAnim = o.extend({}, I); o.each(I, function(O, S) { var R = new o.fx(J, K, O); if (/toggle|show|hide/.test(S)) { R[S == "toggle" ? L ? "show" : "hide" : S](I) } else { var Q = S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/), T = R.cur(true) || 0; if (Q) { var N = parseFloat(Q[2]), P = Q[3] || "px"; if (P != "px") { J.style[O] = (N || 1) + P; T = ((N || 1) / R.cur(true)) * T; J.style[O] = T + P } if (Q[1]) { N = ((Q[1] == "-=" ? -1 : 1) * N) + T } R.custom(T, N, P) } else { R.custom(T, S, "") } } }); return true }) }, stop: function(F, E) { var G = o.timers; if (F) { this.queue([]) } this.each(function() { for (var H = G.length - 1; H >= 0; H--) { if (G[H].elem == this) { if (E) { G[H](true) } G.splice(H, 1) } } }); if (!E) { this.dequeue() } return this } }); o.each({ slideDown: t("show", 1), slideUp: t("hide", 1), slideToggle: t("toggle", 1), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide"} }, function(E, F) { o.fn[E] = function(G, H) { return this.animate(F, G, H) } }); o.extend({ speed: function(G, H, F) { var E = typeof G === "object" ? G : { complete: F || !F && H || o.isFunction(G) && G, duration: G, easing: F && H || H && !o.isFunction(H) && H }; E.duration = o.fx.off ? 0 : typeof E.duration === "number" ? E.duration : o.fx.speeds[E.duration] || o.fx.speeds._default; E.old = E.complete; E.complete = function() { if (E.queue !== false) { o(this).dequeue() } if (o.isFunction(E.old)) { E.old.call(this) } }; return E }, easing: { linear: function(G, H, E, F) { return E + F * G }, swing: function(G, H, E, F) { return ((-Math.cos(G * Math.PI) / 2) + 0.5) * F + E } }, timers: [], fx: function(F, E, G) { this.options = E; this.elem = F; this.prop = G; if (!E.orig) { E.orig = {} } } }); o.fx.prototype = { update: function() { if (this.options.step) { this.options.step.call(this.elem, this.now, this) } (o.fx.step[this.prop] || o.fx.step._default)(this); if ((this.prop == "height" || this.prop == "width") && this.elem.style) { this.elem.style.display = "block" } }, cur: function(F) { if (this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null)) { return this.elem[this.prop] } var E = parseFloat(o.css(this.elem, this.prop, F)); return E && E > -10000 ? E : parseFloat(o.curCSS(this.elem, this.prop)) || 0 }, custom: function(I, H, G) { this.startTime = e(); this.start = I; this.end = H; this.unit = G || this.unit || "px"; this.now = this.start; this.pos = this.state = 0; var E = this; function F(J) { return E.step(J) } F.elem = this.elem; if (F() && o.timers.push(F) && !n) { n = setInterval(function() { var K = o.timers; for (var J = 0; J < K.length; J++) { if (!K[J]()) { K.splice(J--, 1) } } if (!K.length) { clearInterval(n); n = g } }, 13) } }, show: function() { this.options.orig[this.prop] = o.attr(this.elem.style, this.prop); this.options.show = true; this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur()); o(this.elem).show() }, hide: function() { this.options.orig[this.prop] = o.attr(this.elem.style, this.prop); this.options.hide = true; this.custom(this.cur(), 0) }, step: function(H) { var G = e(); if (H || G >= this.options.duration + this.startTime) { this.now = this.end; this.pos = this.state = 1; this.update(); this.options.curAnim[this.prop] = true; var E = true; for (var F in this.options.curAnim) { if (this.options.curAnim[F] !== true) { E = false } } if (E) { if (this.options.display != null) { this.elem.style.overflow = this.options.overflow; this.elem.style.display = this.options.display; if (o.css(this.elem, "display") == "none") { this.elem.style.display = "block" } } if (this.options.hide) { o(this.elem).hide() } if (this.options.hide || this.options.show) { for (var I in this.options.curAnim) { o.attr(this.elem.style, I, this.options.orig[I]) } } this.options.complete.call(this.elem) } return false } else { var J = G - this.startTime; this.state = J / this.options.duration; this.pos = o.easing[this.options.easing || (o.easing.swing ? "swing" : "linear")](this.state, J, 0, 1, this.options.duration); this.now = this.start + ((this.end - this.start) * this.pos); this.update() } return true } }; o.extend(o.fx, { speeds: { slow: 600, fast: 200, _default: 400 }, step: { opacity: function(E) { o.attr(E.elem.style, "opacity", E.now) }, _default: function(E) { if (E.elem.style && E.elem.style[E.prop] != null) { E.elem.style[E.prop] = E.now + E.unit } else { E.elem[E.prop] = E.now } } } }); if (document.documentElement.getBoundingClientRect) { o.fn.offset = function() { if (!this[0]) { return { top: 0, left: 0} } if (this[0] === this[0].ownerDocument.body) { return o.offset.bodyOffset(this[0]) } var G = this[0].getBoundingClientRect(), J = this[0].ownerDocument, F = J.body, E = J.documentElement, L = E.clientTop || F.clientTop || 0, K = E.clientLeft || F.clientLeft || 0, I = G.top + (self.pageYOffset || o.boxModel && E.scrollTop || F.scrollTop) - L, H = G.left + (self.pageXOffset || o.boxModel && E.scrollLeft || F.scrollLeft) - K; return { top: I, left: H} } } else { o.fn.offset = function() { if (!this[0]) { return { top: 0, left: 0} } if (this[0] === this[0].ownerDocument.body) { return o.offset.bodyOffset(this[0]) } o.offset.initialized || o.offset.initialize(); var J = this[0], G = J.offsetParent, F = J, O = J.ownerDocument, M, H = O.documentElement, K = O.body, L = O.defaultView, E = L.getComputedStyle(J, null), N = J.offsetTop, I = J.offsetLeft; while ((J = J.parentNode) && J !== K && J !== H) { M = L.getComputedStyle(J, null); N -= J.scrollTop, I -= J.scrollLeft; if (J === G) { N += J.offsetTop, I += J.offsetLeft; if (o.offset.doesNotAddBorder && !(o.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(J.tagName))) { N += parseInt(M.borderTopWidth, 10) || 0, I += parseInt(M.borderLeftWidth, 10) || 0 } F = G, G = J.offsetParent } if (o.offset.subtractsBorderForOverflowNotVisible && M.overflow !== "visible") { N += parseInt(M.borderTopWidth, 10) || 0, I += parseInt(M.borderLeftWidth, 10) || 0 } E = M } if (E.position === "relative" || E.position === "static") { N += K.offsetTop, I += K.offsetLeft } if (E.position === "fixed") { N += Math.max(H.scrollTop, K.scrollTop), I += Math.max(H.scrollLeft, K.scrollLeft) } return { top: N, left: I} } } o.offset = { initialize: function() { if (this.initialized) { return } var L = document.body, F = document.createElement("div"), H, G, N, I, M, E, J = L.style.marginTop, K = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>'; M = { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" }; for (E in M) { F.style[E] = M[E] } F.innerHTML = K; L.insertBefore(F, L.firstChild); H = F.firstChild, G = H.firstChild, I = H.nextSibling.firstChild.firstChild; this.doesNotAddBorder = (G.offsetTop !== 5); this.doesAddBorderForTableAndCells = (I.offsetTop === 5); H.style.overflow = "hidden", H.style.position = "relative"; this.subtractsBorderForOverflowNotVisible = (G.offsetTop === -5); L.style.marginTop = "1px"; this.doesNotIncludeMarginInBodyOffset = (L.offsetTop === 0); L.style.marginTop = J; L.removeChild(F); this.initialized = true }, bodyOffset: function(E) { o.offset.initialized || o.offset.initialize(); var G = E.offsetTop, F = E.offsetLeft; if (o.offset.doesNotIncludeMarginInBodyOffset) { G += parseInt(o.curCSS(E, "marginTop", true), 10) || 0, F += parseInt(o.curCSS(E, "marginLeft", true), 10) || 0 } return { top: G, left: F} } }; o.fn.extend({ position: function() { var I = 0, H = 0, F; if (this[0]) { var G = this.offsetParent(), J = this.offset(), E = /^body|html$/i.test(G[0].tagName) ? { top: 0, left: 0} : G.offset(); J.top -= j(this, "marginTop"); J.left -= j(this, "marginLeft"); E.top += j(G, "borderTopWidth"); E.left += j(G, "borderLeftWidth"); F = { top: J.top - E.top, left: J.left - E.left} } return F }, offsetParent: function() { var E = this[0].offsetParent || document.body; while (E && (!/^body|html$/i.test(E.tagName) && o.css(E, "position") == "static")) { E = E.offsetParent } return o(E) } }); o.each(["Left", "Top"], function(F, E) { var G = "scroll" + E; o.fn[G] = function(H) { if (!this[0]) { return null } return H !== g ? this.each(function() { this == l || this == document ? l.scrollTo(!F ? H : o(l).scrollLeft(), F ? H : o(l).scrollTop()) : this[G] = H }) : this[0] == l || this[0] == document ? self[F ? "pageYOffset" : "pageXOffset"] || o.boxModel && document.documentElement[G] || document.body[G] : this[0][G] } }); o.each(["Height", "Width"], function(I, G) { var E = I ? "Left" : "Top", H = I ? "Right" : "Bottom", F = G.toLowerCase(); o.fn["inner" + G] = function() { return this[0] ? o.css(this[0], F, false, "padding") : null }; o.fn["outer" + G] = function(K) { return this[0] ? o.css(this[0], F, false, K ? "margin" : "border") : null }; var J = G.toLowerCase(); o.fn[J] = function(K) { return this[0] == l ? document.compatMode == "CSS1Compat" && document.documentElement["client" + G] || document.body["client" + G] : this[0] == document ? Math.max(document.documentElement["client" + G], document.body["scroll" + G], document.documentElement["scroll" + G], document.body["offset" + G], document.documentElement["offset" + G]) : K === g ? (this.length ? o.css(this[0], J) : null) : this.css(J, typeof K === "string" ? K : K + "px") } })
})();


//   this file is composed of:

//   confirmTinyMCEIsDirty()
//   LightboxForThumbnails()
//   ajaxupload.3.0.js
//   effects.core.js
//   jquery.corner.js
//   effects.slide.js
//   jquery.autocomplete.js
//   jquery.calculation.min.js
//   jquery.color.js
//   jquery.cookie.js
//   jquery.easing.js
//   jquery.easytooltip.js
//   jquery.getUrlParam.js
//   jquery.highlightfade.js
//   jquery.hotkeys.js
//   jquery.imghover.js
//   jquery.swap.js
//   jqmodal.js
//   resizable text
//   search in text
//   Thickbox http://jquery.com/demo/thickbox/
//   Highlight
//   URLEncode and URLDecode

// Checks for changes in a tinyMCE text editor.
var tinyMCEIsDirty = false;
function pgSetDirty(id) {
    tinyMCEIsDirty = true;
}

function confirmTinyMCEIsDirty() {
    // check if tinyMCE is defined on the page or on a iframe
    // when $("#TB_overlay").length a popup has opened
    var tmp = null;
    if (typeof tinyMCE != 'undefined' && !$("#TB_overlay").length) {
        tmp = tinyMCE;
    } else if ($("iframe").length == 1 && typeof $("iframe")[0].contentWindow.tinyMCE != 'undefined') {
        tmp = $("iframe")[0].contentWindow.tinyMCE;
    }

    // check the editors
    if (tmp) {
        var ed = new Object();
        for (ed in tmp.editors) {
            if (tmp.editors[ed].isDirty()) {
                tinyMCEIsDirty = true;
            }
        }
    }

    // check of the user will leave the page
    var leavePage = tinyMCEIsDirty
        ? confirm(labels.changesWillNotBeSaved + '\n' + labels.confirmLeavePage)
        : true;

    // reset the isdirty value
    if (leavePage) {
        tinyMCEIsDirty = false;
    }

    // return
    return leavePage;
}












//set a lightbox for thumbs on the website
function LightboxForThumbnails() {
    $("img").each(function() {
        if ($(this).attr("src").match(/\/th_.*\..{1,4}$/)) {
            $(this).wrap('<a class="thickbox" href="' + $(this).attr("src").replace('th_', '') + '" />');
        }
    });
}

//intialised here cause LightboxForThumbnails should be called before the tickbox calls
$(document).ready(function() 
{
   LightboxForThumbnails();
});











// JQUERY LIBRARY - ajaxupload.3.0.js

// *******************************************************************************
// *******************************************************************************
// *******************************************************************************
// *******************************************************************************

/**
* Ajax upload
* Project page - http://valums.com/ajax-upload/
* Copyright (c) 2008 Andris Valums, http://valums.com
* Licensed under the MIT license (http://valums.com/mit-license/)
* Version 2.6 (22.03.2009)
*/

(function() {

    var d = document, w = window;

    /**
    * Get element by id
    */
    function $(element) {
        if (typeof element == "string")
            element = d.getElementById(element);
        return element;
    }

    /**
    * Attaches event to a dom element
    */
    function addEvent(el, type, fn) {
        if (w.addEventListener) {
            el.addEventListener(type, fn, false);
        } else if (w.attachEvent) {
            var f = function() {
                fn.call(el, w.event);
            };
            el.attachEvent('on' + type, f)
        }
    }


    /**
    * Creates and returns element from html chunk
    */
    var toElement = function() {
        var div = d.createElement('div');
        return function(html) {
            div.innerHTML = html;
            var el = div.childNodes[0];
            div.removeChild(el);
            return el;
        }
    } ();

    function hasClass(ele, cls) {
        return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
    }
    function addClass(ele, cls) {
        if (!hasClass(ele, cls)) ele.className += " " + cls;
    }
    function removeClass(ele, cls) {
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
        ele.className = ele.className.replace(reg, ' ');
    }
    /*// getOffset function copied from jQuery lib (http://jquery.com/)
    if ( document.documentElement["getBoundingClientRect"] ){
    // getBoundingClientRect is Awesome
    // http://ejohn.org/blog/getboundingclientrect-is-awesome/
    function getOffset(el){
    var box = el.getBoundingClientRect(),
    doc = el.ownerDocument,
    body = doc.body,
    docElem = doc.documentElement,
    clientTop = docElem.clientTop || body.clientTop || 0,
    clientLeft = docElem.clientLeft || body.clientLeft || 0,
    top = box.top + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop || body.scrollTop) - clientTop,
    left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
    return {
    top: top,
    left: left
    };
    }
    };*/
    function getOffset(el) {
        if (w.jQuery) {
            return jQuery(el).offset();
        }

        var top = 0, left = 0;
        do {
            top += el.offsetTop || 0;
            left += el.offsetLeft || 0;
        } while (el = el.offsetParent);

        return {
            left: left,
            top: top
        };
    }

    function getBox(el) {
        var left, right, top, bottom;
        var offset = getOffset(el);
        left = offset.left;
        top = offset.top;

        right = left + el.offsetWidth;
        bottom = top + el.offsetHeight;

        return {
            left: left,
            right: right,
            top: top,
            bottom: bottom
        };
    }

    /**
    * Crossbrowser mouse coordinates
    */
    function getMouseCoords(e) {
        // pageX/Y is not supported in IE
        // http://www.quirksmode.org/dom/w3c_cssom.html			
        if (!e.pageX && e.clientX) {
            return {
                x: e.clientX + d.body.scrollLeft + d.documentElement.scrollLeft,
                y: e.clientY + d.body.scrollTop + d.documentElement.scrollTop
            };
        }

        return {
            x: e.pageX,
            y: e.pageY
        };

    }
    /**
    * Function generates unique id
    */
    var getUID = function() {
        var id = 0;
        return function() {
            return 'ValumsAjaxUpload' + id++;
        }
    } ();

    function fileFromPath(file) {
        return file.replace(/.*(\/|\\)/, "");
    }

    function getExt(file) {
        return (/[.]/.exec(file)) ? /[^.]+$/.exec(file.toLowerCase()) : '';
    }


    // Please use AjaxUpload , Ajax_upload will be removed in the next version
    Ajax_upload = AjaxUpload = function(button, options) {
        if (button.jquery) {
            // jquery object was passed
            button = button[0];
        } else if (typeof button == "string" && /^#.*/.test(button)) {
            button = button.slice(1);
        }
        button = $(button);

        this._input = null;
        this._button = button;
        this._disabled = false;
        this._submitting = false;

        this._settings = {
            // Location of the server-side upload script
            action: 'upload.php',
            // File upload name
            name: 'userfile',
            // Additional data to send
            data: {},
            // Submit file as soon as it's selected
            autoSubmit: true,
            // When user selects a file, useful with autoSubmit disabled			
            onChange: function(file, extension) { },
            // Callback to fire before file is uploaded
            // You can return false to cancel upload
            onSubmit: function(file, extension) { },
            // Fired when file upload is completed
            onComplete: function(file, response) { }
        };

        // Merge the users options with our defaults
        for (var i in options) {
            this._settings[i] = options[i];
        }

        this._createInput();
        this._rerouteClicks();
    }

    // assigning methods to our class
    AjaxUpload.prototype = {
        setData: function(data) {
            this._settings.data = data;
        },
        disable: function() {
            this._disabled = true;
        },
        enable: function() {
            this._disabled = false;
        },
        // use setData instead, set_data will be removed in the next version
        set_data: function(data) {
            this.setData(data);
        },
        // removes ajaxupload
        destroy: function() {
            if (this._input) {
                if (this._input.parentNode) {
                    this._input.parentNode.removeChild(this._input);
                }
                this._input = null;
            }
        },
        /**
        * Creates invisible file input above the button 
        */
        _createInput: function() {
            var self = this;
            var input = d.createElement("input");
            input.setAttribute('type', 'file');
            input.setAttribute('name', this._settings.name);
            var styles = {
                'position': 'absolute'
            , 'margin': '-5px 0 0 -165px'
			, 'padding': 0
			, 'width': '220px'
			, 'height': '10px'
            , 'opacity': 0
			, 'cursor': 'pointer'
			, 'display': 'none'
			, 'zIndex': 2147483583 //Max zIndex supported by Opera 9.0-9.2x 
                // Strange, I expected 2147483647					
            };
            for (var i in styles) {
                input.style[i] = styles[i];
            }

            // Make sure that element opacity exists
            // (IE uses filter instead)
            if (!(input.style.opacity === "0")) {
                input.style.filter = "alpha(opacity=0)";
            }
            d.body.appendChild(input);

            addEvent(input, 'change', function() {
                // get filename from input
                var file = fileFromPath(this.value);
                if (self._settings.onChange.call(self, file, getExt(file)) == false) {
                    return;
                }
                // Submit form when value is changed
                if (self._settings.autoSubmit) {
                    self.submit();
                }
            });

            this._input = input;
        },
        _rerouteClicks: function() {
            var self = this;

            // IE displays 'access denied' error when using this method
            // other browsers just ignore click()
            // addEvent(this._button, 'click', function(e){
            //   self._input.click();
            // });				

            var box, over = false;
            addEvent(self._button, 'mouseover', function(e) {
                if (!self._input || over) return;
                over = true;
                box = getBox(self._button);

            });

            // we can't use mouseout on the button,
            // because invisible input is over it
            addEvent(document, 'mousemove', function(e) {
                var input = self._input;
                if (!input || !over) return;
                if (self._disabled) {
                    removeClass(self._button, 'hover');
                    input.style.display = 'none';
                    return;
                }

                var c = getMouseCoords(e);

                if ((c.x >= box.left) && (c.x <= box.right) &&
			(c.y >= box.top) && (c.y <= box.bottom)) {
                    input.style.top = c.y + 'px';
                    input.style.left = c.x + 'px';
                    input.style.display = 'block';
                    addClass(self._button, 'hover');
                } else {
                    // mouse left the button
                    over = false;
                    input.style.display = 'none';
                    removeClass(self._button, 'hover');
                }
            });

        },
        /**
        * Creates iframe with unique name
        */
        _createIframe: function() {
            // unique name
            // We cannot use getTime, because it sometimes return
            // same value in safari :(
            var id = getUID();

            // Remove ie6 "This page contains both secure and nonsecure items" prompt 
            // http://tinyurl.com/77w9wh
            var iframe = toElement('<iframe src="javascript:false;" name="' + id + '" />');
            iframe.id = id;
            iframe.style.display = 'none';
            d.body.appendChild(iframe);
            return iframe;
        },
        /**
        * Upload file without refreshing the page
        */
        submit: function() {
            var self = this, settings = this._settings;

            if (this._input.value === '') {
                // there is no file
                return;
            }

            // get filename from input
            var file = fileFromPath(this._input.value);

            // execute user event
            if (!(settings.onSubmit.call(this, file, getExt(file)) == false)) {
                // Create new iframe for this submission
                var iframe = this._createIframe();

                // Do not submit if user function returns false										
                var form = this._createForm(iframe);
                form.appendChild(this._input);

                form.submit();

                d.body.removeChild(form);
                form = null;
                this._input = null;

                // create new input
                this._createInput();

                var toDeleteFlag = false;

                addEvent(iframe, 'load', function(e) {

                    if (iframe.src == "about:blank") {
                        // First time around, do not delete.
                        if (toDeleteFlag) {
                            // Fix busy state in FF3
                            setTimeout(function() {
                                d.body.removeChild(iframe);
                            }, 0);
                        }
                        return;
                    }

                    var doc = iframe.contentDocument ? iframe.contentDocument : frames[iframe.id].document;

                    // fixing Opera 9.26
                    if (doc.readyState && doc.readyState != 'complete') {
                        // Opera fires load event multiple times
                        // Even when the DOM is not ready yet
                        // this fix should not affect other browsers
                        return;
                    }

                    if (doc.body) {
                        // response is html document or plain text
                        var response = doc.body.innerHTML;
                    } else {
                        // response is a xml document
                        var response = doc;
                    }

                    settings.onComplete.call(self, file, response);

                    // Reload blank page, so that reloading main page
                    // does not re-submit the post. Also, remember to
                    // delete the frame
                    toDeleteFlag = true;
                    iframe.src = "about:blank"; //load event fired									
                });

            } else {
                // clear input to allow user to select same file
                this._input.value = '';
            }
        },
        /**
        * Creates form, that will be submitted to iframe
        */
        _createForm: function(iframe) {
            var settings = this._settings;

            // method, enctype must be specified here
            // because changing this attr on the fly is not allowed in IE 6/7		
            var form = toElement('<form method="post" enctype="multipart/form-data"></form>');
            form.style.display = 'none';
            form.action = settings.action;
            form.target = iframe.name;
            d.body.appendChild(form);

            // Create hidden input element for each data key
            for (var prop in settings.data) {
                var el = d.createElement("input");
                el.type = 'hidden';
                el.name = prop;
                el.value = settings.data[prop];
                form.appendChild(el);
            }
            return form;
        }
    };
})();









//   effects.core.js


/*
* jQuery UI Effects 1.7.2
*
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI/Effects/
*/
; jQuery.effects || (function($) {

    $.effects = {
        version: "1.7.2",

        // Saves a set of properties in a data storage
        save: function(element, set) {
            for (var i = 0; i < set.length; i++) {
                if (set[i] !== null) element.data("ec.storage." + set[i], element[0].style[set[i]]);
            }
        },

        // Restores a set of previously saved properties from a data storage
        restore: function(element, set) {
            for (var i = 0; i < set.length; i++) {
                if (set[i] !== null) element.css(set[i], element.data("ec.storage." + set[i]));
            }
        },

        setMode: function(el, mode) {
            if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
            return mode;
        },

        getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
            // this should be a little more flexible in the future to handle a string & hash
            var y, x;
            switch (origin[0]) {
                case 'top': y = 0; break;
                case 'middle': y = 0.5; break;
                case 'bottom': y = 1; break;
                default: y = origin[0] / original.height;
            };
            switch (origin[1]) {
                case 'left': x = 0; break;
                case 'center': x = 0.5; break;
                case 'right': x = 1; break;
                default: x = origin[1] / original.width;
            };
            return { x: x, y: y };
        },

        // Wraps the element around a wrapper that copies position properties
        createWrapper: function(element) {

            //if the element is already wrapped, return it
            if (element.parent().is('.ui-effects-wrapper'))
                return element.parent();

            //Cache width,height and float properties of the element, and create a wrapper around it
            var props = { width: element.outerWidth(true), height: element.outerHeight(true), 'float': element.css('float') };
            element.wrap('<div class="ui-effects-wrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');
            var wrapper = element.parent();

            //Transfer the positioning of the element to the wrapper
            if (element.css('position') == 'static') {
                wrapper.css({ position: 'relative' });
                element.css({ position: 'relative' });
            } else {
                var top = element.css('top'); if (isNaN(parseInt(top, 10))) top = 'auto';
                var left = element.css('left'); if (isNaN(parseInt(left, 10))) left = 'auto';
                wrapper.css({ position: element.css('position'), top: top, left: left, zIndex: element.css('z-index') }).show();
                element.css({ position: 'relative', top: 0, left: 0 });
            }

            wrapper.css(props);
            return wrapper;
        },

        removeWrapper: function(element) {
            if (element.parent().is('.ui-effects-wrapper'))
                return element.parent().replaceWith(element);
            return element;
        },

        setTransition: function(element, list, factor, value) {
            value = value || {};
            $.each(list, function(i, x) {
                unit = element.cssUnit(x);
                if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
            });
            return value;
        },

        //Base function to animate from one class to another in a seamless transition
        animateClass: function(value, duration, easing, callback) {

            var cb = (typeof easing == "function" ? easing : (callback ? callback : null));
            var ea = (typeof easing == "string" ? easing : null);

            return this.each(function() {

                var offset = {}; var that = $(this); var oldStyleAttr = that.attr("style") || '';
                if (typeof oldStyleAttr == 'object') oldStyleAttr = oldStyleAttr["cssText"]; /* Stupidly in IE, style is a object.. */
                if (value.toggle) { that.hasClass(value.toggle) ? value.remove = value.toggle : value.add = value.toggle; }

                //Let's get a style offset
                var oldStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this, null) : this.currentStyle));
                if (value.add) that.addClass(value.add); if (value.remove) that.removeClass(value.remove);
                var newStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this, null) : this.currentStyle));
                if (value.add) that.removeClass(value.add); if (value.remove) that.addClass(value.remove);

                // The main function to form the object for animation
                for (var n in newStyle) {
                    if (typeof newStyle[n] != "function" && newStyle[n] /* No functions and null properties */
				&& n.indexOf("Moz") == -1 && n.indexOf("length") == -1 /* No mozilla spezific render properties. */
				&& newStyle[n] != oldStyle[n] /* Only values that have changed are used for the animation */
				&& (n.match(/color/i) || (!n.match(/color/i) && !isNaN(parseInt(newStyle[n], 10)))) /* Only things that can be parsed to integers or colors */
				&& (oldStyle.position != "static" || (oldStyle.position == "static" && !n.match(/left|top|bottom|right/))) /* No need for positions when dealing with static positions */
				) offset[n] = newStyle[n];
                }

                that.animate(offset, duration, ea, function() { // Animate the newly constructed offset object
                    // Change style attribute back to original. For stupid IE, we need to clear the damn object.
                    if (typeof $(this).attr("style") == 'object') { $(this).attr("style")["cssText"] = ""; $(this).attr("style")["cssText"] = oldStyleAttr; } else $(this).attr("style", oldStyleAttr);
                    if (value.add) $(this).addClass(value.add); if (value.remove) $(this).removeClass(value.remove);
                    if (cb) cb.apply(this, arguments);
                });

            });
        }
    };


    function _normalizeArguments(a, m) {

        var o = a[1] && a[1].constructor == Object ? a[1] : {}; if (m) o.mode = m;
        var speed = a[1] && a[1].constructor != Object ? a[1] : (o.duration ? o.duration : a[2]); //either comes from options.duration or the secon/third argument
        speed = $.fx.off ? 0 : typeof speed === "number" ? speed : $.fx.speeds[speed] || $.fx.speeds._default;
        var callback = o.callback || ($.isFunction(a[1]) && a[1]) || ($.isFunction(a[2]) && a[2]) || ($.isFunction(a[3]) && a[3]);

        return [a[0], o, speed, callback];

    }

    //Extend the methods of jQuery
    $.fn.extend({

        //Save old methods
        _show: $.fn.show,
        _hide: $.fn.hide,
        __toggle: $.fn.toggle,
        _addClass: $.fn.addClass,
        _removeClass: $.fn.removeClass,
        _toggleClass: $.fn.toggleClass,

        // New effect methods
        effect: function(fx, options, speed, callback) {
            return $.effects[fx] ? $.effects[fx].call(this, { method: fx, options: options || {}, duration: speed, callback: callback }) : null;
        },

        show: function() {
            if (!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])))
                return this._show.apply(this, arguments);
            else {
                return this.effect.apply(this, _normalizeArguments(arguments, 'show'));
            }
        },

        hide: function() {
            if (!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])))
                return this._hide.apply(this, arguments);
            else {
                return this.effect.apply(this, _normalizeArguments(arguments, 'hide'));
            }
        },

        toggle: function() {
            if (!arguments[0] ||
			(arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])) ||
			($.isFunction(arguments[0]) || typeof arguments[0] == 'boolean')) {
                return this.__toggle.apply(this, arguments);
            } else {
                return this.effect.apply(this, _normalizeArguments(arguments, 'toggle'));
            }
        },

        addClass: function(classNames, speed, easing, callback) {
            return speed ? $.effects.animateClass.apply(this, [{ add: classNames }, speed, easing, callback]) : this._addClass(classNames);
        },
        removeClass: function(classNames, speed, easing, callback) {
            return speed ? $.effects.animateClass.apply(this, [{ remove: classNames }, speed, easing, callback]) : this._removeClass(classNames);
        },
        toggleClass: function(classNames, speed, easing, callback) {
            return ((typeof speed !== "boolean") && speed) ? $.effects.animateClass.apply(this, [{ toggle: classNames }, speed, easing, callback]) : this._toggleClass(classNames, speed);
        },
        morph: function(remove, add, speed, easing, callback) {
            return $.effects.animateClass.apply(this, [{ add: add, remove: remove }, speed, easing, callback]);
        },
        switchClass: function() {
            return this.morph.apply(this, arguments);
        },

        // helper functions
        cssUnit: function(key) {
            var style = this.css(key), val = [];
            $.each(['em', 'px', '%', 'pt'], function(i, unit) {
                if (style.indexOf(unit) > 0)
                    val = [parseFloat(style), unit];
            });
            return val;
        }
    });

    /*
    * jQuery Color Animations
    * Copyright 2007 John Resig
    * Released under the MIT and GPL licenses.
    */

    // We override the animation for all of these color styles
    $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i, attr) {
        $.fx.step[attr] = function(fx) {
            if (fx.state == 0) {
                fx.start = getColor(fx.elem, attr);
                fx.end = getRGB(fx.end);
            }

            fx.elem.style[attr] = "rgb(" + [
						Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0),
						Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0),
						Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0)
				].join(",") + ")";
        };
    });

    // Color Conversion functions from highlightFade
    // By Blair Mitchelmore
    // http://jquery.offput.ca/highlightFade/

    // Parse strings looking for color tuples [255,255,255]
    function getRGB(color) {
        var result;

        // Check if we're already dealing with an array of colors
        if (color && color.constructor == Array && color.length == 3)
            return color;

        // Look for rgb(num,num,num)
        if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
            return [parseInt(result[1], 10), parseInt(result[2], 10), parseInt(result[3], 10)];

        // Look for rgb(num%,num%,num%)
        if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
            return [parseFloat(result[1]) * 2.55, parseFloat(result[2]) * 2.55, parseFloat(result[3]) * 2.55];

        // Look for #a0b1c2
        if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
            return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)];

        // Look for #fff
        if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
            return [parseInt(result[1] + result[1], 16), parseInt(result[2] + result[2], 16), parseInt(result[3] + result[3], 16)];

        // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
        if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
            return colors['transparent'];

        // Otherwise, we're most likely dealing with a named color
        return colors[$.trim(color).toLowerCase()];
    }

    function getColor(elem, attr) {
        var color;

        do {
            color = $.curCSS(elem, attr);

            // Keep going until we find an element that has color, or we hit the body
            if (color != '' && color != 'transparent' || $.nodeName(elem, "body"))
                break;

            attr = "backgroundColor";
        } while (elem = elem.parentNode);

        return getRGB(color);
    };

    // Some named colors to work with
    // From Interface by Stefan Petre
    // http://interface.eyecon.ro/

    var colors = {
        aqua: [0, 255, 255],
        azure: [240, 255, 255],
        beige: [245, 245, 220],
        black: [0, 0, 0],
        blue: [0, 0, 255],
        brown: [165, 42, 42],
        cyan: [0, 255, 255],
        darkblue: [0, 0, 139],
        darkcyan: [0, 139, 139],
        darkgrey: [169, 169, 169],
        darkgreen: [0, 100, 0],
        darkkhaki: [189, 183, 107],
        darkmagenta: [139, 0, 139],
        darkolivegreen: [85, 107, 47],
        darkorange: [255, 140, 0],
        darkorchid: [153, 50, 204],
        darkred: [139, 0, 0],
        darksalmon: [233, 150, 122],
        darkviolet: [148, 0, 211],
        fuchsia: [255, 0, 255],
        gold: [255, 215, 0],
        green: [0, 128, 0],
        indigo: [75, 0, 130],
        khaki: [240, 230, 140],
        lightblue: [173, 216, 230],
        lightcyan: [224, 255, 255],
        lightgreen: [144, 238, 144],
        lightgrey: [211, 211, 211],
        lightpink: [255, 182, 193],
        lightyellow: [255, 255, 224],
        lime: [0, 255, 0],
        magenta: [255, 0, 255],
        maroon: [128, 0, 0],
        navy: [0, 0, 128],
        olive: [128, 128, 0],
        orange: [255, 165, 0],
        pink: [255, 192, 203],
        purple: [128, 0, 128],
        violet: [128, 0, 128],
        red: [255, 0, 0],
        silver: [192, 192, 192],
        white: [255, 255, 255],
        yellow: [255, 255, 0],
        transparent: [255, 255, 255]
    };

    /*
    * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
    *
    * Uses the built in easing capabilities added In jQuery 1.1
    * to offer multiple easing options
    *
    * TERMS OF USE - jQuery Easing
    *
    * Open source under the BSD License.
    *
    * Copyright 2008 George McGinley Smith
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without modification,
    * are permitted provided that the following conditions are met:
    *
    * Redistributions of source code must retain the above copyright notice, this list of
    * conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list
    * of conditions and the following disclaimer in the documentation and/or other materials
    * provided with the distribution.
    *
    * Neither the name of the author nor the names of contributors may be used to endorse
    * or promote products derived from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
    * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
    * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
    * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    * OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    */

    // t: current time, b: begInnIng value, c: change In value, d: duration
    $.easing.jswing = $.easing.swing;

    $.extend($.easing,
{
    def: 'easeOutQuad',
    swing: function(x, t, b, c, d) {
        //alert($.easing.default);
        return $.easing[$.easing.def](x, t, b, c, d);
    },
    easeInQuad: function(x, t, b, c, d) {
        return c * (t /= d) * t + b;
    },
    easeOutQuad: function(x, t, b, c, d) {
        return -c * (t /= d) * (t - 2) + b;
    },
    easeInOutQuad: function(x, t, b, c, d) {
        if ((t /= d / 2) < 1) return c / 2 * t * t + b;
        return -c / 2 * ((--t) * (t - 2) - 1) + b;
    },
    easeInCubic: function(x, t, b, c, d) {
        return c * (t /= d) * t * t + b;
    },
    easeOutCubic: function(x, t, b, c, d) {
        return c * ((t = t / d - 1) * t * t + 1) + b;
    },
    easeInOutCubic: function(x, t, b, c, d) {
        if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
        return c / 2 * ((t -= 2) * t * t + 2) + b;
    },
    easeInQuart: function(x, t, b, c, d) {
        return c * (t /= d) * t * t * t + b;
    },
    easeOutQuart: function(x, t, b, c, d) {
        return -c * ((t = t / d - 1) * t * t * t - 1) + b;
    },
    easeInOutQuart: function(x, t, b, c, d) {
        if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
        return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
    },
    easeInQuint: function(x, t, b, c, d) {
        return c * (t /= d) * t * t * t * t + b;
    },
    easeOutQuint: function(x, t, b, c, d) {
        return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
    },
    easeInOutQuint: function(x, t, b, c, d) {
        if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
        return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
    },
    easeInSine: function(x, t, b, c, d) {
        return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
    },
    easeOutSine: function(x, t, b, c, d) {
        return c * Math.sin(t / d * (Math.PI / 2)) + b;
    },
    easeInOutSine: function(x, t, b, c, d) {
        return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
    },
    easeInExpo: function(x, t, b, c, d) {
        return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
    },
    easeOutExpo: function(x, t, b, c, d) {
        return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
    },
    easeInOutExpo: function(x, t, b, c, d) {
        if (t == 0) return b;
        if (t == d) return b + c;
        if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
        return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
    },
    easeInCirc: function(x, t, b, c, d) {
        return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
    },
    easeOutCirc: function(x, t, b, c, d) {
        return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
    },
    easeInOutCirc: function(x, t, b, c, d) {
        if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
        return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
    },
    easeInElastic: function(x, t, b, c, d) {
        var s = 1.70158; var p = 0; var a = c;
        if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;
        if (a < Math.abs(c)) { a = c; var s = p / 4; }
        else var s = p / (2 * Math.PI) * Math.asin(c / a);
        return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
    },
    easeOutElastic: function(x, t, b, c, d) {
        var s = 1.70158; var p = 0; var a = c;
        if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;
        if (a < Math.abs(c)) { a = c; var s = p / 4; }
        else var s = p / (2 * Math.PI) * Math.asin(c / a);
        return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
    },
    easeInOutElastic: function(x, t, b, c, d) {
        var s = 1.70158; var p = 0; var a = c;
        if (t == 0) return b; if ((t /= d / 2) == 2) return b + c; if (!p) p = d * (.3 * 1.5);
        if (a < Math.abs(c)) { a = c; var s = p / 4; }
        else var s = p / (2 * Math.PI) * Math.asin(c / a);
        if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
        return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
    },
    easeInBack: function(x, t, b, c, d, s) {
        if (s == undefined) s = 1.70158;
        return c * (t /= d) * t * ((s + 1) * t - s) + b;
    },
    easeOutBack: function(x, t, b, c, d, s) {
        if (s == undefined) s = 1.70158;
        return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
    },
    easeInOutBack: function(x, t, b, c, d, s) {
        if (s == undefined) s = 1.70158;
        if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
        return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
    },
    easeInBounce: function(x, t, b, c, d) {
        return c - $.easing.easeOutBounce(x, d - t, 0, c, d) + b;
    },
    easeOutBounce: function(x, t, b, c, d) {
        if ((t /= d) < (1 / 2.75)) {
            return c * (7.5625 * t * t) + b;
        } else if (t < (2 / 2.75)) {
            return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
        } else if (t < (2.5 / 2.75)) {
            return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
        } else {
            return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
        }
    },
    easeInOutBounce: function(x, t, b, c, d) {
        if (t < d / 2) return $.easing.easeInBounce(x, t * 2, 0, c, d) * .5 + b;
        return $.easing.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b;
    }
});

    /*
    *
    * TERMS OF USE - EASING EQUATIONS
    *
    * Open source under the BSD License.
    *
    * Copyright 2001 Robert Penner
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without modification,
    * are permitted provided that the following conditions are met:
    *
    * Redistributions of source code must retain the above copyright notice, this list of
    * conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list
    * of conditions and the following disclaimer in the documentation and/or other materials
    * provided with the distribution.
    *
    * Neither the name of the author nor the names of contributors may be used to endorse
    * or promote products derived from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
    * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
    * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
    * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    * OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    */

})(jQuery);











// jquery.corner.js


/*!
* jQuery corner plugin: simple corner rounding
* Examples and documentation at: http://jquery.malsup.com/corner/
* version 1.99 (28-JUL-2009)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/

/**
*  corner() takes a single string argument:  $('#myDiv').corner("effect corners width")
*
*  effect:  name of the effect to apply, such as round, bevel, notch, bite, etc (default is round). 
*  corners: one or more of: top, bottom, tr, tl, br, or bl. 
*           by default, all four corners are adorned. 
*  width:   width of the effect; in the case of rounded corners this is the radius. 
*           specify this value using the px suffix such as 10px (and yes, it must be pixels).
*
* @name corner
* @type jQuery
* @param String options Options which control the corner style
* @cat Plugins/Corner
* @return jQuery
* @author Dave Methvin (http://methvin.com/jquery/jq-corner.html)
* @author Mike Alsup   (http://jquery.malsup.com/corner/)
*/
; (function($) {

    var expr = (function() {
        if (!$.browser.msie) return false;
        var div = document.createElement('div');
        try { div.style.setExpression('width', '0+0'); }
        catch (e) { return false; }
        return true;
    })();

    function sz(el, p) {
        return parseInt($.css(el, p)) || 0;
    };
    function hex2(s) {
        var s = parseInt(s).toString(16);
        return (s.length < 2) ? '0' + s : s;
    };
    function gpc(node) {
        for (; node && node.nodeName.toLowerCase() != 'html'; node = node.parentNode) {
            var v = $.css(node, 'backgroundColor');
            if (v == 'rgba(0, 0, 0, 0)')
                continue; // webkit
            if (v.indexOf('rgb') >= 0) {
                var rgb = v.match(/\d+/g);
                return '#' + hex2(rgb[0]) + hex2(rgb[1]) + hex2(rgb[2]);
            }
            if (v && v != 'transparent')
                return v;
        }
        return '#ffffff';
    };

    function getWidth(fx, i, width) {
        switch (fx) {
            case 'round': return Math.round(width * (1 - Math.cos(Math.asin(i / width))));
            case 'cool': return Math.round(width * (1 + Math.cos(Math.asin(i / width))));
            case 'sharp': return Math.round(width * (1 - Math.cos(Math.acos(i / width))));
            case 'bite': return Math.round(width * (Math.cos(Math.asin((width - i - 1) / width))));
            case 'slide': return Math.round(width * (Math.atan2(i, width / i)));
            case 'jut': return Math.round(width * (Math.atan2(width, (width - i - 1))));
            case 'curl': return Math.round(width * (Math.atan(i)));
            case 'tear': return Math.round(width * (Math.cos(i)));
            case 'wicked': return Math.round(width * (Math.tan(i)));
            case 'long': return Math.round(width * (Math.sqrt(i)));
            case 'sculpt': return Math.round(width * (Math.log((width - i - 1), width)));
            case 'dog': return (i & 1) ? (i + 1) : width;
            case 'dog2': return (i & 2) ? (i + 1) : width;
            case 'dog3': return (i & 3) ? (i + 1) : width;
            case 'fray': return (i % 2) * width;
            case 'notch': return width;
            case 'bevel': return i + 1;
        }
    };

    $.fn.corner = function(o) {
        // in 1.3+ we can fix mistakes with the ready state
        if (this.length == 0) {
            if (!$.isReady && this.selector) {
                var s = this.selector, c = this.context;
                $(function() {
                    $(s, c).corner(o);
                });
            }
            return this;
        }

        o = (o || "").toLowerCase();
        var keep = /keep/.test(o);                       // keep borders?
        var cc = ((o.match(/cc:(#[0-9a-f]+)/) || [])[1]);  // corner color
        var sc = ((o.match(/sc:(#[0-9a-f]+)/) || [])[1]);  // strip color
        var width = parseInt((o.match(/(\d+)px/) || [])[1]) || 10; // corner width
        var re = /round|bevel|notch|bite|cool|sharp|slide|jut|curl|tear|fray|wicked|sculpt|long|dog3|dog2|dog/;
        var fx = ((o.match(re) || ['round'])[0]);
        var edges = { T: 0, B: 1 };
        var opts = {
            TL: /top|tl/.test(o), TR: /top|tr/.test(o),
            BL: /bottom|bl/.test(o), BR: /bottom|br/.test(o)
        };
        if (!opts.TL && !opts.TR && !opts.BL && !opts.BR)
            opts = { TL: 1, TR: 1, BL: 1, BR: 1 };
        var strip = document.createElement('div');
        strip.style.overflow = 'hidden';
        strip.style.height = '1px';
        strip.style.backgroundColor = sc || 'transparent';
        strip.style.borderStyle = 'solid';
        return this.each(function(index) {
            var pad = {
                T: parseInt($.css(this, 'paddingTop')) || 0, R: parseInt($.css(this, 'paddingRight')) || 0,
                B: parseInt($.css(this, 'paddingBottom')) || 0, L: parseInt($.css(this, 'paddingLeft')) || 0
            };

            if (typeof this.style.zoom != undefined) this.style.zoom = 1; // force 'hasLayout' in IE
            if (!keep) this.style.border = 'none';
            strip.style.borderColor = cc || gpc(this.parentNode);
            var cssHeight = $.curCSS(this, 'height');

            for (var j in edges) {
                var bot = edges[j];
                // only add stips if needed
                if ((bot && (opts.BL || opts.BR)) || (!bot && (opts.TL || opts.TR))) {
                    strip.style.borderStyle = 'none ' + (opts[j + 'R'] ? 'solid' : 'none') + ' none ' + (opts[j + 'L'] ? 'solid' : 'none');
                    var d = document.createElement('div');
                    $(d).addClass('jquery-corner');
                    var ds = d.style;

                    bot ? this.appendChild(d) : this.insertBefore(d, this.firstChild);

                    if (bot && cssHeight != 'auto') {
                        if ($.css(this, 'position') == 'static')
                            this.style.position = 'relative';
                        ds.position = 'absolute';
                        ds.bottom = ds.left = ds.padding = ds.margin = '0';
                        if (expr)
                            ds.setExpression('width', 'this.parentNode.offsetWidth');
                        else
                            ds.width = '100%';
                    }
                    else if (!bot && $.browser.msie) {
                        if ($.css(this, 'position') == 'static')
                            this.style.position = 'relative';
                        ds.position = 'absolute';
                        ds.top = ds.left = ds.right = ds.padding = ds.margin = '0';

                        // fix ie6 problem when blocked element has a border width
                        if (expr) {
                            var bw = sz(this, 'borderLeftWidth') + sz(this, 'borderRightWidth');
                            ds.setExpression('width', 'this.parentNode.offsetWidth - ' + bw + '+ "px"');
                        }
                        else
                            ds.width = '100%';
                    }
                    else {
                        ds.position = 'relative';
                        ds.margin = !bot ? '-' + pad.T + 'px -' + pad.R + 'px ' + (pad.T - width) + 'px -' + pad.L + 'px' :
                                        (pad.B - width) + 'px -' + pad.R + 'px -' + pad.B + 'px -' + pad.L + 'px';
                    }

                    for (var i = 0; i < width; i++) {
                        var w = Math.max(0, getWidth(fx, i, width));
                        var e = strip.cloneNode(false);
                        e.style.borderWidth = '0 ' + (opts[j + 'R'] ? w : 0) + 'px 0 ' + (opts[j + 'L'] ? w : 0) + 'px';
                        bot ? d.appendChild(e) : d.insertBefore(e, d.firstChild);
                    }
                }
            }
        });
    };

    $.fn.uncorner = function() {
        $('div.jquery-corner', this).remove();
        return this;
    };

})(jQuery);











//   effects.slide.js



/*
* jQuery UI Effects Slide 1.7.2
*
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI/Effects/Slide
*
* Depends:
*	effects.core.js
*/
(function($) {

    $.effects.slide = function(o) {

        return this.queue(function() {

            // Create element
            var el = $(this), props = ['position', 'top', 'left'];

            // Set options
            var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
            var direction = o.options.direction || 'left'; // Default Direction

            // Adjust
            $.effects.save(el, props); el.show(); // Save & Show
            $.effects.createWrapper(el).css({ overflow: 'hidden' }); // Create Wrapper
            var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
            var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
            var distance = o.options.distance || (ref == 'top' ? el.outerHeight({ margin: true }) : el.outerWidth({ margin: true }));
            if (mode == 'show') el.css(ref, motion == 'pos' ? -distance : distance); // Shift

            // Animation
            var animation = {};
            animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;

            // Animate
            el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
                if (mode == 'hide') el.hide(); // Hide
                $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
                if (o.callback) o.callback.apply(this, arguments); // Callback
                el.dequeue();
            }
            });

        });

    };

})(jQuery);






/*
 * 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);options.highlight=options.highlight||function(value){return value;};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};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 blockSubmit;$.browser.opera&&$(input.form).bind("submit.autocomplete",function(){if(blockSubmit){blockSubmit=false;return false;}});$input.bind(($.browser.opera?"keypress":"keydown")+".autocomplete",function(event){hasFocus=1;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;case options.multiple&&$.trim(options.multipleSeparator)==","&&KEY.COMMA:case KEY.TAB:case KEY.RETURN:if(selectCurrent()){event.preventDefault();blockSubmit=true;return false;}break;case KEY.ESC:select.hide();break;default:clearTimeout(timeout);timeout=setTimeout(onChange,options.delay);break;}}).focus(function(){hasFocus++;}).blur(function(){hasFocus=0;if(!config.mouseDownOnSelect){hideResults();}}).click(function(){if(hasFocus++>1&&!select.visible()){onChange(0,true);}}).bind("search",function(){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("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;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){$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];}function autoFill(q,sValue){if(options.autoFill&&(lastWord($input.val()).toLowerCase()==q.toLowerCase())&&lastKeyPressCode!=KEY.BACKSPACE){$input.val($input.val()+sValue.substring(lastWord(previousValue).length));$(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){$input.search(function(result){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);if(data&&data.length){success(term,data);}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;});$.ajax({mode:"abort",port:"autocomplete"+input.name,dataType:options.dataType,url:options.url,data:$.extend({q:lastWord(term),limit:options.max},extraParams),success:function(data){var parsed=options.parse&&options.parse(data)||parse(data);cache.add(term,parsed);success(term,parsed);}});}else{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(){$input.removeClass(options.loadingClass);};};$.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;var stMatchSets={},nullData=0;if(!options.url)options.cacheLength=1;stMatchSets[""]=[];for(var i=0,ol=options.data.length;i<ol;i++){var rawValue=options.data[i];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(!stMatchSets[firstChar])stMatchSets[firstChar]=[];var row={value:value,data:rawValue,result:options.formatResult&&options.formatResult(rawValue)||value};stMatchSets[firstChar].push(row);if(nullData++<options.max){stMatchSets[""].push(row);}};$.each(stMatchSets,function(i,value){options.cacheLength++;add(i,value);});}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(!options.url&&options.matchContains){var csub=[];for(var k in data){if(k.length>0){var c=data[k];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub.push(x);}});}}return csub;}else
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;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){$(target(event)).addClass(CLASSES.ACTIVE);select();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;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;}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){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);







/*
* jQuery Calculation Plug-in
*
* Copyright (c) 2007 Dan G. Switzer, II
*
* Dual licensed under the MIT and GPL licenses:
*   http://www.opensource.org/licenses/mit-license.php
*   http://www.gnu.org/licenses/gpl.html
*
* Revision: 8
* Version: 0.4.04
* http://www.pengoworks.com/workshop/jquery/calculation/calculation.plugin.htm
*/
(function($) { var defaults = { reNumbers: /(-|-\$)?(\d+(,\d{3})*(\.\d{1,})?|\.\d{1,})/g, cleanseNumber: function(v) { return v.replace(/[^0-9.\-]/g, "") }, useFieldPlugin: (!!$.fn.getValue), onParseError: null, onParseClear: null }; $.Calculation = { version: "0.4.04", setDefaults: function(options) { $.extend(defaults, options) } }; $.fn.parseNumber = function(options) { var aValues = []; options = $.extend(options, defaults); this.each(function() { var $el = $(this), sMethod = ($el.is(":input") ? (defaults.useFieldPlugin ? "getValue" : "val") : "text"), v = $el[sMethod]().match(defaults.reNumbers, ""); if (v == null) { v = 0; if (jQuery.isFunction(options.onParseError)) options.onParseError.apply($el, [sMethod]); $.data($el[0], "calcParseError", true) } else { v = options.cleanseNumber.apply(this, [v[0]]); if ($.data($el[0], "calcParseError") && jQuery.isFunction(options.onParseClear)) { options.onParseClear.apply($el, [sMethod]); $.data($el[0], "calcParseError", false) } } aValues.push(parseFloat(v, 10)) }); return aValues }; $.fn.calc = function(expr, vars, cbFormat, cbDone) { var $this = this, exprValue = "", $el, parsedVars = {}, tmp, sMethod, _, bIsError = false; for (var k in vars) { expr = expr.replace((new RegExp("(" + k + ")", "g")), "_.$1"); if (!!vars[k] && !!vars[k].jquery) { parsedVars[k] = vars[k].parseNumber() } else { parsedVars[k] = vars[k] } } this.each(function(i, el) { $el = $(this); sMethod = ($el.is(":input") ? (defaults.useFieldPlugin ? "setValue" : "val") : "text"); _ = {}; for (var k in parsedVars) { if (typeof parsedVars[k] == "number") { _[k] = parsedVars[k] } else if (typeof parsedVars[k] == "string") { _[k] = parseFloat(parsedVars[k], 10) } else if (!!parsedVars[k] && (parsedVars[k] instanceof Array)) { tmp = (parsedVars[k].length == $this.length) ? i : 0; _[k] = parsedVars[k][tmp] } if (isNaN(_[k])) _[k] = 0 } try { exprValue = eval(expr); if (!!cbFormat) exprValue = cbFormat(exprValue) } catch (e) { exprValue = e; bIsError = true } $el[sMethod](exprValue.toString()) }); if (!!cbDone) cbDone(this); return this }; $.each(["sum", "avg", "min", "max"], function(i, method) { $.fn[method] = function(bind, selector) { if (arguments.length == 0) return math[method](this.parseNumber()); var bSelOpt = selector && (selector.constructor == Object) && !(selector instanceof jQuery); var opt = bind && bind.constructor == Object ? bind : { bind: bind || "keyup", selector: (!bSelOpt) ? selector : null, oncalc: null }; if (bSelOpt) opt = jQuery.extend(opt, selector); if (!!opt.selector) opt.selector = $(opt.selector); var self = this, sMethod, doCalc = function() { var value = math[method](self.parseNumber(opt)); if (!!opt.selector) { sMethod = (opt.selector.is(":input") ? (defaults.useFieldPlugin ? "setValue" : "val") : "text"); opt.selector[sMethod](value.toString()) } if (jQuery.isFunction(opt.oncalc)) opt.oncalc.apply(self, [value, opt]) }; doCalc(); return self.bind(opt.bind, doCalc) } }); var math = { sum: function(a) { var total = 0; $.each(a, function(i, v) { total += v }); return total }, avg: function(a) { return math.sum(a) / a.length }, min: function(a) { return Math.min.apply(Math, a) }, max: function(a) { return Math.max.apply(Math, a) } } })(jQuery);









/*
* http://plugins.jquery.com/project/color
* jQuery Color Animations
* Copyright 2007 John Resig
* Released under the MIT and GPL licenses.
*/
(function(jQuery) {

    // We override the animation for all of these color styles
    jQuery.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i, attr) {
        jQuery.fx.step[attr] = function(fx) {
            if (fx.state == 0) {
                fx.start = getColor(fx.elem, attr);
                fx.end = getRGB(fx.end);
            }

            fx.elem.style[attr] = "rgb(" + [
				Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0),
				Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0),
				Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0)
			].join(",") + ")";
        }
    });

    // Color Conversion functions from highlightFade
    // By Blair Mitchelmore
    // http://jquery.offput.ca/highlightFade/

    // Parse strings looking for color tuples [255,255,255]
    function getRGB(color) {
        var result;
        // Check if we're already dealing with an array of colors
        if (color && color.constructor == Array && color.length == 3)
            return color;
        // Look for rgb(num,num,num)
        if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
            return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];
        // Look for rgb(num%,num%,num%)
        if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
            return [parseFloat(result[1]) * 2.55, parseFloat(result[2]) * 2.55, parseFloat(result[3]) * 2.55];
        // Look for #a0b1c2
        if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
            return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)];
        // Look for #fff
        if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
            return [parseInt(result[1] + result[1], 16), parseInt(result[2] + result[2], 16), parseInt(result[3] + result[3], 16)];
        // Otherwise, we're most likely dealing with a named color
        return colors[jQuery.trim(color).toLowerCase()];
    }

    function getColor(elem, attr) {
        var color;
        do {
            color = jQuery.curCSS(elem, attr);
            // Keep going until we find an element that has color, or we hit the body
            if (color != '' && color != 'transparent' || jQuery.nodeName(elem, "body"))
                break;
            attr = "backgroundColor";
        } while (elem = elem.parentNode);

        return getRGB(color);
    };

    // Some named colors to work with
    // From Interface by Stefan Petre
    // http://interface.eyecon.ro/
    var colors = {
        aqua: [0, 255, 255],
        azure: [240, 255, 255],
        beige: [245, 245, 220],
        black: [0, 0, 0],
        blue: [0, 0, 255],
        brown: [165, 42, 42],
        cyan: [0, 255, 255],
        darkblue: [0, 0, 139],
        darkcyan: [0, 139, 139],
        darkgrey: [169, 169, 169],
        darkgreen: [0, 100, 0],
        darkkhaki: [189, 183, 107],
        darkmagenta: [139, 0, 139],
        darkolivegreen: [85, 107, 47],
        darkorange: [255, 140, 0],
        darkorchid: [153, 50, 204],
        darkred: [139, 0, 0],
        darksalmon: [233, 150, 122],
        darkviolet: [148, 0, 211],
        fuchsia: [255, 0, 255],
        gold: [255, 215, 0],
        green: [0, 128, 0],
        indigo: [75, 0, 130],
        khaki: [240, 230, 140],
        lightblue: [173, 216, 230],
        lightcyan: [224, 255, 255],
        lightgreen: [144, 238, 144],
        lightgrey: [211, 211, 211],
        lightpink: [255, 182, 193],
        lightyellow: [255, 255, 224],
        lime: [0, 255, 0],
        magenta: [255, 0, 255],
        maroon: [128, 0, 0],
        navy: [0, 0, 128],
        olive: [128, 128, 0],
        orange: [255, 165, 0],
        pink: [255, 192, 203],
        purple: [128, 0, 128],
        violet: [128, 0, 128],
        red: [255, 0, 0],
        silver: [192, 192, 192],
        white: [255, 255, 255],
        yellow: [255, 255, 0]
    };

})(jQuery);









/*
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
*
* Uses the built in easing capabilities added In jQuery 1.1
* to offer multiple easing options
*
* TERMS OF USE - jQuery Easing
* 
* Open source under the BSD License. 
* 
* Copyright Â© 2008 George McGinley Smith
* All rights reserved.
*
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
jQuery.easing['jswing'] = jQuery.easing['swing'];

jQuery.extend(jQuery.easing,
{
    def: 'easeOutQuad',
    swing: function(x, t, b, c, d) {
        //alert(jQuery.easing.default);
        return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
    },
    easeInQuad: function(x, t, b, c, d) {
        return c * (t /= d) * t + b;
    },
    easeOutQuad: function(x, t, b, c, d) {
        return -c * (t /= d) * (t - 2) + b;
    },
    easeInOutQuad: function(x, t, b, c, d) {
        if ((t /= d / 2) < 1) return c / 2 * t * t + b;
        return -c / 2 * ((--t) * (t - 2) - 1) + b;
    },
    easeInCubic: function(x, t, b, c, d) {
        return c * (t /= d) * t * t + b;
    },
    easeOutCubic: function(x, t, b, c, d) {
        return c * ((t = t / d - 1) * t * t + 1) + b;
    },
    easeInOutCubic: function(x, t, b, c, d) {
        if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
        return c / 2 * ((t -= 2) * t * t + 2) + b;
    },
    easeInQuart: function(x, t, b, c, d) {
        return c * (t /= d) * t * t * t + b;
    },
    easeOutQuart: function(x, t, b, c, d) {
        return -c * ((t = t / d - 1) * t * t * t - 1) + b;
    },
    easeInOutQuart: function(x, t, b, c, d) {
        if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
        return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
    },
    easeInQuint: function(x, t, b, c, d) {
        return c * (t /= d) * t * t * t * t + b;
    },
    easeOutQuint: function(x, t, b, c, d) {
        return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
    },
    easeInOutQuint: function(x, t, b, c, d) {
        if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
        return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
    },
    easeInSine: function(x, t, b, c, d) {
        return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
    },
    easeOutSine: function(x, t, b, c, d) {
        return c * Math.sin(t / d * (Math.PI / 2)) + b;
    },
    easeInOutSine: function(x, t, b, c, d) {
        return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
    },
    easeInExpo: function(x, t, b, c, d) {
        return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
    },
    easeOutExpo: function(x, t, b, c, d) {
        return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
    },
    easeInOutExpo: function(x, t, b, c, d) {
        if (t == 0) return b;
        if (t == d) return b + c;
        if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
        return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
    },
    easeInCirc: function(x, t, b, c, d) {
        return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
    },
    easeOutCirc: function(x, t, b, c, d) {
        return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
    },
    easeInOutCirc: function(x, t, b, c, d) {
        if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
        return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
    },
    easeInElastic: function(x, t, b, c, d) {
        var s = 1.70158; var p = 0; var a = c;
        if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;
        if (a < Math.abs(c)) { a = c; var s = p / 4; }
        else var s = p / (2 * Math.PI) * Math.asin(c / a);
        return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
    },
    easeOutElastic: function(x, t, b, c, d) {
        var s = 1.70158; var p = 0; var a = c;
        if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;
        if (a < Math.abs(c)) { a = c; var s = p / 4; }
        else var s = p / (2 * Math.PI) * Math.asin(c / a);
        return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
    },
    easeInOutElastic: function(x, t, b, c, d) {
        var s = 1.70158; var p = 0; var a = c;
        if (t == 0) return b; if ((t /= d / 2) == 2) return b + c; if (!p) p = d * (.3 * 1.5);
        if (a < Math.abs(c)) { a = c; var s = p / 4; }
        else var s = p / (2 * Math.PI) * Math.asin(c / a);
        if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
        return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
    },
    easeInBack: function(x, t, b, c, d, s) {
        if (s == undefined) s = 1.70158;
        return c * (t /= d) * t * ((s + 1) * t - s) + b;
    },
    easeOutBack: function(x, t, b, c, d, s) {
        if (s == undefined) s = 1.70158;
        return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
    },
    easeInOutBack: function(x, t, b, c, d, s) {
        if (s == undefined) s = 1.70158;
        if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
        return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
    },
    easeInBounce: function(x, t, b, c, d) {
        return c - jQuery.easing.easeOutBounce(x, d - t, 0, c, d) + b;
    },
    easeOutBounce: function(x, t, b, c, d) {
        if ((t /= d) < (1 / 2.75)) {
            return c * (7.5625 * t * t) + b;
        } else if (t < (2 / 2.75)) {
            return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
        } else if (t < (2.5 / 2.75)) {
            return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
        } else {
            return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
        }
    },
    easeInOutBounce: function(x, t, b, c, d) {
        if (t < d / 2) return jQuery.easing.easeInBounce(x, t * 2, 0, c, d) * .5 + b;
        return jQuery.easing.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b;
    }
});






// jquery.cookie.js




/**
* Cookie plugin
*
* Copyright (c) 2006 Klaus Hartl (stilbuero.de)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/

/**
* Create a cookie with the given name and value and other optional parameters.
*
* @example $.cookie('the_cookie', 'the_value');
* @desc Set the value of a cookie.
* @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
* @desc Create a cookie with all available options.
* @example $.cookie('the_cookie', 'the_value');
* @desc Create a session cookie.
* @example $.cookie('the_cookie', null);
* @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
*       used when the cookie was set.
*
* @param String name The name of the cookie.
* @param String value The value of the cookie.
* @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
* @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
*                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
*                             If set to null or omitted, the cookie will be a session cookie and will not be retained
*                             when the the browser exits.
* @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
* @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
* @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
*                        require a secure protocol (like HTTPS).
* @type undefined
*
* @name $.cookie
* @cat Plugins/Cookie
* @author Klaus Hartl/klaus.hartl@stilbuero.de
*/

/**
* Get the value of a cookie with the given name.
*
* @example $.cookie('the_cookie');
* @desc Get the value of a cookie.
*
* @param String name The name of the cookie.
* @return The value of the cookie.
* @type String
*
* @name $.cookie
* @cat Plugins/Cookie
* @author Klaus Hartl/klaus.hartl@stilbuero.de
*/
jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options = $.extend({}, options); // clone object since it's unexpected behavior if the expired property were changed
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // NOTE Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};








/* 	Easy Tooltip 1.0 - jQuery plugin
*	written by Alen Grakalic	
*	http://cssglobe.com/post/4380/easy-tooltip--jquery-plugin
*/
eval(function(p, a, c, k, e, r) { e = function(c) { return (c < a ? '' : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36)) }; if (!''.replace(/^/, String)) { while (c--) r[e(c)] = k[c] || e(c); k = [function(e) { return r[e] } ]; e = function() { return '\\w+' }; c = 1 }; while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]); return p } ('(2($){$.A.p=2(d){5 f={q:10,r:B,3:"p",s:C,l:"",m:""};5 d=$.D(f,d);5 g;d.7=2(e){5 a=(e.E-d.r);5 b=$("#"+d.3).t();6(a+b>$(n.o).t()-15)a-=(b+F);u a};d.8=2(e){5 a=(e.G+d.q);5 b=$("#"+d.3).v();6(a+b>$(n.o).v()-15)a-=(b+H);u a};4.I(2(){5 c=$(4).9("h");6(c&&c.w>0){$(4).J(2(e){g=(d.l!="")?d.l:c;g=(d.m!="")?$("#"+d.m).x():g;$(4).9("h","");6(g!=""&&g!=K){5 b=$("#"+d.3);6(b.w!=1){$("o").L("<y M=\'"+d.3+"\' N=\'O:P;Q:R;z-S:T;\'></y>");b=$("#"+d.3)}b.x(g);b.j("7",d.7(e)+"k").j("8",d.8(e)+"k").U("V",2(){W(\'$("#\'+d.3+\'").i();\',X)});$(n).Y(\'Z\',2(a){b.i()})}},2(){$("#"+d.3).i();$(4).9("h",c)});$(4).11(2(e){$("#"+d.3).j("7",d.7(e)+"k").j("8",d.8(e)+"k")});$(4).12(2(e){$("#"+d.3).i();$(4).9("h",c)});6(d.s){$(4).13(2(e){$("#"+d.3).i();$(4).9("h",c)})}}})}})(14);', 62, 68, '||function|tooltipId|this|var|if|top|left|attr||||||||title|hide|css|px|content|useElement|document|body|easyTooltip|xOffset|yOffset|clickRemove|height|return|width|length|html|div||fn|25|true|extend|pageY|20|pageX|30|each|hover|undefined|append|id|style|position|absolute|display|none|index|1000|fadeIn|fast|setTimeout|5000|one|click||mousemove|mouseout|mousedown|jQuery|'.split('|'), 0, {}))







// JQUERY LIBRARY - jquery.getUrlParam.js 

// *******************************************************************************
// *******************************************************************************
// *******************************************************************************
// *******************************************************************************

jQuery.fn.extend({
    getUrlParam: function(strParamName) {
        strParamName = escape(unescape(strParamName));
        var returnVal = new Array();
        var qString = null;
        if ($(this).attr("nodeName") == "#document") {
            if (window.location.search.search(strParamName) > -1) {
                qString = window.location.search.substr(1, window.location.search.length).split("&");
            }
        } else if ($(this).attr("src") != "undefined") {
            var strHref = $(this).attr("src")
            if (strHref.indexOf("?") > -1) {
                var strQueryString = strHref.substr(strHref.indexOf("?") + 1);
                qString = strQueryString.split("&");
            }
        } else if ($(this).attr("href") != "undefined") {
            var strHref = $(this).attr("href")
            if (strHref.indexOf("?") > -1) {
                var strQueryString = strHref.substr(strHref.indexOf("?") + 1);
                qString = strQueryString.split("&");
            }
        } else {
            return null;
        }
        if (qString == null) return null;
        for (var i = 0; i < qString.length; i++) {
            if (escape(unescape(qString[i].split("=")[0])) == strParamName) {
                returnVal.push(qString[i].split("=")[1]);
            }
        }
        if (returnVal.length == 0) return null;
        else if (returnVal.length == 1) return returnVal[0];
        else return returnVal;
    }
});







// jquery.highlightFade



/**
*  jQuery Plugin highlightFade (jquery.offput.ca/highlightFade)
*  (c) 2006 Blair Mitchelmore (offput.ca) blair@offput.ca
*/
/**
* This is version 0.7 of my highlightFade plugin. It follows the yellow fade technique of Web 2.0 fame
* but expands it to allow any starting colour and allows you to specify the end colour as well.
*
* For the moment, I'm done with this plug-in. Unless I come upon a really cool feature it should have
* this plug-in will only receive updates to ensure future compatibility with jQuery.
*
* As of now (Aug. 16, 2006) the plugin has been written with the 1.0.1 release of jQuery (rev 249) which
* is available from http://jquery.com/src/jquery-1.0.1.js
*
* A note regarding rgb() syntax: I noticed that most browsers implement rgb syntax as either an integer 
* (0-255) or percentage (0-100%) value for each field, that is, rgb(i/p,i/p,i/p); however, the W3C 
* standard clearly defines it as "either three integer values or three percentage values" [http://www.w3.org/TR/CSS21/syndata.html] 
* which I choose to follow despite the error redundancy of the typical behaviour browsers employ.
*
* Changelog:
*
*    0.7:
*        - Added the awesome custom attribute support written by George Adamson (slightly modified)
*        - Removed bgColor plugin dependency seeing as attr is customizable now...
*    0.6:
*        - Abstracted getBGColor into its own plugin with optional test and data retrieval functions
*        - Converted all $ references to jQuery references as John's code seems to be shifting away
*          from that and I don't want to have to update this for a long time.
*    0.5:
*        - Added simple argument syntax for only specifying start colour of event
*        - Removed old style argument syntax
*        - Added 'interval', 'final, and 'end' properties
*        - Renamed 'color' property to 'start'
*        - Added second argument to $.highlightFade.getBGColor to bypass the e.highlighting check
*    0.4:
*        - Added rgb(%,%,%) color syntax
*    0.3:
*        - Fixed bug when event was called while parent was also running event corrupting the
*          the background colour of the child
*    0.2:
*        - Fixed bug where an unspecified onComplete function made the page throw continuous errors
*        - Fixed bug where multiple events on the same element would speed each subsequent event
*    0.1:
*        - Initial Release
* 
* @author          Blair Mitchelmore (blair@offput.ca)
* @version         0.5
*/
jQuery.fn.highlightFade = function(settings) {
    var o = (settings && settings.constructor == String) ? { start: settings} : settings || {};
    var d = jQuery.highlightFade.defaults;
    var i = o['interval'] || d['interval'];
    var a = o['attr'] || d['attr'];
    var ts = {
        'linear': function(s, e, t, c) { return parseInt(s + (c / t) * (e - s)); },
        'sinusoidal': function(s, e, t, c) { return parseInt(s + Math.sin(((c / t) * 90) * (Math.PI / 180)) * (e - s)); },
        'exponential': function(s, e, t, c) { return parseInt(s + (Math.pow(c / t, 2)) * (e - s)); }
    };
    var t = (o['iterator'] && o['iterator'].constructor == Function) ? o['iterator'] : ts[o['iterator']] || ts[d['iterator']] || ts['linear'];
    if (d['iterator'] && d['iterator'].constructor == Function) t = d['iterator'];
    return this.each(function() {
        if (!this.highlighting) this.highlighting = {};
        var e = (this.highlighting[a]) ? this.highlighting[a].end : jQuery.highlightFade.getBaseValue(this, a) || [255, 255, 255];
        var c = jQuery.highlightFade.getRGB(o['start'] || o['colour'] || o['color'] || d['start'] || [255, 255, 128]);
        var s = jQuery.speed(o['speed'] || d['speed']);
        var r = o['final'] || (this.highlighting[a] && this.highlighting[a].orig) ? this.highlighting[a].orig : jQuery.curCSS(this, a);
        if (o['end'] || d['end']) r = jQuery.highlightFade.asRGBString(e = jQuery.highlightFade.getRGB(o['end'] || d['end']));
        if (typeof o['final'] != 'undefined') r = o['final'];
        if (this.highlighting[a] && this.highlighting[a].timer) window.clearInterval(this.highlighting[a].timer);
        this.highlighting[a] = { steps: ((s.duration) / i), interval: i, currentStep: 0, start: c, end: e, orig: r, attr: a };
        jQuery.highlightFade(this, a, o['complete'], t);
    });
};

jQuery.highlightFade = function(e, a, o, t) {
    e.highlighting[a].timer = window.setInterval(function() {
        var newR = t(e.highlighting[a].start[0], e.highlighting[a].end[0], e.highlighting[a].steps, e.highlighting[a].currentStep);
        var newG = t(e.highlighting[a].start[1], e.highlighting[a].end[1], e.highlighting[a].steps, e.highlighting[a].currentStep);
        var newB = t(e.highlighting[a].start[2], e.highlighting[a].end[2], e.highlighting[a].steps, e.highlighting[a].currentStep);
        jQuery(e).css(a, jQuery.highlightFade.asRGBString([newR, newG, newB]));
        if (e.highlighting[a].currentStep++ >= e.highlighting[a].steps) {
            jQuery(e).css(a, e.highlighting[a].orig || '');
            window.clearInterval(e.highlighting[a].timer);
            e.highlighting[a] = null;
            if (o && o.constructor == Function) o.call(e);
        }
    }, e.highlighting[a].interval);
};

jQuery.highlightFade.defaults = {
    start: [255, 255, 128],
    interval: 50,
    speed: 400,
    attr: 'backgroundColor'
};

jQuery.highlightFade.getRGB = function(c, d) {
    var result;
    if (c && c.constructor == Array && c.length == 3) return c;
    if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))
        return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];
    else if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))
        return [parseFloat(result[1]) * 2.55, parseFloat(result[2]) * 2.55, parseFloat(result[3]) * 2.55];
    else if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))
        return [parseInt("0x" + result[1]), parseInt("0x" + result[2]), parseInt("0x" + result[3])];
    else if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))
        return [parseInt("0x" + result[1] + result[1]), parseInt("0x" + result[2] + result[2]), parseInt("0x" + result[3] + result[3])];
    else
        return jQuery.highlightFade.checkColorName(c) || d || null;
};

jQuery.highlightFade.asRGBString = function(a) {
    return "rgb(" + a.join(",") + ")";
};

jQuery.highlightFade.getBaseValue = function(e, a, b) {
    var s, t;
    b = b || false;
    t = a = a || jQuery.highlightFade.defaults['attr'];
    do {
        s = jQuery(e).css(t || 'backgroundColor');
        if ((s != '' && s != 'transparent') || (e.tagName.toLowerCase() == "body") || (!b && e.highlighting && e.highlighting[a] && e.highlighting[a].end)) break;
        t = false;
    } while (e = e.parentNode);
    if (!b && e.highlighting && e.highlighting[a] && e.highlighting[a].end) s = e.highlighting[a].end;
    if (s == undefined || s == '' || s == 'transparent') s = [255, 255, 255];
    return jQuery.highlightFade.getRGB(s);
};

jQuery.highlightFade.checkColorName = function(c) {
    if (!c) return null;
    switch (c.replace(/^\s*|\s*$/g, '').toLowerCase()) {
        case 'aqua': return [0, 255, 255];
        case 'black': return [0, 0, 0];
        case 'blue': return [0, 0, 255];
        case 'fuchsia': return [255, 0, 255];
        case 'gray': return [128, 128, 128];
        case 'green': return [0, 128, 0];
        case 'lime': return [0, 255, 0];
        case 'maroon': return [128, 0, 0];
        case 'navy': return [0, 0, 128];
        case 'olive': return [128, 128, 0];
        case 'purple': return [128, 0, 128];
        case 'red': return [255, 0, 0];
        case 'silver': return [192, 192, 192];
        case 'teal': return [0, 128, 128];
        case 'white': return [255, 255, 255];
        case 'yellow': return [255, 255, 0];
    }
};










// JQUERY LIBRARY - jquery.hotkeys.js

// *******************************************************************************
// *******************************************************************************
// *******************************************************************************
// *******************************************************************************


(function(B) { B.fn.__bind__ = B.fn.bind; B.fn.__unbind__ = B.fn.unbind; B.fn.__find__ = B.fn.find; var A = { version: "0.7.8", override: /keydown|keypress|keyup/g, triggersMap: {}, specialKeys: { 27: "esc", 9: "tab", 32: "space", 13: "return", 8: "backspace", 145: "scroll", 20: "capslock", 144: "numlock", 19: "pause", 45: "insert", 36: "home", 46: "del", 35: "end", 33: "pageup", 34: "pagedown", 37: "left", 38: "up", 39: "right", 40: "down", 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8", 120: "f9", 121: "f10", 122: "f11", 123: "f12" }, shiftNums: { "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&", "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ":", "'": '"', ",": "<", ".": ">", "/": "?", "\\": "|" }, newTrigger: function(E, D, F) { var C = {}; C[E] = {}; C[E][D] = { cb: F, disableInInput: false }; return C } }; if (B.browser.mozilla) { A.specialKeys = B.extend(A.specialKeys, { 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7", 104: "8", 105: "9" }) } B.fn.find = function(C) { this.query = C; return B.fn.__find__.apply(this, arguments) }; B.fn.unbind = function(H, E, G) { if (B.isFunction(E)) { G = E; E = null } if (E && typeof E === "string") { var F = ((this.prevObject && this.prevObject.query) || (this[0].id && this[0].id) || this[0]).toString(); var D = H.split(" "); for (var C = 0; C < D.length; C++) { delete A.triggersMap[F][D[C]][E] } } return this.__unbind__(H, G) }; B.fn.bind = function(J, F, K) { var H = J.match(A.override); if (B.isFunction(F) || !H) { return this.__bind__(J, F, K) } else { var N = null, I = B.trim(J.replace(A.override, "")); if (I) { N = this.__bind__(I, F, K) } if (typeof F === "string") { F = { combi: F} } if (F.combi) { for (var M = 0; M < H.length; M++) { var D = H[M]; var G = F.combi.toLowerCase(), E = A.newTrigger(D, G, K), L = ((this.prevObject && this.prevObject.query) || (this[0].id && this[0].id) || this[0]).toString(); E[D][G].disableInInput = F.disableInInput; if (!A.triggersMap[L]) { A.triggersMap[L] = E } else { if (!A.triggersMap[L][D]) { A.triggersMap[L][D] = E[D] } } var C = A.triggersMap[L][D][G]; if (!C) { A.triggersMap[L][D][G] = [E[D][G]] } else { if (C.constructor !== Array) { A.triggersMap[L][D][G] = [C] } else { A.triggersMap[L][D][G][C.length] = E[D][G] } } this.each(function() { var O = B(this); if (O.attr("hkId") && O.attr("hkId") !== L) { L = O.attr("hkId") + ";" + L } O.attr("hkId", L) }); N = this.__bind__(H.join(" "), F, A.handler) } } return N } }; A.findElement = function(C) { if (!B(C).attr("hkId")) { if (B.browser.opera || B.browser.safari) { while (!B(C).attr("hkId") && C.parentNode) { C = C.parentNode } } } return C }; A.handler = function(E) { var O = A.findElement(E.currentTarget), I = B(O), D = I.attr("hkId"); if (D) { D = D.split(";"); var G = E.which, Q = E.type, P = A.specialKeys[G], N = !P && String.fromCharCode(G).toLowerCase(), H = E.shiftKey, C = E.ctrlKey, M = E.altKey || E.originalEvent.altKey, F = null; for (var R = 0; R < D.length; R++) { if (A.triggersMap[D[R]][Q]) { F = A.triggersMap[D[R]][Q]; break } } if (F) { var J; if (!H && !C && !M) { J = F[P] || (N && F[N]) } else { var L = ""; if (M) { L += "alt+" } if (C) { L += "ctrl+" } if (H) { L += "shift+" } J = F[L + P]; if (!J) { if (N) { J = F[L + N] || F[L + A.shiftNums[N]] || (L === "shift+" && F[A.shiftNums[N]]) } } } if (J) { var S = false; for (var R = 0; R < J.length; R++) { if (J[R].disableInInput) { var K = B(E.target); if (I.is("input") || I.is("textarea") || K.is("input") || K.is("textarea")) { return true } } S = S || J[R].cb.apply(this, [E]) } return S } } } }; window.hotkeys = A; return B })(jQuery);









// JQUERY LIBRARY - jquery.imghover.js

// *******************************************************************************
// *******************************************************************************
// *******************************************************************************
// *******************************************************************************


/**
*  jquery.popupt
*  (c) 2008 Semooh (http://semooh.jp/)
*
*  Dual licensed under the MIT (MIT-LICENSE.txt)
*  and GPL (GPL-LICENSE.txt) licenses.
*
**/
(function($) {
    $.fn.extend({
        imghover: function(opt) {
            return this.each(function() {
                opt = $.extend({
                    prefix: '',
                    suffix: '_o',
                    src: '',
                    btnOnly: true,
                    fade: false,
                    fadeSpeed: 500
                }, opt || {});

                var node = $(this);
                if (!node.is('img') && !node.is(':image')) {
                    var sel = 'img,:image';
                    if (opt.btnOnly) sel = 'a ' + sel;
                    node.find(sel).imghover(opt);
                    return;
                }

                var orgImg = node.attr('src');

                var hoverImg;
                if (opt.src) {
                    hoverImg = opt.src;
                } else {
                    hoverImg = orgImg;
                    if (opt.prefix) {
                        var pos = hoverImg.lastIndexOf('/');
                        if (pos > 0) {
                            hoverImg = hoverImg.substr(0, pos - 1) + opt.prefix + hoverImg.substr(pos - 1);
                        } else {
                            hoverImg = opt.prefix + hoverImg;
                        }
                    }
                    if (opt.suffix) {
                        var pos = hoverImg.lastIndexOf('.');
                        if (pos > 0) {
                            hoverImg = hoverImg.substr(0, pos) + opt.suffix + hoverImg.substr(pos);
                        } else {
                            hoverImg = hoverImg + opt.suffix;
                        }
                    }
                }

                if (opt.fade) {
                    var offset = node.offset();
                    var hover = node.clone(true);
                    hover.attr('src', hoverImg);
                    hover.css({
                        position: 'absolute',
                        left: offset.left,
                        top: offset.top,
                        zIndex: 1000
                    }).hide().insertAfter(node);
                    node.mouseover(
            function() {
                var offset = node.offset();
                hover.css({ left: offset.left, top: offset.top });
                hover.fadeIn(opt.fadeSpeed);
                node.fadeOut(opt.fadeSpeed, function() { node.show() });
            }
          );
                    hover.mouseout(
            function() {
                node.fadeIn(opt.fadeSpeed);
                hover.fadeOut(opt.fadeSpeed);
            }
          );
                } else {
                    node.hover(
            function() { node.attr('src', hoverImg) },
            function() { node.attr('src', orgImg) }
          );
                }
            });
        }
    });
})(jQuery);






// jquery.swap.js


/*! Copyright (c) 2008 Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*/

/**
* Swaps out one element with another. It can take either a DOM element,
* a selector or a jQuery object. It only swaps the first matched element.
*/
jQuery.fn.swap = function(b) {
    b = jQuery(b)[0];
    var a = this[0];

    var t = a.parentNode.insertBefore(document.createTextNode(''), a);
    b.parentNode.insertBefore(a, b);
    t.parentNode.insertBefore(b, t);
    t.parentNode.removeChild(t);

    return this;
};








// JQUERY LIBRARY - jqmodal.js

// *******************************************************************************
// *******************************************************************************
// *******************************************************************************
// *******************************************************************************

(function($) {
    $.fn.jqm = function(o) {
        var p = {
            overlay: 50,
            overlayClass: 'jqmOverlay',
            closeClass: 'jqmClose',
            trigger: '.jqModal',
            ajax: F,
            ajaxText: '',
            target: F,
            modal: F,
            toTop: F,
            onShow: F,
            onHide: F,
            onLoad: F
        };
        return this.each(function() {
            if (this._jqm) return H[this._jqm].c = $.extend({}, H[this._jqm].c, o); s++; this._jqm = s;
            H[s] = { c: $.extend(p, $.jqm.params, o), a: F, w: $(this).addClass('jqmID' + s), s: s };
            if (p.trigger) $(this).jqmAddTrigger(p.trigger);
        });
    };

    $.fn.jqmAddClose = function(e) { return hs(this, e, 'jqmHide'); };
    $.fn.jqmAddTrigger = function(e) { return hs(this, e, 'jqmShow'); };
    $.fn.jqmShow = function(t) { return this.each(function() { $.jqm.open(this._jqm, t); }); };
    $.fn.jqmHide = function(t) { return this.each(function() { $.jqm.close(this._jqm, t) }); };

    $.jqm = {
        hash: {},
        open: function(s, t) {
            var h = H[s], c = h.c, cc = '.' + c.closeClass, z = (parseInt(h.w.css('z-index'))), z = (z > 0) ? z : 3000, o = $('<div></div>').css({ height: '100%', width: '100%', position: 'fixed', left: 0, top: 0, 'z-index': z - 1, opacity: c.overlay / 100 }); if (h.a) return F; h.t = t; h.a = true; h.w.css('z-index', z);
            if (c.modal) { if (!A[0]) L('bind'); A.push(s); }
            else if (c.overlay > 0) h.w.jqmAddClose(o);
            else o = F;

            h.o = (o) ? o.addClass(c.overlayClass).prependTo('body') : F;
            if (ie6) { $('html,body').css({ height: '100%', width: '100%' }); if (o) { o = o.css({ position: 'absolute' })[0]; for (var y in { Top: 1, Left: 1 }) o.style.setExpression(y.toLowerCase(), "(_=(document.documentElement.scroll" + y + " || document.body.scroll" + y + "))+'px'"); } }

            if (c.ajax) {
                var r = c.target || h.w, u = c.ajax, r = (typeof r == 'string') ? $(r, h.w) : $(r), u = (u.substr(0, 1) == '@') ? $(t).attr(u.substring(1)) : u;
                r.html(c.ajaxText).load(u, function() { if (c.onLoad) c.onLoad.call(this, h); if (cc) h.w.jqmAddClose($(cc, h.w)); e(h); });
            }
            else if (cc) h.w.jqmAddClose($(cc, h.w));

            if (c.toTop && h.o) h.w.before('<span id="jqmP' + h.w[0]._jqm + '"></span>').insertAfter(h.o);
            (c.onShow) ? c.onShow(h) : h.w.show(); e(h); return F;
        },
        close: function(s) {
            var h = H[s]; if (!h.a) return F; h.a = F;
            if (A[0]) { A.pop(); if (!A[0]) L('unbind'); }
            if (h.c.toTop && h.o) $('#jqmP' + h.w[0]._jqm).after(h.w).remove();
            if (h.c.onHide) h.c.onHide(h); else { h.w.hide(); if (h.o) h.o.remove(); } return F;
        },
        params: {}
    };
    var s = 0, H = $.jqm.hash, A = [], ie6 = $.browser.msie && ($.browser.version == "6.0"), F = false,
i = $('<iframe src="javascript:false;document.write(\'\');" class="jqm"></iframe>').css({ opacity: 0 }),
e = function(h) { if (ie6) if (h.o) h.o.html('<p style="width:100%;height:100%"/>').prepend(i); else if (!$('iframe.jqm', h.w)[0]) h.w.prepend(i); f(h); },
f = function(h) { try { $(':input:visible', h.w)[0].focus(); } catch (_) { } },
L = function(t) { $()[t]("keypress", m)[t]("keydown", m)[t]("mousedown", m); },
m = function(e) { var h = H[A[A.length - 1]], r = (!$(e.target).parents('.jqmID' + h.s)[0]); if (r) f(h); return !r; },
hs = function(w, t, c) {
    return w.each(function() {
        var s = this._jqm; $(t).each(function() {
            if (!this[c]) { this[c] = []; $(this).click(function() { for (var i in { jqmShow: 1, jqmHide: 1 }) for (var s in this[i]) if (H[this[i][s]]) H[this[i][s]].w[i](this); return F; }); } this[c].push(s);
        });
    });
};
})(jQuery);









// jquery.tablednd_0_5.js | http://www.isocra.com/2008/02/table-drag-and-drop-jquery-plugin/
jQuery.tableDnD = {
    /** Keep hold of the current table being dragged */
    currentTable: null,
    /** Keep hold of the current drag object if any */
    dragObject: null,
    /** The current mouse offset */
    mouseOffset: null,
    /** Remember the old value of Y so that we don't do too much processing */
    oldY: 0,

    /** Actually build the structure */
    build: function(options) {
        // Set up the defaults if any

        this.each(function() {
            // This is bound to each matching table, set up the defaults and override with user options
            this.tableDnDConfig = jQuery.extend({
                onDragStyle: null,
                onDropStyle: null,
                // Add in the default class for whileDragging
                onDragClass: "tDnD_whileDrag",
                onDrop: null,
                onDragStart: null,
                scrollAmount: 5,
                serializeRegexp: /[^\-]*$/, // The regular expression to use to trim row IDs
                serializeParamName: null, // If you want to specify another parameter name instead of the table ID
                dragHandle: "reorder" // If you give the name of a class here, then only Cells with this class will be draggable
            }, options || {});
            // Now make the rows draggable
            jQuery.tableDnD.makeDraggable(this);
        });

        // Now we need to capture the mouse up and mouse move event
        // We can use bind so that we don't interfere with other event handlers
        jQuery(document)
            .bind('mousemove', jQuery.tableDnD.mousemove)
            .bind('mouseup', jQuery.tableDnD.mouseup);

        // Don't break the chain
        return this;
    },

    /** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */
    makeDraggable: function(table) {
        var config = table.tableDnDConfig;
        if (table.tableDnDConfig.dragHandle) {
            // We only need to add the event to the specified cells
            var cells = jQuery("td." + table.tableDnDConfig.dragHandle, table);
            cells.each(function() {
                // The cell is bound to "this"
                jQuery(this).mousedown(function(ev) {
                    jQuery.tableDnD.dragObject = this.parentNode;
                    jQuery.tableDnD.currentTable = table;
                    jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(this, ev);
                    if (config.onDragStart) {
                        // Call the onDrop method if there is one
                        config.onDragStart(table, this);
                    }
                    return false;
                }).css("cursor", "move");
            })
        } else {
            // For backwards compatibility, we add the event to the whole row
            var rows = jQuery("tr", table); // get all the rows as a wrapped set
            rows.each(function() {
                // Iterate through each row, the row is bound to "this"
                var row = jQuery(this);
                if (!row.hasClass("nodrag")) {
                    row.mousedown(function(ev) {
                        if (ev.target.tagName == "TD") {
                            jQuery.tableDnD.dragObject = this;
                            jQuery.tableDnD.currentTable = table;
                            jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(this, ev);
                            if (config.onDragStart) {
                                // Call the onDrop method if there is one
                                config.onDragStart(table, this);
                            }
                            return false;
                        }
                    }).css("cursor", "move"); // Store the tableDnD object
                }
            });
        }
    },

    updateTables: function() {
        this.each(function() {
            // this is now bound to each matching table
            if (this.tableDnDConfig) {
                jQuery.tableDnD.makeDraggable(this);
            }
        })
    },

    /** Get the mouse coordinates from the event (allowing for browser differences) */
    mouseCoords: function(ev) {
        if (ev.pageX || ev.pageY) {
            return { x: ev.pageX, y: ev.pageY };
        }
        return {
            x: ev.clientX + document.body.scrollLeft - document.body.clientLeft,
            y: ev.clientY + document.body.scrollTop - document.body.clientTop
        };
    },

    /** Given a target element and a mouse event, get the mouse offset from that element.
    To do this we need the element's position and the mouse position */
    getMouseOffset: function(target, ev) {
        ev = ev || window.event;

        var docPos = this.getPosition(target);
        var mousePos = this.mouseCoords(ev);
        return { x: mousePos.x - docPos.x, y: mousePos.y - docPos.y };
    },

    /** Get the position of an element by going up the DOM tree and adding up all the offsets */
    getPosition: function(e) {
        var left = 0;
        var top = 0;
        /** Safari fix -- thanks to Luis Chato for this! */
        if (e.offsetHeight == 0) {
            /** Safari 2 doesn't correctly grab the offsetTop of a table row
            this is detailed here:
            http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/
            the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild.
            note that firefox will return a text node as a first child, so designing a more thorough
            solution may need to take that into account, for now this seems to work in firefox, safari, ie */
            e = e.firstChild; // a table cell
        }

        while (e.offsetParent) {
            left += e.offsetLeft;
            top += e.offsetTop;
            e = e.offsetParent;
        }

        left += e.offsetLeft;
        top += e.offsetTop;

        return { x: left, y: top };
    },

    mousemove: function(ev) {
        if (jQuery.tableDnD.dragObject == null) {
            return;
        }

        var dragObj = jQuery(jQuery.tableDnD.dragObject);
        var config = jQuery.tableDnD.currentTable.tableDnDConfig;
        var mousePos = jQuery.tableDnD.mouseCoords(ev);
        var y = mousePos.y - jQuery.tableDnD.mouseOffset.y;
        //auto scroll the window
        var yOffset = window.pageYOffset;
        if (document.all) {
            // Windows version
            //yOffset=document.body.scrollTop;
            if (typeof document.compatMode != 'undefined' &&
	             document.compatMode != 'BackCompat') {
                yOffset = document.documentElement.scrollTop;
            }
            else if (typeof document.body != 'undefined') {
                yOffset = document.body.scrollTop;
            }

        }

        if (mousePos.y - yOffset < config.scrollAmount) {
            window.scrollBy(0, -config.scrollAmount);
        } else {
            var windowHeight = window.innerHeight ? window.innerHeight
                    : document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight;
            if (windowHeight - (mousePos.y - yOffset) < config.scrollAmount) {
                window.scrollBy(0, config.scrollAmount);
            }
        }


        if (y != jQuery.tableDnD.oldY) {
            // work out if we're going up or down...
            var movingDown = y > jQuery.tableDnD.oldY;
            // update the old value
            jQuery.tableDnD.oldY = y;
            // update the style to show we're dragging
            if (config.onDragClass) {
                dragObj.addClass(config.onDragClass);
            } else {
                dragObj.css(config.onDragStyle);
            }
            // If we're over a row then move the dragged row to there so that the user sees the
            // effect dynamically
            var currentRow = jQuery.tableDnD.findDropTargetRow(dragObj, y);
            if (currentRow) {
                // TODO worry about what happens when there are multiple TBODIES
                if (movingDown && jQuery.tableDnD.dragObject != currentRow) {
                    jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow.nextSibling);
                } else if (!movingDown && jQuery.tableDnD.dragObject != currentRow) {
                    jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow);
                }
            }
        }

        return false;
    },

    /** We're only worried about the y position really, because we can only move rows up and down */
    findDropTargetRow: function(draggedRow, y) {
        var rows = jQuery.tableDnD.currentTable.rows;
        for (var i = 0; i < rows.length; i++) {
            var row = rows[i];
            var rowY = this.getPosition(row).y;
            var rowHeight = parseInt(row.offsetHeight) / 2;
            if (row.offsetHeight == 0) {
                rowY = this.getPosition(row.firstChild).y;
                rowHeight = parseInt(row.firstChild.offsetHeight) / 2;
            }
            // Because we always have to insert before, we need to offset the height a bit
            if ((y > rowY - rowHeight) && (y < (rowY + rowHeight))) {
                // that's the row we're over
                // If it's the same as the current row, ignore it
                if (row == draggedRow) { return null; }
                var config = jQuery.tableDnD.currentTable.tableDnDConfig;
                if (config.onAllowDrop) {
                    if (config.onAllowDrop(draggedRow, row)) {
                        return row;
                    } else {
                        return null;
                    }
                } else {
                    // If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic)
                    var nodrop = jQuery(row).hasClass("nodrop");
                    if (!nodrop) {
                        return row;
                    } else {
                        return null;
                    }
                }
                return row;
            }
        }
        return null;
    },

    mouseup: function(e) {
        if (jQuery.tableDnD.currentTable && jQuery.tableDnD.dragObject) {
            var droppedRow = jQuery.tableDnD.dragObject;
            var config = jQuery.tableDnD.currentTable.tableDnDConfig;
            // If we have a dragObject, then we need to release it,
            // The row will already have been moved to the right place so we just reset stuff
            if (config.onDragClass) {
                jQuery(droppedRow).removeClass(config.onDragClass);
            } else {
                jQuery(droppedRow).css(config.onDropStyle);
            }
            jQuery.tableDnD.dragObject = null;
            if (config.onDrop) {
                // Call the onDrop method if there is one
                config.onDrop(jQuery.tableDnD.currentTable, droppedRow);
            }
            jQuery.tableDnD.currentTable = null; // let go of the table too
        }
    },

    serialize: function() {
        if (jQuery.tableDnD.currentTable) {
            return jQuery.tableDnD.serializeTable(jQuery.tableDnD.currentTable);
        } else {
            return "Error: No Table id set, you need to set an id on your table and every row";
        }
    },

    serializeTable: function(table) {
        var result = "";
        var tableId = table.id;
        if (tableId && table.tableDnDConfig && table.tableDnDConfig.serializeRegexp) {
            tableId = tableId.match(table.tableDnDConfig.serializeRegexp)[0];
        }
        var rows = table.rows;
        for (var i = 0; i < rows.length; i++) {
            if (result.length > 0) result += "&";
            var rowId = rows[i].id;
            if (rowId && table.tableDnDConfig && table.tableDnDConfig.serializeRegexp) {
                rowId = rowId.match(table.tableDnDConfig.serializeRegexp)[0];
            }

            result += tableId + '[]=' + rowId;
        }
        return result;
    },

    serializeTables: function() {
        var result = "";
        this.each(function() {
            // this is now bound to each matching table
            result += jQuery.tableDnD.serializeTable(this);
        });
        return result;
    }
}

jQuery.fn.extend(
	{
	    tableDnD: jQuery.tableDnD.build,
	    tableDnDUpdate: jQuery.tableDnD.updateTables,
	    tableDnDSerialize: jQuery.tableDnD.serializeTables
	}
);






// add default the menuID to the data of a json handler
//  if(!data) data = {} added so Delete on Element Tree Component Works;
jQuery.extend({
    getJSON: function(url, data, callback) {
        if (data && !data.ID) data.ID = menuID;
        return jQuery.get(url, data, callback, "json");
    }
});


// reorder a table
jQuery.extend({
    reorder: function(objectType, data, startIndex) {
        if (!startIndex) startIndex = 0;
        jQuery.getJSON(baseURL + 'ValentNet/Views/Shared/Handlers/ReorderHandler.ashx',
{ action: 'Reorder', objectType: objectType, data: data, startIndex: startIndex, pageUrl: document.location.href });
    },
    tableDnDResult: function(table) {

        var result = '';
        var rows = table.rows;
        for (var i = 0; i < rows.length; i++) {
            if (result.length > 0) result += "&";
            var rowId = rows[i].id;
            if (!rowId) continue;
            result += rowId.match(/[^_]*$/)[0];

            // zebra row
            if (i % 2) {
                $(rows[i]).removeClass("rowOdd");
                $(rows[i]).addClass("rowEven");
                $(rows[i]).mouseout(function() { this.className = 'rowEven'; });
            } else {
                $(rows[i]).removeClass("rowEven");
                $(rows[i]).addClass("rowOdd");
                $(rows[i]).mouseout(function() { this.className = 'rowOdd'; });
            }
        }
        return result;
    }
});






// toggle an image (boolean)
jQuery.extend({
    toggleImg: function(img, objectType, field, assemblyName, options) {
        var el = $(img);
        while (el && el.get(0).tagName != 'TR') el = el.parent();

        var rowId = el.attr('id');
        if (!rowId) return;
        rowId = rowId.match(/[^_]*$/)[0];

        if (!options) {
            options = { ok: labels.yes, cancel: labels.no }
        }

        jQuery.getJSON(baseURL + 'ValentNet/Views/Shared/Handlers/ToggleHandler.ashx',
            { action: 'Toggle', objectType: objectType, objectId: rowId, field: field, assemblyName: assemblyName, pageUrl: document.location.href },
            function(data) {
                if (data.saved) {
                    if (img.src.indexOf('ok.gif') != -1) {
                        img.src = img.src.replace('ok.gif', 'cancel.gif');
                        img.title = options.cancel;
                    } else {
                        img.src = img.src.replace('cancel.gif', 'ok.gif');
                        img.title = options.ok;
                    }
                    $(img).easyTooltip();

                    toggleImgCallback(el, img, rowId, objectType);
                }
            });
    }
});
function toggleImgCallback(row, image, objectID, objectType) {
}







// check of a file exists
jQuery.extend({
    fileExists: function(path, data, options) {
    var exists = false;
        var handler = baseURL + 'ValentNet/Views/Shared/Handlers/FileHandler.ashx';
        if (!path) path = '';

        if (!data) data = {};
        data.ID = data.menuID || menuID;
        data.action = 'Exists';
        data.path = path;
        data.pageUrl =  document.location.href

        /// rename: is it possible to rename the file
        /// check: checkt the file by true otherwise not
        /// overwritable: can the file be overwriten
        if (!options) options = { rename: true, check: true, overwritable: true };
        if ('rename' in options == false) options.rename = true;
        if ('check' in options == false) options.check = true;
        if ('overwritable' in options == false) options.overwritable = true;

        if (data.type) {
            var obj = eval(data.type);
            if (typeof (obj.Options) == "function")
                options = obj.Options(data);
        }
        data.overwritable = options.overwritable;

        if (options.check) {
            jQuery.ajax({
                url: handler,
                data: data,
                dataType: 'json',
                success: function(result) {
                    exists = result.Exists;
                },
                async: false
            });
        }

        if (exists && options.rename) {
            data.action = 'Rename';
            tb_show('File', handler + '?height=120&width=350&modal=true', '', data);
        }

        return exists;
    }
});








// fit a image to his parent
jQuery.extend({
    fitImage: function(image, options) {
        var parent = $(image);
        while (parent && parent.hasClass('fit') == false) {
            parent = parent.parent();
        }

        if (!parent) return;
        if (!options) options = { stretch: false, resize: false };

        var maxwidth = parseInt(parent.css("width").replace('px', ''), 10);
        var maxheight = parseInt(parent.css("height").replace('px', ''), 10);

        var width = image.width | 0;
        var height = image.height | 0;

        if (width == 0) width = maxwidth;
        if (height == 0) height = maxheight;

        var widthPerc = maxwidth / width;
        var heightPerc = maxheight / height;

        var perc = widthPerc > heightPerc ? widthPerc : heightPerc;
        if (options.resize) perc = widthPerc > heightPerc ? heightPerc : widthPerc;
        if (!options.stretch && perc > 1) perc = 1;

        var newwidth = parseInt(perc * width);
        var newheight = parseInt(perc * height);

        if (newwidth > maxwidth) {
            $(image).css("margin-left", "-" + ((newwidth - maxwidth) / 2) + 'px');
        } else {
            $(image).css("margin-left", ((maxwidth - newwidth) / 2) + 'px');
        }
        if (newheight > maxheight) {
            $(image).css("margin-top", "-" + ((newheight - maxheight) / 2) + 'px');
        } else {
            $(image).css("margin-top", ((maxheight - newheight) / 2) + 'px');
        }

        image.width = newwidth;
        image.height = newheight;
    }
});








// like contains but case insensitive
$.expr[':'].search = function(obj, index, meta, stack) {
    return (obj.textContent || obj.innerText || jQuery(obj).text() || '').toLowerCase().indexOf(meta[3].toLowerCase()) >= 0;
};








// JQUERY LIBRARY - Thickbox (http://jquery.com/demo/thickbox/)

// *******************************************************************************
// *******************************************************************************
// *******************************************************************************
// *******************************************************************************


/*
* Thickbox 3 - One Box To Rule Them All.
* By Cody Lindley (http://www.codylindley.com)
* Copyright (c) 2007 cody lindley
* Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
*/

var tb_pathToImage = "ValentNet/Content/icons/loading.gif";
var tb_pathToClose = "valentnet/content/icons/error.png";
var imgCloseLoader;
eval(function(p, a, c, k, e, r) { e = function(c) { return (c < a ? '' : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36)) }; if (!''.replace(/^/, String)) { while (c--) r[e(c)] = k[c] || e(c); k = [function(e) { return r[e] } ]; e = function() { return '\\w+' }; c = 1 }; while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]); return p } ('$(r).2G(9(){1B(\'a.1k, 2H.1k, 2I.1k\');Z=11 1e();Z.s=1Q+1R;12=11 1e();12.s=1Q+1S});9 1B(b){$(b).A(9(){6 t=13.M||13.1C||U;6 a=13.D||13.1T;6 g=13.1U||N;1l(t,a,g);13.2J();J N})}9 1l(d,f,g,h){2K{3(1m(i)=="1n"){i=\'/\'}3(1m(Z)=="1n"){Z=11 1e();Z.s=i+1R;12=11 1e();12.s=i+1S}3(1m r.E.O.1V==="1n"){$("E","1f").B({G:"1W%",F:"1W%"});$("1f").B("1X","2L");3(r.1Y("1D")===U){$("E").C("<14 5=\'1D\'></14><4 5=\'H\'></4><4 5=\'8\'></4>");$("#H").A(P)}}q{3(r.1Y("H")===U){$("E").C("<4 5=\'H\'></4><4 5=\'8\'></4>");$("#H").A(P)}}3(1Z()){$("#H").20("2M")}q{$("#H").20("2N")}3(d===U){d=""}$("E").C("<4 5=\'Q\'><1o s=\'"+Z.s+"\' /></4>");$(\'#Q\').2O();6 i;3(f.V("?")!==-1){i=f.2P(0,f.V("?"))}q{i=f}6 j=/\\.21$|\\.22$|\\.23$|\\.24$|\\.25$/;6 k=i.1p().26(j);3(k==\'.21\'||k==\'.22\'||k==\'.23\'||k==\'.24\'||k==\'.25\'){1q="";1r="";15="";1s="";1t="";W="";1E="";1F=N;3(g){v=$("a[1U=\'"+g+"\']").2Q();28(u=0;((u<v.X)&&(W===""));u++){6 l=v[u].D.1p().26(j);3(u==0&&v.X>1){1q=v[u].M;15="<R 5=\'1G\'>&S;&S;&2a; "+K.2b+"</R>"}3(u==v.X-1){1s=v[u].M;W="<R 5=\'1H\'>&S;&S;"+K.2c+" &2d;</R>"}3(!(v[u].D==f)){3(1F){1s=v[u].M;1t=v[u].D;W="<R 5=\'1H\'>&S;&S;<a D=\'#\'>"+K.2c+" &2d;</a></R>"}q{1q=v[u].M;1r=v[u].D;15="<R 5=\'1G\'>&S;&S;<a D=\'#\'>&2a; "+K.2b+"</a></R>"}}q{1F=1u;1E=K.2R.1v("{0}",u+1).1v("{1}",v.X)}}}16=11 1e();16.1w=9(){16.1w=U;6 a=1I();6 x=a[0]-1x;6 y=a[1]-1x;6 b=16.F;6 c=16.G;3(b>x){c=c*(x/b);b=x;3(c>y){b=b*(y/c);c=y}}q 3(c>y){b=b*(y/c);c=y;3(b>x){c=c*(x/b);b=x}}18=b+30;1g=c+2S;$("#8").C("<a D=\'\' 5=\'2e\' M=\'"+K.1y+"\'><1o 5=\'2T\' s=\'"+f+"\' F=\'"+b+"\' G=\'"+c+"\' 1T=\'"+d+"\'/></a>"+"<4 5=\'2U\'>"+d+"<4 5=\'2V\'>"+1E+15+W+"</4></4><4 5=\'2W\'><a D=\'#\' 5=\'19\' M=\'"+K.1y+"\'>"+K.1y.1p()+"</a></4>");$("#19").A(P);3((!(15===""))&&(!(1r===""))){9 1h(){3($(r).Y("A",1h)){$(r).Y("A",1h)}$("#8").I();$("E").C("<4 5=\'8\'></4>");1l(1q,1r,g);J N}$("#1G").A(1h)}3((!(W===""))&&(!(1t===""))){9 1J(){$("#8").I();$("E").C("<4 5=\'8\'></4>");1l(1s,1t,g);J N}$("#1H").A(1J)}r.1z=9(e){3(e==U){T=2f.2g}q{T=e.2h}3(T==27){P()}q 3(T==2X){3(!(W=="")){r.1z="";1J()}}q 3(T==2Y){3(!(15=="")){r.1z="";1h()}}};1i();$("#Q").I();$("#2e").A(P);$("#8").B({1a:"1b"})};16.s=f}q{6 m=f.1v(/^[^\\?]+\\??/,\'\');6 n=2i(m);18=(n[\'F\']*1)+30||2Z;1g=(n[\'G\']*1)+31||32;3(n["33"]){6 o=1I();18=o[0]-1x;1g=o[1]-1x}1c=18-30;1d=1g-34;6 p=d&&d.X>0?"<4 5=\'2j\'>"+d+"</4>":"";3(f.V(\'2k\')!=-1){1K=f.1L(\'35\');$("#1j").I();3(n[\'1M\']!="1u"){$("#8").C("<4 5=\'2l\'>"+p+"<4 5=\'2m\'><a D=\'#\' 5=\'19\' M=\'"+K.1y+"\'><1o s=\'"+12.s+"\' /></a></4></4><14 2n=\'0\' 2o=\'0\' s=\'"+1K[0]+"\' 5=\'1j\' 1C=\'1j"+1A.2p(1A.1N()*2q)+"\' 1w=\'1O()\' O=\'F:"+(1c+29)+"z;G:"+(1d+17)+"z;\' > </14>")}q{$("#H").Y();$("#8").C("<14 2n=\'0\' 2o=\'0\' s=\'"+1K[0]+"\' 5=\'1j\' 1C=\'1j"+1A.2p(1A.1N()*2q)+"\' 1w=\'1O()\' O=\'F:"+(1c+29)+"z;G:"+(1d+17)+"z;\'> </14>")}}q{3($("#8").B("1a")!="1b"){3(n[\'1M\']!="1u"){$("#8").C("<4 5=\'2l\'>"+p+"<4 5=\'2m\'><a D=\'#\' 5=\'19\'><1o s=\'"+12.s+"\' /></a></4></4><4 5=\'L\' O=\'F:"+1c+"z;G:"+1d+"z\'></4>")}q{$("#H").Y();$("#8").C("<4 5=\'L\' 36=\'37\' O=\'F:"+1c+"z;G:"+1d+"z;\'></4>")}}q{$("#L")[0].O.F=1c+"z";$("#L")[0].O.G=1d+"z";$("#L")[0].38=0;$("#2j").1f(d)}}$("#19").A(P);3(f.V(\'39\')!=-1){$("#L").C($(\'#\'+n[\'2r\']).2s());$("#8").2t(9(){$(\'#\'+n[\'2r\']).C($("#L").2s())});1i();$("#Q").I();$("#8").B({1a:"1b"})}q 3(f.V(\'2k\')!=-1){1i();3($.1P.3a){$("#Q").I();$("#8").B({1a:"1b"})}}q{3(!h)h=\'1N=\'+(11 3b().3c());$("#L").3d(f,h,9(){1i();$("#Q").I();1B("#L a.1k");$("#8").B({1a:"1b"})})}}3(!n[\'1M\']){r.2u=9(e){3(e==U){T=2f.2g}q{T=e.2h}3(T==27){P()}}}}3e(e){}}9 1O(){$("#Q").I();$("#8").B({1a:"1b"})}9 P(){3(N==3f()){J N}$("#3g").Y("A");$("#19").Y("A");$("#8").3h("3i",9(){$(\'#8,#H,#1D\').3j("2t").Y().I()});$("#Q").I();3(1m r.E.O.1V=="1n"){$("E","1f").B({G:"2v",F:"2v"});$("1f").B("1X","")}r.1z="";r.2u="";J N}9 1i(){$("#8").B({3k:\'-\'+2w((18/2),10)+\'z\',F:18+\'z\'});3(!(2x.1P.3l&&2x.1P.3m<7)){$("#8").B({3n:\'-\'+2w((1g/2),10)+\'z\'})}}9 2i(a){6 b={};3(!a){J b}6 c=a.1L(/[;&]/);28(6 i=0;i<c.X;i++){6 d=c[i].1L(\'=\');3(!d||d.X!=2){3o}6 e=2y(d[0]);6 f=2y(d[1]);f=f.1v(/\\+/g,\' \');b[e]=f}J b}9 1I(){6 a=r.3p;6 w=2z.2A||2B.2A||(a&&a.2C)||r.E.2C;6 h=2z.2D||2B.2D||(a&&a.2E)||r.E.2E;2F=[w,h];J 2F}9 1Z(){6 a=3q.3r.1p();3(a.V(\'3s\')!=-1&&a.V(\'3t\')!=-1){J 1u}}', 62, 216, '|||if|div|id|var||TB_window|function|||||||||||||||||else|document|src||TB_Counter|TB_TempArray||||px|click|css|append|href|body|width|height|TB_overlay|remove|return|labels|TB_ajaxContent|title|false|style|tb_remove|TB_load|span|nbsp|keycode|null|indexOf|TB_NextHTML|length|unbind|imgLoader||new|imgCloseLoader|this|iframe|TB_PrevHTML|imgPreloader||TB_WIDTH|TB_closeWindowButton|display|block|ajaxContentW|ajaxContentH|Image|html|TB_HEIGHT|goPrev|tb_position|TB_iframeContent|thickbox|tb_show|typeof|undefined|img|toLowerCase|TB_PrevCaption|TB_PrevURL|TB_NextCaption|TB_NextURL|true|replace|onload|150|close|onkeydown|Math|tb_init|name|TB_HideSelect|TB_imageCount|TB_FoundURL|TB_prev|TB_next|tb_getPageSize|goNext|urlNoQuery|split|modal|random|tb_showIframe|browser|baseURL|tb_pathToImage|tb_pathToClose|alt|rel|maxHeight|100|overflow|getElementById|tb_detectMacXFF|addClass|jpg|jpeg|png|gif|bmp|match||for||lt|prev|next|gt|TB_ImageOff|event|keyCode|which|tb_parseQuery|TB_ajaxWindowTitle|TB_iframe|TB_title|TB_closeAjaxWindow|frameborder|hspace|round|1000|inlineId|children|unload|onkeyup|auto|parseInt|jQuery|unescape|window|innerWidth|self|clientWidth|innerHeight|clientHeight|arrayPageSize|ready|area|input|blur|try|hidden|TB_overlayMacFFBGHack|TB_overlayBG|show|substr|get|imageOf|60|TB_Image|TB_caption|TB_secondLine|TB_closeWindow|190|188|630||40|440|maximize|45|TB_|class|TB_modal|scrollTop|TB_inline|safari|Date|getTime|load|catch|confirmTinyMCEIsDirty|TB_imageOff|fadeOut|fast|trigger|marginLeft|msie|version|marginTop|continue|documentElement|navigator|userAgent|mac|firefox'.split('|'), 0, {}))


// Thickbox loading box
function tb_waiting(message, showTimer) {
    if (message) { $("#waiting_message").html(message) };
    tb_show('', '#TB_inline?inlineId=waiting&width=200&height=60&modal=true');
    if (showTimer) { tb_waiting_timer($('#waiting_message').html(), new Stopwatch()); }
}
function tb_waiting_timer(message, stopwatch) {
    $("#waiting_message").html(message + stopwatch.Display());
    setTimeout(function() { tb_waiting_timer(message, stopwatch); }, 1000);
}


/*

highlight v3

Highlights arbitrary terms.

<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>

MIT license.

Johann Burkard
<http://johannburkard.de>
<mailto:jb@eaio.com>

*/

jQuery.fn.highlight = function(pat) {
 function innerHighlight(node, pat) {
  var skip = 0;
  if (node.nodeType == 3) {
   var pos = node.data.toUpperCase().indexOf(pat);
   if (pos >= 0) {
    var spannode = document.createElement('span');
    spannode.className = 'highlight';
    var middlebit = node.splitText(pos);
    var endbit = middlebit.splitText(pat.length);
    var middleclone = middlebit.cloneNode(true);
    spannode.appendChild(middleclone);
    middlebit.parentNode.replaceChild(spannode, middlebit);
    skip = 1;
   }
  }
  else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
   for (var i = 0; i < node.childNodes.length; ++i) {
    i += innerHighlight(node.childNodes[i], pat);
   }
  }
  return skip;
 }
 return this.each(function() {
  innerHighlight(this, pat.toUpperCase());
 });
};

jQuery.fn.removeHighlight = function() {
 return this.find("span.highlight").each(function() {
  this.parentNode.firstChild.nodeName;
  with (this.parentNode) {
   replaceChild(this.firstChild, this);
   normalize();
  }
 }).end();
};

//URLEncode and URLDecode
//http://0061276.netsolhost.com/tony/javascript/urlEncode.js

$.extend({ URLEncode: function(c) {
    var o = ''; var x = 0; c = c.toString(); var r = /(^[a-zA-Z0-9_.]*)/;
    while (x < c.length) {
        var m = r.exec(c.substr(x));
        if (m != null && m.length > 1 && m[1] != '') {
            o += m[1]; x += m[1].length;
        } else {
            if (c[x] == ' ') o += '+'; else {
                var d = c.charCodeAt(x); var h = d.toString(16);
                o += '%' + (h.length < 2 ? '0' : '') + h.toUpperCase();
            } x++;
        } 
    } return o;
},
    URLDecode: function(s) {
        var o = s; var binVal, t; var r = /(%[^%]{2})/;
        while ((m = r.exec(o)) != null && m.length > 1 && m[1] != '') {
            b = parseInt(m[1].substr(1), 16);
            t = String.fromCharCode(b); o = o.replace(m[1], t);
        } return o;
    }
});



// css.js
function get_css(rule_name, stylesheet, delete_flag) { if (!document.styleSheets) return false; rule_name = rule_name.toLowerCase(); stylesheet = stylesheet || 0; for (var i = stylesheet; i < document.styleSheets.length; i++) { var styleSheet = document.styleSheets[i]; css_rules = document.styleSheets[i].cssRules || document.styleSheets[i].rules; if (!css_rules) continue; var j = 0; do { if (css_rules.length && j > css_rules.length + 5) return false; if (css_rules[j].selectorText && css_rules[j].selectorText.toLowerCase() == rule_name) { if (delete_flag == true) { if (document.styleSheets[i].removeRule) document.styleSheets[i].removeRule(j); if (document.styleSheets[i].deleteRule) document.styleSheets[i].deleteRule(j); return true } else return css_rules[j] } } while (css_rules[++j]) } return false } function add_css(rule_name, stylesheet) { rule_name = rule_name.toLowerCase(); stylesheet = stylesheet || 0; if (!document.styleSheets || get_css(rule_name, stylesheet)) return false; (document.styleSheets[stylesheet].insertRule) ? document.styleSheets[stylesheet].insertRule(rule_name + ' { }', 0) : document.styleSheets[stylesheet].addRule(rule_name, null, 0); return get_css(rule_name, stylesheet) } function get_sheet_num(href_name) { if (!document.styleSheets) return false; for (var i = 0; i < document.styleSheets.length; i++) { if (document.styleSheets[i].href && document.styleSheets[i].href.toString().match(href_name)) return i } return false } function remove_css(rule_name, stylesheet) { return get_css(rule_name, stylesheet, true) } function add_sheet(url, media) { if (document.createStyleSheet) { document.createStyleSheet(url) } else { var newSS = document.createElement('link'); newSS.rel = 'stylesheet'; newSS.type = 'text/css'; newSS.media = media || "all"; newSS.href = url; document.getElementsByTagName("head")[0].appendChild(newSS) } }

function ValentNetPage_Validate() {
    try { if (Page_ClientValidate() == false) return false; } catch (err) { }

    try {
        var upload = eval('vnUpload');
        if (typeof (upload) != 'object') return true;
        return upload.Validate();
    } catch (err) {
        return true;
    }
}


var baseURL = '/';
var decimalSeparator = '.';
var menuID = 0;
var languageID = 'NL';
var jsTreeLabels;
var labels;

var nav = window.Event ? true : false;
if (nav) {
    //window.captureEvents(Event.KEYDOWN); 
    window.onkeydown = NetscapeEventHandler_KeyDown;
} else {
    document.onkeydown = MicrosoftEventHandler_KeyDown;
}
function NetscapeEventHandler_KeyDown(e) {
    if (e.which == 13 && e.target.type != 'textarea' && e.target.type != 'submit' && e.target.type != 'image') {
        return false;
    } else {
        return true;
    }
}

function MicrosoftEventHandler_KeyDown() {
    if (event.keyCode == 13 && event.srcElement.type != 'textarea' && event.srcElement.type != 'submit' && event.srcElement.type != 'image') {
        return false;
    } else {
        return true;
    }
}

$(document).ready(function () {
    setAjaxComplete();
});

function setAjaxComplete() {
    $("div[id$='divMessages']").ajaxComplete(GetMessages);
}

function GetMessages(request, settings) {
    if (settings.responseText == '' || settings.responseText.indexOf('{') != 0)
        return;

    var json = eval("(" + settings.responseText + ")");

    // If loginRequired boolean is present, the session has timed out, the person is redirected to the login page.
    if (json.loginRequired) {
        // If there is a returnUrl specified, redirect to it.
        if (json.returnUrl != 'undefined') {
            document.location.href = json.returnUrl;
        }
        else {
            document.location.href = baseURL + 'login/?c=timeout';
        }
    }

    if (!json || typeof (json) != 'object' || typeof (json.messages) == 'undefined') return;

    showMessages(json.messages, $(this));
    messagesComplete($(this));
}
function messagesComplete(element) {
    setTooltips();
}

function showMessages(messages, obj) {
    if (!obj) {
        obj = $("div[id$='divMessages']");
    }

    if (obj.length == 0) {
        var container = $(".container");
        if (container.length == 0) {
            container = $("body");
        }

        container.prepend('<div id="divMessages" class="displaymessages"></div>');
        obj = $("#divMessages");
    }

    obj.empty().show();
    addMessages(obj, messages.error, "error");
    addMessages(obj, messages.warning, "warning");
    addMessages(obj, messages.information, "information");
    addMessages(obj, messages.success, "success");
    addMessages(obj, messages.hint, "hint");
}
function addMessages(obj, messages, messagetype) {
    if (!messages)
        return;

    var html = '<div class="displayMessage ' + messagetype + '">';
    for (var index = 0; index < messages.length; index++)
        html += messages[index];
    html += '</div>';
    obj.append(html);
}
function setTooltips() {
    $("a, img, input, div").filter("[title!='']").easyTooltip();
}


function createPDF() {
    tb_waiting();

    $("textarea[id$='editor']").show();
    $("table.PropertyGrid input[type=text]").addClass("textbox");

    var created = false;
    jQuery.ajax({
        url: baseURL + 'ValentNet/Views/Shared/Handlers/Print.ashx',
        data: { html: $("#content").html(), pageUrl: document.location.href },
        success: function(data) { created = true; },
        async: false,
        dataType: 'html',
        type: 'POST'
    });

    $("textarea[id$='editor']").hide();
    tb_remove();

    return created;
}

function ieSecurityWorkAround() {
    // Prevents the message 'Click to activate this control' from displaying
    /*$("object").each(function(index) {
        $(this).replaceWith($(this));
    });*/
}

function addToFavorites(strURL, strTitle) {
    if (navigator.userAgent.indexOf('MSIE') >= 0 && navigator.userAgent.indexOf('Opera') < 0) {
        window.external.AddFavorite(strURL, strTitle);
    } else {
        document.body.innerHTML += '<' + 'a href="' + strURL + '" title="' + strTitle + '" rel="sidebar" style="display: none;" id="addbookmark">click<' + '/a>';
        document.getElementById('addbookmark').click();
        document.getElementById('addbookmark').outerHTML = '';
    }
}

function cboKeySort_onKeyPress(cbo, caseSensitive, e) {
    if (!e) e = window.event;
    var undefined;
    if (cbo.keypressBuffer == undefined) {
        cbo.keypressBuffer = '';
    }
    var key = String.fromCharCode(e.keyCode);
    cbo.keypressBuffer += key;
    if (!caseSensitive) {
        cbo.keypressBuffer = cbo.keypressBuffer.toLowerCase();
    }
    var optionsLength = cbo.options.length;
    for (var n = 0; n < optionsLength; n++) {
        var optionText = cbo.options[n].text;
        if (!caseSensitive) {
            optionText = optionText.toLowerCase();
        }
        if (optionText.indexOf(cbo.keypressBuffer, 0) == 0) {
            cbo.selectedIndex = n;
            return false;
        }
    }
    cbo.keypressBuffer = key;
    return true;
}

function onEnter(strCommand, e) {
    if (keyEnter(13, e)) {
        eval(strCommand);
    }
}

function keyEnter(number, e) {
    var keynum = 0;
    if (window.event) { keynum = e.keyCode; }
    else if (e.which) { keynum = e.which; }

    return keynum == number;
}

function integerValidation(e, information) {
    var key;
    if (window.event) {
        key = e.keyCode;
    } else if (e.which) {
        key = e.which;
    }

    // 8: backspace | 9: tab | 37: left | 39: right | 46: delete
    return ((key >= 48 && key <= 57) || (key >= 96 && key <= 105) || key == 8 || key == 9 || key == 37 || key == 39 || key == 46);
}
function decimalValidation(e) {
    var key;
    if (window.event) {
        key = e.keyCode;
    } else if (e.which) {
        key = e.which;
    }

    return integerValidation(e) || key == 188 || key == 190 || key == 110;
}

function Trim(STRING) {
    STRING = LTrim(STRING);
    return RTrim(STRING);
}

function RTrim(STRING) {
    while (STRING.charAt((STRING.length - 1)) == " ") {
        STRING = STRING.substring(0, STRING.length - 1);
    }
    return STRING;
}

function LTrim(STRING) {
    while (STRING.charAt(0) == " ") {
        STRING = STRING.replace(STRING.charAt(0), "");
    }
    return STRING;
}

// * * * * dialog window * * * * //
function DialogWindow(strURL, lngImgWidth, lngImgHeight, blnScrollbars) {
    var lngLeftMargin;
    var lngTopMargin;
    var lngScrHeight = screen.height;
    var lngScrWidth = screen.width;
    var lngWinHeight;
    var lngWinWidth;
    var returnValue;
    if (((lngScrWidth - 40) / lngImgWidth) <= ((lngScrHeight - 55) / lngImgHeight)) {
        // Width is leading
        if ((lngScrWidth - 40) < lngImgWidth) {
            //Image width is larger than the screen width, change the image size
            lngImgHeight = Math.round(lngImgHeight * (lngScrWidth - 40) / lngImgWidth);
            lngImgWidth = lngScrWidth - 40;
        }
    } else {
        // Height is leading
        if ((lngScrHeight - 55) < lngImgHeight) {
            //Image height is larger than the screen height, change the image size
            lngImgWidth = Math.round(lngImgWidth * (lngScrHeight - 55) / lngImgHeight);
            lngImgHeight = lngScrHeight - 55;
        }
    }
    lngWinWidth = lngImgWidth + 40;
    if (lngWinWidth < 420) {
        lngWinWidth = 420;
    }
    lngWinHeight = lngImgHeight + 100;
    lngLeftMargin = (lngScrWidth - lngWinWidth) / 2;
    lngTopMargin = (lngScrHeight - lngWinHeight) / 2;
    if (!nav) {
        window.showModalDialog(strURL + "&intWidth=" + lngImgWidth + "&intHeight=" + lngImgHeight, "ValentNet",
		"dialogWidth:" + lngWinWidth + "px;dialogHeight=" + lngWinHeight + "px;dialogLeft:" + lngLeftMargin + "px;dialogTop:" + lngTopMargin + "px;edge:sunken;scroll:" + blnScrollbars + ";status:1;help:0;resizable:1");
    } else {
        window.open(strURL + '&intWidth=' + lngImgWidth + '&intHeight=' + lngImgHeight, 'ValentNet',
        'height=' + lngWinHeight + ',width=' + lngWinWidth + ',toolbar=no,directories=no,status=yes,menubar=no,scrollbars=' + blnScrollbars + ',resizable=yes ,modal=yes,left=' + lngLeftMargin + ',top=' + lngTopMargin);
    }
}
// * * * * popup window * * * * //
function PopupWindow(strUrl, lngImgWidth, lngImgHeight) {
    PopupWindow(strUrl, lngImgWidth, lngImgHeight, false);
}

function PopupWindow(strURL, lngImgWidth, lngImgHeight, blnScrollbars, blnResizable) {
    var lngWinWidth, lngWinHeight, lngLeftMargin, lngTopMargin;
    var lngScrWidth = screen.width;
    var lngScrHeight = screen.height;
    if (((lngScrWidth - 40) / lngImgWidth) <= ((lngScrHeight - 55) / lngImgHeight)) {
        // Width is leading
        if ((lngScrWidth - 40) < lngImgWidth) {
            //Image width is larger than the screen width, change the image size
            lngImgHeight = Math.round(lngImgHeight * (lngScrWidth - 40) / lngImgWidth);
            lngImgWidth = lngScrWidth - 40;
        }
    } else {
        // Height is leading
        if ((lngScrHeight - 55) < lngImgHeight) {
            //Image height is larger than the screen height, change the image size
            lngImgWidth = Math.round(lngImgWidth * (lngScrHeight - 55) / lngImgHeight);
            lngImgHeight = lngScrHeight - 55;
        }
    }
    lngWinWidth = lngImgWidth + 40;
    if (lngWinWidth < 200) {
        lngWinWidth = 200;
    }
    lngWinHeight = lngImgHeight + 55;
    lngLeftMargin = (lngScrWidth - lngWinWidth) / 2;
    lngTopMargin = (lngScrHeight - lngWinHeight) / 2;
    myWin = open(strURL + "&intWidth=" + lngImgWidth + "&intHeight=" + lngImgHeight, "ValentNet",
		"width=" + lngWinWidth + ",height=" + lngWinHeight + ",status=no,toolbar=no,menubar=no,resizable=" + ((blnResizable) ? "yes" : "no") + ",scrollbars=" + ((blnScrollbars) ? "yes" : "no") + ",left=" + lngLeftMargin + ",top=" + lngTopMargin);
    myWin.focus();
}

// * * * * Window Resize * * * * //
function setWinSize(intHeight, intWidth) {
    if (window.outerWidth) {
        window.outerWidth = intWidth;
        window.outerHeight = intHeight;
    } else if (window.resizeTo) {
        window.resizeTo(intWidth, intHeight);
    }
}

// * * * * AJAX * * * * //

function getJsonCI(typeName, action, callback, postData) {
    if (!postData) postData = new Object();
    postData.ID = menuID;
    postData.action = action;
    postData.name = typeName;
    postData.pageUrl = document.location.href;
    $.post(baseURL + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx', postData, callback, 'json');
}

// server validate
function serverValidate(text, action, required) {
    var isValid = false;
    jQuery.ajax({
        url: baseURL + 'ValentNet/Views/Shared/ValidationHandler.ashx?action=' + action + '&text=' + text + '&required=' + required + '&pageUrl=' + document.location.href,
        success: function(data) {
            isValid = data.isValid;
        },
        async: false,
        dataType: 'json'
    });
    return isValid;
}

// * AJAX version 1 * //
var id;
var obj;
function getResponse(strUrl, strFunction, strID) {
    obj = GetXmlHttpObject();
    if (obj != null) {
        if (strID != undefined && strID != null) {
            if (strID.length > 0) {
                id = strID;
            }
        }
        obj.onreadystatechange = strFunction;
        obj.open("GET", strUrl + '&' + Math.random(), true);
        obj.send(null);
    } else {
        alert('No AJAX-support!/nPlease use FireFox or Internet Explorer.');
    }
}
function GetXmlHttpObject() {
    var objXMLHttp = null;
    if (window.XMLHttpRequest) {
        objXMLHttp = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        objXMLHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    return objXMLHttp;
}
// * AJAX version 2 * //
var fAJAXResponse;
var objAJAX;

function sendAJAX(strUrl, postData) {
    objAJAX = GetXmlHttpObject();
    if (objAJAX != null) {
        objAJAX.onreadystatechange = showAJAXResponse;
        objAJAX.open("GET", strUrl + '?' + postData + '&' + Math.random(), true);
        objAJAX.send(postData);
    } else {
        alert('No AJAX-support!/nPlease use FireFox or Internet Explorer.');
    }
}
function getAJAXResponse(strURL) {
    objAJAX = GetXmlHttpObject();
    if (objAJAX != null) {
        if (objAJAX.readyState > 0 && objAJAX.readyState < 4) {
            objAJAX.abort(); // kill if 1,2,3
        }
        objAJAX.onreadystatechange = showAJAXResponse;
        objAJAX.open("GET", strURL + '&' + Math.random(), true);
        objAJAX.send(null);
    } else {
        alert('No AJAX-support!/nPlease use FireFox or Internet Explorer.');
    }
}
function showAJAXResponse() {
    if (objAJAX.readyState == 4) {
        if (objAJAX.status == 200) {
            if (fAJAXResponse != null) {
                fAJAXResponse();
            }
        }
    }
}

// * AJAX version 3 - supports simultaneous requests * //

function sendAJAX3(url, postData, strReceiveFunc) {
    var httpRequest = GetXmlHttpObject();
    httpRequest.onreadystatechange = function() { showAJAXResponse3(httpRequest, strReceiveFunc); };

    if (postData != null)
        httpRequest.open("GET", url + '?' + postData + '&' + Math.random(), true);
    else
        httpRequest.open("GET", url + '?' + Math.random(), true);

    httpRequest.send('');

}

function showAJAXResponse3(httpRequest, strReceiveFunc) {
    if (httpRequest.readyState == 4) {
        if (httpRequest.status == 200) {
            eval(strReceiveFunc);

        }
        else {
            alert('There was a problem with the request.\n' + httpRequest.status + '\n' + httpRequest.responseText);
        }
    }
}

function setPageMenuButton(id, index) {
    var pagemenu = document.getElementById(id + '_pnlMenu');
    if (!pagemenu) return;
    var buttons = pagemenu.getElementsByTagName('input');
    var l = buttons.length;
    for (var i = 0; i < l; i++)
        buttons[i].className = i == index ? 'selected' : '';
}

function toggleResponse(strImgID, intID, txtOK, txtCancel, imgOK, imgCancel) {
    var img = document.getElementById(strImgID);
    if (!img) { alert('Image not found!'); return; }
    switch (objAJAX.responseText) {
        case "0":
            img.src = baseURL + "ValentNet/Content/icons/" + imgCancel;
            img.title = txtCancel;
            break;
        case "1":
            img.src = baseURL + "ValentNet/Content/icons/" + imgOK;
            img.title = txtOK;
            break;
        default:
            alert(objAJAX.responseText);
            break;
    }
}
function toggleItem(strImgID, intID, url, txtOK, txtCancel, imgOK, imgCancel) {
    if (!txtOK) txtOK = 'Zet `dit item` uit';
    if (!txtCancel) txtCancel = 'Zet `dit item` aan';
    if (!imgOK) imgOK = 'ok.gif';
    if (!imgCancel) imgCancel = 'cancel.gif';

    fAJAXResponse = new Function("toggleResponse('" + strImgID + "'," + intID + ",'" + txtOK + "','" + txtCancel + "','" + imgOK + "','" + imgCancel + "');");
    getAJAXResponse(url);
}

function switchEditToSettings(classname, back) {
    var trList = document.getElementsByTagName('tr');
    var l = trList.length;
    for (var i = 0; i < l; i++) {
        var tr = trList[i];
        if (!tr.className) continue;

        if (tr.className.indexOf(classname + 'field') != -1) {
            if (back) tr.className = tr.className.replace('hidden', '');
            else tr.className = tr.className + ' hidden';
            continue;
        }
        if (tr.className.indexOf(classname + 'setting') != -1) {
            if (back) tr.className = tr.className + ' hidden';
            else tr.className = tr.className.replace('hidden', '');
        }
    }
}

function switchListToSettings(listID, settingsID, back) {
    var list = $get(listID);
    var settings = $get(settingsID);
    if (!list || !settings) return;

    list.className = back ? list.className.replace('hidden', '') : list.className + ' hidden';
    settings.className = back ? settings.className + ' hidden' : settings.className.replace('hidden', '');
}

// * * * * DTPicker *  * * * //
function clearPicker(strBase, blnTime) {
    document.getElementById(strBase + 'txtDisplayDate').value = '';
    if (blnTime == true) {
        document.getElementById(strBase + 'cboHours').selectedIndex = 0;
        document.getElementById(strBase + 'cboMinutes').selectedIndex = 0;
    }
    closePicker(strBase);
    document.getElementById(strBase + 'txtDisplayDate').focus();
}

function closePicker(strBase) {
    document.getElementById(strBase + 'pnlPicker').style.display = 'none';
}

function getPickerDateSelected(strBase) {
    return document.getElementById(strBase + 'txtDisplayDate').value;
}

function getPickerResponse(strBase, strLanguage, strBaseDate, strSelDate) {

    fAJAXResponse = new Function('showPicker(\'' + strBase + '\',\'' + strLanguage + '\');');

    getAJAXResponse(baseURL + 'ValentNet/Views/Shared/Controls/DateTime/DTPickerCallbacks.aspx?lan=' + strLanguage + '&dtm=' + strBaseDate + '&dtmSel=' + strSelDate);
}

function loadPicker(strBase, strLanguage) {
    var oDivs = document.getElementsByTagName('div');
    var strDate = getPickerDateSelected(strBase);

    // Close any other calendar popups
    for (var n = 0; n < oDivs.length; n++) {
        if (oDivs[n].id != null && oDivs[n].id.indexOf('pnlPicker') > 0 && oDivs[n].id.indexOf(strBase) < 0)
            oDivs[n].style.display = 'none';
    }

    getPickerResponse(strBase, strLanguage, strDate, strDate);
}

function navigatePicker(strBase, strLanguage, strBaseDate) {
    var strDateSelected = getPickerDateSelected(strBase);

    getPickerResponse(strBase, strLanguage, strBaseDate, strDateSelected);
}

function setPickerDate(strBase, strDate) {
    document.getElementById(strBase + 'txtDisplayDate').value = strDate;
    document.getElementById(strBase + 'pnlPicker').style.display = 'none';
    document.getElementById(strBase + 'txtDisplayDate').focus();
}

function showPicker(strBase, strLanguage) {
    //alert(objAJAX.responseText);
    var intCss = 7;
    var intDay = 3;
    var intDisplay = 0;
    var intMainButtons = 5;
    var intMainDates = 0;
    var intMainMonth = 2;
    var intMainWeek = 3;
    var intMainWeekDays = 4;
    var intMainYear = 1;
    var intMonth = 4;
    var intMonthName = 5;
    var intYear = 6;
    var intWeek = 1;
    var intWeekday = 2;
    var n;
    var oButton;
    var oButtons;
    var oDate;
    var oDates;
    var oPicker = document.getElementById(strBase + 'pnlPicker');
    var oWeekDays;
    var strMonth;
    var strResult = '';
    var strWeek;
    var strYear;
    var tbCal = document.getElementById(strBase + 'tbCalendar');
    var td;
    var tr;
    var x = 0;
    var xmlDates = LoadXMLText(objAJAX.responseText);
    var y = 0;

    for (n = tbCal.rows.length - 1; n > 3; n--) {
        tbCal.deleteRow(n);
    }
    //alert(xmlDates.childNodes[0].childNodes.length);
    oButtons = xmlDates.childNodes[0].childNodes[intMainButtons].childNodes;
    oDates = xmlDates.childNodes[0].childNodes[intMainDates].childNodes;
    oWeekDays = xmlDates.childNodes[0].childNodes[intMainWeekDays].childNodes;
    strYear = xmlDates.childNodes[0].childNodes[intMainYear].childNodes[0].nodeValue;
    strMonth = xmlDates.childNodes[0].childNodes[intMainMonth].childNodes[0].nodeValue;
    strWeek = xmlDates.childNodes[0].childNodes[intMainWeek].childNodes[0].nodeValue;

    //Years
    // -1
    td = tbCal.rows[1].cells[0]
    td.onclick = new Function('navigatePicker(\'' + strBase + '\', \'' + strLanguage + '\', \'' + oButtons[0].childNodes[1].childNodes[0].nodeValue + '\');');
    td.title = oButtons[0].childNodes[0].childNodes[0].nodeValue
    // -10
    td = tbCal.rows[1].cells[1]
    td.onclick = new Function('navigatePicker(\'' + strBase + '\', \'' + strLanguage + '\', \'' + oButtons[1].childNodes[1].childNodes[0].nodeValue + '\');');
    td.title = oButtons[1].childNodes[0].childNodes[0].nodeValue
    // current year
    tbCal.rows[1].cells[2].innerHTML = strYear;
    // +1
    td = tbCal.rows[1].cells[3]
    td.onclick = new Function('navigatePicker(\'' + strBase + '\', \'' + strLanguage + '\', \'' + oButtons[3].childNodes[1].childNodes[0].nodeValue + '\');');
    td.title = oButtons[3].childNodes[0].childNodes[0].nodeValue
    // +10
    td = tbCal.rows[1].cells[4]
    td.onclick = new Function('navigatePicker(\'' + strBase + '\', \'' + strLanguage + '\', \'' + oButtons[2].childNodes[1].childNodes[0].nodeValue + '\');');
    td.title = oButtons[2].childNodes[0].childNodes[0].nodeValue

    //Months
    // -1
    td = tbCal.rows[2].cells[0]
    td.onclick = new Function('navigatePicker(\'' + strBase + '\', \'' + strLanguage + '\', \'' + oButtons[4].childNodes[1].childNodes[0].nodeValue + '\');');
    td.title = oButtons[4].childNodes[0].childNodes[0].nodeValue
    // current month
    tbCal.rows[2].cells[1].innerHTML = strMonth;
    // +1
    td = tbCal.rows[2].cells[2]
    td.onclick = new Function('navigatePicker(\'' + strBase + '\', \'' + strLanguage + '\', \'' + oButtons[5].childNodes[1].childNodes[0].nodeValue + '\');');
    td.title = oButtons[5].childNodes[0].childNodes[0].nodeValue

    for (n = 0; n < 7; n++) {
        tbCal.rows[3].cells[n + 1].innerHTML = oWeekDays[n].childNodes[0].nodeValue.substring(0, 1);
        tbCal.rows[3].cells[n + 1].title = oWeekDays[n].childNodes[0].nodeValue;
    }

    for (n = 0; n < oDates.length; n++) {
        oDate = oDates[n];
        if (oDate.childNodes[intWeekday].childNodes[0].nodeValue == '1') {
            tbCal.insertRow(tbCal.rows.length);
            tr = tbCal.rows[tbCal.rows.length - 1];
            tr.insertCell(tr.cells.length);
            td = tr.cells[tr.cells.length - 1];
            td.className = 'DPWeekNr';
            td.innerHTML = oDate.childNodes[intWeek].childNodes[0].nodeValue;
            td.title = strWeek + ' ' + oDate.childNodes[intWeek].childNodes[0].nodeValue;
        }
        tr.insertCell(tr.cells.length);
        td = tr.cells[tr.cells.length - 1];
        td.className = oDate.childNodes[intCss].childNodes[0].nodeValue;
        td.innerHTML = oDate.childNodes[intDay].childNodes[0].nodeValue;
        td.onclick = new Function('setPickerDate(\'' + strBase + '\', \'' + oDate.childNodes[intDisplay].childNodes[0].nodeValue + '\');');
        td.title = oWeekDays[parseInt(oDate.childNodes[intWeekday].childNodes[0].nodeValue) - 1].childNodes[0].nodeValue + ' ' + oDate.childNodes[intDay].childNodes[0].nodeValue + ' ' + oDate.childNodes[intMonthName].childNodes[0].nodeValue + ' ' + oDate.childNodes[intYear].childNodes[0].nodeValue;
    }
    x = Sys.UI.DomElement.getLocation(document.getElementById(strBase + 'txtDisplayDate')).x;
    y = Sys.UI.DomElement.getLocation(document.getElementById(strBase + 'txtDisplayDate')).y;

    Sys.UI.DomElement.setLocation(oPicker, x, y + 20);

    // remove the relative attribute from the parent divs
    oPicker.parentNode.style.position = 'static';
    oPicker.parentNode.parentNode.style.position = 'static';
    oPicker.style.display = 'block';
}

function isValidDate(date) {
    // permits / . - as separators
    // permits 10.11.2010, 10.31.2010, 10.11.1066,
    var regExDate = /((?:0[1-9]|[12][0-9]|3[01])(-|\.|\/)(?:0[1-9]|1[0-2])|(?:0[1-9]|1[0-2])(-|\.|\/)(?:0[1-9]|[12][0-9]|3[01]))(-|\.|\/)(?:0|1|2\d{3})/;
    return regExDate.test(date);
}

function validateDate(dateFieldID) {
    // changes the appearence of the date field by adding/removing the css class validation error, if the date entered is valid/invalid.
    var dateField = $("[id$=" + dateFieldID + "]");
    var date = dateField.attr('value');

    if (date != '' && isValidDate(date) == false) {
        dateField.addClass('fieldValidationError');
    }
    else {
        dateField.removeClass('fieldValidationError');
    }
}

// * * * * Menu Tree * * * * //
var MT_ul = null;
function MT_AppendChilds(id, pid, mt, cmdID) {
    var ID = 0;
    var intTimer;
    var intName = 1;
    var intURL = 2;
    var intChilds = 3;
    var t;
    var tbId;
    var n;
    var xmlItem;
    var xmlMenu = LoadXMLText(objAJAX.responseText);

    var img = document.getElementById(cmdID);
    var li = img.parentNode;
    var ul = document.createElement('ul');
    li.appendChild(ul);
    MT_ul = ul;

    for (n = 0; n < xmlMenu.childNodes[0].childNodes.length; n++) {
        intTimer = (n + 1) * 25;
        //MT_AppendItem(id, mt, tbId, xmlMenu.childNodes[0].childNodes[n].childNodes[ID].childNodes[0].nodeValue, xmlMenu.childNodes[0].childNodes[n].childNodes[intName].childNodes[0].nodeValue, xmlMenu.childNodes[0].childNodes[n].childNodes[intURL].childNodes[0].nodeValue, xmlMenu.childNodes[0].childNodes[n].childNodes[intChilds].childNodes[0].nodeValue);
        xmlItem = xmlMenu.childNodes[0].childNodes[n];
        setTimeout("MT_AppendItem('" + id + "', '" + mt + "', '" + ul.id + "', '" + xmlItem.childNodes[ID].childNodes[0].nodeValue + "', '" + xmlItem.childNodes[intName].childNodes[0].nodeValue + "', '" + xmlItem.childNodes[intURL].childNodes[0].nodeValue + "', '" + xmlItem.childNodes[intChilds].childNodes[0].nodeValue + "')", intTimer);
    }
    img.src = baseURL + 'ValentNet/Content/icons/trvmin.gif';
}

function MT_AppendItem(id, mt, ul, intMenuID, strName, strURL, intHasChilds) {
    var image = '<img src="' + baseURL + 'ValentNet/Content/icons/empty.gif"  height="16" width="16" alt="" />';
    if (intHasChilds != '0')
        image = '<img id="cmd' + intMenuID + '" src="' + baseURL + 'ValentNet/Content/icons/trvplus.gif" height="16" width="16" alt="open" onclick="' +
           'MT_ToggleChilds(\'' + id + '\', \'' + intMenuID + '\', \'' + mt + '\', this);" />';

    var li = document.createElement('li');
    li.id = 'li' + intMenuID;
    li.innerHTML = image + '<a href="' + strURL + '" title="' + strName + '">' + strName + '</a>';
    MT_ul.appendChild(li);
}

function MT_GetChilds(id, pid, mt, cmdID) {
    fAJAXResponse = new Function('MT_AppendChilds(\'' + id + '\', \'' + pid + '\', \'' + mt + '\', \'' + cmdID.id + '\');');

    getAJAXResponse(baseURL + 'ValentNet/Views/Shared/Controls/MenuTree/MenuTreeCallbacks.aspx?ID=' + id + '&pID=' + pid + '&mt=' + mt);
}

function MT_ShowOrHideChilds(liList, cmdID, show) {
    var intTimer;
    var n;
    var src = !show ? 'plus' : 'min';
    show = !show ? 'none' : '';

    for (n = 0; n < liList.length; n++) {
        intTimer = (n + 1) * 25;
        setTimeout("document.getElementById('" + liList[n].id + "').style.display = '" + show + "'", intTimer);
    }
    cmdID.src = baseURL + 'ValentNet/Content/icons/trv' + src + '.gif';
}

function MT_ToggleChilds(id, pid, mt, cmdID) {
    var li = cmdID.parentNode;
    // search for ul
    var ulList = li.getElementsByTagName('ul');
    if (ulList.length > 0) {
        var liList = ulList[0].getElementsByTagName('li');
        MT_ShowOrHideChilds(liList, cmdID, liList[0].style.display == 'none');
    } else {
        MT_GetChilds(id, pid, mt, cmdID);
    }
}

// * * * * Printing * * * * //
function printSpecial(blnAuto) {
    if (document.getElementById != null) {
        var html = '<HTML>\n<HEAD>\n';

        if (document.getElementsByTagName != null) {
            var headTags = document.getElementsByTagName("head");
            if (headTags.length > 0) {
                html += headTags[0].innerHTML;
            }
        }

        html += '\n</HE' + 'AD>\n<BODY>\n';

        var printReadyElem = document.getElementById("printReady");

        if (printReadyElem != null) {
            html += printReadyElem.innerHTML;
        } else {
            alert("Could not find the printReady section in the HTML");
            return;
        }

        html += '\n</BO' + 'DY>\n</HT' + 'ML>';

        var printWin = window.open("", "printSpecial");
        printWin.document.open();
        printWin.document.write(html);
        printWin.document.close();
        if (blnAuto) {
            printWin.print();
        }
    } else {
        alert("Sorry, the print ready feature is only available in modern browsers.");
    }
}

// * * * * Email Validation * * * * //
function CheckEmail(strUrl, strFunction, id) {
    if (id != null && id != '') {
        //alert(o);
        var value = document.getElementById(id).value;
        // alert(value);
        var strImgId = id.replace('txt1', 'imgStatus');
        //alert(strImgId);

        imgStatus = document.getElementById(strImgId);

        if (value == '') {
            imgStatus.src = baseURL + 'ValentNet/Content/icons/cancel.gif';
            return
        }

        var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;

        if (filter.test(value)) {

            // disable the textbox
            document.getElementById(id).disabled = true;

            var strHdnId = id.replace('txt1', 'hdnEmailCheckStatus');
            hdnStatus = document.getElementById(strHdnId);
            hdnStatus.value = '0';

            imgStatus.src = baseURL + 'ValentNet/Content/icons/loading.gif';
            //alert(strUrl);   
            getResponse(strUrl, strFunction, id);
            //alert('called');          

        }
        else {

            imgStatus.src = baseURL + 'ValentNet/Content/icons/cancel.gif';
            return
        }
    }
}

function generatePassword(btnName, passLength) {
    var chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
    var password = '';
    while (password.length < passLength) {
        password += chars.charAt(Math.round(Math.random() * (chars.length)));
    }
    var txtName = btnName.replace(/btnGenerate/, 'txt1');
    var textbox = document.getElementById(txtName);
    textbox.value = password;
}
// * * * * Password Validation * * * * //
function vnValidatePasswordStrength(source, args) {
    var score = 0;
    var result;

    if (args.Value.length > 0) {
        if (args.Value.length < 6) {
            score = score - 1;
        }
        if (!args.Value.match(/[a-z_]/i) || !args.Value.match(/[0-9]/)) {
            score = score - 1;
        }
        //        if(!pass.match(/\W/)){
        //          score = score - 1;
        //        }
        //        switch(score){
        //            case 0:
        //                result = 'Excellent';
        //                break;
        //            case -1:
        //                result = 'Good';
        //                break;
        //            case -2:
        //                result = 'Fair';
        //                break;
        //            default:
        //                result = 'Poor';
        //                break;
        //        }
        if (score == 0) {
            args.IsValid = true;
        } else {
            args.IsValid = false;
        }
    } else {
        args.IsValid = true;
    }
}

// * * * * Validation * * * * //
var Page_Validators_Copy;
function addValidator(id) {
    var n;
    for (n = 0; n < Page_Validators_Copy.length; n++) {
        if (Page_Validators_Copy[n].id.indexOf(id) >= 0) {
            Page_Validators.push(Page_Validators_Copy[n]);
        }
    }
}

function disableFileUpload() {
    //alert('dis');
    var arrInput = document.getElementsByTagName('input');
    var n = 0;
    for (n = 0; n < arrInput.length; n++) {
        //alert(arrInput[n].id);
        if (arrInput[n].type == 'file') {
            arrInput[n].disabled = true;
        }
    }
}

// * * * * XML * * * * //
function LoadXMLText(strText) {
    var xmlDoc;

    if (window.ActiveXObject) {
        // code for IE
        xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = "false";
        xmlDoc.loadXML(strText);
    } else if (document.implementation && document.implementation.createDocument) {
        // code for Mozilla, Firefox, Opera, etc.
        var parser = new DOMParser();
        //xmlDoc.async = false;
        xmlDoc = parser.parseFromString(strText, "text/xml");
    } else {
        alert('Your browser cannot handle this script');
    }

    return (xmlDoc);
}

function FillFormByXML(oXML) {
    var n;
    var oField;
    var oNode;

    if (oXML) {
        if (oXML.firstChild.childNodes.length > 0) {
            for (n = 0; n < oXML.firstChild.childNodes.length; n++) {
                oNode = oXML.firstChild.childNodes[n];
                oField = document.getElementById(oNode.childNodes[0].firstChild.nodeValue);
                if (oField.type.toLowerCase() == 'radio') {
                    if (oNode.childNodes[1].childNodes.length > 0) {
                        if (oNode.childNodes[1].firstChild.nodeValue == '1') {
                            oField.checked = true;
                            document.getElementById(oNode.childNodes[0].firstChild.nodeValue.replace('Yes', 'No')).checked = false;
                        } else {
                            oField.checked = false;
                            document.getElementById(oNode.childNodes[0].firstChild.nodeValue.replace('Yes', 'No')).checked = true;
                        }
                    }
                } else {
                    if (oNode.childNodes[1].childNodes.length > 0) {
                        oField.value = oNode.childNodes[1].firstChild.nodeValue;
                    } else {
                        oField.value = '';
                    }
                }
            }
        }
    }
}

function ClearList(listID) {
    var lb;
    var n;

    lb = document.getElementById(listID);

    for (n = lb.options.length - 1; n > -1; n--) {
        lb.options[n] = null;
    }
}

function FillListByXML(listID, oXML) {
    var lb;
    var li;
    var n;
    var oNode;

    if (oXML) {
        if (oXML.firstChild.childNodes.length > 0) {

            lb = document.getElementById(listID);

            for (n = 0; n < oXML.firstChild.childNodes.length; n++) {
                oNode = oXML.firstChild.childNodes[n];
                li = new Option(oNode.childNodes[1].firstChild.nodeValue, oNode.childNodes[0].firstChild.nodeValue, false, false);
                lb.options[lb.length] = li;
            }
        }
    }
}

function GetWindowHeight() {
    if (nav) {
        return window.innerHeight;
    }
    else {
    }
}
function GetWindowWidth() {
    if (nav) {
        return window.innerWidth;
    } else {
        return document.body.offsetWidth;
    }
}

// * * * * MaxLangth function for textarea * * * * //
function ismaxlength(obj, maxlength) {
    if (!maxlength) {
        maxlength = obj.getAttribute ? parseInt(obj.getAttribute("maxlength")) : ""
    }

    if (obj.getAttribute && obj.value.length > maxlength) {
        obj.value = obj.value.substring(0, maxlength)
    }
}

// Clears a dropdown list //
function clearSelectList(select_id) {
    var select = document.getElementById(select_id);
    select.options.length = 0;
}

// ********************************************************************************************
//    specific functions for Invoice and Contract
// ********************************************************************************************
var url = document.location.href;
var start = url.indexOf("?");
if (start > 0) url = url.substring(0, start);
var rowcount = 1;
function fillInvoiceRow(rowId) {
    var row = document.getElementById(rowId);
    if (!row) return;
    var values = objAJAX.responseText.split('|');
    fillInput(row.cells[2], values[0]);
    fillInput(row.cells[3], values[1]);
    fillInput(row.cells[4], values[2]);
    row.cells[5].innerHTML = parseFloat(values[1]) * parseFloat(values[2]);
    var vatInput = row.cells[6].getElementsByTagName('select');
    if (vatInput.length > 0) {
        for (var i = 0; i < vatInput[0].length; i++) {
            if (vatInput[0].options[i].value = values[4]) {
                vatInput[0].options[i].selected = true;
                break;
            }
        }
    }
    else row.cells[6].innerHTML = values[4] + '%';
    math(row, values[5], values[6], values[7]);
    addInvoiceRow(row);
}
function fillInput(cell, value) {
    var input = cell.getElementsByTagName('input');
    if (input) input[0].value = value;
}
function addInvoiceRow(row) {
    var rows = row.parentNode.rows;
    var last = rows[rowcount];
    if ((last.className == 'show' && last.cells[1].getElementsByTagName('select')[0].value == '')) return;
    rowcount++;
    rows[rowcount].className = 'show';
}
function getProduct(obj) {
    var id = obj.parentNode.parentNode.id;
    fAJAXResponse = new Function("fillInvoiceRow('" + id + "');");
    sendAJAX(url, "productID=" + obj.value + "&rowID=" + id);
}
function math(obj, deciml, group, symbol) {
    var row = obj.tagName == 'TR' ? obj : obj.parentNode.parentNode;
    var count = parseFloat(0 + row.cells[3].getElementsByTagName('input')[0].value.replace(/_/ig, '').replace(',', '.'));
    var price = parseFloat(0 + row.cells[4].getElementsByTagName('input')[0].value.replace(/_/ig, '').replace(',', '.'));
    var total = parseFloat(count * price);
    var vatpercent = '';

    var vatInput = row.cells[6].getElementsByTagName('select');
    if (vatInput.length > 0) vatpercent = vatInput[0].options[vatInput[0].selectedIndex].text.replace(/_/ig, '');
    else vatpercent = row.cells[6].innerHTML.replace('%', '');
    vatpercent = parseFloat(0 + vatpercent.replace(',', '.') / 100);

    row.cells[5].innerHTML = currency(total, deciml, group, symbol);
    row.cells[7].innerHTML = currency(parseFloat(total + (total * vatpercent)), deciml, group, symbol);

    var tdAmount = document.getElementById('tdAmount');
    var tdVat = document.getElementById('tdVat');
    var tdAmountTotal = document.getElementById('tdAmountTotal');
    if (!tdAmount || !tdVat || !tdAmountTotal) return;
    var amount = 0;
    var vat = 0;
    var rows = row.parentNode.rows;
    for (i = 1; i < rows.length - 1; i++) {
        var cell5 = rows[i].cells[5].innerHTML;
        if (cell5 == '0' || cell5 == '') continue;
        var a = currencyToFloat(cell5, deciml, group);
        amount += a;
        vat += (a * vatpercent);
    }
    tdAmount.innerHTML = currency(amount, deciml, group, symbol);
    tdVat.innerHTML = currency(vat, deciml, group, symbol);
    tdAmountTotal.innerHTML = currency(amount + vat, deciml, group, symbol);
}
function currency(value, deciml, group, symbol) {
    value = value.toFixed(2);
    value = value.replace(value.substr(value.length - 3, 1), deciml).replace(/,\./ig, group);
    return symbol + ' ' + value;
}
function currencyToFloat(value, deciml, group) {
    return parseFloat(0 + value.substr(2).replace(group, '').replace(deciml, '.'));
}
function selectInvoices(obj) {
    var check = obj.checked;
    while (obj && obj.tagName && obj.tagName.toLowerCase() != 'table')
        obj = obj.parentNode;
    if (!obj || !obj.tagName || obj.tagName.toLowerCase() != 'table') return;
    var list = obj.getElementsByTagName('input');
    for (var i = 0; i < list.length; i++) {
        if (list[i].type == 'checkbox') list[i].checked = check;
    }
}

// ******** Property Grid functions ****************************************************
function Visible_CheckedChanged(element) {
    elementBaseName = element.name.replace('visible', '');
    visible = document.getElementsByName(elementBaseName + 'visible').item(0);
    editable = document.getElementsByName(elementBaseName + 'editable').item(0);
    required = document.getElementsByName(elementBaseName + 'required').item(0);

    if (visible.checked) {
    }
    else {
        editable.checked = false;
        required.checked = false;
    }
}
function Editable_CheckedChanged(element) {
    elementBaseName = element.name.replace('editable', '');
    visible = document.getElementsByName(elementBaseName + 'visible').item(0);
    editable = document.getElementsByName(elementBaseName + 'editable').item(0);
    required = document.getElementsByName(elementBaseName + 'required').item(0);

    if (editable.checked) {
        visible.checked = true;
    }
    else {
        required.checked = false;
    }

    if (required.disabled) {
        required.checked = editable.checked;
    }
}
function Required_CheckedChanged(element) {
    elementBaseName = element.name.replace('required', '');
    visible = document.getElementsByName(elementBaseName + 'visible').item(0);
    editable = document.getElementsByName(elementBaseName + 'editable').item(0);
    required = document.getElementsByName(elementBaseName + 'required').item(0);

    if (required.checked) {
        visible.checked = true;
        editable.checked = true;
    }
    else {
    }
}

// ******** Stopwatch ***********************************************************
function Stopwatch(useExplicitStart) {
    // useExplicitStart: Use the Start method of the stopwatch to start
    // If not specified, the stopwatch imediately starts running
    var startedAt = useExplicitStart ? null : new Date();
    var stoppedAt = null;

    this.Display = function(showMilliseconds) {
        var totalMs = this.Read();
        var sec = Math.floor((totalMs / 1000) % 60);
        var min = Math.floor(totalMs / 60000);
        var ms = totalMs - (1000 * sec) - (60000 * min);
        if (showMilliseconds) {
            return min + ':' + AddLeadingZeroes(sec, 2) + '.' + AddLeadingZeroes(ms, 3);
        }
        return min + ':' + AddLeadingZeroes(sec, 2);
    }
    this.Read = function() {
        if (startedAt == null) {
            return 0;
        } else {
            if (stoppedAt == null) {
                return new Date().getTime() - startedAt.getTime();
            } else {
                return stoppedAt.getTime() - startedAt.getTime();
            }
        }
    }
    this.Start = function() {
        startedAt = new Date();
    }
    this.Stop = function() {
        stoppedAt = new Date();
    }
}
// ******** NUMBER FUNCTIONS ***********************************************************
function AddLeadingZeroes(number, length) {
    if (number == null || String(number).length >= length) {
        return number;
    }
    var output = String(number);
    for (var n = 0; n < (length - output.length); n++) {
        output = '0' + output;
    }
    return output;
}
function setNumberInTabelCell(selector, number, decimals, strong, euro) {
    var innerHtml = roundNumber(number, decimals);

    if (euro) {
        innerHtml = '&euro;&nbsp;' + innerHtml;
    }
    if (strong) {
        innerHtml = '<strong>' + innerHtml + '</strong>';
    }
    $(selector).html(innerHtml);
}


function toFloat(num) {
    if (num == null) {
        return 0;
    }

    if (!num) {
        num = 0;
    }

    num = num
        .toString()
        .replace('€', '')
        .replace('&euro;', '')
        .replace(String.fromCharCode(8364), '')
        .replace(',', '.')
        .replace(/^\s+|\s+$/g, '');

    return parseFloat(num);
}

function toEuro(num, dec) {
    return '&euro; ' + roundNumber(num, dec);
}

function toCultureNumber(num) {
    return toFloat(num).toString().replace('.', decimalSeparator);
}

function toCultureInvariantNumber(num) {

    if (!num) {
        return 0;
    }
    
    return toFloat(num.toString()
        .replace(decimalSeparator, '|')
        .replace(/\./gi, '')
        .replace(/,/gi, '')
        .replace('|', '.'));
}

function roundNumber(num, dec) {
    if (dec == null) dec = 2;
    var floatNumber = toFloat(num)

    result = 0;
    if (dec == -1) {
        result = floatNumber.toString();
    }
    else {
        result = floatNumber.toFixed(dec);
    }

    var arr = result.split('.');
    return arr.join(',');
}

// ******** VALIDATION FUNCTIONS ***********************************************************

var validationServiceUrl = 'ValentNet/Views/Shared/ValidationHandler.ashx';

// general function to show and hide messages after validation

function handleValidation(isValid, valid, invalid) {
    if (isValid) {
        $(valid).show();
        $(invalid).hide();
    }
    else {
        $(valid).hide();
        $(invalid).show();
    }
}

// should have value

function addShouldHaveValueHtmlValidation(control, valid, invalid) {
    $(control).blur(function() {
        var value = $(control).html();
        var isValid = shouldHaveValue(value);
        handleValidation(isValid, valid, invalid);
    });
    $(valid).hide();
    $(invalid).hide();
}
function addShouldHaveValueValidation(control, valid, invalid) {
    $(control).blur(function() {
        var value = $(control).val();
        var isValid = shouldHaveValue(value);
        handleValidation(isValid, valid, invalid);
    });
    $(valid).hide();
    $(invalid).hide();
}
function shouldHaveValue(value) {
    return value.length > 0;
}

// should equal

function addShouldEqualValidation(control, confirmControl, valid, invalid) {
    $(control).blur(function() {
        var value = $(control).val();
        var valueToEqual = $(confirmControl).val();
        var isValid = shouldEqual(value, valueToEqual);
        handleValidation(isValid, valid, invalid);
    });
    $(valid).hide();
    $(invalid).hide();
}
function shouldEqual(value, valueToEqual) {
    return value == valueToEqual;
}

// should be correct password

function addShouldBeCorrectPassword(passwordControl, loginNameControl, valid, invalid) {
    $(passwordControl).blur(function() {
        var password = $(passwordControl).val();
        var loginName = $(loginNameControl).text();
        var isValid = shouldBeCorrectPassword(password, loginName);
        handleValidation(isValid, valid, invalid);
    });
    $(valid).hide();
    $(invalid).hide();
}
function shouldBeCorrectPassword(password, loginName) {
    var isValid = null;
    jQuery.ajax({
        url: baseURL + validationServiceUrl +
                  '?action=ShouldBeCorrectPassword' +
                  '&password=' + password +
                  '&loginName=' + loginName,
        success: function(result) {
            var json = JSON.parse(result.toString());
            isValid = json.isValid;
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert('status: ' + textStatus + '\n' + 'error: ' + errorThrown + '\n' + XMLHttpRequest.responseText);
        },
        async: false
    });
    return isValid;
}

// should be strong password

function addShouldBeStrongPasswordValidation(passwordControl, length, numericRequired, valid, invalid) {
    $(passwordControl).blur(function() {
        var password = $(passwordControl).val();
        var isValid = shouldBeStrongPassword(password, length, numericRequired);
        handleValidation(isValid, valid, invalid);
    });
    $(valid).hide();
    $(invalid).hide();
}
function shouldBeStrongPassword(password, length, numericRequired) {
    var isValid = null;
    jQuery.ajax({
        url: baseURL + validationServiceUrl +
                  '?action=ShouldBeStrongPassword' +
                  '&password=' + password +
                  '&length=' + length +
                  '&numericRequired=' + numericRequired,
        success: function(result) {
            var json = JSON.parse(result.toString());
            isValid = json.isValid;
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert('status: ' + textStatus + '\n' + 'error: ' + errorThrown + '\n' + XMLHttpRequest.responseText);
        },
        async: false
    });
    return isValid;
}

// should be valid postcode

function addShouldBeValidPostcode(postcodeControl, countryCodeControl, valid, invalid) {
    $(postcodeControl).blur(function() {
        var postcode = $(postcodeControl).val();
        var countryCode = $(countryCodeControl).val();
        var isValid = (postcode.length > 0);
        if (isValid) {
            isValid = shouldBeValidPostcode(postcode, countryCode);
        }
        handleValidation(isValid, valid, invalid);
    });
    $(valid).hide();
    $(invalid).hide();
}
function shouldBeValidPostcode(postcode, countryCode) {
    var isValid = null;
    jQuery.ajax({
        url: baseURL + validationServiceUrl +
                  '?action=ShouldBeValidPostcode' +
                  '&postcode=' + postcode +
                  '&countryCode=' + countryCode,
        success: function(result) {
            var json = JSON.parse(result.toString());
            isValid = json.isValid;
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert('status: ' + textStatus + '\n' + 'error: ' + errorThrown + '\n' + XMLHttpRequest.responseText);
        },
        async: false
    });
    return isValid;
}

// should be correct vat number

function addShouldBeValidVatNumber(vatNumberControl, countryCodeControl, valid, invalid) {
    $(vatNumberControl).blur(function() {
        var vatNumber = $(vatNumberControl).val();
        var countryCode = $(countryCodeControl).val();
        var isValid = shouldBeValidVatNumber(vatNumber, countryCode);
        handleValidation(isValid, valid, invalid);
    });
    $(valid).hide();
    $(invalid).hide();
}
function shouldBeValidVatNumber(vatNumber, countryCode) {
    var isValid = null;
    jQuery.ajax({
        url: baseURL + validationServiceUrl +
                  '?action=ShouldBeValidVatNumber' +
                  '&vatNumber=' + vatNumber +
                  '&countryCode=' + countryCode,
        success: function(result) {
            var json = JSON.parse(result.toString());
            isValid = json.isValid;
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert('status: ' + textStatus + '\n' + 'error: ' + errorThrown + '\n' + XMLHttpRequest.responseText);
        },
        async: false
    });
    return isValid;
}


// ******** CODE FROM IVAN FOR ELEMENT TREE ***********************************************
var elementsHandler;
function GetElementsHandler(action) {
    if (!elementsHandler) {
        elementsHandler = baseURL + "ValentNet/Views/Generic/Elements/AjaxHandler.ashx";
    }
    return elementsHandler + "?action=" + action;
}
$(function() {
    var elements
    if ($("#container_panel").size() > 0) {
        Panel = {};
        Panel.id = menuID;
        Panel.language = languageID;
        $("a.lang[href$=" + languageID.toLowerCase() + "]").prependTo($("a.lang[href$=" + languageID.toLowerCase() + "]").parent());
        Panel.is_copy = false;
        Panel.lang_change = false;

        // TinyMCE setup
        Panel.tinyMCE = new tinymce.Editor('editor-panel', {
            mode: 'exact',
            elements: "editor",
            relative_urls: true,
            plugins: 'table,advimage,advlink,preview,searchreplace,paste',
            theme: 'advanced',
            theme_advanced_toolbar_align: 'left',
            theme_advanced_toolbar_location: 'top',
            content_css: '/css/css_texteditor.css',
            height: "392",
            language: languageID == 'UK' ? 'en' : languageID.toLowerCase(),
            external_link_list_url: baseURL + 'ValentNet/Views/Shared/Controls/TinyMCE/InternalLinks.ashx?ID=' + menuID,
            external_document_list_url: baseURL + 'ValentNet/Views/Shared/Controls/TinyMCE/Documents.ashx?ID=' + menuID,
            external_form_list_url: baseURL + 'ValentNet/Views/Shared/Controls/TinyMCE/Forms.ashx?ID=' + menuID,
            theme_advanced_image_image_browser_callback: 'tinyMCE_ImageBrowser',
            urlconverter_callback: 'tinyMCE_URLConverter',
            theme_advanced_buttons1: 'savebutton,newdocument,cleanup,removeformat,|,undo,redo,|,cut,copy,paste,pastetext,|,bold,italic,underline,strikethrough,|,charmap,|,forecolor,backcolor',
            theme_advanced_buttons2: 'justifyleft,justifycenter,justifyright,justifyfull,|,numlist,bullist,|,indent,outdent,|,table,hr,|,image,|,anchor,link,unlink,|,code,|,preview,search',
            theme_advanced_buttons3: ''
        });
        Panel.tinyMCE.addButton('savebutton', {
            title: jsTreeLabels.save,
            image: baseURL + 'ValentNet/Content/js/jstree/themes/default/save.png',
            onclick: function() {
                if (Panel.jsTree.selected && !Panel.tinyMCE.isHidden()) {
                    Panel.tinyMCE.setProgressState(1);
                    $.ajax({ type: 'POST', async: false, url: GetElementsHandler("SetDescription") + "&ID=" + Panel.id + "&elementID=" + Panel.jsTree.selected.attr("id") + "&language=" + Panel.language,
                        data: { description: Panel.tinyMCE.getContent() },
                        dataType: 'json'
                    });
                    setTimeout(function() { Panel.tinyMCE.setProgressState(0) }, 500);
                }
            }
        });
        Panel.tinyMCE.render_state = 0;

        // jsTree setup
        Panel.jsTree = $.tree_create();
        Panel.jsTree.init($("#tree-panel .tree"), {
            data: { type: "json", async: true, url: GetElementsHandler("GetElements"), async_data: function(NODE) { return { parentID: $(NODE).attr("id") || 0, ID: Panel.id, language: Panel.language} } },
            lang: { new_node: "Nieuw element" },
            ui: { hover_mode: true,
                theme_path: baseURL + "valentnet/content/js/jstree/themes/",
                context: [
				{
				    id: "create_lower", label: jsTreeLabels.create + " " + jsTreeLabels.lower, icon: "create_lower.png",
				    visible: function(NODE, TREE_OBJ) { if (NODE.length != 1) return false; return TREE_OBJ.check("creatable", NODE); },
				    action: function(NODE, TREE_OBJ) { Panel.jsTree.create(false, $(NODE)); }
				},
				{
				    id: "create_after", label: jsTreeLabels.create + " " + jsTreeLabels.after, icon: "create_after.png",
				    visible: function(NODE, TREE_OBJ) { if (NODE.length != 1) return false; return TREE_OBJ.check("creatable", NODE); },
				    action: function(NODE, TREE_OBJ) { Panel.jsTree.create(false, $(NODE), "after"); }
				},
				{
				    id: "create_before", label: jsTreeLabels.create + " " + jsTreeLabels.before, icon: "create_before.png",
				    visible: function(NODE, TREE_OBJ) { if (NODE.length != 1) return false; return TREE_OBJ.check("creatable", NODE); },
				    action: function(NODE, TREE_OBJ) { Panel.jsTree.create(false, $(NODE), "before"); }
				},
				{
				    id: "rename", label: jsTreeLabels.rename, icon: "rename.png",
				    visible: function(NODE, TREE_OBJ) { if (NODE.length != 1) return false; return TREE_OBJ.check("renameable", NODE); },
				    action: function(NODE, TREE_OBJ) { TREE_OBJ.rename(NODE); }
				},
				{
				    id: "change_type", label: jsTreeLabels.change + " " + jsTreeLabels.type, icon: "cubes.png",
				    visible: function(NODE, TREE_OBJ) { return true },
				    action: function(NODE, TREE_OBJ) { Panel.doc('/?server&type=types&id=' + $(NODE).attr('id')); }
				},
				{
				    id: "remove", label: jsTreeLabels.remove, icon: "remove.png",
				    visible: function(NODE, TREE_OBJ) { var ok = true; $.each(NODE, function() { if (TREE_OBJ.check("deletable", this) == false) ok = false; return false; }); return ok; },
				    action: function(NODE, TREE_OBJ) { $.each(NODE, function() { TREE_OBJ.remove(this); }); }
				},
				{
				    id: "copy", label: jsTreeLabels.copy, icon: "copy.png",
				    visible: function(NODE, TREE_OBJ) { return true; },
				    action: function(NODE, TREE_OBJ) { TREE_OBJ.copy($(NODE)); $('.paste-cmenu').removeClass("disabled").find("[rel=paste_disabled]").hide(); }
				},
				{
				    id: "cut", label: jsTreeLabels.cut, icon: "cut.png",
				    visible: function(NODE, TREE_OBJ) { return true; },
				    action: function(NODE, TREE_OBJ) { TREE_OBJ.cut($(NODE)); $('.paste-cmenu').removeClass("disabled").find("[rel=paste_disabled]").hide(); }
				},
				{
				    id: "paste_lower", label: jsTreeLabels.paste + " " + jsTreeLabels.lower, icon: "paste_lower.png",
				    visible: function(NODE, TREE_OBJ) { return true },
				    action: function(NODE, TREE_OBJ) { Panel.jsTree.paste(NODE); $('.paste-cmenu').addClass("disabled").find("[rel=paste_disabled]").show(); }
				},
				{
				    id: "paste_after", label: jsTreeLabels.paste + " " + jsTreeLabels.after, icon: "paste_after.png",
				    visible: function(NODE, TREE_OBJ) { return true },
				    action: function(NODE, TREE_OBJ) { Panel.jsTree.paste(NODE, "after"); $('.paste-cmenu').addClass("disabled").find("[rel=paste_disabled]").show(); }
				},
				{
				    id: "paste_before", label: jsTreeLabels.paste + " " + jsTreeLabels.before, icon: "paste_before.png",
				    visible: function(NODE, TREE_OBJ) { return true },
				    action: function(NODE, TREE_OBJ) { Panel.jsTree.paste(NODE, "before"); $('.paste-cmenu').addClass("disabled").find("[rel=paste_disabled]").show(); }
				},
				{
				    id: "refresh", label: jsTreeLabels.refresh, icon: "refresh.png",
				    visible: function(NODE, TREE_OBJ) { return true },
				    action: function(NODE, TREE_OBJ) { Panel.jsTree.refresh($(NODE)); }
				}
			]
            },
            rules: { draggable: "all" },

            callback: {
                onJSONdata: function(data) {
                    var tmp = [];
                    for (var i in data.Items) {
                        tmp.push({ attributes: { id: data.Items[i].ID }, state: (data.Items[i].HasChildren == true ? "closed" : ""), data: { title: (data.Items[i].Name.length ? data.Items[i].Name : " "), icon: data.Items[i].Icon} });
                    }
                    return tmp;
                },
                beforechange: function(n, t) {
                    if (!Panel.lang_change && Panel.jsTree.selected && !Panel.tinyMCE.isHidden()) {
                        Panel.tinyMCE.setProgressState(1);
                        $.ajax({ type: 'POST', async: false, url: GetElementsHandler("SetDescription") + "&ID=" + Panel.id + "&elementID=" + Panel.jsTree.selected.attr("id") + "&language=" + Panel.language,
                            data: { description: Panel.tinyMCE.getContent() },
                            dataType: 'json'
                        });
                        setTimeout(function() { Panel.tinyMCE.setProgressState(0) }, 500);
                    }
                    return true;
                },
                onchange: function(n) {
                    if (n.id) Panel.loadContent(n.id);
                },

                // THINK OF ROLLBACK!
                oncreate: function(n, r, h, t) {
                    if (!Panel.tinyMCE.isHidden()) Panel.tinyMCE.hide();
                    $("#editor").html("<p class='message'>Please create the node first</p>");
                    Panel.creating = 1;
                    $(n).children("a").addClass($(n).attr("rel"));
                    Panel.move(n, r, h);
                },
                onrename: function(n, l, t, r) {
                    $.getJSON(GetElementsHandler("Rename"), { newName: $(n).children("a:visible").text(), language: Panel.language, elementID: n.id });
                    if (Panel.creating == 1) {
                        Panel.loadContent(n.id);
                        Panel.creating = 0;
                    }
                },
                onmove: function(n, r, h) {
                    Panel.move(n, r, h);
                },
                oncopy: function(n, r, h) {
                    Panel.move(n, r, h, true);
                },
                beforedelete: function(n) {
                    return confirm(labels.areYouSure);
                },
                ondelete: function(n) {
                    $.getJSON(GetElementsHandler("Delete") + "&ID=" + Panel.id + "&elementID=" + n.id + "&language=" + Panel.language);
                    if (!Panel.tinyMCE.isHidden()) Panel.tinyMCE.hide();
                    $("#editor").html("<p class='message'>Click a node on the left to edit its content</p>");
                },
                onload: function(t) {
                    if (Panel.lang_change) { Panel.lang_change = false; }
                    else if (Panel.is_copy) { Panel.is_copy = false; }
                    else { t.select_branch(t.container.find("li:eq(0)")); }
                    switch (Panel.language) {
                        case "NL": t.settings.lang.new_node = "Nieuw element"; break;
                        case "UK": t.settings.lang.new_node = "New element"; break;
                        case "DE": t.settings.lang.new_node = "Neues element"; break;
                        case "FR": t.settings.lang.new_node = "Nouvel élément"; break;
                        default: t.settings.lang.new_node = "New element"; break;
                    }
                },
                onerror: function(str) { alert(str); }
            }
        });
        Panel.creating = 0;

        // Functions
        Panel.loadContent = function(id) {
            if (Panel.tinyMCE.render_state == 0) {
                Panel.tinyMCE.onInit.add(function(ed) {
                    ed.setContent("");
                    ed.render_state = 1;
                    Panel.loadContent(id);
                });
                Panel.tinyMCE.render();
            }
            else {
                if (Panel.tinyMCE.isHidden()) Panel.tinyMCE.show();
                //Panel.tinyMCE.setProgressState(1);
                $.ajax({ type: 'POST', async: false, url: GetElementsHandler("GetDescription") + "&ID=" + Panel.id + "&elementID=" + id + "&language=" + Panel.language,
                    dataType: 'json',
                    success: function(data) {
                        if (data.Description.length) Panel.tinyMCE.setContent(data.Description);
                        else Panel.tinyMCE.setContent("");
                        //setTimeout(function() { Panel.tinyMCE.setProgressState(0) }, 500);
                    }
                });
            }
        }
        Panel.move = function(n, r, h, is_copy) {
            var position = "";
            if (!n.id || n.id == "") {
                if (h == "inside") position = "Lower";
                if (h == "before") position = "Before";
                if (h == "after") position = "After";
                $.getJSON(GetElementsHandler("Create") + "&ID=" + Panel.id + "&referenceElementID=" + r.id + "&position=" + position + "&language=" + Panel.language, function(data) {
                    n.id = data.ID;
                    $(n).children("a, span").css("background-image", "url(" + data.Icon + ")");
                });
            }
            else {
                if (h == "inside") position = "Lower";
                if (h == "before") position = "Before";
                if (h == "after") position = "After";
                if (is_copy && Panel.jsTree.selected && !Panel.tinyMCE.isHidden()) {
                    Panel.tinyMCE.setProgressState(1);
                    $.ajax({ type: 'POST', async: false, url: GetElementsHandler("SetDescription") + "&ID=" + Panel.id + "&elementID=" + Panel.jsTree.selected.attr("id") + "&language=" + Panel.language,
                        data: { description: Panel.tinyMCE.getContent() },
                        dataType: 'json'
                    });
                    setTimeout(function() { Panel.tinyMCE.setProgressState(0) }, 500);
                }
                $.getJSON(GetElementsHandler("Move") + "&elementID=" + n.id.toString().replace(/_copy/ig, "") + "&ID=" + Panel.id + "&referenceElementID=" + r.id + "&position=" + position + "&language=" + Panel.language + "&copy=" + (is_copy ? "true" : "false"), function(data) {
                    if (is_copy) {
                        n.id = data.ID;
                        $(n).children("a, span").css("background-image", "url(" + data.Icon + ")");
                        Panel.is_copy = true;
                        Panel.jsTree.refresh(n);
                    }
                });
            }
        }
        Panel.create_lower = function() { Panel.jsTree.create(false, (Panel.jsTree.container.find("li").size() == 0 ? -1 : false)); }
        Panel.create_after = function() { Panel.jsTree.create(false, false, "after"); }
        Panel.create_before = function() { Panel.jsTree.create(false, false, "before"); }
        Panel.rename = function() { Panel.jsTree.rename(); }
        Panel.change_type = function() { if (Panel.jsTree.selected) Panel.doc('/?server&type=types&id=' + Panel.jsTree.selected.attr('id')); }
        Panel.remove = function() { Panel.jsTree.remove(); }
        Panel.copy = function() { if (Panel.jsTree.selected) { Panel.jsTree.copy(); $('.paste-cmenu').removeClass("disabled").find("[rel=paste_disabled]").hide(); } }
        Panel.cut = function() { if (Panel.jsTree.selected) { Panel.jsTree.cut(); $('.paste-cmenu').removeClass("disabled").find("[rel=paste_disabled]").hide(); } }
        Panel.paste_lower = function() { Panel.jsTree.paste(); $('.paste-cmenu').addClass("disabled").find("[rel=paste_disabled]").show(); }
        Panel.paste_after = function() { Panel.jsTree.paste(false, "after"); $('.paste-cmenu').addClass("disabled").find("[rel=paste_disabled]").show(); }
        Panel.paste_before = function() { Panel.jsTree.paste(false, "before"); $('.paste-cmenu').addClass("disabled").find("[rel=paste_disabled]").show(); }
        Panel.paste_disabled = function() { alert("Cut or copy nodes first!"); }
        Panel.type_save = function(id, tp, icon) {
            $.getJSON(GetElementsHandler("SetElementType") + "&ID=" + Panel.id + "&elementID=" + id + "&language=" + Panel.language + "&elementTypeID=" + tp, function(data) {
                $("#" + id).children("a:visible").attr("rel", tp).css("background-image", "url(" + data.Icon + ")");
                Panel.blend(false);
            });
        }

        // Lightbox functions
        Panel.blend = function(on) {
            if (on) {
                var b = $("<div id='blend'>&nbsp;</div>");
                $("html, body").css("overflow", "hidden");
                b.height($(document).height()).width($(document).width()).css("opacity", "0.5");
                $("body").append(b);
            }
            else {
                $("#blend, #document").remove();
                $("html, body").css("overflow", "auto");
            }
        }
        Panel.doc = function(url) {
            Panel.blend(true);
            $("body").append("<div id='document'>&nbsp;</div>");
            var c = $.tree_focused().selected.children("a:visible").attr("rel");
            var t = $.tree_focused().selected.children("a:visible").css("background-image").replace(/^url\(/i, "").replace(/\)$/i, "");
            $.getJSON(GetElementsHandler("GetElementTypes") + "&Language=" + Panel.language + "&ID=" + Panel.id, function(data) {
                var str = "";
                for (i in data.ItemTypes) {
                    str += "<a href='#' ondblclick='Panel.type_save($.tree_focused().selected.attr(\"id\")," + data.ItemTypes[i].ID + ",\"" + data.ItemTypes[i].Icon + "\"); return false' class='a_type " + ((data.ItemTypes[i].ID == c || t.indexOf(data.ItemTypes[i].Icon) != -1) ? "selected" : "") + "' onclick='$(this).parent().children().removeClass(\"selected\"); $(this).addClass(\"selected\"); return false;' rel='" + data.ItemTypes[i].ID + "' style='background-image:url(\"" + data.ItemTypes[i].Icon + "\");'>" + data.ItemTypes[i].Name + "</a>";
                }
                str += "<div style='clear:both; height:1px;'>&nbsp;</div>";
                str += "<input type='button' onclick='Panel.type_save($.tree_focused().selected.attr(\"id\"),$(\"#document a.selected\").attr(\"rel\"),$(\"#document a.selected\").css(\"backgroundImage\"));' value='" + jsTreeLabels.save + "' class='save' />";
                str += "<input type='button' value='" + jsTreeLabels.cancel + "' onclick='Panel.blend(false);' class='cancel' />";
                $("#document").html(str).css("background", "white");
            });
            return false;
        }

        // Keyboard shortcuts
        $(document)
		    .bind('keydown', { combi: 'up', disableInInput: true }, function() { Panel.jsTree.get_prev(); return false; })
		    .bind('keydown', { combi: 'down', disableInInput: true }, function() { Panel.jsTree.get_next(); return false; })
		    .bind('keydown', { combi: 'left', disableInInput: true }, function() { Panel.jsTree.get_left(); return false; })
		    .bind('keydown', { combi: 'right', disableInInput: true }, function() { Panel.jsTree.get_right(); return false; })
		    .bind('keydown', { combi: 'return', disableInInput: true }, function() { if (Panel.jsTree.hovered) Panel.jsTree.select_branch(Panel.jsTree.hovered); return false; })
		    .bind('keydown', { combi: 'f2', disableInInput: true }, function() { Panel.jsTree.rename(); return false; })
		    .bind('keydown', { combi: 'del', disableInInput: true }, function() { if (Panel.jsTree.selected) Panel.jsTree.remove(); return false; })
		    .bind('keydown', { combi: 'Ctrl+l', disableInInput: true }, function() { if (Panel.jsTree.selected) Panel.jsTree.create(); return false; })
		    .bind('keydown', { combi: 'Ctrl+b', disableInInput: true }, function() { if (Panel.jsTree.selected) Panel.jsTree.create(false, false, "before"); return false; })
		    .bind('keydown', { combi: 'insert', disableInInput: true }, function() { if (Panel.jsTree.selected) Panel.jsTree.create(false, false, "after"); return false; })
		    .bind('keydown', { combi: 'f5', disableInInput: true }, function() { Panel.jsTree.refresh(); return false; })
		    .bind('keydown', { combi: 'f4', disableInInput: true }, function() { if (Panel.jsTree.selected) doc('/?server&type=types&id=' + Panel.jsTree.selected.attr('id')); return false; })
		    .bind('keydown', { combi: 'ctrl+v', disableInInput: true }, function() { Panel.jsTree.paste(false, "after"); return false; })
		    .bind('keydown', { combi: 'ctrl+c', disableInInput: true }, function() { Panel.jsTree.copy(); return false; })
            .bind('keydown', { combi: 'ctrl+x', disableInInput: true }, function() { Panel.jsTree.cut(); return false; })

        // Interface hooks
        $("#tree-panel .menu")
		.find("a").not(".lang")
			.bind("click", function(event) {
			    try { Panel[$(this).attr("rel")](); } catch (err) { }
			    $(this).parents(".cmenu").removeClass("hover");
			    this.blur();
			    event.preventDefault();
			    event.stopPropagation();
			    return false;
			})
			.end().end()
		.children(".cmenu")
			.hover(function() { if (!$(this).hasClass("disabled")) $(this).addClass("hover"); }, function() { $(this).removeClass("hover") })
        $("#tree-panel .menu a.lang")
				.live("click", function(event) {
				    $("#easyTooltip").remove();
				    if (Panel.jsTree.selected && !Panel.tinyMCE.isHidden()) {
				        Panel.tinyMCE.setProgressState(1);
				        $.ajax({ type: 'POST', async: false, url: GetElementsHandler("SetDescription") + "&ID=" + Panel.id + "&elementID=" + Panel.jsTree.selected.attr("id") + "&language=" + Panel.language,
				            data: { description: Panel.tinyMCE.getContent() },
				            dataType: 'json'
				        });
				        setTimeout(function() { Panel.tinyMCE.setProgressState(0) }, 500);
				    }
				    var newLanguage = $(this).attr("href").replace(/.*?#/ig, "").toUpperCase();
				    if (newLanguage != Panel.language) {
				        Panel.language = newLanguage;
				        Panel.lang_change = true;
				        Panel.jsTree.refresh();
				        $(this).clone().prependTo($(this).parent());
				        $(this).parent().removeClass("hover")
				        $(this).remove();
				    }
				    event.preventDefault();
				    event.stopPropagation();
				    return false;
				});
    }

});


function replaceNewLine(text, replacement) {
    return text.replace(/\n/g, replacement);
}

function pausecomp(millis) {
    var date = new Date();
    var curDate = null;

    do { curDate = new Date(); }
    while (curDate - date < millis);
}


var vnGridView = {
    confirmDeleteMessages: {},

    deleteItem: function (objectTypeName, objectID, deleteToRecycleBin, objectName, postData) {
        if (!this.confirmDeleteMessages[objectTypeName]) {
            this.confirmDeleteMessages[objectTypeName] = labels.confirmDeleteItem;
        }

        if (confirm(this.confirmDeleteMessages[objectTypeName].replace('{0}', objectName)) == false) {
            return;
        }

        if (!postData) postData = {};
        postData.action = 'Delete';
        postData.objectTypeName = "Octavalent.ValentNet.Models.DomainObjects." + objectTypeName + ", Octavalent.ValentNet.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
        postData.objectID = objectID;
        postData.deleteToRecycleBin = deleteToRecycleBin;
        postData.objectName = objectName;
        postData.pageUrl = document.location.href;

        $.getJSON(baseURL + "ValentNet/Views/Shared/Handlers/DeleteHandler.ashx", postData);

        // Check if actions exist for the object type.
        if (eval("typeof " + objectTypeName + "Actions != 'undefined'")) {
            eval(objectTypeName + "Actions").raiseDeleteEvent(objectTypeName, objectName);
        }

        var row = $("tr[id$='_" + objectID + "']");

        row.find('td').fadeOut(1250, function () {
            var table = row.parent();
            row.remove();

            // zebra rows
            var rows = table.children();
            for (var i = 0; i < rows.length; i++) {
                var rowId = rows[i].id;
                if (!rowId) continue;

                if (i % 2) {
                    $(rows[i]).removeClass("rowOdd");
                    $(rows[i]).addClass("rowEven");
                    $(rows[i]).mouseout(function () { this.className = 'rowEven'; });
                } else {
                    $(rows[i]).removeClass("rowEven");
                    $(rows[i]).addClass("rowOdd");
                    $(rows[i]).mouseout(function () { this.className = 'rowOdd'; });
                }
            }
        });
    },

    search: function (searchBoxId, searchInputId, url) {
        // get search tags.
        var searchTags = encodeURIComponent($.trim($("input[id$='" + searchInputId + "']").val()));

        // add search tags to the query string.
        if (searchTags.length > 0) {
            url += -1 == url.indexOf('?') ? '?' : '&';
            url += "search=" + searchTags;

            var type = encodeURIComponent($.trim($("[id$='" + searchBoxId + "'] input[type='radio']:checked").val()));
            if (type.length > 0) {
                url += "&type=" + type;
            }
        }

        // set the location
        location.href = url;
    },

    autoComplete: function (searchInputId, disable) {
        if (disable) {
            //$("#" + searchInputId).setOptions({ url: '' });
            //alert($("#" + searchInputId).length);
            $("input[id$='" + searchInputId + "']").unautocomplete();
        } else {
            var url = baseURL + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?ID=' + menuID + '&action=Get&name=UntypedTags&pageUrl=' + document.location.href;
            $("input[id$='" + searchInputId + "']").autocomplete(url, {
                formatItem: function (item) {
                    return item[0].split(';')[0] + ' (' + item[0].split(';')[1] + ')';
                },
                formatResult: function (item) {
                    return item[0].split(';')[0];
                },
                multiple: true,
                multipleSeparator: ' '
            });
        }
    }
};

var DocumentActions = {
    
    // Raise a delete event using the handler.
    raiseDeleteEvent: function(objectTypeName, objectName) {
        $.getJSON(baseURL + "ValentNet/Views/Shared/Handlers/RaiseEventHandler.ashx", {
            "action": "Deleted",
            "objectTypeName": objectTypeName,
            "objectName": objectName
        });
    }
};

function sleep(ms) {
    var dt = new Date();
    dt.setTime(dt.getTime() + ms);
    while (new Date().getTime() < dt.getTime());
}


/*
    http://www.JSON.org/json2.js
    2008-06-08

    Public Domain.

    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.

    See http://www.JSON.org/js.html

    This file creates a global JSON object containing two methods: stringify
    and parse.


        JSON.stringify(value, replacer, space)
            value       any JavaScript value, usually an object or array.

            replacer    an optional parameter that determines how object
                        values are stringified for objects without a toJSON
                        method. It can be a function or an array.

            space       an optional parameter that specifies the indentation
                        of nested structures. If it is omitted, the text will
                        be packed without extra whitespace. If it is a number,
                        it will specify the number of spaces to indent at each
                        level. If it is a string (such as '\t' or '&nbsp;'),
                        it contains the characters used to indent at each level.

            This method produces a JSON text from a JavaScript value.

            When an object value is found, if the object contains a toJSON
            method, its toJSON method will be called and the result will be
            stringified. A toJSON method does not serialize: it returns the
            value represented by the name/value pair that should be serialized,
            or undefined if nothing should be serialized. The toJSON method
            will be passed the key associated with the value, and this will be
            bound to the object holding the key.

            For example, this would serialize Dates as ISO strings.

                Date.prototype.toJSON = function (key) {
                    function f(n) {
                        // Format integers to have at least two digits.
                        return n < 10 ? '0' + n : n;
                    }

                    return this.getUTCFullYear()   + '-' +
                         f(this.getUTCMonth() + 1) + '-' +
                         f(this.getUTCDate())      + 'T' +
                         f(this.getUTCHours())     + ':' +
                         f(this.getUTCMinutes())   + ':' +
                         f(this.getUTCSeconds())   + 'Z';
                };

            You can provide an optional replacer method. It will be passed the
            key and value of each member, with this bound to the containing
            object. The value that is returned from your method will be
            serialized. If your method returns undefined, then the member will
            be excluded from the serialization.

            If the replacer parameter is an array, then it will be used to
            select the members to be serialized. It filters the results such
            that only members with keys listed in the replacer array are
            stringified.

            Values that do not have JSON representaions, such as undefined or
            functions, will not be serialized. Such values in objects will be
            dropped; in arrays they will be replaced with null. You can use
            a replacer function to replace those with JSON values.
            JSON.stringify(undefined) returns undefined.

            The optional space parameter produces a stringification of the
            value that is filled with line breaks and indentation to make it
            easier to read.

            If the space parameter is a non-empty string, then that string will
            be used for indentation. If the space parameter is a number, then
            then indentation will be that many spaces.

            Example:

            text = JSON.stringify(['e', {pluribus: 'unum'}]);
            // text is '["e",{"pluribus":"unum"}]'


            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'

            text = JSON.stringify([new Date()], function (key, value) {
                return this[key] instanceof Date ?
                    'Date(' + this[key] + ')' : value;
            });
            // text is '["Date(---current time---)"]'


        JSON.parse(text, reviver)
            This method parses a JSON text to produce an object or array.
            It can throw a SyntaxError exception.

            The optional reviver parameter is a function that can filter and
            transform the results. It receives each of the keys and values,
            and its return value is used instead of the original value.
            If it returns what it received, then the structure is not modified.
            If it returns undefined then the member is deleted.

            Example:

            // Parse the text. Values that look like ISO date strings will
            // be converted to Date objects.

            myData = JSON.parse(text, function (key, value) {
                var a;
                if (typeof value === 'string') {
                    a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
                    if (a) {
                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
                            +a[5], +a[6]));
                    }
                }
                return value;
            });

            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
                var d;
                if (typeof value === 'string' &&
                        value.slice(0, 5) === 'Date(' &&
                        value.slice(-1) === ')') {
                    d = new Date(value.slice(5, -1));
                    if (d) {
                        return d;
                    }
                }
                return value;
            });


    This is a reference implementation. You are free to copy, modify, or
    redistribute.

    This code should be minified before deployment.
    See http://javascript.crockford.com/jsmin.html

    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD THIRD PARTY
    CODE INTO YOUR PAGES.
*/

/*jslint evil: true */

/*global JSON */

/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", call,
    charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, getUTCMinutes,
    getUTCMonth, getUTCSeconds, hasOwnProperty, join, lastIndex, length,
    parse, propertyIsEnumerable, prototype, push, replace, slice, stringify,
    test, toJSON, toString
*/

if (!this.JSON) {

// Create a JSON object only if one does not already exist. We create the
// object in a closure to avoid global variables.

    JSON = function () {

        function f(n) {
            // Format integers to have at least two digits.
            return n < 10 ? '0' + n : n;
        }

        Date.prototype.toJSON = function (key) {

            return this.getUTCFullYear()   + '-' +
                 f(this.getUTCMonth() + 1) + '-' +
                 f(this.getUTCDate())      + 'T' +
                 f(this.getUTCHours())     + ':' +
                 f(this.getUTCMinutes())   + ':' +
                 f(this.getUTCSeconds())   + 'Z';
        };

        var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
            escapeable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
            gap,
            indent,
            meta = {    // table of character substitutions
                '\b': '\\b',
                '\t': '\\t',
                '\n': '\\n',
                '\f': '\\f',
                '\r': '\\r',
                '"' : '\\"',
                '\\': '\\\\'
            },
            rep;


        function quote(string) {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.

            escapeable.lastIndex = 0;
            return escapeable.test(string) ?
                '"' + string.replace(escapeable, function (a) {
                    var c = meta[a];
                    if (typeof c === 'string') {
                        return c;
                    }
                    return '\\u' + ('0000' +
                            (+(a.charCodeAt(0))).toString(16)).slice(-4);
                }) + '"' :
                '"' + string + '"';
        }


        function str(key, holder) {

// Produce a string from holder[key].

            var i,          // The loop counter.
                k,          // The member key.
                v,          // The member value.
                length,
                mind = gap,
                partial,
                value = holder[key];

// If the value has a toJSON method, call it to obtain a replacement value.

            if (value && typeof value === 'object' &&
                    typeof value.toJSON === 'function') {
                value = value.toJSON(key);
            }

// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.

            if (typeof rep === 'function') {
                value = rep.call(holder, key, value);
            }

// What happens next depends on the value's type.

            switch (typeof value) {
            case 'string':
                return quote(value);

            case 'number':

// JSON numbers must be finite. Encode non-finite numbers as null.

                return isFinite(value) ? String(value) : 'null';

            case 'boolean':
            case 'null':

// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.

                return String(value);

// If the type is 'object', we might be dealing with an object or an array or
// null.

            case 'object':

// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.

                if (!value) {
                    return 'null';
                }

// Make an array to hold the partial results of stringifying this object value.

                gap += indent;
                partial = [];

// If the object has a dontEnum length property, we'll treat it as an array.

                if (typeof value.length === 'number' &&
                        !(value.propertyIsEnumerable('length'))) {

// The object is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.

                    length = value.length;
                    for (i = 0; i < length; i += 1) {
                        partial[i] = str(i, value) || 'null';
                    }

// Join all of the elements together, separated with commas, and wrap them in
// brackets.

                    v = partial.length === 0 ? '[]' :
                        gap ? '[\n' + gap +
                                partial.join(',\n' + gap) + '\n' +
                                    mind + ']' :
                              '[' + partial.join(',') + ']';
                    gap = mind;
                    return v;
                }

// If the replacer is an array, use it to select the members to be stringified.

                if (rep && typeof rep === 'object') {
                    length = rep.length;
                    for (i = 0; i < length; i += 1) {
                        k = rep[i];
                        if (typeof k === 'string') {
                            v = str(k, value, rep);
                            if (v) {
                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
                            }
                        }
                    }
                } else {

// Otherwise, iterate through all of the keys in the object.

                    for (k in value) {
                        if (Object.hasOwnProperty.call(value, k)) {
                            v = str(k, value, rep);
                            if (v) {
                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
                            }
                        }
                    }
                }

// Join all of the member texts together, separated with commas,
// and wrap them in braces.

                v = partial.length === 0 ? '{}' :
                    gap ? '{\n' + gap +
                            partial.join(',\n' + gap) + '\n' +
                            mind + '}' :
                          '{' + partial.join(',') + '}';
                gap = mind;
                return v;
            }
        }


// Return the JSON object containing the stringify, parse, and quote methods.

        return {
            stringify: function (value, replacer, space) {

// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.

                var i;
                gap = '';
                indent = '';
                if (space) {

// If the space parameter is a number, make an indent string containing that
// many spaces.

                    if (typeof space === 'number') {
                        for (i = 0; i < space; i += 1) {
                            indent += ' ';
                        }

// If the space parameter is a string, it will be used as the indent string.

                    } else if (typeof space === 'string') {
                        indent = space;
                    }
                }

// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.

                rep = replacer;
                if (replacer && typeof replacer !== 'function' &&
                        (typeof replacer !== 'object' ||
                         typeof replacer.length !== 'number')) {
                    throw new Error('JSON.stringify');
                }

// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.

                return str('', {'': value});
            },


            parse: function (text, reviver) {

// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.

                var j;

                function walk(holder, key) {

// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.

                    var k, v, value = holder[key];
                    if (value && typeof value === 'object') {
                        for (k in value) {
                            if (Object.hasOwnProperty.call(value, k)) {
                                v = walk(value, k);
                                if (v !== undefined) {
                                    value[k] = v;
                                } else {
                                    delete value[k];
                                }
                            }
                        }
                    }
                    return reviver.call(holder, key, value);
                }


// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.

                cx.lastIndex = 0;
                if (cx.test(text)) {
                    text = text.replace(cx, function (a) {
                        return '\\u' + ('0000' +
                                (+(a.charCodeAt(0))).toString(16)).slice(-4);
                    });
                }

// In the second stage, we run the text against
// regular expressions that look for non-JSON patterns. We are especially
// concerned with '()' and 'new' because they can cause invocation, and '='
// because it can cause mutation. But just to be safe, we want to reject all
// unexpected forms.

// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace all backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

                if (/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/bfnrtu]/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

                    j = eval('(' + text + ')');

// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.

                    return typeof reviver === 'function' ?
                        walk({'': j}, '') : j;
                }

// If the text is not JSON parseable, then a SyntaxError is thrown.

                throw new SyntaxError('JSON.parse');
            }
        };
    }();
}


var is_ie = (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent));
var is_ie5 = (is_ie && /msie 5\.0/i.test(navigator.userAgent) );
var is_opera = /opera/i.test(navigator.userAgent);
var is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);
// ===================================================================
// Author: Denis Howlett <feedback@isocra.com>
// WWW: http://www.isocra.com/
//
// NOTICE: You may use this code for any purpose, commercial or
// private, without any further permission from the author. You may
// remove this notice from your final code if you wish, however we
// would appreciate it if at least the web site address is kept.
//
// You may *NOT* re-distribute this code in any way except through its
// use. That means, you can include it in your product, or your web
// site, or any other form where the code is actually being used. You
// may not put the plain javascript up on your site for download or
// include it in your javascript libraries for download.
// If you wish to share this code with others, please just point them
// to the URL instead.
//
// Please DO NOT link directly to this .js files from your site. Copy
// the files to your server and use them there. Thank you.
// ===================================================================

/** Keep hold of the current table being dragged */
var currenttable = null;
var draggedFinish = true;
var draggedRows = null;
var draggedTable = null;
/** Capture the onmousemove so that we can see if a row from the current
 *  table if any is being dragged.
 * @param ev the event (for Firefox and Safari, otherwise we use window.event for IE)
 */

function dragFinish(category) {
    draggedFinish = true;
    var allrows = draggedTable.tBodies[0].rows;
    var rows = Array();
    var odd = true;
    for (var i=0; i<allrows.length; i++) {
        if(allrows[i].className == "header") continue;
        if(allrows[i].style.display != 'none') { 
            var c = odd ? "rowOdd" : "rowOdd";
            odd = !odd;
            allrows[i].className = allrows[i].className.replace("rowOdd",c).replace("rowOdd",c);
            allrows[i].onmouseout = new Function("this.className = '" + c + "'");
        }
        if(getParam(allrows[i], "category") == category) rows.push(allrows[i]);
    }

    var xmlMenu = LoadXMLText(objAJAX.responseText);
    var root = xmlMenu.childNodes[0]; 
    
    for(var i=0; i<root.childNodes.length; i++) {
        var item = root.childNodes[i];
        setParam(rows[i], "id", item.getAttribute("id"));
        setParam(rows[i], "index", item.getAttribute("index"));
    }
    draggedTable = null;
}

function dragTR(ev){
    var target = getEventSource(ev);
    if ((target.tagName == "INPUT" && target.type == "TEXT") || target.tagName == "SELECT")
        target.style.cursor = "default";
    else if(target.tagName == 'IMG' || target.tagName == 'INPUT')
        target.style.cursor = "hand";

    if (currenttable && currenttable.dragObject) {
        if(is_ie) document.selection.empty();
        draggedFinish = false;
        var dragRow = currenttable.dragObject;
        if(draggedRows == null && getParam(dragRow, "open") != "none") {
            draggedRows = Array();
            var id = getParam(dragRow, "id");
            var rows = currenttable.table.tBodies[0].rows; //getElementsByTagName("tr")
            var count = rows.length;
            for (var i=0; i<count; i++) {
                if(getParam(rows[i], "category") != id) continue;
                draggedRows.push(rows[i]);
                rows[i].style.display = 'none';
            }
            dragRow.cells[0].innerHTML = dragRow.cells[0].innerHTML.replace('trvmin','trvplus');
        }
        ev   = ev || window.event;
        var mousePos = currenttable.mouseCoords(ev);
        var y = mousePos.y - currenttable.mouseOffset.y;
        if (y != currenttable.oldY) {
            // work out if we're going up or down...
            var movingDown = y > currenttable.oldY;
            // update the old value
            currenttable.oldY = y;
            // update the style to show we're dragging
            currenttable.dragObject.style.backgroundColor = "#eee";
            // If we're over a row then move the dragged row to there so that the user sees the
            // effect dynamically
            var currentRow = currenttable.findDropTargetRow(y);
            if (currentRow) {
                if (movingDown && currenttable.dragObject != currentRow) 
                {
                    currenttable.dragObject.parentNode.insertBefore(currenttable.dragObject, currentRow.nextSibling);
                } 
                else if (! movingDown && currenttable.dragObject != currentRow) 
                {
                    currenttable.dragObject.parentNode.insertBefore(currenttable.dragObject, currentRow);
                }
            }
        }

        return false;
    }
}
document.onmousemove = dragTR;

    // Similarly for the mouseup
    document.onmouseup = function(ev)
    {
        if (currenttable && currenttable.dragObject) 
        {
            var droppedRow = currenttable.dragObject;
            // If we have a dragObject, then we need to release it,
            // The row will already have been moved to the right place so we just reset stuff
            droppedRow.style.backgroundColor = 'transparent';
            currenttable.dragObject   = null;
            // And then call the onDrop method in case anyone wants to do any post processing
            currenttable.onDrop(currenttable.table, droppedRow, currenttable.url, currenttable.queryId);
            currenttable = null; // let go of the table too
        } 
        else 
        {
            draggedFinish = true;
        }
    }


/** get the source element from an event in a way that works for IE and Firefox and Safari
 * @param evt the source event for Firefox (but not IE--IE uses window.event) */
function getEventSource(evt) {
    if (window.event) {
        evt = window.event; // For IE
        return evt.srcElement;
    } else {
        return evt.target; // For Firefox
    }
}

/**
 * Encapsulate table Drag and Drop in a class. We'll have this as a Singleton
 * so we don't get scoping problems.
 */
 getParam = function(row, parameter) {
    var drag = row.getAttribute("drag");
    if(drag == null) return null;
    var pos = drag.indexOf(parameter + '=');
    if(pos == -1 || pos == drag.length) return null;
    pos += parameter.length + 1;
    var end = drag.indexOf('|', pos);
    if(end == -1) end = drag.length;
    return drag.substring(pos, end);
}
setParam = function(row, parameter, value) {
    var drag = row.getAttribute("drag");
    if(drag == null) return null;
    var param = getParam(row, parameter);
    drag = drag.replace(parameter + '=' + param, parameter + '=' + value);
    row.setAttribute("drag", drag);
}

var treeRows = null;
function ajaxTree(category, index) {
    var odd = true;
    var img = 'trvplus';
    var open = 'false';
    var display = 'none';
    var ids = Array();
    var categories = Array();
    var previous = null;
    for(var i=0; i<treeRows.length; i++) {
        if(treeRows[i].className == "header") continue;
        if(getParam(treeRows[i], "id") == category) {
            if(getParam(treeRows[i], "open") == "false") {
                img = 'trvmin';
                open = 'true';
                display = is_ie ? 'block' : 'table-row';
            }
            ids.push(category);
            setParam(treeRows[i], "open", open);
            categories[category] = treeRows[i];
            treeRows[i].cells[0].innerHTML = treeRows[i].cells[0].innerHTML.replace("trvmin", img).replace("trvplus", img);
        }
        var current = getParam(treeRows[i], "category");
        for(var index=0; index<ids.length; index++) {
            if(current == ids[index]) {
                var id = getParam(treeRows[i], "id")
                treeRows[i].style.display = getParam(categories[current], "open") == "false" ? 'none' : categories[current].style.display;
                ids.push(id);
                categories[id] = treeRows[i];
            }
        }
        if(!treeRows[i].style.display || (treeRows[i].style.display && treeRows[i].style.display != 'none')) {
            var c = odd ? "rowOdd" : "rowEven";
            odd = !odd;
            treeRows[i].className = treeRows[i].className.replace("rowOdd",c).replace("rowEven",c);
            treeRows[i].onmouseout = new Function("this.className = '" + c + "'");
        }
        previous = treeRows[i];
    }
}

function TableDnD() {
    /** Keep hold of the current drag object if any */
    this.dragObject = null;
    /** The current mouse offset */
    this.mouseOffset = null;
    /** The current table */
    this.table = null;
    /** Remember the old value of Y so that we don't do too much processing */
    this.oldY = 0;
    this.url = "";
    this.queryId = "menuid";

    /** Initialise the drag and drop by capturing mouse move events */
    this.init = function(table, url, queryId) {
        if(typeof(queryId) == 'undefined' || !queryId) {
            queryId = url;
            url = document.location.href;
            var start = url.indexOf("?");
            if(start > 0) url = url.substring(0, start);
        }
        this.table = table;
        this.url = url;
        this.queryId = queryId;
        
        if(!table) return;
        var rows = table.tBodies[0].rows;
        for (var i=0; i<rows.length; i++) {
			// John Tarr: added to ignore rows that I've added the NoDnD attribute to (Category and Header rows)
			var nodrag = getParam(rows[i], "nodrag");
			//var nodrag = rows[i].getAttribute("NoDrag")
			if (nodrag == null || nodrag == "undefined") { //There is no NoDnD attribute on rows I want to drag
				this.makeDraggable(rows[i]);
			}
        }
    }

    this.childRows = function(category) {
        var rows = this.table.tBodies[0].rows;
        var found = false;
        for(var i=0; i<rows.length; i++) {
            if(getParam(rows[i], "id") != category) continue;
            found = true;
            var status = getParam(rows[i], "open");
            status = status == "true" ? "false" : status == "false" ? "true" : "none";
            treeRows = rows;
            fAJAXResponse = new Function("ajaxTree('" + category + "'," + (i + 1) + ");");
            sendAJAX(this.url, this.queryId + "=" + getParam(rows[i], "id") + "&status=" + status);
            break;
        }
        if(!found) alert('Er is een fout opgetreden bij het vinden van de onderliggende elementen!');
    }

    /** This function is called when you drop a row, so redefine it in your code
        to do whatever you want, for example use Ajax to update the server */
    this.onDrop = function(table, droppedRow, url, queryId) {
        // get the old index of the current row

        var oldIndex = parseInt(getParam(droppedRow, "index"), 10);

        // find the index of the previous row

        var previousRow = droppedRow.previousSibling;
        var previousIndex = 0;
        if (previousRow && previousRow.tagName && previousRow.tagName.toLowerCase() == 'tr') {
            previousIndex = parseInt(getParam(previousRow, "index"), 10);
        }

        // find the index of the next row

        var nextRow = droppedRow.nextSibling;
        var nextIndex = 0;
        if (nextRow && nextRow.tagName && nextRow.tagName.toLowerCase() == 'tr') {
            nextIndex = parseInt(getParam(nextRow, "index"), 10);
        }

        // determine the new index

        var newIndex = oldIndex;
        if (previousIndex == 0 && nextIndex > 0) {
            newIndex = nextIndex;
        }
        if (previousIndex > 0) {
            newIndex = previousIndex + 1;
        }

        // send new index to the webserver if changed

        var queryString = '';
        if (newIndex != oldIndex) {
            queryString = queryId + "=" + getParam(droppedRow, "id") + "&order=" + newIndex;
            sendAJAX(url, queryString);
        }

        // update index

        var allrows = table.tBodies[0].rows;
        for (var i = 0; i < allrows.length; i++) {
            setParam(allrows[i], "index", i);
        }

        draggedFinish = true;

        // No idea what this does

        //        var category = getParam(droppedRow, "category");
        //        Response = new Function("dragFinish('" + category + "');");


        var isOpen = getParam(droppedRow, "open") == "true";
        if (draggedRows) {
            for (var i = 0; i < draggedRows.length; i++) {
                if (isOpen) draggedRows[i].style.display = is_ie ? 'block' : 'table-row';
                droppedRow.parentNode.insertBefore(draggedRows[i], next);
            }
        }
        if (isOpen) droppedRow.cells[0].innerHTML = droppedRow.cells[0].innerHTML.replace("trvplus", "trvmin");
        draggedRows = null;
        draggedTable = table;

        //        alert('oldIndex = ' + oldIndex + '\r\n' +
        //            'newIndex = ' + newIndex + '\r\n' +
        //            'previousIndex = ' + previousIndex + '\r\n' +
        //            'nextIndex = ' + nextIndex + '\r\n' +
        //            'queryString = ' + queryString)

    }



	/** Get the position of an element by going up the DOM tree and adding up all the offsets */
    this.getPosition = function(e){
        var left = 0;
        var top  = 0;
		/** Safari fix -- thanks to Luis Chato for this! */
		if (e.offsetHeight == 0) {
			/** Safari 2 doesn't correctly grab the offsetTop of a table row
			    this is detailed here:
			    http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/
			    the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild.
			    note that firefox will return a text node as a first child, so designing a more thorough
			    solution may need to take that into account, for now this seems to work in firefox, safari, ie */
			e = e.firstChild; // a table cell
		}

        while (e.offsetParent){
            left += e.offsetLeft;
            top  += e.offsetTop;
            e     = e.offsetParent;
        }

        left += e.offsetLeft;
        top  += e.offsetTop;

        return {x:left, y:top};
    }

	/** Get the mouse coordinates from the event (allowing for browser differences) */
    this.mouseCoords = function(ev){
        if(ev.pageX || ev.pageY){
            return {x:ev.pageX, y:ev.pageY};
        }
        return {
            x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
            y:ev.clientY + document.body.scrollTop  - document.body.clientTop
        };
    }

	/** Given a target element and a mouse event, get the mouse offset from that element.
		To do this we need the element's position and the mouse position */
    this.getMouseOffset = function(target, ev){
        ev = ev || window.event;

        var docPos    = this.getPosition(target);
        var mousePos  = this.mouseCoords(ev);
        return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
    }

	/** Take an item and add an onmousedown method so that we can make it draggable */
    this.makeDraggable = function(item) 
    {
        if(!item) return;
        var self = this; // Keep the context of the TableDnd inside the function
        item.onmousedown = function(ev) {
            if(!draggedFinish) { alert('Trying to save your move, please wait'); return true; }
            // Need to check to see if we are an input or not, if we are an input, then
            // return true to allow normal processing
            var target = getEventSource(ev);
            if (target.tagName == 'INPUT' || target.tagName == 'SELECT') return true;
            currenttable = self;
            self.dragObject  = this;
            self.mouseOffset = self.getMouseOffset(this, ev);
            return false;
        }
        item.style.cursor = "move";
    }

    /** We're only worried about the y position really, because we can only move rows up and down */
    this.findDropTargetRow = function(y) {
	    var currentCategory = getParam(currenttable.dragObject, "category");
        var rows = this.table.tBodies[0].rows;
		for (var i=0; i<rows.length; i++) {
			var row = rows[i];
			// John Tarr added to ignore rows that I've added the NoDnD attribute to (Header rows)
			var nodrop = getParam(row, "nodrop");
			var category = getParam(row, "category");
			if ((nodrop == null || nodrop == "undefined") && category == currentCategory) {  //There is no NoDnD attribute on rows I want to drag.
				var rowY    = this.getPosition(row).y;
				var rowHeight = parseInt(row.offsetHeight)/2;
				if (row.offsetHeight == 0) {
					rowY = this.getPosition(row.firstChild).y;
					rowHeight = parseInt(row.firstChild.offsetHeight)/2;
				}
				// Because we always have to insert before, we need to offset the height a bit
				if ((y > rowY - rowHeight) && (y < (rowY + rowHeight))) {
					// that's the row we're over
					return row;
				}
			}
		}
		return null;
	}
}

function GalleryReorderClass(menuID, target, columns, rows, imgWidth, imgHeight) {

    var blnInitialized = false;
    var tblID = tblID;
    var imgMover = null;
    var intMenuID = menuID;
    var intFrom = 0;
    var intXDiff = 0;
    var intYDiff = 0;
    var intColumns = columns;
    var intRows = rows;
    var intImgWidth = imgWidth;
    var intImgHeight = imgHeight;
    var intSnapDistance = 70;
    var strTarget = target;
    var Cells = Array();
    
    function Cell(img, id) {
        
        this.img = img;
        this.ID = id;
        this.X = 0;
        this.Y = 0;
    }
    
    function Initialize() {
        var cell, position, intBaseX, intBaseY, intStrideX, intStrideY;
        
        position = FindPosition(Cells[0].img);
        
        // IE fix
        if(document.all) {
        
            intBaseX = position[0] + 1;
            intBaseY = position[1] + 1;
            
        } else {
        
            intBaseX = position[0];
            intBaseY = position[1];
        }
        
        position = FindPosition(Cells[intColumns + 1].img);
        
        // IE fix
        if(document.all) {
        
            intStrideX = (position[0] - intBaseX) + 1;
            intStrideY = (position[1] - intBaseY) + 1;
            
        } else {
        
            intStrideX = position[0] - intBaseX;
            intStrideY = position[1] - intBaseY;
        }
        
        for(i = Cells.length;i--;) {

            cell = Cells[i];
            if (!cell) continue;
            cell.X = intBaseX + ((i % intColumns) * intStrideX);
            cell.Y = intBaseY + (Math.floor(i / intColumns) * intStrideY);
        }
        
        blnInitialized = true;
    }
    
    function ImageDown(e) {
        var position;
        var targ;
            
        if(!e) var e = window.event;
        if (e.target) targ = e.target;
	    else if (e.srcElement) targ = e.srcElement;
	    if (targ.nodeType == 3) // opvangen Safari bug
		    targ = targ.parentNode;
           
        if(!blnInitialized) Initialize();	
    
        intFrom = e.currentTarget ? e.currentTarget.CellID : targ.CellID;
        imgMover.src = e.currentTarget ? e.currentTarget.src : targ.src;
        
        position = MousePosition(e);
        
        intXDiff = (position[0] - Cells[intFrom].X);
        intYDiff = (position[1] - Cells[intFrom].Y);
    
        imgMover.style.left = (position[0] - intXDiff) + 'px';
        imgMover.style.top = (position[1] - intYDiff) + 'px';
        
        Cells[intFrom].img.style.visibility = 'hidden';
        imgMover.style.visibility = 'visible';
    
        document.onmouseup = DropImage;
        document.onmousemove = DragImage;
        
        return false;
    }

    function DragImage(e) {
        var position;
    
        if (!e) var e = window.event;
        
        position = MousePosition(e);
    
        imgMover.style.left = (position[0] - intXDiff) + 'px';
        imgMover.style.top = (position[1] - intYDiff) + 'px';
    }

    function DropImage() {
        var xDiff, yDiff, cell, srcCell;

        document.onmousemove = null;
        document.onmouseup = null;
        srcCell = Cells[intFrom];
        
        for (i = Cells.length;i--;) {

            cell = Cells[i];
            if (!cell) continue;
        
            xDiff = parseInt(imgMover.style.left) - cell.X;
            yDiff = parseInt(imgMover.style.top) - cell.Y;
        
            if(Math.sqrt((xDiff * xDiff) + (yDiff * yDiff)) < intSnapDistance) {
            
                if(intFrom != cell.ID) {
                
                    PostBack(intFrom, cell.ID);
                    
                    srcCell.img.src = cell.img.src;
                    cell.img.src = imgMover.src;
                    
                    break;
                }
            }
        }
                            
        srcCell.img.style.visibility = 'visible';
        imgMover.style.visibility = 'hidden';
        
        imgMover.style.left = -1000 + 'px';
        imgMover.style.top = -1000 + 'px';
    }

    function RegisterImage(img) {
        var position, re, m, id;
        
        re = new RegExp('_img([0-9]+)$');
        m = re.exec(img.id);
        
        if(m != null) {
            
            id = parseInt(m[1]);
            img.CellID = id;
            Cells[id] = new Cell(img, id);
        }
        
        img.onload = null;
        img.onmousedown = ImageDown;
    }
    
    function RegisterMoveable(img) {
    
        imgMover = img;
        img.onclick = null;
    }
    
    function FindPosition(obj) {
	    var curleft = curtop = 0;
	
	    if (obj.offsetParent) {
		    curleft = obj.offsetLeft;
		    curtop = obj.offsetTop;
		
		    while (obj = obj.offsetParent) {
			    curleft += obj.offsetLeft
			    curtop += obj.offsetTop
		    }
	    }
	
	    return [curleft,curtop];
    }
    
    function MousePosition(e) {
        var mouseX, mouseY;
    
        if (e.pageX || e.pageY) {
    
		    mouseX = e.pageX;
		    mouseY = e.pageY;
		
	    } else {
	
	        if (e.clientX || e.clientY) {
	    
		        mouseX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
	    	    mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	        }
	    }
    
        return [mouseX, mouseY];
    }
    
    function PostBack(intFrom, intTo) {
    
        fAJAXResponse = new Function('return;');
        getAJAXResponse(strTarget + '?ID=' + intMenuID + '&imgSwap=' + intFrom + '_' + intTo);
    }

    this.Initialize = Initialize;
    this.ImageDown = ImageDown;
    this.DragImage = DragImage;
    this.RegisterImage = RegisterImage;
    this.RegisterMoveable = RegisterMoveable;
    this.FindPosition = FindPosition;
    this.MousePosition = MousePosition;
    this.PostBack = PostBack;
}

/*
 * jsTree 0.9.7
 * http://jstree.com/
 *
 * Copyright (c) 2009 Ivan Bozhanov (vakata.com)
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Date: 2009-04-08
 *
 */

(function($) {
	// jQuery plugin
	$.fn.tree = function (opts) {
		return this.each(function() {
			var conf = $.extend({},opts);
			if(tree_component.inst && tree_component.inst[$(this).attr('id')]) tree_component.inst[$(this).attr('id')].destroy();
			if(conf !== false) new tree_component().init(this, conf);
		});
	};
	$.tree_create = function() {
		return new tree_component();
	};
	$.tree_focused = function() {
		return tree_component.inst[tree_component.focused];
	};
	$.tree_reference = function(id) {
		return tree_component.inst[id] || null;
	};

	// rollback
	$.tree_rollback = function(data) {
		for(var i in data) {
			var tmp = tree_component.inst[i];
			var lock = !tmp.locked;

			// if not locked - lock the tree
			if(lock) tmp.lock(true);
			// Cancel ongoing rename
			if(tmp.inp) tmp.inp.val("").blur();
			tmp.context.append = false;
			tmp.container.html(data[i].html).find(".dragged").removeClass("dragged").end().find("div.context").remove();

			if(data[i].selected) {
				tmp.selected = $("#" + data[i].selected);
				tmp.selected_arr = [];
				tmp.container
					.find("a.clicked").each( function () {
						tmp.selected_arr.push(tmp.get_node(this));
					});
			}
			// if this function set the lock - unlock
			if(lock) tmp.lock(false);

			delete lock;
			delete tmp;
		}
	};

	// core
	function tree_component () {
		// instance manager
		if(typeof tree_component.inst == "undefined") {
			tree_component.cntr = 0;
			tree_component.inst = {};

			// DRAG'N'DROP STUFF
			tree_component.drag_drop = {
				isdown		: false,	// Is there a drag
				drag_node	: false,	// The actual node
				drag_help	: false,	// The helper

				init_x		: false,
				init_y		: false,
				moving		: false,

				origin_tree	: false,
				marker		: false,

				move_type	: false,	// before, after or inside
				ref_node	: false,	// reference node
				appended	: false,	// is helper appended

				foreign		: false,	// Is the dragged node a foreign one
				droppable	: [],		// Array of classes that can be dropped onto the tree

				open_time	: false,	// Timeout for opening nodes
				scroll_time	: false		// Timeout for scrolling
			};
			// listening for clicks on foreign nodes
			tree_component.mousedown = function(event) {
				var tmp = $(event.target);
				if(tree_component.drag_drop.droppable.length && tmp.is("." + tree_component.drag_drop.droppable.join(", .")) ) {
					tree_component.drag_drop.drag_help	= $("<li id='dragged' class='dragged foreign " + event.target.className + "'><a href='#'>" + tmp.text() + "</a></li>");
					tree_component.drag_drop.drag_node	= tree_component.drag_drop.drag_help;
					tree_component.drag_drop.isdown		= true;
					tree_component.drag_drop.foreign	= tmp;
					tmp.blur();
					event.preventDefault(); 
					event.stopPropagation();
					return false;
				}
				event.stopPropagation();
				return true;
			};
			tree_component.mouseup = function(event) {
				var tmp = tree_component.drag_drop;
				if(tmp.open_time)	clearTimeout(tmp.open_time);
				if(tmp.scroll_time)	clearTimeout(tmp.scroll_time);
				if(tmp.foreign === false && tmp.drag_node && tmp.drag_node.size()) {
					tmp.drag_help.remove();
					if(tmp.move_type) {
						var tree1 = tree_component.inst[tmp.ref_node.parents(".tree:eq(0)").attr("id")];
						if(tree1) tree1.moved(tmp.origin_tree.container.find("li.dragged"), tmp.ref_node, tmp.move_type, false, (tmp.origin_tree.settings.rules.drag_copy == "on" || (tmp.origin_tree.settings.rules.drag_copy == "ctrl" && event.ctrlKey) ) );
					}
					tmp.move_type	= false;
					tmp.ref_node	= false;
				}
				if(tmp.drag_node && tmp.foreign !== false) {
					tmp.drag_help.remove();
					if(tmp.move_type) {
						var tree1 = tree_component.inst[tmp.ref_node.parents(".tree:eq(0)").attr("id")];
						if(tree1) tree1.settings.callback.ondrop.call(null, tmp.foreign.get(0), tree1.get_node(tmp.ref_node).get(0), tmp.move_type, tree1);
					}
					tmp.foreign		= false;
					tmp.move_type	= false;
					tmp.ref_node	= false;
				}
				// RESET EVERYTHING
				tree_component.drag_drop.marker.hide();
				tmp.drag_help	= false;
				tmp.drag_node	= false;
				tmp.isdown		= false;
				tmp.init_x		= false;
				tmp.init_y		= false;
				tmp.moving		= false;
				tmp.appended	= false;
				if(tmp.origin_tree) tmp.origin_tree.container.find("li.dragged").removeClass("dragged");
				tmp.origin_tree	= false;
				event.preventDefault(); 
				event.stopPropagation();
				return false;
			};
			tree_component.mousemove = function(event) {
				var tmp		= tree_component.drag_drop;

				if(tmp.isdown) {
					if(!tmp.moving && Math.abs(tmp.init_x - event.pageX) < 5 && Math.abs(tmp.init_y - event.pageY) < 5) {
						event.preventDefault();
						event.stopPropagation();
						return false;
					}
					else tree_component.drag_drop.moving = true;

					if(tmp.open_time) clearTimeout(tmp.open_time);
					if(!tmp.appended) {
						if(tmp.foreign !== false) tmp.origin_tree = $.tree_focused();
						tmp.origin_tree.container.children("ul:eq(0)").append(tmp.drag_help);
						var temp = $(tmp.drag_help).offsetParent();
						if(temp.is("html")) temp = $("body");
						tmp.po = temp.offset();
						tmp.po.top -= (temp.is("body")) ? 0 : temp.scrollTop();
						tmp.po.left -= (temp.is("body")) ? 0 : temp.scrollLeft();
						tmp.w = tmp.drag_help.width();
						tmp.appended = true;
					}
					tmp.drag_help.css({ "left" : (event.pageX - tmp.po.left - (tmp.origin_tree.settings.ui.rtl ? tmp.w : -5 ) ), "top" : (event.pageY - tmp.po.top + 15) });

					if(event.target.tagName == "IMG" && event.target.id == "marker") return false;

					var cnt = $(event.target).parents(".tree:eq(0)");

					// if not moving over a tree
					if(cnt.size() == 0) {
						if(tmp.scroll_time) clearTimeout(tmp.scroll_time);
						if(tmp.drag_help.children("IMG").size() == 0) {
							tmp.drag_help.append("<img style='position:absolute; " + (tmp.origin_tree.settings.ui.rtl ? "right" : "left" ) + ":4px; top:0px; background:white; padding:2px;' src='" + tmp.origin_tree.settings.ui.theme_path + "remove.png' />");
						}
						tmp.move_type	= false;
						tmp.ref_node	= false;
						tree_component.drag_drop.marker.hide();
						return false;
					}

					var tree2 = tree_component.inst[cnt.attr("id")];
					tree2.off_height();

					// if moving over another tree and multitree is false
					if( tmp.foreign === false && tmp.origin_tree.container.get(0) != tree2.container.get(0) && (!tmp.origin_tree.settings.rules.multitree || !tree2.settings.rules.multitree) ) {
						if(tmp.drag_help.children("IMG").size() == 0) {
							tmp.drag_help.append("<img style='position:absolute; " + (tmp.origin_tree.settings.ui.rtl ? "right" : "left" ) + ":4px; top:0px; background:white; padding:2px;' src='" + tmp.origin_tree.settings.ui.theme_path + "remove.png' />");
						}
						tmp.move_type	= false;
						tmp.ref_node	= false;
						tree_component.drag_drop.marker.hide();
						return false;
					}

					if(tmp.scroll_time) clearTimeout(tmp.scroll_time);
					tmp.scroll_time = setTimeout( function() { tree2.scrollCheck(event.pageX,event.pageY); }, 50);

					var mov = false;
					var st = cnt.scrollTop();

					var et = $(event.target);
					if(event.target.tagName == "A" ) {
						// just in case if hover is over the draggable
						if(et.is("#dragged")) return false;
						if(tree2.get_node(event.target).hasClass("closed")) {
							tmp.open_time = setTimeout( function () { tree2.open_branch(et); }, 500);
						}

						var atmp = 0;
						var btmp = parseInt($.curCSS(tree2.container.get(0), "borderTopWidth", true),10);
						if(btmp) atmp += btmp;
						var ptmp = parseInt($.curCSS(tree2.container.get(0), "paddingTop", true),10);
						if(ptmp) atmp += ptmp;

						var et_off = et.offset();

						var goTo = { 
							x : (et_off.left - 1),
							y : (event.pageY - et_off.top)
						};

						if(cnt.hasClass("rtl")) goTo.x += et.width() - 8;
						var arr = [];

						if(goTo.y < tree2.li_height/3 + 1 )			arr = ["before","inside","after"];
						else if(goTo.y > tree2.li_height*2/3 - 1 )	arr = ["after","inside","before"];
						else {
							if(goTo.y < tree2.li_height/2)			arr = ["inside","before","after"];
							else									arr = ["inside","after","before"];
						}
						var ok	= false;
						$.each(arr, function(i, val) {
							if(tree2.checkMove(tmp.origin_tree.container.find("li.dragged"), et, val)) {
								mov = val;
								ok = true;
								return false;
							}
						});
						if(ok) {
							switch(mov) {
								case "before":
									goTo.y = et_off.top - 2;
									if(cnt.hasClass("rtl"))	{ tree_component.drag_drop.marker.attr("src", tree2.settings.ui.theme_path + "marker_rtl.gif").width(40); }
									else					{ tree_component.drag_drop.marker.attr("src", tree2.settings.ui.theme_path + "marker.gif").width(40); }
									break;
								case "after":
									goTo.y = et_off.top - 2 + tree2.li_height;
									if(cnt.hasClass("rtl"))	{ tree_component.drag_drop.marker.attr("src", tree2.settings.ui.theme_path + "marker_rtl.gif").width(40); }
									else					{ tree_component.drag_drop.marker.attr("src", tree2.settings.ui.theme_path + "marker.gif").width(40); }
									break;
								case "inside":
									goTo.x -= 2;
									if(cnt.hasClass("rtl")) {
										goTo.x += 36;
									}
									goTo.y = et_off.top - 2 + tree2.li_height/2;
									tree_component.drag_drop.marker.attr("src", tree2.settings.ui.theme_path + "plus.gif").width(11);
									break;
							}
							tmp.move_type	= mov;
							tmp.ref_node	= $(event.target);
							tmp.drag_help.children("IMG").remove();
							tree_component.drag_drop.marker.css({ "left" : goTo.x , "top" : goTo.y }).show();
						}
					}
					if(event.target.tagName != "A" || !ok) {
						if(tmp.drag_help.children("IMG").size() == 0) {
							tmp.drag_help.append("<img style='position:absolute; " + (tmp.origin_tree.settings.ui.rtl ? "right" : "left" ) + ":4px; top:0px; background:white; padding:2px;' src='" + tmp.origin_tree.settings.ui.theme_path + "remove.png' />");
						}
						tmp.move_type	= false;
						tmp.ref_node	= false;
						tree_component.drag_drop.marker.hide();
					}
					event.preventDefault();
					event.stopPropagation();
					return false;
				}
				return true;
			};
		};
		return {
			cntr : ++tree_component.cntr,
			settings : {
				data	: {
					type	: "predefined",	// ENUM [json, xml_flat, xml_nested, predefined]
					method	: "GET",		// HOW TO REQUEST FILES
					async	: false,		// BOOL - async loading onopen
					async_data : function (NODE) { return { id : $(NODE).attr("id") || 0 } }, // PARAMETERS PASSED TO SERVER
					url		: false,		// FALSE or STRING - url to document to be used (async or not)
					json	: false,		// FALSE or OBJECT if type is JSON and async is false - the tree dump as json
					xml		: false			// FALSE or STRING if type is XML_FLAT or XML_NESTED and async is false - a string to generate the tree from
				},
				selected	: false,		// FALSE or STRING or ARRAY
				opened		: [],			// ARRAY OF INITIALLY OPENED NODES
				languages	: [],			// ARRAY of string values (which will be used as CSS classes - so they must be valid)
				path		: false,		// FALSE or STRING (if false - will be autodetected)
				cookies		: false,		// FALSE or OBJECT (prefix, open, selected, opts - from jqCookie - expires, path, domain, secure)
				ui		: {
					dots		: true,		// BOOL - dots or no dots
					rtl			: false,	// BOOL - is the tree right-to-left
					animation	: 0,		// INT - duration of open/close animations in miliseconds
					hover_mode	: true,		// SHOULD get_* functions chage focus or change hovered item
					scroll_spd	: 4,
					theme_path	: false,	// Path to themes
					theme_name	: "default",// Name of theme
					context		: [ 
						{
							id		: "create",
							label	: "Create", 
							icon	: "create.png",
							visible	: function (NODE, TREE_OBJ) { if(NODE.length != 1) return false; return TREE_OBJ.check("creatable", NODE); }, 
							action	: function (NODE, TREE_OBJ) { TREE_OBJ.create(false, TREE_OBJ.get_node(NODE)); } 
						},
						"separator",
						{ 
							id		: "rename",
							label	: "Rename", 
							icon	: "rename.png",
							visible	: function (NODE, TREE_OBJ) { if(NODE.length != 1) return false; return TREE_OBJ.check("renameable", NODE); }, 
							action	: function (NODE, TREE_OBJ) { TREE_OBJ.rename(NODE); } 
						},
						{ 
							id		: "delete",
							label	: "Delete",
							icon	: "remove.png",
							visible	: function (NODE, TREE_OBJ) { var ok = true; $.each(NODE, function () { if(TREE_OBJ.check("deletable", this) == false) ok = false; return false; }); return ok; }, 
							action	: function (NODE, TREE_OBJ) { $.each(NODE, function () { TREE_OBJ.remove(this); }); } 
						}
					]
				},
				rules	: {
					multiple	: false,	// FALSE | CTRL | ON - multiple selection off/ with or without holding Ctrl
					metadata	: false,	// FALSE or STRING - attribute name (use metadata plugin)
					type_attr	: "rel",	// STRING attribute name (where is the type stored if no metadata)
					multitree	: false,	// BOOL - is drag n drop between trees allowed
					createat	: "bottom",	// STRING (top or bottom) new nodes get inserted at top or bottom
					use_inline	: false,	// CHECK FOR INLINE RULES - REQUIRES METADATA
					clickable	: "all",	// which node types can the user select | default - all
					renameable	: "all",	// which node types can the user select | default - all
					deletable	: "all",	// which node types can the user delete | default - all
					creatable	: "all",	// which node types can the user create in | default - all
					draggable	: "none",	// which node types can the user move | default - none | "all"
					dragrules	: "all",	// what move operations between nodes are allowed | default - none | "all"
					drag_copy	: false,	// FALSE | CTRL | ON - drag to copy off/ with or without holding Ctrl
					droppable	: [],
					drag_button	: "left"	// left, right or both
				},
				lang : {
					new_node	: "New folder",
					loading		: "Loading ..."
				},
				callback	: {				// various callbacks to attach custom logic to
					// before focus  - should return true | false
					beforechange: function(NODE,TREE_OBJ) { return true },
					beforeopen	: function(NODE,TREE_OBJ) { return true },
					beforeclose	: function(NODE,TREE_OBJ) { return true },
					// before move   - should return true | false
					beforemove  : function(NODE,REF_NODE,TYPE,TREE_OBJ) { return true }, 
					// before create - should return true | false
					beforecreate: function(NODE,REF_NODE,TYPE,TREE_OBJ) { return true }, 
					// before rename - should return true | false
					beforerename: function(NODE,LANG,TREE_OBJ) { return true }, 
					// before delete - should return true | false
					beforedelete: function(NODE,TREE_OBJ) { return true }, 

					onJSONdata	: function(DATA,TREE_OBJ) { return DATA; },
					onselect	: function(NODE,TREE_OBJ) { },					// node selected
					ondeselect	: function(NODE,TREE_OBJ) { },					// node deselected
					onchange	: function(NODE,TREE_OBJ) { },					// focus changed
					onrename	: function(NODE,LANG,TREE_OBJ,RB) { },				// node renamed ISNEW - TRUE|FALSE, current language
					onmove		: function(NODE,REF_NODE,TYPE,TREE_OBJ,RB) { },	// move completed (TYPE is BELOW|ABOVE|INSIDE)
					oncopy		: function(NODE,REF_NODE,TYPE,TREE_OBJ,RB) { },	// copy completed (TYPE is BELOW|ABOVE|INSIDE)
					oncreate	: function(NODE,REF_NODE,TYPE,TREE_OBJ,RB) { },	// node created, parent node (TYPE is createat)
					ondelete	: function(NODE,TREE_OBJ,RB) { },				// node deleted
					onopen		: function(NODE,TREE_OBJ) { },					// node opened
					onopen_all	: function(TREE_OBJ) { },						// all nodes opened
					onclose		: function(NODE,TREE_OBJ) { },					// node closed
					error		: function(TEXT,TREE_OBJ) { },					// error occured
					// double click on node - defaults to open/close & select
					ondblclk	: function(NODE,TREE_OBJ) { TREE_OBJ.toggle_branch.call(TREE_OBJ, NODE); TREE_OBJ.select_branch.call(TREE_OBJ, NODE); },
					// right click - to prevent use: EV.preventDefault(); EV.stopPropagation(); return false
					onrgtclk	: function(NODE,TREE_OBJ,EV) { },
					onload		: function(TREE_OBJ) { },
					onfocus		: function(TREE_OBJ) { },
					ondrop		: function(NODE,REF_NODE,TYPE,TREE_OBJ) {}
				}
			},
			// INITIALIZATION
			init : function(elem, opts) {
				var _this = this;
				this.container		= $(elem);
				if(this.container.size == 0) { alert("Invalid container node!"); return }

				tree_component.inst[this.cntr] = this;
				if(!this.container.attr("id")) this.container.attr("id","jstree_" + this.cntr); 
				tree_component.inst[this.container.attr("id")] = tree_component.inst[this.cntr];
				tree_component.focused = this.cntr;

				// MERGE OPTIONS WITH DEFAULTS
				if(opts && opts.cookies) {
					this.settings.cookies = $.extend({},this.settings.cookies,opts.cookies);
					delete opts.cookies;
					if(!this.settings.cookies.opts) this.settings.cookies.opts = {};
				}
				if(opts && opts.callback) {
					this.settings.callback = $.extend({},this.settings.callback,opts.callback);
					delete opts.callback;
				}
				if(opts && opts.data) {
					this.settings.data = $.extend({},this.settings.data,opts.data);
					delete opts.data;
				}
				if(opts && opts.ui) {
					this.settings.ui = $.extend({},this.settings.ui,opts.ui);
					delete opts.ui;
				}
				if(opts && opts.rules) {
					this.settings.rules = $.extend({},this.settings.rules,opts.rules);
					delete opts.rules;
				}
				if(opts && opts.lang) {
					this.settings.langlang = $.extend({},this.settings.lang,opts.lang);
					delete opts.lang;
				}
				this.settings		= $.extend({},this.settings,opts);

				// PATH TO IMAGES AND XSL
				if(this.settings.path == false) {
					this.path = "";
					$("script").each( function () { 
						if(this.src.toString().match(/tree_component.*?js$/)) {
							_this.path = this.src.toString().replace(/tree_component.*?js$/, "");
						}
					});
				}
				else this.path = this.settings.path;

				// DEAL WITH LANGUAGE VERSIONS
				this.current_lang	= this.settings.languages && this.settings.languages.length ? this.settings.languages[0] : false;
				if(this.settings.languages && this.settings.languages.length) {
					this.sn = get_sheet_num("tree_component.css");
					if(this.sn === false && document.styleSheets.length) this.sn = document.styleSheets.length;
					var st = false;
					var id = this.container.attr("id") ? "#" + this.container.attr("id") : ".tree";
					for(var ln = 0; ln < this.settings.languages.length; ln++) {
						st = add_css(id + " ." + this.settings.languages[ln], this.sn);
						if(st !== false) {
							if(this.settings.languages[ln] == this.current_lang)	st.style.display = "";
							else													st.style.display = "none";
						}
					}
				}

				// DROPPABLES 
				if(this.settings.rules.droppable.length) {
					for(var i in this.settings.rules.droppable) {
						tree_component.drag_drop.droppable.push(this.settings.rules.droppable[i]);
					}
					tree_component.drag_drop.droppable = $.unique(tree_component.drag_drop.droppable);
				}

				// THEMES
				if(this.settings.ui.theme_path === false) this.settings.ui.theme_path = this.path + "themes/";
				this.theme = this.settings.ui.theme_path; 
				if(_this.settings.ui.theme_name) {
					this.theme += _this.settings.ui.theme_name + "/";
					if(_this.settings.ui.theme_name != "themeroller" && !tree_component.def_style) { add_sheet(_this.settings.ui.theme_path + "default/style.css"); tree_component.def_style = true; }
					add_sheet(_this.theme + "style.css");
					// if(this.settings.ui.theme_name && this.settings.ui.theme_name != "default") add_sheet(_this.theme + "style.css");
				}

				this.container.addClass("tree");
				if(this.settings.ui.theme_name == "themeroller") this.container.addClass("ui-widget ui-widget-content");
				if(this.settings.ui.rtl) this.container.addClass("rtl");
				if(this.settings.rules.multiple) this.selected_arr = [];
				this.offset = false;

				if(this.settings.ui.dots == false) this.container.addClass("no_dots");

				// CONTEXT MENU
				this.context_menu();

				this.hovered = false;
				this.locked = false;

				// CREATE DUMMY FOR MOVING
				if(this.settings.rules.draggable != "none" && tree_component.drag_drop.marker === false) {
					var _this = this;
					tree_component.drag_drop.marker = $("<img>")
						.attr({
							id		: "marker", 
							src	: _this.settings.ui.theme_path + "marker.gif"
						})
						.css({
							height		: "5px",
							width		: "40px",
							display		: "block",
							position	: "absolute",
							left		: "30px",
							top			: "30px",
							zIndex		: "1000"
						}).hide().appendTo("body");
				}
				this.refresh();
				this.attachEvents();
				this.focus();
			},
			off_height : function () {
				if(this.offset === false) {
					this.container.css({ position : "relative" });
					this.offset = this.container.offset();
					var tmp = 0;
					tmp = parseInt($.curCSS(this.container.get(0), "paddingTop", true),10);
					if(tmp) this.offset.top += tmp;
					tmp = parseInt($.curCSS(this.container.get(0), "borderTopWidth", true),10);
					if(tmp) this.offset.top += tmp;
					this.container.css({ position : "" });
				}
				if(!this.li_height) {
					var tmp = this.container.find("ul li.closed, ul li.leaf").eq(0);
					this.li_height = tmp.height();
					if(tmp.children("ul:eq(0)").size()) this.li_height -= tmp.children("ul:eq(0)").height();
					if(!this.li_height) this.li_height = 18;
				}
			},
			context_menu : function () {
				this.context = false;
				if(this.settings.ui.context != false) {
					var str = '<div class="tree-default-context tree-' + this.settings.ui.theme_name + '-context">';
					for(var i in this.settings.ui.context) {
						if(typeof this.settings.ui.context[i] == "function") continue;
						if(this.settings.ui.context[i] == "separator") {
							str += "<span class='separator'>&nbsp;</span>";
							continue;
						}
						var icn = "";
						if(this.settings.ui.context[i].icon) icn = 'background-image:url(\'' + ( this.settings.ui.context[i].icon.indexOf("/") == -1 ? this.theme + this.settings.ui.context[i].icon : this.settings.ui.context[i].icon ) + '\');';
						str += '<a rel="' + this.settings.ui.context[i].id + '" href="#" style="' + icn + '">' + this.settings.ui.context[i].label + '</a>';
					}
					str += '</div>';
					this.context = $(str);
					this.context.hide();
					this.context.append = false;
				}
			},
			// REPAINT TREE
			refresh : function (obj) {
				if(this.locked) return this.error("LOCKED");
				var _this = this;

				// SAVE OPENED
				this.opened = Array();
				if(this.settings.cookies && $.cookie(this.settings.cookies.prefix + '_open')) {
					var str = $.cookie(this.settings.cookies.prefix + '_open');
					var tmp = str.split(",");
					$.each(tmp, function () {
						_this.opened.push("#" + this.replace(/^#/,""));
					});
					this.settings.opened = false;
				}
				else if(this.settings.opened != false) {
					$.each(this.settings.opened, function (i, item) {
						_this.opened.push("#" + this.replace(/^#/,""));
					});
					this.settings.opened = false;
				}
				else {
					this.container.find("li.open").each(function (i) { _this.opened.push("#" + this.id); });
				}

				// SAVE SELECTED
				if(this.selected) {
					this.settings.selected = Array();
					if(this.selected_arr) {
						$.each(this.selected_arr, function () {
							if(this.attr("id")) _this.settings.selected.push("#" + this.attr("id"));
						});
					}
					else {
						if(this.selected.attr("id")) this.settings.selected.push("#" + this.selected.attr("id"));
					}
				}
				else if(this.settings.cookies && $.cookie(this.settings.cookies.prefix + '_selected')) {
					this.settings.selected = Array();
					var str = $.cookie(this.settings.cookies.prefix + '_selected');
					var tmp = str.split(",");
					$.each(tmp, function () {
						_this.settings.selected.push("#" + this.replace(/^#/,""));
					});
				}
				else if(this.settings.selected !== false) {
					var tmp = Array();
					if((typeof this.settings.selected).toLowerCase() == "object") {
						$.each(this.settings.selected, function () {
							if(this.replace(/^#/,"").length > 0) tmp.push("#" + this.replace(/^#/,""));
						});
					}
					else {
						if(this.settings.selected.replace(/^#/,"").length > 0) tmp.push("#" + this.settings.selected.replace(/^#/,""));
					}
					this.settings.selected = tmp;
				}

				if(obj && this.settings.data.async) {
					this.opened = Array();
					obj = this.get_node(obj);
					obj.find("li.open").each(function (i) { _this.opened.push("#" + this.id); });
					if(obj.hasClass("open")) this.close_branch(obj, true);
					if(obj.hasClass("leaf")) obj.removeClass("leaf");
					obj.children("ul:eq(0)").html("");
					return this.open_branch(obj, true, function () { _this.reselect.apply(_this); });
				}

				var cls = "tree-default";
				if(this.settings.ui.theme_name != "default") cls += " tree-" + _this.settings.ui.theme_name;
				if(this.settings.ui.theme_name == "themeroller") cls = "tree-themeroller";

				if(this.settings.data.type == "xml_flat" || this.settings.data.type == "xml_nested") {
					this.scrtop = this.container.get(0).scrollTop;
					var xsl = (this.settings.data.type == "xml_flat") ? "flat.xsl" : "nested.xsl";
					if(this.settings.data.xml)	this.container.getTransform(this.path + xsl, this.settings.data.xml, { params : { theme_name : cls, theme_path : _this.theme }, meth : _this.settings.data.method, dat : _this.settings.data.async_data.apply(_this,[obj]) ,callback: function () { _this.context_menu.apply(_this); _this.reselect.apply(_this); } });
					else						this.container.getTransform(this.path + xsl, this.settings.data.url, { params : { theme_name : cls, theme_path : _this.theme }, meth : _this.settings.data.method, dat : _this.settings.data.async_data.apply(_this,[obj]) ,callback: function () { _this.context_menu.apply(_this); _this.reselect.apply(_this); } });
					return;
				}
				else if(this.settings.data.type == "json") {
					if(this.settings.data.json) {
						var str = "";
						if(this.settings.data.json.length) {
							for(var i = 0; i < this.settings.data.json.length; i++) {
								str += this.parseJSON(this.settings.data.json[i]);
							}
						} else str = this.parseJSON(this.settings.data.json);
						this.container.html("<ul class='" + cls + "'>" + str + "</ul>");
						this.container.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");
						this.container.find("li").not(".open").not(".closed").addClass("leaf");
						this.context_menu();
						this.reselect();
					}
					else {
						var _this = this;
						$.ajax({
						    type        : this.settings.data.method,
							url         : this.settings.data.url, 
							data		: this.settings.data.async_data(false),
							dataType    : "json",
							success		: function (data) {
								data = _this.settings.callback.onJSONdata.call(null, data, _this);
								var str = "";
								if(data.length) {
									for(var i = 0; i < data.length; i++) {
										str += _this.parseJSON(data[i]);
									}
								} else str = _this.parseJSON(data);
								_this.container.html("<ul class='" + cls + "'>" + str + "</ul>");
								_this.container.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");
								_this.container.find("li").not(".open").not(".closed").addClass("leaf");
								_this.context_menu.apply(_this);
								_this.reselect.apply(_this);
				            },
							error : function (xhttp, textStatus, errorThrown) { _this.error(errorThrown + " " + textStatus); }
						});
					}
				}
				else {
					this.container.children("ul:eq(0)").attr("class", cls);
					this.container.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");
					this.container.find("li").not(".open").not(".closed").addClass("leaf");
					this.reselect();
				}
			},
			// CONVERT JSON TO HTML
			parseJSON : function (data) {
				if(!data || !data.data) return "";
				var str = "";
				str += "<li ";
				var cls = false;
				if(data.attributes) {
					for(var i in data.attributes) {
						if(i == "class") {
							str += " class='" + data.attributes[i] + " ";
							if(data.state == "closed" || data.state == "open") str += " " + data.state + " ";
							str += "' ";
							cls = true;
						}
						else str += " " + i + "='" + data.attributes[i] + "' ";
					}
				}
				if(!cls && (data.state == "closed" || data.state == "open")) str += " class='" + data.state + "' ";
				str += ">";
				if(this.settings.languages.length) {
					for(var i = 0; i < this.settings.languages.length; i++) {
						var attr = {};
						attr["href"] = "#";
						attr["style"] = "";
						attr["class"] = this.settings.languages[i];
						if(data.data[this.settings.languages[i]] && (typeof data.data[this.settings.languages[i]].attributes).toLowerCase() != "undefined") {
							for(var j in data.data[this.settings.languages[i]].attributes) {
								if(j == "style" || j == "class")	attr[j] += " " + data.data[this.settings.languages[i]].attributes[j];
								else								attr[j]  = data.data[this.settings.languages[i]].attributes[j];
							}
						}
						if(data.data[this.settings.languages[i]] && data.data[this.settings.languages[i]].icon && this.settings.theme_name != "themeroller") {
							var icn = data.data[this.settings.languages[i]].icon.indexOf("/") == -1 ? this.theme + data.data[this.settings.languages[i]].icon : data.data[this.settings.languages[i]].icon;
							attr["style"] += " ; background-image:url('" + icn + "'); ";
						}
						str += "<a";
						for(var j in attr) str += ' ' + j + '="' + attr[j] + '" ';
						str += ">";
						if(data.data[this.settings.languages[i]] && data.data[this.settings.languages[i]].icon && this.settings.theme_name == "themeroller") {
							str += "<ins class='ui-icon " + data.data[this.settings.languages[i]].icon + "'>&nbsp;</ins>";
						}
						str += ( (typeof data.data[this.settings.languages[i]].title).toLowerCase() != "undefined" ? data.data[this.settings.languages[i]].title : data.data[this.settings.languages[i]] ) + "</a>";
					}
				}
				else {
					var attr = {};
					attr["href"] = "#";
					attr["style"] = "";
					attr["class"] = "";
					if((typeof data.data.attributes).toLowerCase() != "undefined") {
						for(var i in data.data.attributes) {
							if(i == "style" || i == "class")	attr[i] += " " + data.data.attributes[i];
							else								attr[i]  = data.data.attributes[i];
						}
					}
					if(data.data.icon && this.settings.ui.theme_name != "themeroller") {
						var icn = data.data.icon.indexOf("/") == -1 ? this.theme + data.data.icon : data.data.icon;
						attr["style"] += " ; background-image:url('" + icn + "');";
					}
					str += "<a";
					for(var i in attr) str += ' ' + i + '="' + attr[i] + '" ';
					str += ">";
					if(data.data.icon && this.settings.ui.theme_name == "themeroller") {
						str += "<ins class='ui-icon " + data.data.icon + "'>&nbsp;</ins>";
					}
					str += ( (typeof data.data.title).toLowerCase() != "undefined" ? data.data.title : data.data ) + "</a>";
				}
				if(data.children && data.children.length) {
					str += '<ul>';
					for(var i = 0; i < data.children.length; i++) {
						str += this.parseJSON(data.children[i]);
					}
					str += '</ul>';
				}
				str += "</li>";
				return str;
			},
			// getJSON from HTML
			getJSON : function (nod, outer_attrib, inner_attrib, force) {
				var _this = this;
				if(!nod || $(nod).size() == 0) {
					nod = this.container.children("ul").children("li");
				}
				else nod = $(nod);

				if(nod.size() > 1) {
					var arr = [];
					nod.each(function () {
						arr.push(_this.getJSON(this, outer_attrib, inner_attrib, force));
					});
					return arr;
				}

				if(!outer_attrib) outer_attrib = [ "id", "rel", "class" ];
				if(!inner_attrib) inner_attrib = [ ];
				var obj = { attributes : {}, data : false };
				for(var i in outer_attrib) {
					var val = (outer_attrib[i] == "class") ? nod.attr(outer_attrib[i]).replace("last","").replace("leaf","").replace("closed","").replace("open","") : nod.attr(outer_attrib[i]);
					if(typeof val != "undefined" && val.replace(" ","").length > 0) obj.attributes[outer_attrib[i]] = val;
					delete val;
				}
				if(this.settings.languages.length) {
					obj.data = {};
					for(var i in this.settings.languages) {
						var a = nod.children("a." + this.settings.languages[i]);
						if(force || inner_attrib.length || a.get(0).style.backgroundImage.toString().length) {
							obj.data[this.settings.languages[i]] = {};
							obj.data[this.settings.languages[i]].title = a.text();
							if(a.get(0).style.backgroundImage.length) {
								obj.data[this.settings.languages[i]].icon = a.get(0).style.backgroundImage.replace("url(","").replace(")","");
							}
							if(this.settings.ui.theme_name == "themeroller" && a.children("ins").size()) {
								var tmp = a.children("ins").attr("class");
								var cls = false;
								$.each(tmp.split(" "), function (i, val) {
									if(val.indexOf("ui-icon-") == 0) {
										cls = val;
										return false;
									}
								});
								if(cls) obj.data[this.settings.languages[i]].icon = cls;
							}
							if(inner_attrib.length) {
								obj.data[this.settings.languages[i]].attributes = {};
								for(var j in inner_attrib) {
									var val = a.attr(inner_attrib[j]);
									if(typeof val != "undefined" && val.replace(" ","").length > 0) obj.data[this.settings.languages[i]].attributes[inner_attrib[j]] = val;
									delete val;
								}
							}
						}
						else {
							obj.data[this.settings.languages[i]] = a.text();
						}
					}
				}
				else {
					var a = nod.children("a");
					if(force || inner_attrib.length || a.get(0).style.backgroundImage.toString().length) {
						obj.data = {};
						obj.data.title = a.text();
						if(a.get(0).style.backgroundImage.length) {
							obj.data.icon = a.get(0).style.backgroundImage.replace("url(","").replace(")","");
						}
						if(this.settings.ui.theme_name == "themeroller" && a.children("ins").size()) {
							var tmp = a.children("ins").attr("class");
							var cls = false;
							$.each(tmp.split(" "), function (i, val) {
								if(val.indexOf("ui-icon-") == 0) {
									cls = val;
									return false;
								}
							});
							if(cls) obj.data[this.settings.languages[i]].icon = cls;
						}
						if(inner_attrib.length) {
							obj.data.attributes = {};
							for(var j in inner_attrib) {
								var val = a.attr(inner_attrib[j]);
								if(typeof val != "undefined" && val.replace(" ","").length > 0) obj.data.attributes[inner_attrib[j]] = val;
								delete val;
							}
						}
					}
					else {
						obj.data = a.text();
					}
				}

				if(nod.children("ul").size() > 0) {
					obj.children = [];
					nod.children("ul").children("li").each(function () {
						obj.children.push(_this.getJSON(this, outer_attrib, inner_attrib, force));
					});
				}
				return obj;
			},
			// getXML from HTML
			getXML : function (tp, nod, outer_attrib, inner_attrib, cb) {
				var _this = this;
				if(tp != "flat") tp = "nested";
				if(!nod || $(nod).size() == 0) {
					nod = this.container.children("ul").children("li");
				}
				else nod = $(nod);

				if(nod.size() > 1) {
					var obj = '<root>';
					nod.each(function () {
						obj += _this.getXML(tp, this, outer_attrib, inner_attrib, true);
					});
					obj += '</root>';
					return obj;
				}

				if(!outer_attrib) outer_attrib = [ "id", "rel", "class" ];
				if(!inner_attrib) inner_attrib = [ ];
				var obj = '';

				if(!cb) obj = '<root>';

				obj += '<item ';
				
				if(tp == "flat") {
					var tmp_id = nod.parents("li:eq(0)").size() ? nod.parents("li:eq(0)").attr("id") : 0;
					obj += ' parent_id="' + tmp_id + '" ';
					delete tmp_id;
				}
				for(var i in outer_attrib) {
					var val = (outer_attrib[i] == "class") ? nod.attr(outer_attrib[i]).replace("last","").replace("leaf","").replace("closed","").replace("open","") : nod.attr(outer_attrib[i]);
					if(typeof val != "undefined" && val.replace(" ","").length > 0) obj += ' ' + outer_attrib[i] + '="' + val + '" ';
					delete val;
				}
				obj += '>';

				obj += '<content>';
				if(this.settings.languages.length) {
					for(var i in this.settings.languages) {
						var a = nod.children("a." + this.settings.languages[i]);
						obj += '<name ';
						if(inner_attrib.length || a.get(0).style.backgroundImage.toString().length || this.settings.ui.theme_name == "themeroller") {
							if(a.get(0).style.backgroundImage.length) {
								obj += ' icon="' + a.get(0).style.backgroundImage.replace("url(","").replace(")","") + '" ';
							}
							if(this.settings.ui.theme_name == "themeroller" && a.children("ins").size()) {
								var tmp = a.children("ins").attr("class");
								var cls = false;
								$.each(tmp.split(" "), function (i, val) {
									if(val.indexOf("ui-icon-") == 0) {
										cls = val;
										return false;
									}
								});
								if(cls) obj += ' icon="' + cls + '" ';
							}
							if(inner_attrib.length) {
								for(var j in inner_attrib) {
									var val = a.attr(inner_attrib[j]);
									if(typeof val != "undefined" && val.replace(" ","").length > 0) obj += ' ' + inner_attrib[j] + '="' + val + '" ';
									delete val;
								}
							}
						}
						obj += '><![CDATA[' + a.text() + ']]></name>';
					}
				}
				else {
					var a = nod.children("a");
					obj += '<name ';
					if(inner_attrib.length || a.get(0).style.backgroundImage.toString().length || this.settings.ui.theme_name == "themeroller") {
						if(a.get(0).style.backgroundImage.length) {
							obj += ' icon="' + a.get(0).style.backgroundImage.replace("url(","").replace(")","") + '" ';
						}
						if(this.settings.ui.theme_name == "themeroller" && a.children("ins").size()) {
							var tmp = a.children("ins").attr("class");
							var cls = false;
							$.each(tmp.split(" "), function (i, val) {
								if(val.indexOf("ui-icon-") == 0) {
									cls = val;
									return false;
								}
							});
							if(cls) obj += ' icon="' + cls + '" ';
						}
						if(inner_attrib.length) {
							for(var j in inner_attrib) {
								var val = a.attr(inner_attrib[j]);
								if(typeof val != "undefined" && val.replace(" ","").length > 0) obj += ' ' + inner_attrib[j] + '="' + val + '" ';
								delete val;
							}
						}
					}
					obj += '><![CDATA[' + a.text() + ']]></name>';
				}
				obj += '</content>';

				if(tp == "flat") obj += '</item>';

				if(nod.children("ul").size() > 0) {
					nod.children("ul").children("li").each(function () {
						obj += _this.getXML(tp, this, outer_attrib, inner_attrib, true);
					});
				}

				if(tp == "nested") obj += '</item>';

				if(!cb) obj += '</root>';
				return obj;
			},
			focus : function () {
				if(this.locked) return false;
				if(tree_component.focused != this.cntr) {
					tree_component.focused = this.cntr;
					this.settings.callback.onfocus.call(null, this);
				}
			},
			show_context : function (obj, x, y) {
				var tmp = this.context.show().offsetParent();
				if(tmp.is("html")) tmp = $("body");
				tmp = tmp.offset();
				this.context.css({ "left" : (x - tmp.left - (this.settings.ui.rtl ? $(this.context).width() : 0 ) ), "top" : (y - tmp.top  + ($.browser.opera ? this.container.scrollTop() : 0) + 0) });
			},
			hide_context : function () {
				if(this.context.remove && this.context.apply_to) this.context.apply_to.children("a").removeClass("clicked");
				this.context.apply_to = false;
				this.context.hide();
			},
			// ALL EVENTS
			attachEvents : function () {
				var _this = this;

				this.container
					.bind("mousedown", function (event) {
						if(tree_component.drag_drop.isdown) {
							tree_component.drag_drop.move_type = false;
							event.preventDefault();
							event.stopPropagation();
							event.stopImmediatePropagation();
							return false;
						}
					})
					.bind("mouseup", function (event) {
						setTimeout( function() { _this.focus.apply(_this); }, 5);
					})
					.bind("click", function (event) { 
						//event.stopPropagation(); 
						return true;
					});
				$("#" + this.container.attr("id") + " li")
					.live("click", function(event) { // WHEN CLICK IS ON THE ARROW
						if(event.target.tagName != "LI") return true;
						_this.off_height();
						if(event.pageY - $(event.target).offset().top > _this.li_height) return true;
						_this.toggle_branch.apply(_this, [event.target]);
						event.stopPropagation();
						return false;
					});
				$("#" + this.container.attr("id") + " li a")
					.live("click", function (event) { // WHEN CLICK IS ON THE TEXT OR ICON
						if(event.which && event.which == 3) return true;
						if(_this.locked) {
							event.preventDefault(); 
							event.target.blur();
							return _this.error("LOCKED");
						}
						_this.select_branch.apply(_this, [event.target, event.ctrlKey || _this.settings.rules.multiple == "on"]);
						if(_this.inp) { _this.inp.blur(); }
						event.preventDefault(); 
						event.target.blur();
						return false;
					})
					.live("dblclick", function (event) { // WHEN DOUBLECLICK ON TEXT OR ICON
						if(_this.locked) {
							event.preventDefault(); 
							event.stopPropagation();
							event.target.blur();
							return _this.error("LOCKED");
						}
						_this.settings.callback.ondblclk.call(null, _this.get_node(event.target).get(0), _this);
						event.preventDefault(); 
						event.stopPropagation();
						event.target.blur();
					})
					.live("contextmenu", function (event) {
						if(_this.locked) {
							event.target.blur();
							return _this.error("LOCKED");
						}
						var val = _this.settings.callback.onrgtclk.call(null, _this.get_node(event.target).get(0), _this, event);
						if(_this.context) {
							if(_this.context.append == false) {
								$("body").append(_this.context);
								_this.context.append = true;
								for(var i in _this.settings.ui.context) {
									if(typeof _this.settings.ui.context[i] == "function") continue;
									if(_this.settings.ui.context[i] == "separator") continue;
									(function () {
										var func = _this.settings.ui.context[i].action;
										_this.context.children("[rel=" + _this.settings.ui.context[i].id +"]")
											.bind("click", function (event) {
												if(!$(this).hasClass("disabled")) {
													func.call(null, _this.context.apply_to || null, _this);
													_this.hide_context();
												}
												event.stopPropagation();
												event.preventDefault();
												return false;
											})
											.bind("mouseup", function (event) {
												this.blur();
												if($(this).hasClass("disabled")) {
													event.stopPropagation();
													event.preventDefault();
													return false;
												}
											})
											.bind("mousedown", function (event) {
												event.stopPropagation();
												event.preventDefault();
											});
									})();
								}
							}
							var obj = _this.get_node(event.target);
							if(_this.inp) { _this.inp.blur(); }
							if(obj) {
								if(!obj.children("a:eq(0)").hasClass("clicked")) {
									// _this.select_branch.apply(_this, [event.target, event.ctrlKey || _this.settings.rules.multiple == "on"]);
									_this.context.apply_to = obj;
									_this.context.remove = true;
									_this.context.apply_to.children("a").addClass("clicked");
									event.target.blur();
								}
								else { _this.context.remove = false; _this.context.apply_to = _this.selected_arr || _this.selected; }

								_this.context.children("a").removeClass("disabled").show();
								var go = false;
								for(var i in _this.settings.ui.context) {
									if(typeof _this.settings.ui.context[i] == "function") continue;
									if(_this.settings.ui.context[i] == "separator") continue;
									var state = _this.settings.ui.context[i].visible.call(null, _this.context.apply_to, _this);
									if(state === false)	_this.context.children("[rel=" + _this.settings.ui.context[i].id +"]").addClass("disabled");
									if(state === -1)	_this.context.children("[rel=" + _this.settings.ui.context[i].id +"]").hide();
									else				go = true;
								}
								if(go == true) _this.show_context(obj, event.pageX, event.pageY);
								event.preventDefault(); 
								event.stopPropagation();
								return false;
							}
						}
						return val;
					})
					.live("mouseover", function (event) {
						if(_this.locked) {
							event.preventDefault();
							event.stopPropagation();
							return _this.error("LOCKED");
						}
						if( (_this.settings.ui.hover_mode || _this.settings.ui.theme_name == "themeroller" ) && _this.hovered !== false && event.target.tagName == "A") {
							_this.hovered.children("a").removeClass("hover ui-state-hover");
							_this.hovered = false;
						}
						if(_this.settings.ui.theme_name == "themeroller") {
							_this.hover_branch.apply(_this, [event.target]);
						}
					});
				if(_this.settings.ui.theme_name == "themeroller") {
					$("#" + this.container.attr("id") + " li a").live("mouseout", function (event) {
						if(_this.hovered) _this.hovered.children("a").removeClass("hover ui-state-hover");
					});
				}

				// ATTACH DRAG & DROP ONLY IF NEEDED
				if(this.settings.rules.draggable != "none") {
					$("#" + this.container.attr("id") + " li a")
						.live("mousedown", function (event) {
							if(_this.settings.rules.drag_button == "left" && event.which && event.which != 1)	return false;
							if(_this.settings.rules.drag_button == "right" && event.which && event.which != 3)	return false;
							_this.focus.apply(_this);
							if(_this.locked) return _this.error("LOCKED");
							// SELECT LIST ITEM NODE
							var obj = _this.get_node(event.target);
							// IF ITEM IS DRAGGABLE
							if(_this.settings.rules.multiple != false && _this.selected_arr.length > 1 && obj.children("a:eq(0)").hasClass("clicked")) {
								var counter = 0;
								for(var i in _this.selected_arr) {
									if(_this.check("draggable", _this.selected_arr[i])) {
										_this.selected_arr[i].addClass("dragged");
										tree_component.drag_drop.origin_tree = _this;
										counter ++;
									}
								}
								if(counter > 0) {
									if(_this.check("draggable", obj))	tree_component.drag_drop.drag_node = obj;
									else								tree_component.drag_drop.drag_node = _this.container.find("li.dragged:eq(0)");
									tree_component.drag_drop.isdown		= true;
									tree_component.drag_drop.drag_help	= $(tree_component.drag_drop.drag_node.get(0).cloneNode(true));
									tree_component.drag_drop.drag_help.attr("id","dragged");
									tree_component.drag_drop.drag_help.children("a").html("Multiple selection").end().children("ul").remove();
								}
							}
							else {
								if(_this.check("draggable", obj)) {
									tree_component.drag_drop.drag_node	= obj;
									tree_component.drag_drop.drag_help	= $(obj.get(0).cloneNode(true));
									tree_component.drag_drop.drag_help.attr("id","dragged");
									tree_component.drag_drop.isdown		= true;
									tree_component.drag_drop.foreign	= false;
									tree_component.drag_drop.origin_tree = _this;
									obj.addClass("dragged");
								}
							}
							tree_component.drag_drop.init_x = event.pageX;
							tree_component.drag_drop.init_y = event.pageY;
							obj.blur();
							event.preventDefault(); 
							event.stopPropagation();
							return false;
						});
					$(document)
						.bind("mousedown",	tree_component.mousedown)
						.bind("mouseup",	tree_component.mouseup)
						.bind("mousemove",	tree_component.mousemove);
				} 
				// ENDIF OF DRAG & DROP FUNCTIONS
				if(_this.context) $(document).bind("mousedown", function() { _this.hide_context(); });
			},
			checkMove : function (NODES, REF_NODE, TYPE) {
				if(this.locked) return this.error("LOCKED");
				var _this = this;

				// OVER SELF OR CHILDREN
				if(REF_NODE.parents("li.dragged").size() > 0 || REF_NODE.is(".dragged")) return this.error("MOVE: NODE OVER SELF");
				// CHECK AGAINST DRAG_RULES
				if(NODES.size() == 1) {
					var NODE = NODES.eq(0);
					if(tree_component.drag_drop.foreign) {
						if(this.settings.rules.droppable.length == 0) return false;
						if(!NODE.is("." + this.settings.rules.droppable.join(", ."))) return false;
						var ok = false;
						for(var i in this.settings.rules.droppable) {
							if(NODE.is("." + this.settings.rules.droppable[i])) {
								if(this.settings.rules.metadata) {
									$.metadata.setType("attr", this.settings.rules.metadata);
									NODE.attr(this.settings.rules.metadata, "type: '" + this.settings.rules.droppable[i] + "'");
								}
								else {
									NODE.attr(this.settings.rules.type_attr, this.settings.rules.droppable[i]);
								}
								ok = true;
								break;
							}
						}
						if(!ok) return false;
					}
					if(!this.check("dragrules", [NODE, TYPE, REF_NODE.parents("li:eq(0)")])) return this.error("MOVE: AGAINST DRAG RULES");
				}
				else {
					var ok = true;
					NODES.each(function (i) {
						if(ok == false) return false;
						//if(i > 0) {
						//	var ref = NODES.eq( (i - 1) );
						//	var mv = "after";
						//}
						//else {
							var ref = REF_NODE;
							var mv = TYPE;
						//}
						if(!_this.check.apply(_this,["dragrules", [$(this), mv, ref]])) ok = false;
					});
					if(ok == false) return this.error("MOVE: AGAINST DRAG RULES");
				}
				// CHECK AGAINST METADATA
				if(this.settings.rules.use_inline && this.settings.rules.metadata) {
					var nd = false;
					if(TYPE == "inside")	nd = REF_NODE.parents("li:eq(0)");
					else					nd = REF_NODE.parents("li:eq(1)");
					if(nd.size()) {
						// VALID CHILDREN CHECK
						if(typeof nd.metadata()["valid_children"] != "undefined") {
							var tmp = nd.metadata()["valid_children"];
							var ok = true;
							NODES.each(function (i) {
								if(ok == false) return false;
								if($.inArray(_this.get_type(this), tmp) == -1) ok = false;
							});
							if(ok == false) return this.error("MOVE: NOT A VALID CHILD");
						}
						// CHECK IF PARENT HAS FREE SLOTS FOR CHILDREN
						if(typeof nd.metadata()["max_children"] != "undefined") {
							if((nd.children("ul:eq(0)").children("li").not(".dragged").size() + NODES.size()) > nd.metadata().max_children) return this.error("MOVE: MAX CHILDREN REACHED");
						}
						// CHECK FOR MAXDEPTH UP THE CHAIN
						var incr = 0;
						NODES.each(function (j) {
							var i = 1;
							var t = $(this);
							while(i < 100) {
								t = t.children("ul").children("li");
								if(t.size() == 0) break;
								i ++
							}
							incr = Math.max(i,incr);
						});
						var ok = true;

						if((typeof $(nd).metadata().max_depth).toLowerCase() != "undefined" && $(nd).metadata().max_depth < incr) ok = false;
						else {
							nd.parents("li").each(function(i) {
								if(ok == false) return false;
								if((typeof $(this).metadata().max_depth).toLowerCase() != "undefined") {
									if( (i + incr) >= $(this).metadata().max_depth) ok = false;
								}
							});
						}
						if(ok == false) return this.error("MOVE: MAX_DEPTH REACHED");
					}
				}
				return true;
			},
			// USED AFTER REFRESH
			reselect : function () {
				var _this = this;
				// REOPEN BRANCHES
				if(this.opened && this.opened.length) {
					var opn = false;
					for(var j = 0; j < this.opened.length; j++) {
						if(this.settings.data.async) {
							if(this.get_node(this.opened[j]).size() > 0) {
								opn = true;
								var tmp = this.opened[j];
								delete this.opened[j];
								this.open_branch(tmp, true, function () { _this.reselect.apply(_this); } );
								break;
							}
						}
						else this.open_branch(this.opened[j], true);
					}
					if(this.settings.data.async && opn) return;
					delete this.opened;
				}
				// REPOSITION SCROLL
				if(this.scrtop) {
					this.container.scrollTop(_this.scrtop);
					delete this.scrtop;
				}
				// RESELECT PREVIOUSLY SELECTED
				if(this.settings.selected !== false) {
					$.each(this.settings.selected, function (i) {
						_this.select_branch($(_this.settings.selected[i], _this.container), (_this.settings.rules.multiple !== false && i > 0) );
					});
					this.settings.selected = false;
				}
				if(this.settings.ui.theme_name == "themeroller") this.container.find("a").addClass("ui-state-default");
				this.settings.callback.onload.call(null, _this);
			},
			// GET THE EXTENDED LI ELEMENT
			get_node : function (obj) {
				var obj = $(obj);
				return obj.is("li") ? obj : obj.parents("li:eq(0)");
			},
			// GET THE TYPE OF THE NODE
			get_type : function (obj) {
				obj = !obj ? this.selected : this.get_node(obj);
				if(!obj) return;
				if(this.settings.rules.metadata) {
					$.metadata.setType("attr", this.settings.rules.metadata);
					var tmp = obj.metadata().type;
					if(tmp) return tmp;
				} 
				return obj.attr(this.settings.rules.type_attr);
			},
			// SCROLL CONTAINER WHILE DRAGGING
			scrollCheck : function (x,y) { 
				var _this = this;
				var cnt = _this.container;
				var off = _this.container.offset();

				var st = cnt.scrollTop();
				var sl = cnt.scrollLeft();
				// DETECT HORIZONTAL SCROLL
				var h_cor = (cnt.get(0).scrollWidth > cnt.width()) ? 40 : 20;

				if(y - off.top < 20)						cnt.scrollTop(Math.max( (st - _this.settings.ui.scroll_spd) ,0));	// NEAR TOP
				if(cnt.height() - (y - off.top) < h_cor)	cnt.scrollTop(st + _this.settings.ui.scroll_spd);					// NEAR BOTTOM
				if(x - off.left < 20)						cnt.scrollLeft(Math.max( (sl - _this.settings.ui.scroll_spd),0));	// NEAR LEFT
				if(cnt.width() - (x - off.left) < 40)		cnt.scrollLeft(sl + _this.settings.ui.scroll_spd);					// NEAR RIGHT

				if(cnt.scrollLeft() != sl || cnt.scrollTop() != st) {
					_this.moveType = false;
					_this.moveRef = false;
					tree_component.drag_drop.marker.hide();
				}
				tree_component.drag_drop.scroll_time = setTimeout( function() { _this.scrollCheck(x,y); }, 50);
			},
			check : function (rule, nodes) {
				if(this.locked) return this.error("LOCKED");
				// CHECK LOCAL RULES IF METADATA
				if(rule != "dragrules" && this.settings.rules.use_inline && this.settings.rules.metadata) {
					$.metadata.setType("attr", this.settings.rules.metadata);
					if(typeof this.get_node(nodes).metadata()[rule] != "undefined") return this.get_node(nodes).metadata()[rule];
				}
				if(!this.settings.rules[rule])			return false;
				if(this.settings.rules[rule] == "none")	return false;
				if(this.settings.rules[rule] == "all")	return true;

				if(rule == "dragrules") {
					var nds = new Array();
					nds[0] = this.get_type(nodes[0]);
					nds[1] = nodes[1];
					nds[2] = this.get_type(nodes[2]);
					for(var i = 0; i < this.settings.rules.dragrules.length; i++) {
						var r = this.settings.rules.dragrules[i];
						var n = (r.indexOf("!") === 0) ? false : true;
						if(!n) r = r.replace("!","");
						var tmp = r.split(" ");
						for(var j = 0; j < 3; j++) {
							if(tmp[j] == nds[j] || tmp[j] == "*") tmp[j] = true;
						}
						if(tmp[0] === true && tmp[1] === true && tmp[2] === true) return n;
					}
					return false;
				}
				else 
					return ($.inArray(this.get_type(nodes),this.settings.rules[rule]) != -1) ? true : false;
			},
			hover_branch : function (obj) {
				if(this.locked) return this.error("LOCKED");
				if(this.settings.ui.hover_mode == false && this.settings.theme_name != "themeroller") return this.select_branch(obj);
				var _this = this;
				var obj = _this.get_node(obj);
				if(!obj.size()) return this.error("HOVER: NOT A VALID NODE");
				// CHECK AGAINST RULES FOR SELECTABLE NODES
				if(!_this.check("clickable", obj)) return this.error("SELECT: NODE NOT SELECTABLE");
				if(this.hovered) this.hovered.children("A").removeClass("hover ui-state-hover");

				// SAVE NEWLY SELECTED
				this.hovered = obj;

				// FOCUS NEW NODE AND OPEN ALL PARENT NODES IF CLOSED
				this.hovered.children("a").removeClass("hover ui-state-hover").addClass( this.settings.ui.theme_name == "themeroller" ? "hover ui-state-hover" : "hover");

				// SCROLL SELECTED NODE INTO VIEW
				var off_t = this.hovered.offset().top;
				var beg_t = this.container.offset().top;
				var end_t = beg_t + this.container.height();
				var h_cor = (this.container.get(0).scrollWidth > this.container.width()) ? 40 : 20;
				if(off_t + 5 < beg_t) this.container.scrollTop(this.container.scrollTop() - (beg_t - off_t + 5) );
				if(off_t + h_cor > end_t) this.container.scrollTop(this.container.scrollTop() + (off_t + h_cor - end_t) );
			},
			select_branch : function (obj, multiple) {
				if(this.locked) return this.error("LOCKED");
				if(!obj && this.hovered !== false) obj = this.hovered;
				var _this = this;
				obj = _this.get_node(obj);
				if(!obj.size()) return this.error("SELECT: NOT A VALID NODE");
				obj.children("a").removeClass("hover ui-state-hover");
				// CHECK AGAINST RULES FOR SELECTABLE NODES
				if(!_this.check("clickable", obj)) return this.error("SELECT: NODE NOT SELECTABLE");
				if(_this.settings.callback.beforechange.call(null,obj.get(0),_this) === false) return this.error("SELECT: STOPPED BY USER");
				// IF multiple AND obj IS ALREADY SELECTED - DESELECT IT
				if(this.settings.rules.multiple != false && multiple && obj.children("a.clicked").size() > 0) {
					return this.deselect_branch(obj);
				}
				if(this.settings.rules.multiple != false && multiple) {
					this.selected_arr.push(obj);
				}
				if(this.settings.rules.multiple != false && !multiple) {
					for(var i in this.selected_arr) {
						this.selected_arr[i].children("A").removeClass("clicked ui-state-active");
						this.settings.callback.ondeselect.call(null, this.selected_arr[i].get(0), _this);
					}
					this.selected_arr = [];
					this.selected_arr.push(obj);
					if(this.selected && this.selected.children("A").hasClass("clicked")) {
						this.selected.children("A").removeClass("clicked ui-state-active");
						this.settings.callback.ondeselect.call(null, this.selected.get(0), _this);
					}
				}
				if(!this.settings.rules.multiple) {
					if(this.selected) {
						this.selected.children("A").removeClass("clicked ui-state-active");
						this.settings.callback.ondeselect.call(null, this.selected.get(0), _this);
					}
				}
				// SAVE NEWLY SELECTED
				this.selected = obj;
				if( (this.settings.ui.hover_mode || this.settings.ui.theme_name == "themeroller") && this.hovered !== false) {
					this.hovered.children("A").removeClass("hover ui-state-hover");
					this.hovered = obj;
				}

				// FOCUS NEW NODE AND OPEN ALL PARENT NODES IF CLOSED
				this.selected.children("a").removeClass("clicked ui-state-active").addClass( this.settings.ui.theme_name == "themeroller" ? "clicked ui-state-active" : "clicked").end().parents("li.closed").each( function () { _this.open_branch(this, true); });

				// SCROLL SELECTED NODE INTO VIEW
				var off_t = this.selected.offset().top;
				var beg_t = this.container.offset().top;
				var end_t = beg_t + this.container.height();
				var h_cor = (this.container.get(0).scrollWidth > this.container.width()) ? 40 : 20;
				if(off_t + 5 < beg_t) this.container.scrollTop(this.container.scrollTop() - (beg_t - off_t + 5) );
				if(off_t + h_cor > end_t) this.container.scrollTop(this.container.scrollTop() + (off_t + h_cor - end_t) );

				this.set_cookie("selected");
				this.settings.callback.onselect.call(null, this.selected.get(0), _this);
				this.settings.callback.onchange.call(null, this.selected.get(0), _this);
			},
			deselect_branch : function (obj) {
				if(this.locked) return this.error("LOCKED");
				var _this = this;
				var obj = this.get_node(obj);
				obj.children("a").removeClass("clicked ui-state-active");
				this.settings.callback.ondeselect.call(null, obj.get(0), _this);
				if(this.settings.rules.multiple != false && this.selected_arr.length > 1) {
					this.selected_arr = [];
					this.container.find("a.clicked").filter(":first-child").parent().each(function () {
						_this.selected_arr.push($(this));
					});
					if(obj.get(0) == this.selected.get(0)) {
						this.selected = this.selected_arr[0];
						this.set_cookie("selected");
					}
				}
				else {
					if(this.settings.rules.multiple != false) this.selected_arr = [];
					this.selected = false;
					this.set_cookie("selected");
				}
				if(this.selected)	this.settings.callback.onchange.call(null, this.selected.get(0), _this);
				else				this.settings.callback.onchange.call(null, false, _this);
			},
			toggle_branch : function (obj) {
				if(this.locked) return this.error("LOCKED");
				var obj = this.get_node(obj);
				if(obj.hasClass("closed"))	return this.open_branch(obj);
				if(obj.hasClass("open"))	return this.close_branch(obj); 
			},
			open_branch : function (obj, disable_animation, callback) {
				if(this.locked) return this.error("LOCKED");
				var obj = this.get_node(obj);
				if(!obj.size()) return this.error("OPEN: NO SUCH NODE");
				if(obj.hasClass("leaf")) return this.error("OPEN: OPENING LEAF NODE");

				if(this.settings.data.async && obj.find("li").size() == 0) {
					if(this.settings.callback.beforeopen.call(null,obj.get(0),this) === false) return this.error("OPEN: STOPPED BY USER");
					var _this = this;
					obj.children("ul:eq(0)").remove().end().append("<ul><li class='last'><a class='loading' href='#'>" + (_this.settings.lang.loading || "Loading ...") + "</a></li></ul>");
					obj.removeClass("closed").addClass("open");
					if(this.settings.data.type == "xml_flat" || this.settings.data.type == "xml_nested") {
						var xsl = (this.settings.data.type == "xml_flat") ? "flat.xsl" : "nested.xsl";
						obj.children("ul:eq(0)").getTransform(this.path + xsl, this.settings.data.url, { params : { theme_path : _this.theme }, meth : this.settings.data.method, dat : this.settings.data.async_data(obj), repl : true, callback: function (str, json) { 
								if(str.length < 15) {
									obj.removeClass("closed").removeClass("open").addClass("leaf").children("ul").remove();
									if(callback) callback.call();
									return;
								}
								_this.open_branch.apply(_this, [obj]); 
								if(callback) callback.call();
							} 
						});
					}
					else {
						$.ajax({
							type		: this.settings.data.method,
							url			: this.settings.data.url, 
							data		: this.settings.data.async_data(obj), 
							dataType	: "json",
							success		: function (data, textStatus) {
								data = _this.settings.callback.onJSONdata.call(null, data, _this);
								if(!data || data.length == 0) {
									obj.removeClass("closed").removeClass("open").addClass("leaf").children("ul").remove();
									if(callback) callback.call();
									return;
								}
								var str = "";
								if(data.length) {
									for(var i = 0; i < data.length; i++) {
										str += _this.parseJSON(data[i]);
									}
								}
								else str = _this.parseJSON(data);
								if(str.length > 0) {
									obj.children("ul:eq(0)").replaceWith("<ul>" + str + "</ul>");
									obj.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");
									obj.find("li").not(".open").not(".closed").addClass("leaf");
									_this.open_branch.apply(_this, [obj]);
								}
								else obj.removeClass("closed").removeClass("open").addClass("leaf").children("ul").remove();
								if(callback) callback.call();
							}
						});
					}
					return true;
				}
				else {
					if(!this.settings.data.async) {
						if(this.settings.callback.beforeopen.call(null,obj.get(0),this) === false) return this.error("OPEN: STOPPED BY USER");
					}
					if(this.settings.ui.theme_name == "themeroller") obj.find("a").not(".ui-state-default").addClass("ui-state-default");
					if(parseInt(this.settings.ui.animation) > 0 && !disable_animation ) {
						obj.children("ul:eq(0)").css("display","none");
						obj.removeClass("closed").addClass("open");
						obj.children("ul:eq(0)").slideDown(parseInt(this.settings.ui.animation), function() {
							$(this).css("display","");
							if(callback) callback.call();
						});
					} else {
						obj.removeClass("closed").addClass("open");
						if(callback) callback.call();
					}
					this.set_cookie("open");
					this.settings.callback.onopen.call(null, obj.get(0), this);
					return true;
				}
			},
			close_branch : function (obj, disable_animation) {
				if(this.locked) return this.error("LOCKED");
				var _this = this;
				var obj = this.get_node(obj);
				if(!obj.size()) return this.error("CLOSE: NO SUCH NODE");
				if(_this.settings.callback.beforeclose.call(null,obj.get(0),_this) === false) return this.error("CLOSE: STOPPED BY USER");
				if(parseInt(this.settings.ui.animation) > 0 && !disable_animation && obj.children("ul:eq(0)").size() == 1) {
					obj.children("ul:eq(0)").slideUp(parseInt(this.settings.ui.animation), function() {
						if(obj.hasClass("open")) obj.removeClass("open").addClass("closed");
						_this.set_cookie("open");
						$(this).css("display","");
					});
				} 
				else {
					if(obj.hasClass("open")) obj.removeClass("open").addClass("closed");
					this.set_cookie("open");
				}
				if(this.selected && obj.children("ul:eq(0)").find("a.clicked").size() > 0) {
					obj.find("li:has(a.clicked)").each(function() {
						_this.deselect_branch(this);
					});
					if(obj.children("a.clicked").size() == 0) this.select_branch(obj, (this.settings.rules.multiple != false && this.selected_arr.length > 0) );
				}
				this.settings.callback.onclose.call(null, obj.get(0), this);
			},
			open_all : function (obj, callback) {
				if(this.locked) return this.error("LOCKED");
				var _this = this;
				obj = obj ? $(obj) : this.container;

				var s = obj.find("li.closed").size();
				if(!callback)	this.cl_count = 0;
				else			this.cl_count --;
				if(s > 0) {
					this.cl_count += s;
					obj.find("li.closed").each( function () { var __this = this; _this.open_branch.apply(_this, [this, true, function() { _this.open_all.apply(_this, [__this, true]); } ]); });
				}
				else if(this.cl_count == 0) this.settings.callback.onopen_all.call(null,this);
			},
			close_all : function () {
				if(this.locked) return this.error("LOCKED");
				var _this = this;
				this.container.find("li.open").each( function () { _this.close_branch(this, true); });
			},
			show_lang : function (i) { 
				if(this.locked) return this.error("LOCKED");
				if(this.settings.languages[i] == this.current_lang) return true;
				var st = false;
				var id = this.container.attr("id") ? "#" + this.container.attr("id") : ".tree";
				st = get_css(id + " ." + this.current_lang, this.sn);
				if(st !== false) st.style.display = "none";
				st = get_css(id + " ." + this.settings.languages[i], this.sn);
				if(st !== false) st.style.display = "";
				this.current_lang = this.settings.languages[i];
				return true;
			},
			cycle_lang : function() {
				if(this.locked) return this.error("LOCKED");
				var i = $.inArray(this.current_lang, this.settings.languages);
				i ++;
				if(i > this.settings.languages.length - 1) i = 0;
				this.show_lang(i);
			},
			create : function (obj, ref_node, position) { 
				if(this.locked) return this.error("LOCKED");
				
				var root = false;
				if(ref_node == -1) { root = true; ref_node = this.container; }
				else ref_node = ref_node ? this.get_node(ref_node) : this.selected;

				if(!root && (!ref_node || !ref_node.size())) return this.error("CREATE: NO NODE SELECTED");

				var pos = position;

				var tmp = ref_node; // for type calculation
				if(position == "before") {
					position = ref_node.parent().children().index(ref_node);
					ref_node = ref_node.parents("li:eq(0)");
				}
				if(position == "after") {
					position = ref_node.parent().children().index(ref_node) + 1;
					ref_node = ref_node.parents("li:eq(0)");
				}
				if(!root && ref_node.size() == 0) { root = true; ref_node = this.container; }

				if(!root) {
					if(!this.check("creatable", ref_node)) return this.error("CREATE: CANNOT CREATE IN NODE");
					if(ref_node.hasClass("closed")) {
						if(this.settings.data.async && ref_node.children("ul").size() == 0) {
							var _this = this;
							return this.open_branch(ref_node, true, function () { _this.create.apply(_this, [obj, ref_node, position]); } );
						}
						else this.open_branch(ref_node, true);
					}
				}

				// creating new object to pass to parseJSON
				var torename = false; 
				if(!obj) obj = {};
				if(!obj.attributes) obj.attributes = {};
				if(this.settings.rules.metadata) {
					if(!obj.attributes[this.settings.rules.metadata]) obj.attributes[this.settings.rules.metadata] = '{ "type" : "' + (this.get_type(tmp) || "") + '" }';
				}
				else {
					if(!obj.attributes[this.settings.rules.type_attr]) obj.attributes[this.settings.rules.type_attr] = this.get_type(tmp) || "";
				}
				if(this.settings.languages.length) {
					if(!obj.data) { obj.data = {}; torename = true; }
					for(var i = 0; i < this.settings.languages.length; i++) {
						if(!obj.data[this.settings.languages[i]]) obj.data[this.settings.languages[i]] = ((typeof this.settings.lang.new_node).toLowerCase() != "string" && this.settings.lang.new_node[i]) ? this.settings.lang.new_node[i] : this.settings.lang.new_node;
					}
				}
				else {
					if(!obj.data) { obj.data = this.settings.lang.new_node; torename = true; }
				}

				var $li = $(this.parseJSON(obj));
				$li.addClass("leaf");

				if(!root && this.settings.rules.use_inline && this.settings.rules.metadata) {
					var t = this.get_type($li) || "";
					$.metadata.setType("attr", this.settings.rules.metadata);
					if(typeof ref_node.metadata()["valid_children"] != "undefined") {
						if($.inArray(t, ref_node.metadata()["valid_children"]) == -1) return this.error("CREATE: NODE NOT A VALID CHILD");
					}
					if(typeof ref_node.metadata()["max_children"] != "undefined") {
						if( (ref_node.children("ul:eq(0)").children("li").size() + 1) > ref_node.metadata().max_children) return this.error("CREATE: MAX_CHILDREN REACHED");
					}
					var ok = true;
					if((typeof $(ref_node).metadata().max_depth).toLowerCase() != "undefined" && $(ref_node).metadata().max_depth === 0) ok = false;
					else {
						ref_node.parents("li").each(function(i) {
							if($(this).metadata().max_depth) {
								if( (i + 1) >= $(this).metadata().max_depth) {
									ok = false;
									return false;
								}
							}
						});
					}
					if(!ok) return this.error("CREATE: MAX_DEPTH REACHED");
				}

				if((typeof position).toLowerCase() == "undefined" || position == "inside") 
					position = (this.settings.rules.createat == "top") ? 0 : ref_node.children("ul:eq(0)").children("li").size();
				if(ref_node.children("ul").size() == 0 || (root == true && ref_node.children("ul").children("li").size() == 0) ) {
					if(!root)	var a = this.moved($li,ref_node.children("a:eq(0)"),"inside", true);
					else		var a = this.moved($li,this.container.children("ul:eq(0)"),"inside", true);
				}
				else if(pos == "before" && ref_node.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").size())
					var a = this.moved($li,ref_node.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").children("a:eq(0)"),"before", true);
				else if(pos == "after" &&  ref_node.children("ul:eq(0)").children("li:nth-child(" + (position) + ")").size())
					var a = this.moved($li,ref_node.children("ul:eq(0)").children("li:nth-child(" + (position) + ")").children("a:eq(0)"),"after", true);
				else if(ref_node.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").size())
					var a = this.moved($li,ref_node.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").children("a:eq(0)"),"before", true);
				else
					var a = this.moved($li,ref_node.children("ul:eq(0)").children("li:last").children("a:eq(0)"),"after",true);

				if(a === false) return this.error("CREATE: ABORTED");

				this.select_branch($li.children("a:eq(0)"));
				if(torename) this.rename();
				return $li;
			},
			rename : function (obj) {
				if(this.locked) return this.error("LOCKED");
				obj = obj ? this.get_node(obj) : this.selected;
				var _this = this;
				if(!obj || !obj.size()) return this.error("RENAME: NO NODE SELECTED");
				if(!this.check("renameable", obj)) return this.error("RENAME: NODE NOT RENAMABLE");
				if(!this.settings.callback.beforerename.call(null,obj.get(0), _this.current_lang, _this)) return this.error("RENAME: STOPPED BY USER");

				obj.parents("li.closed").each(function () { _this.open_branch(this) });
				if(this.current_lang)	obj = obj.find("a." + this.current_lang).get(0);
				else					obj = obj.find("a:first").get(0);
				last_value = obj.innerHTML;
				_this.inp = $("<input type='text' autocomplete='off' />");
				_this.inp
					.val(last_value.replace(/&amp;/g,"&").replace(/&gt;/g,">").replace(/&lt;/g,"<"))
					.bind("mousedown",		function (event) { event.stopPropagation(); })
					.bind("mouseup",		function (event) { event.stopPropagation(); })
					.bind("click",			function (event) { event.stopPropagation(); })
					.bind("keyup",			function (event) { 
							var key = event.keyCode || event.which;
							if(key == 27) { this.value = last_value; this.blur(); return }
							if(key == 13) { this.blur(); return }
						});

				// Rollback
				var rb = {}; 
				rb[this.container.attr("id")] = this.get_rollback();
					
				_this.inp.blur(function(event) {
						if(this.value == "") this.value = last_value; 
						$(obj).text( $(obj).parent().find("input").eq(0).attr("value") ).get(0).style.display = ""; 
						$(obj).prevAll("span").remove(); 
						_this.settings.callback.onrename.call(null, _this.get_node(obj).get(0), _this.current_lang, _this, rb);
						_this.inp = false;
					});
				var spn = $("<span />").addClass(obj.className).append(_this.inp);
				spn.attr("style", $(obj).attr("style"));
				obj.style.display = "none";
				$(obj).parent().prepend(spn);
				_this.inp.get(0).focus();
				_this.inp.get(0).select();
			},
			// REMOVE NODES
			remove : function(obj) {
				if(this.locked) return this.error("LOCKED");

				// Rollback
				var rb = {}; 
				rb[this.container.attr("id")] = this.get_rollback();

				if(obj && (!this.selected || this.get_node(obj).get(0) != this.selected.get(0) )) {
					obj = this.get_node(obj);
					if(obj.size()) {
						if(!this.check("deletable", obj)) return this.error("DELETE: NODE NOT DELETABLE");
						if(!this.settings.callback.beforedelete.call(null,obj.get(0), _this)) return this.error("DELETE: STOPPED BY USER");
						$parent = obj.parent();
						obj = obj.remove();
						$parent.children("li:last").addClass("last");
						if($parent.children("li").size() == 0) {
							$li = $parent.parents("li:eq(0)");
							$li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove();
							this.set_cookie("open");
						}
						this.settings.callback.ondelete.call(null, obj.get(0), this, rb);
					}
				}
				else if(this.selected) {
					if(!this.check("deletable", this.selected)) return this.error("DELETE: NODE NOT DELETABLE");
					if(!this.settings.callback.beforedelete.call(null,this.selected.get(0), _this)) return this.error("DELETE: STOPPED BY USER");
					$parent = this.selected.parent();
					var obj = this.selected;
					if(this.settings.rules.multiple == false || this.selected_arr.length == 1) {
						var stop = true;
						var tmp = (this.selected.prev("li:eq(0)").size()) ? this.selected.prev("li:eq(0)") : this.selected.parents("li:eq(0)");
						// this.get_prev(true);
					}
					obj = obj.remove();
					$parent.children("li:last").addClass("last");
					if($parent.children("li").size() == 0) {
						$li = $parent.parents("li:eq(0)");
						$li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove();
						this.set_cookie("open");
					}
					//this.selected = false;
					this.settings.callback.ondelete.call(null, obj.get(0), this, rb);
					if(stop && tmp) this.select_branch(tmp);
					if(this.settings.rules.multiple != false && !stop) {
						var _this = this;
						this.selected_arr = [];
						this.container.find("a.clicked").filter(":first-child").parent().each(function () {
							_this.selected_arr.push($(this));
						});
						if(this.selected_arr.length > 0) {
							this.selected = this.selected_arr[0];
							this.remove();
						}
					}
				}
				else return this.error("DELETE: NO NODE SELECTED");
			},
			// FOR EXPLORER-LIKE KEYBOARD SHORTCUTS
			get_next : function(force) {
				var obj = this.hovered || this.selected;
				if(obj) {
					if(obj.hasClass("open"))						return force ? this.select_branch(obj.find("li:eq(0)")) : this.hover_branch(obj.find("li:eq(0)"));
					else if($(obj).nextAll("li").size() > 0)	return force ? this.select_branch(obj.nextAll("li:eq(0)")) : this.hover_branch(obj.nextAll("li:eq(0)"));
					else											return force ? this.select_branch(obj.parents("li").next("li").eq(0)) : this.hover_branch(obj.parents("li").next("li").eq(0));
				}
			},
			get_prev : function(force) {
				var obj = this.hovered || this.selected;
				if(obj) {
					if(obj.prev("li").size()) {
						var obj = obj.prev("li").eq(0);
						while(obj.hasClass("open")) obj = obj.children("ul:eq(0)").children("li:last");
						return force ? this.select_branch(obj) : this.hover_branch(obj);
					}
					else { return force ? this.select_branch(obj.parents("li:eq(0)")) : this.hover_branch(obj.parents("li:eq(0)")); }
				}
			},
			get_left : function(force, rtl) {
				if(this.settings.ui.rtl && !rtl) return this.get_right(force, true);
				var obj = this.hovered || this.selected;
				if(obj) {
					if(obj.hasClass("open"))	this.close_branch(obj);
					else {
						return force ? this.select_branch(obj.parents("li:eq(0)")) : this.hover_branch(obj.parents("li:eq(0)"));
					}
				}
			},
			get_right : function(force, rtl) {
				if(this.settings.ui.rtl && !rtl) return this.get_left(force, true);
				var obj = this.hovered || this.selected;
				if(obj) {
					if(obj.hasClass("closed"))	this.open_branch(obj);
					else {
						return force ? this.select_branch(obj.find("li:eq(0)")) : this.hover_branch(obj.find("li:eq(0)"));
					}
				}
			},
			toggleDots : function () {
				this.container.toggleClass("no_dots");
			},
			set_cookie : function (type) {
				if(this.settings.cookies === false) return false;
				if(this.settings.cookies[type] === false) return false;
				switch(type) {
					case "selected":
						if(this.settings.rules.multiple != false && this.selected_arr.length > 1) {
							var val = Array();
							$.each(this.selected_arr, function () {
								val.push(this.attr("id"));
							});
							val = val.join(",");
						}
						else var val = this.selected ? this.selected.attr("id") : false;
						$.cookie(this.settings.cookies.prefix + '_selected',val,this.settings.cookies.opts);
						break;
					case "open":
						var str = "";
						this.container.find("li.open").each(function (i) { str += this.id + ","; });
						$.cookie(this.settings.cookies.prefix + '_open',str.replace(/,$/ig,""),this.settings.cookies.opts);
						break;
				}
			},
			get_rollback : function () {
				var rb = {};
				if(this.context.remove && this.context.apply_to) this.context.apply_to.children("a").removeClass("clicked");
				rb.html = this.container.html();
				if(this.context.remove && this.context.apply_to) this.context.apply_to.children("a").addClass("clicked");
				rb.selected = this.selected ? this.selected.attr("id") : false;
				return rb;
			},
			moved : function (what, where, how, is_new, is_copy, rb) {
				var what	= $(what);
				var $parent	= $(what).parents("ul:eq(0)");
				var $where	= $(where);

				// Rollback
				if(!rb) {
					var rb = {}; 
					rb[this.container.attr("id")] = this.get_rollback();
					if(!is_new) {
						var tmp = what.size() > 1 ? what.eq(0).parents(".tree:eq(0)") : what.parents(".tree:eq(0)");
						if(tmp.get(0) != this.container.get(0)) {
							tmp = tree_component.inst[tmp.attr("id")];
							rb[tmp.container.attr("id")] = tmp.get_rollback();
						}
						delete tmp;
					}
				}

				if(how == "inside" && this.settings.data.async && this.get_node($where).hasClass("closed")) {
					var _this = this;
					return this.open_branch(this.get_node($where), true, function () { _this.moved.apply(_this, [what, where, how, is_new, is_copy, rb]); });
				}

				// IF MULTIPLE
				if(what.size() > 1) {
					var _this = this;
					var tmp = this.moved(what.eq(0), where, how, false, is_copy, rb);
					what.each(function (i) {
						if(i == 0) return;
						if(tmp) { // if tmp is false - the previous move was a no-go
							tmp = _this.moved(this, tmp.children("a:eq(0)"), "after", false, is_copy, rb);
						}
					});
					return;
				}

				if(is_copy) {
					_what = what.clone();
					_what.each(function (i) {
						this.id = this.id + "_copy";
						$(this).find("li").each(function () {
							this.id = this.id + "_copy";
						});
						$(this).removeClass("dragged").find("a.clicked").removeClass("clicked ui-state-active").end().find("li.dragged").removeClass("dragged");
					});
				}
				else _what = what;
				if(is_new) {
					if(!this.settings.callback.beforecreate.call(null,this.get_node(what).get(0), this.get_node(where).get(0),how,this)) return false;
				}
				else {
					if(!this.settings.callback.beforemove.call(null,this.get_node(what).get(0), this.get_node(where).get(0),how,this)) return false;
				}

				if(!is_new) {
					var tmp = what.parents(".tree:eq(0)");
					// if different trees
					if(tmp.get(0) != this.container.get(0)) {
						tmp = tree_component.inst[tmp.attr("id")];

						// if there are languages - otherwise - no cleanup needed
						if(tmp.settings.languages.length) {
							var res = [];
							// if new tree has no languages - use current visible
							if(this.settings.languages.length == 0) res.push("." + tmp.current_lang);
							else {
								for(var i in this.settings.languages) {
									for(var j in tmp.settings.languages) {
										if(this.settings.languages[i] == tmp.settings.languages[j]) res.push("." + this.settings.languages[i]);
									}
								}
							}
							if(res.length == 0) return this.error("MOVE: NO COMMON LANGUAGES");
							what.find("a").not(res.join(",")).remove();
						}
						what.find("a.clicked").removeClass("clicked ui-state-active");
					}
				}
				what = _what;

				// ADD NODE TO NEW PLACE
				switch(how) {
					case "before":
						$where.parents("ul:eq(0)").children("li.last").removeClass("last");
						$where.parent().before(what.removeClass("last"));
						$where.parents("ul:eq(0)").children("li:last").addClass("last");
						break;
					case "after":
						$where.parents("ul:eq(0)").children("li.last").removeClass("last");
						$where.parent().after(what.removeClass("last"));
						$where.parents("ul:eq(0)").children("li:last").addClass("last");
						break;
					case "inside":
						if($where.parent().children("ul:first").size()) {
							if(this.settings.rules.createat == "top")	$where.parent().children("ul:first").prepend(what.removeClass("last")).children("li:last").addClass("last");
							else										$where.parent().children("ul:first").children(".last").removeClass("last").end().append(what.removeClass("last")).children("li:last").addClass("last");
						}
						else {
							what.addClass("last");
							$where.parent().append("<ul/>").removeClass("leaf").addClass("closed");
							$where.parent().children("ul:first").prepend(what);
						}
						if($where.parent().hasClass("closed")) { this.open_branch($where); }
						break;
					default:
						break;
				}
				// CLEANUP OLD PARENT
				if($parent.find("li").size() == 0) {
					var $li = $parent.parent();
					$li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove();
					$li.parents("ul:eq(0)").children("li.last").removeClass("last").end().children("li:last").addClass("last");
					this.set_cookie("open");
				}
				else {
					$parent.children("li.last").removeClass("last");
					$parent.children("li:last").addClass("last");
				}

				// NO LONGER CORRECT WITH position PARAM - if(is_new && how != "inside") where = this.get_node(where).parents("li:eq(0)");
				if(is_copy)		this.settings.callback.oncopy.call(null, this.get_node(what).get(0), this.get_node(where).get(0), how, this, rb);
				else if(is_new)	this.settings.callback.oncreate.call(null, this.get_node(what).get(0), ($where.is("ul") ? -1 : this.get_node(where).get(0) ), how, this, rb);
				else			this.settings.callback.onmove.call(null, this.get_node(what).get(0), this.get_node(where).get(0), how, this, rb);
				return what;
			},
			error : function (code) {
				this.settings.callback.error.call(null,code,this);
				return false;
			},
			lock : function (state) {
				this.locked = state;
				if(this.locked)	this.container.addClass("locked");
				else			this.container.removeClass("locked");
			},
			cut : function (obj) {
				if(this.locked) return this.error("LOCKED");
				obj = obj ? this.get_node(obj) : this.container.find("a.clicked").filter(":first-child").parent();
				if(!obj || !obj.size()) return this.error("CUT: NO NODE SELECTED");
				this.copy_nodes = false;
				this.cut_nodes = obj;
			},
			copy : function (obj) {
				if(this.locked) return this.error("LOCKED");
				obj = obj ? this.get_node(obj) : this.container.find("a.clicked").filter(":first-child").parent();
				if(!obj || !obj.size()) return this.error("COPY: NO NODE SELECTED");
				this.copy_nodes = obj;
				this.cut_nodes = false;
			},
			paste : function (obj, position) {
				if(this.locked) return this.error("LOCKED");

				var root = false;
				if(obj == -1) { root = true; obj = this.container; }
				else obj = obj ? this.get_node(obj) : this.selected;

				if(!root && (!obj || !obj.size())) return this.error("PASTE: NO NODE SELECTED");
				if(!this.copy_nodes && !this.cut_nodes) return this.error("PASTE: NOTHING TO DO");

				var _this = this;

				var pos = position;

				if(position == "before") {
					position = obj.parent().children().index(obj);
					obj = obj.parents("li:eq(0)");
				}
				else if(position == "after") {
					position = obj.parent().children().index(obj) + 1;
					obj = obj.parents("li:eq(0)");
				}
				else if((typeof position).toLowerCase() == "undefined" || position == "inside") {
					position = (this.settings.rules.createat == "top") ? 0 : obj.children("ul:eq(0)").children("li").size();
				}
				if(!root && obj.size() == 0) { root = true; obj = this.container; }

				if(this.copy_nodes && this.copy_nodes.size()) {
					var ok = true;
					//obj.parents().andSelf().each(function () {
					//	if(_this.copy_nodes.index(this) != -1) {
					//		ok = false;
					//		return false;
					//	}
					//});
					if(!ok) return this.error("Invalid paste");
					if(!root && !this.checkMove(this.copy_nodes, obj.children("a:eq(0)"), "inside")) return false;

					if(obj.children("ul").size() == 0 || (root == true && obj.children("ul").children("li").size() == 0) ) {
						if(!root)	var a = this.moved(this.copy_nodes,obj.children("a:eq(0)"),"inside", false, true);
						else		var a = this.moved(this.copy_nodes,this.container.children("ul:eq(0)"),"inside", false, true);
					}
					else if(pos == "before" && obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").size())
						var a = this.moved(this.copy_nodes,obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").children("a:eq(0)"),"before", false, true);
					else if(pos == "after" && obj.children("ul:eq(0)").children("li:nth-child(" + (position) + ")").size())
						var a = this.moved(this.copy_nodes,obj.children("ul:eq(0)").children("li:nth-child(" + (position) + ")").children("a:eq(0)"),"after", false, true);
					else if(obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").size())
						var a = this.moved(this.copy_nodes,obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").children("a:eq(0)"),"before", false, true);
					else
						var a = this.moved(this.copy_nodes,obj.children("ul:eq(0)").children("li:last").children("a:eq(0)"),"after", false, true);
					this.copy_nodes = false;
				}
				if(this.cut_nodes && this.cut_nodes.size()) {
					var ok = true;
					obj.parents().andSelf().each(function () {
						if(_this.cut_nodes.index(this) != -1) {
							ok = false;
							return false;
						}
					});
					if(!ok) return this.error("Invalid paste");
					if(!root && !this.checkMove(this.cut_nodes, obj.children("a:eq(0)"), "inside")) return false;

					if(obj.children("ul").size() == 0 || (root == true && obj.children("ul").children("li").size() == 0) ) {
						if(!root)	var a = this.moved(this.cut_nodes,obj.children("a:eq(0)"),"inside");
						else		var a = this.moved(this.cut_nodes,this.container.children("ul:eq(0)"),"inside");
					}
					else if(pos == "before" && obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").size())
						var a = this.moved(this.cut_nodes,obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").children("a:eq(0)"),"before");
					else if(pos == "after" && obj.children("ul:eq(0)").children("li:nth-child(" + (position) + ")").size())
						var a = this.moved(this.cut_nodes,obj.children("ul:eq(0)").children("li:nth-child(" + (position) + ")").children("a:eq(0)"),"after");
					else if(obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").size())
						var a = this.moved(this.cut_nodes,obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").children("a:eq(0)"),"before");
					else
						var a = this.moved(this.cut_nodes,obj.children("ul:eq(0)").children("li:last").children("a:eq(0)"),"after");
					this.cut_nodes = false;
				}
			},
			search : function(str) {
				var _this = this;
				if(!str || (this.srch && str != this.srch) ) {
					this.srch = "";
					this.srch_opn = false;
					this.container.find("a.search").removeClass("search ui-state-highlight");
				}
				this.srch = str;
				if(!str) return;
				if(this.settings.data.async) {
					if(!this.srch_opn) {
						var dd = $.extend( { "search" : str } , this.settings.data.async_data(false) );
						$.ajax({
							type		: this.settings.data.method,
							url			: this.settings.data.url, 
							data		: dd, 
							dataType	: "text",
							success		: function (data) {
								_this.srch_opn = $.unique(data.split(","));
								_this.search.apply(_this,[str]);
							} 
						});
					}
					else if(this.srch_opn.length) {
						if(this.srch_opn && this.srch_opn.length) {
							var opn = false;
							for(var j = 0; j < this.srch_opn.length; j++) {
								if(this.get_node("#" + this.srch_opn[j]).size() > 0) {
									opn = true;
									var tmp = "#" + this.srch_opn[j];
									delete this.srch_opn[j];
									this.open_branch(tmp, true, function () { _this.search.apply(_this,[str]); } );
								}
							}
							if(!opn) {
								this.srch_opn = [];
								 _this.search.apply(_this,[str]);
							}
						}
					}
					else {
						var selector = "a";
						// IF LANGUAGE VERSIONS
						if(this.settings.languages.length) selector += "." + this.current_lang;
						this.container.find(selector + ":contains('" + str + "')").addClass( this.settings.ui.theme_name == "themeroller" ? "search ui-state-highlight" : "search");
						this.srch_opn = false;
					}
				}
				else {
					var selector = "a";
					// IF LANGUAGE VERSIONS
					if(this.settings.languages.length) selector += "." + this.current_lang;
					this.container.find(selector + ":contains('" + str + "')").addClass( this.settings.ui.theme_name == "themeroller" ? "search ui-state-highlight" : "search").parents("li.closed").each( function () { _this.open_branch(this, true); });
				}
			},

			destroy : function() {
				this.container.unbind().find("li").die().find("a").die();
				this.container.removeClass("tree ui-widget ui-widget-content").children("ul").removeClass("tree-" + this.settings.ui.theme_name).find("li").removeClass("leaf").removeClass("open").removeClass("closed").removeClass("last").children("a").removeClass("clicked hover search ui-state-active ui-state-hover ui-state-highlight ui-state-default");

				if(this.cntr == tree_component.focused) {
					for(var i in tree_component.inst) {
						if(i != this.cntr && i != this.container.attr("id")) {
							tree_component.inst[i].focus();
							break;
						}
					}
				}
				delete tree_component.inst[this.cntr];
				delete tree_component.inst[this.container.attr("id")];
				tree_component.cntr --;
			}
		}
	};
})(jQuery);


var ObjectRelationImage = {
    uploadStart: function(swfupload, file) {
    },

    uploadProgress: function(swfupload, file, bytesLoaded, bytesTotal) {
    },

    uploadSuccess: function(swfupload, file, serverData) {
        var data = JSON.parse(serverData);

        // set the id of the image
        $("input[id$='" + swfupload.settings.post_params.FileUploadID + "_ImageID']").val(data.ID);

        // show the image
        $("span[id$='" + swfupload.settings.post_params.FileUploadID + "_Image']").html('<img src="' + data.src + '" />');

        // show the delete link
        var a = $("a[id$='" + swfupload.settings.post_params.FileUploadID + "_Delete']");
        a.html(a.html().replace('deleteImage(0)', 'deleteImage(' + data.ID + ')'));
        a.show();

        // save the object
        var save = $("ul a[id$='btnSave']");
        if (save.click()) {
            eval(save.attr('href').replace('javascript:', ''));
        }
    },

    uploadError: function(swfupload, file, errorCode, message) {
    },

    uploadComplete: function(swfupload, file) {
    },

    deleteImage: function(propertyName, imageID, objectTypeName,  objectID) {
        // delete the image
        var handler = baseURL + '/valentnet/views/shared/controls/propertygrid/upload/ObjectRelationImageHandler.ashx';

        $.post(handler, { ID: menuID, imageID: imageID, propertyName: propertyName, objectTypeName: objectTypeName, objectID: objectID, action: 'Delete' },
            function(data) {
                // set the id of the image to zero
                $("input[id$='" + propertyName + "_ImageID']").val('0');

                // remove the image from the UI
                $("span[id$='" + propertyName + "_Image']").html('');

                // hide the delete link
                $("a[id$='" + propertyName + "_Delete']").hide();

                // save the object
                var save = $("ul a[id$='btnSave']");
                if (save.click()) {
                    eval(save.attr('href').replace('javascript:', ''));
                }
            });
    }
};


var PropertyGridStringUpload = {
    mySwfUpload: {},
    fileId: '',

    fileQueued: function(swfupload, file) {
        this.mySwfUpload = swfupload;
        this.fileId = file.id;

        // check if the file exists passing the custom settings as options.
        if ($.fileExists(file.name, { type: 'PropertyGridStringUpload' }, { overwritable: swfupload.customSettings.overwritable })) {
        }
    },

    uploadStart: function(swfupload, file) {
    },

    uploadProgress: function(swfupload, file, bytesLoaded, bytesTotal) {
    },

    uploadSuccess: function(swfupload, file, serverData) {
        var data = JSON.parse(serverData);

        // set the filename
        $("input[id$='" + swfupload.settings.post_params.FileUploadID + "_File']").val(data.relativePath);
    },

    uploadError: function(swfupload, file, errorCode, message) {
    },

    uploadComplete: function(swfupload, file) {
    },

    deleteFile: function(controlID, file) {
        // delete the image
        var handler = baseURL + '/valentnet/views/shared/controls/propertygrid/upload/StringHandler.ashx';
        var saveID = this.mySwfUpload.customSettings.saveID;

        $.post(handler, { ID: menuID, file: file, action: 'Delete' },
            function(data) {
                // set the current file to nothing
                $("input[id$='" + controlID + "_File']").val('');

                // save the object
                var save = $("#" + saveID);
                if (save.click()) {
                    eval(save.attr('href').replace('javascript:', ''));
                }
            });
    },

    Cancel: function(data) {
        this.mySwfUpload.cancelUpload();
    },

    Submit: function(data) {
        $("#" + this.fileId + " .progressName").html(data.path);
        this.mySwfUpload.addFileParam(this.fileId, 'path', data.path);
        this.mySwfUpload.addFileParam(this.fileId, 'overwrite', data.overwrite);
    }
};

var MenuTreeCallbacks = {
    Toggle: function(data) {
        var li = $(data.img).parent();
        var tmp = li.attr('id').split('_');
        var id = li.attr('id').replace('_' + tmp[tmp.length - 1], '');

        var ul = li.find("ul:first");
        if (ul.length > 0) {
            this.ShowOrHide(data, ul);
        } else {
            this.Get(data, id);
        }
    },

    Get: function(data, controlID) {
        data.ID = menuID;
        data.pageUrl = document.location.href;
        $.post(baseURL + 'ValentNet/Views/Shared/Controls/MenuTree/MenuTreeCallbacks.aspx', data,
            function(menu) {
                if (menu.items) {
                    var ul = document.createElement('ul');
                    ul.className = 'hidden';
                    $(ul).attr('hidden', 'true');
                    $(data.img).parent().append(ul);
                    for (var index = 0; index < menu.items.length; index++) {
                        menu.items[index].mt = data.mt;
                        MenuTreeCallbacks.Append(ul, menu.items[index], controlID);
                    }

                    MenuTreeCallbacks.ShowOrHide(data, $(ul));
                }
            }, 'json');
    },

    Append: function(ul, item, controlID) {
        var image = '<img src="' + baseURL + 'ValentNet/Content/icons/empty.gif"  height="16" width="16" alt="" />';
        if (item.hasChilds) {
            image = '<img id="cmd' + item.id + '" src="' + baseURL + 'ValentNet/Content/icons/trvplus.gif" height="16" width="16" alt="open" onclick="' +
               'MenuTreeCallbacks.Toggle({ pID: ' + item.id + ', mt: \'' + item.mt + '\', img: this});" />';
        }

        var target = '';
        if (item.target && item.target.length > 0) {
            target = ' target="' + item.target + '"';
        }

        var li = document.createElement('li');
        li.id = controlID + '_li' + item.id;
        li.innerHTML = image + '<a href="' + item.url + '"' + target + ' title="" class="' + (item.hidden ? "invisible" : "") + '">' + item.name + '</a>';
        ul.appendChild(li);

        // Add the context menu handler
        li.oncontextmenu = function(event) { return ContentItemMenuManager.contextMenuEventHandler(event, item.id); };
    },

    ShowOrHide: function(data, ul) {

        var isHidden = ul.attr('hidden') == 'true';
        if (isHidden) ul.show();
        else ul.hide();

        ul.attr('hidden', isHidden ? 'false' : 'true');
        var src = isHidden ? 'min' : 'plus';
        $(data.img).attr('src', baseURL + 'ValentNet/Content/icons/trv' + src + '.gif');
    }
};


var CurrencyExchangeRateEdit = {
    // used by onchange of the DropDownlist
    setExchangeRate: function(idlist, idedit) {
        // selection changed -> get the DropDownList and TextBox
        var list = document.getElementById(idlist);
        var edit = document.getElementById(idedit);

        // get the selected text of the DropDownList
        var txtsel = list.options[list.selectedIndex].text;
        var valsel = list.options[list.selectedIndex].value;
        if (valsel == "none" || txtsel == "") {
            // none selected so empty the edit box
            edit.value = "";

            // reset the text color, just in case
            edit.style.color = "red";

            // disable the box
            edit.disabled = true;
        }
        else {            
            // an exchange rate has been selected, enable the TextBox
            edit.disabled = false;

            // reset the TextBox tex color
            edit.style.color = "red";

            // set the decimal value of the selected exchange rate in DropDownList in TextBox
            edit.value = this.getExchangeRateFromText(txtsel);            
        }

    }, // setExchangeRate

    // used by onchange of the TextBox
    editExchangeRate: function(idlist, idedit) {
        // value in text box changed, check if value different from selected value in the DropDownlist
        var list = document.getElementById(idlist);
        var edit = document.getElementById(idedit);

        // if value in TextBox different from DropDownList
        var txtsel = list.options[list.selectedIndex].value;
        var valsel = list.options[list.selectedIndex].value;
        if (valsel != "none" && txtsel != "") {
            // get the rate in text format
            var rate = this.getExchangeRateFromText(txtsel);

            // check for change
            if (rate != "" && edit.value != rate) {
                // if changed set it to blue
                edit.style.color = "blue";
            }
            else edit.style.color = "red"; // reset again
        }
    },

    // helper function for getting the selected rate in the DropDownList
    getExchangeRateFromText: function(txt) {
        var txtret = "";

        // valid string?
        if ("" == txt) return txtret;
        // none?
        if ("none" == txt) return txtret;

        // try parse: format = "<symbol> -> <symbol> (1,24 ; 24-09-2010)"
        var split_string = txt.split("("); // "<symbol> -> <symbol> " and "1,24 ; 24-09-2010)"
        if (split_string.length == 2) {
            if (split_string[1].length < 1) return txtret;

            // split string "1,24 ; 24-09-2010)" again using ";"
            var split_string_two = split_string[1].split(";"); // "1,24 "
            if (split_string_two[0].length < 1) return txtret;

            // trim the decimal, leaves "1,24"
            var dectext = split_string_two[0].replace(/^\s*/, "").replace(/\s*$/, "");
            if (dectext.length > 0) txtret = dectext;
        }

        return txtret;
    }

};  // CurrencyExchangeRateEdit

var ContentItem = {
    highLightContentItem: function(id) {
        var ci = $('#' + id);
        ci.highlightFade({ speed: 1500 });
    }
};


$(document).ready(function() {
    var buttons = $('.contentItemConfigButton');

    buttons.each(function() {
        var ci = $(this).parent().parent().parent();
        $(this).attr('onmouseOver', "ContentItem.highLightContentItem('" + ci.attr('id') + "')");
    });
});



/* ContentItemWebsiteSubscribe.cs.js */

var ContentItemWebsiteSubscribe = {
    getStepTwoPanel: function(controlID) {
        getJsonCI('WebsiteSubscribe',
        'GetStepTwoPanel',
        function(data) {
            if (data.stepTwoPanel != null) {
                $("[id$='" + controlID + "']").html(data.stepTwoPanel);
            }
        }
        , { controlID: controlID });
    }
};

$(document).ready(function () {
    if (null != $(document).getUrlParam('searchTerm')) {
        // get the search term from the query string and highlight the search term.
        var searchTerm = $.URLDecode($(document).getUrlParam('searchTerm')).replace('+', ' ');
        $('#content').highlight(searchTerm);
    }
});

/* ContentItemUntypedVote.cs.js */
var ContentItemUntypedVote = {
    vote: function(score, objectID, objectTypeName, voterID) {
        getJsonCI('UntypedVote', 'Vote', function(data) {
            // Update vote score.
            if (data.score != undefined) {
                // Update VoteScore
                $("[id$='Score_" + objectTypeName + "_" + objectID + "']").html(data.score);

                // Set vote images.
                var voteImagePath = 'ValentNet/Content/icons/forum/';
                var voteUpImage = voteImagePath + 'voteUp.png';
                var voteDownImage = voteImagePath + 'voteDown.png';

                if (score == 1) {
                    if (data.voteCancelled == false) {
                        voteUpImage = voteImagePath + 'voteUpHighlighted.png';
                    }

                    // Set Vote Images
                    $("[id$='VoteUpImage_" + objectTypeName + "_" + objectID + "']").attr({ src: baseURL + voteUpImage });
                    $("[id$='VoteDownImage_" + objectTypeName + "_" + objectID + "']").attr({ src: baseURL + voteDownImage });
                }
                else if (score == -1) {
                    if (data.voteCancelled == false) {
                        voteDownImage = voteImagePath + 'voteDownHighlighted.png';
                    }

                    // Set Vote Images
                    $("[id$='VoteUpImage_" + objectTypeName + "_" + objectID + "']").attr({ src: baseURL + voteUpImage });
                    $("[id$='VoteDownImage_" + objectTypeName + "_" + objectID + "']").attr({ src: baseURL + voteDownImage });
                }
            }
        }, { score: score, objectID: objectID, objectTypeName: objectTypeName, voterID: voterID });
    }
};

function MarkAsSolution(objectID, objectTypeName, voterID) {
    getJsonCI('UntypedVote', 'MarkAsSolution', function(data) {
        if (data.markAsSolution != undefined) {
            if (data.markAsSolution == true) {
                // Change image to indicate that the object is now the solution.
                $("[id$='MarkAsSolutionImage_" + objectTypeName + "_" + objectID + "']").attr({ src: baseURL + 'ValentNet/Content/icons/forum/solutionCheck.png' });

                // If there was a previous solution.
                if (data.previousSolutionID != 0) {
                    // Change image to indicate that any previous objects are no longer the solution.
                    $("[id$='MarkAsSolutionImage_" + objectTypeName + "_" + data.previousSolutionID + "']").attr({ src: baseURL + 'ValentNet/Content/icons/forum/check.png' });
                }
            }
            else {
                // Change image to indicate that the object is not the solution.
                $("[id$='MarkAsSolutionImage_" + objectTypeName + "_" + objectID + "']").attr({ src: baseURL + 'ValentNet/Content/icons/forum/check.png' });
            }
        }
    }, { objectID: objectID, objectTypeName: objectTypeName, voterID: voterID });
};

/* ContentItemUntypedTags.cs.js */

var ContentItemUntypedTags = {
    save: function(controlID, objectTypeName, objectID, menuID) {
        // get tags
        var tags = $("input[id$='" + controlID + "_TagBox']").val();

        getJsonCI('UntypedTags', 'Save', function(data) {
        }, { objectTypeName: objectTypeName, objectID: objectID, tags: tags, menuID: menuID });
    }
};

$(document).ready(function() {

    var url = baseURL + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?ID=' + menuID + '&action=Get&name=UntypedTags&pageUrl=' + document.location.href;
    $('.UntypedTags input').autocomplete(url, {
        formatItem: function(item) {
            return item[0].split(';')[0] + ' (' + item[0].split(';')[1] + ')';
        },
        formatResult: function(item) {
            return item[0].split(';')[0];
        },
        multiple: true,
        multipleSeparator: ' '
    });
});

/* ContentItemUntypedTagsConfig.cs.js */

var ContentItemUntypedTagsConfig = {

    save: function(menuID, uniqueName) {
        var text = $("input[id='Text']").val();
        getJsonCI('UntypedTagsConfig',
            'Save',
            function() { window.location.reload(); },
            {
                menuID: menuID,
                uniqueName: uniqueName,
                scope: scope
            });
    }
};

/* ContentItemUntypedPromoCodes.cs.js */

$(document).ready(function() {
    if ($('.untypedPromoCodes').length > 0) {
        ContentItemUntypedPromoCodes.attachEvents();

        $('.untypedPromoCodes .add').click(function() {
            ContentItemUntypedPromoCodes.addRelation($('.untypedPromoCodes select').val());
        });
    }
});

var ContentItemUntypedPromoCodes = {
    attachEvents: function() {
        if ($('.untypedPromoCodes select option').size() > 0) {
            $('.untypedPromoCodes .add').show();
        } else {
            $('.untypedPromoCodes select').hide();
            $('.untypedPromoCodes .add').hide();
        }

        $('.untypedPromoCodes .delete').click(function() {
            ContentItemUntypedPromoCodes.deleteRelation(this.rel);
        });
    },

    deleteRelation: function(objectRelationID) {
        // delete relation on server
        var objectTypeName = $(".untypedPromoCodes input[id$='objectTypeName']").val();
        var objectID = $(".untypedPromoCodes input[id$='objectID']").val();
        getJsonCI('UntypedPromoCodes', 'Delete', function(data) {
            // refresh html for table and select
            ContentItemUntypedPromoCodes.refreshHtml(data.promoCodeTable, data.addPromoCodeSelect);
        }, { objectTypeName: objectTypeName, objectID: objectID, objectRelationID: objectRelationID });
    },

    addRelation: function(promoCodeID) {
        var objectTypeName = $(".untypedPromoCodes input[id$='objectTypeName']").val();
        var objectID = $(".untypedPromoCodes input[id$='objectID']").val();
        getJsonCI('UntypedPromoCodes', 'Add', function(data) {
            // refresh html for table and select
            ContentItemUntypedPromoCodes.refreshHtml(data.promoCodeTable, data.addPromoCodeSelect);
        }, { objectTypeName: objectTypeName, objectID: objectID, promoCodeID: promoCodeID });
    },

    refreshHtml: function(tableHtml, selectHtml) {
        $('.untypedPromoCodes table').replaceWith(tableHtml);
        $('.untypedPromoCodes select').replaceWith(selectHtml);
        this.attachEvents();
    }
};


var ContentItemUntypedImages = {
    Upload: {},

    DeleteImage: function (objectTypeName, objectID, imageID) {
        // send update to the server
        getJsonCI('UntypedImages', 'Delete', function (data) {
            // remove row from table
            $("tr[id$='image_" + imageID + "']").remove();
        }, { imageID: imageID });

        // cancel event bubble
        return false;
    },

    toggleActiveImage: function (domElement, objectType, assemblyName, options, imageID) {
        // Toggle active image.
        $.toggleImg(domElement, objectType, 'blnActive', assemblyName, options);

        // Get image and show if it is active or inactive by adding or removing the inactiveImage class.
        var imageThumbnail = $("[id$='" + imageID + "']");
        if (imageThumbnail.hasClass('inactiveImage')) {
            imageThumbnail.removeClass('inactiveImage');
        }
        else {
            imageThumbnail.addClass('inactiveImage');
        }

        return false;
    },

    SetUpAjaxUpload: function (objectTypeName, objectID, imageListID, uploadButtonID, httpBaseUrl, showActivateLink, showInformation) {
        if (httpBaseUrl[httpBaseUrl.length - 1] != '/') httpBaseUrl += '/';

        this.Upload = new AjaxUpload($('#' + uploadButtonID),
            {
                action: httpBaseUrl + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?ID=' + menuID +
                    '&name=UntypedImages&action=Upload&objectID=' + objectID + '&objectTypeName=' + objectTypeName +
                    '&showActivateLink=' + showActivateLink + '&showInformation=' + showInformation + '&pageUrl=' + document.location.href,
                onChange: function (file, extension) {
                    if ($.fileExists(file, { objectTypeName: objectTypeName, objectID: objectID, type: 'ContentItemUntypedImages' })) {
                        return false;
                    }
                },
                onComplete: function (file, response) {
                    var data = JSON.parse(response);
                    if (data.newImage.length > 0) {
                        $('#' + imageListID).append(data.newImage);
                    } else {
                        var img = $("tr[id$='image_" + data.imageID + "'] .image img");
                        var src = img.attr('src').split('?')[0];
                        img.attr('src', src + '?' + (new Date().getTime()));
                    }

                    $('#' + imageListID).tableDnD({ onDrop: function (table, row) { $.reorder('Image', $.tableDnDResult(table)); } });
                    /* reload thickboxfunctions */
                    if (window.tb_init) {
                        tb_init('a.thickbox, area.thickbox, input.thickbox');
                    }
                }
            });

        $('#' + imageListID).tableDnD({ onDrop: function (table, row) { $.reorder('Image', $.tableDnDResult(table)); } });
    },

    Cancel: function (data) {
        this.Upload._input.value = '';
    },

    Submit: function (data) {
        this.Upload.setData({ 'filename': data.path, 'overwrite': data.overwrite });
        this.Upload.submit();
    }
};

var ContentItemUntypedDocuments = {
    Upload: {},

    DeleteDocument: function (objectTypeName, objectID, documentID) {
        // send update to the server
        getJsonCI('UntypedDocuments', 'Delete', function (data) {
            // remove item from list
            $("li[id$='document_" + documentID + "']").remove();
        }, { documentID: documentID });

        // cancel event bubble
        return false;
    },

    SaveDescriptions: function (controlID, documentID, activeLanguages) {
        // get the active languages.
        var languages = JSON.parse(activeLanguages);

        var descriptionsArray = new Array(languages.length);
        // for each active language find the control, save description and add it to the array.
        for (var index = 0; index < languages.length; index++) {

            // add to array of descriptions
            descriptionsArray[index] = $(controlID + "_DescriptionInput_" + languages[index]).val();
        }

        // convert array of descriptions to JSON object.
        var descriptionsJSONObject = JSON.stringify(descriptionsArray);

        // save descriptions
        getJsonCI('UntypedDocuments', 'SaveDescriptions', null, { documentID: documentID, descriptionsJSONObject: descriptionsJSONObject });

        // cancel the event bubble
        return false;
    },

    SetUpAjaxUpload: function (objectTypeName, objectID, documentItemsID, uploadButtonID, httpBaseUrl, allowedExtensions, errorMessage) {
        if (httpBaseUrl[httpBaseUrl.length - 1] != '/') httpBaseUrl += '/';

        this.Upload = new AjaxUpload($('#' + uploadButtonID), {
            // Upload document and append it to the list.
            action: httpBaseUrl + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?ID=' + menuID +
            '&name=UntypedDocuments&action=Upload&objectID=' + objectID + '&objectTypeName=' + objectTypeName + '&pageUrl=' + document.location.href,

            onChange: function (file, extension) {
                if ($.fileExists(file, { objectTypeName: objectTypeName, objectID: objectID, type: 'ContentItemUntypedDocuments' })) {
                    return false;
                }
            },

            onSubmit: function (file, ext) {
                if (!allowedExtensions || 0 == allowedExtensions.length) {
                    return true;
                }

                var myregexp = new RegExp("^(" + allowedExtensions + ")$", "i");
                if (!(ext && myregexp.test(ext))) {
                    // extension is not allowed
                    alert(errorMessage);
                    // cancel upload
                    return false;
                }
            },

            onComplete: function (file, response) {
                var data = JSON.parse(response);

                if (data.newDocument.length > 0) {
                    $('#' + documentItemsID).append(data.newDocument);
                }
            }
        });
    },

    Cancel: function (data) {
        this.Upload._input.value = '';
    },

    Submit: function (data) {
        this.Upload.setData({ 'filename': data.path, 'overwrite': data.overwrite });
        this.Upload.submit();
    }
};

var ContentItemUntypedComments = {

    newComment: function (objectTypeName, objectID, newCommentID, commentListID, numberOfAnswersTitle, controlID) {
        // get body text and check if there is text
        var body = tinyMCE.get('ctl00_cs1_' + controlID + '_NewCommentTextArea_editor') || tinyMCE.get('ctl01_Cs1_' + controlID + '_NewCommentTextArea_editor');
        if (body.length == 0) return false;

        // send update to the server
        getJsonCI('UntypedComments', 'Save', function (data) {
            $('#' + commentListID).append(data.newComment);
            $('#' + newCommentID).val('');
            $("[id$='NumberOfAnswersTitle']").html(data.numberOfAnswersTitle);

        }, { body: body.getContent(), objectTypeName: objectTypeName, objectID: objectID, numberOfAnswersTitle: numberOfAnswersTitle });

        // clear the text editor after posting.
        body.setContent('');

        // cancel event bubble
        return false;
    },

    editComment: function (commentID, controlID) {
        // Open the text editor in a lightbox
        tb_show('', baseURL + 'ValentNet/Views/Shared/Controls/ContentItems/UntypedComments/ContentItemUntypedCommentsPopup.aspx?commentID=' + commentID + '&controlID=' + controlID + '&TB_iframe=true&width=806&height=295', '',
            {});

        // cancel event bubble
        return false;
    },

    deleteComment: function (commentID, controlID) {
        // send update to the server
        getJsonCI('UntypedComments', 'Delete', function (data) {
            if (data.deleted == true) {
                // Remove comment from interface
                $("[id$='" + controlID + "_Comment_" + commentID + "']").remove();
                // Update answer count.
                $("[id$='NumberOfAnswersTitle']").html(data.numberOfAnswersTitle);
            }
        }, { commentID: commentID });

        // cancel event bubble
        return false;
    },

    saveComment: function (commentID, controlID) {
        /*Get body using tinyMCE 
        tinyMCE.get('ctl00_cs1_' + controlID + '_EditCommentTextArea_' + commentID + '_editor').getContent()
        */
        var body = $("[id$='" + controlID + "_EditCommentTextArea_" + commentID + "']").val();

        // send update to the server
        getJsonCI('UntypedComments', 'Save', function (data) {
            $("[id$='" + controlID + "_Comment_" + commentID + "']", top.document).html(data.newComment);
        }, { commentID: commentID, body: body });

        // hide lightbox
        self.parent.tb_remove();

        // cancel event bubble
        return false;
    }
};


var ContentItemUntypedCollection = {
    SaveVisibleUntyped: function(menuID, name, untypedName, value) {
        getJsonCI('UntypedCollection', 'SaveVisibleUntyped', null, { uniqueName: name, untypedName: untypedName, visible: value });
    }
};

var ContentItemUntypedCollectionConfig = {
    SaveVisibleUntyped: function(menuID, name, untypedName, value) {
        getJsonCI('UntypedCollectionConfig', 'SaveVisibleUntyped', null, { uniqueName: name, untypedName: untypedName, visible: value });
    }
};

var ContentItemUntypedAttributes = {

DeleteAttribute: function(objectTypeName, objectID, attributeID) {
    // send update to the server
    getJsonCI('UntypedAttributes', 'Delete', function(data) {
        // remove row from table
        $("tr[id$='attribute_" + attributeID + "']").remove();
    }, { attributeID : attributeID });

    // cancel event bubble
    return false;
},

NewAttribute: function(objectTypeName, objectID, attributeTableID) {
    // send update to the server
    getJsonCI('UntypedAttributes', 'Create', function(data) {
        $('#' + attributeTableID).append(data.newAttribute);
    }, { objectTypeName: objectTypeName, objectID: objectID });

    // cancel event bubble
    return false;
}
};

var ContentItemUntypedAds = {
    getObjects: function(tblBuyAdID) {
        // Get packageID from radio button list.
        adPackageID = $("[id$='rblAdPackages'] input:checked").val();

        getJsonCI('UntypedAds', 'GetObjects', function(data) {
            // If objects drop down list has already been created, remove it.
            $("table[id$='" + tblBuyAdID + "'] tr[id$='rowPackageObjects']").remove();
            // If there are objects in the drop down list, add row and show buy package button.
            if (data != undefined) {
                $("table[id$='" + tblBuyAdID + "'] tr:first").after(data.NewRow);
                ContentItemUntypedAds.showBuyPackage();
            }
        }, { adPackageID: adPackageID });
    },

    showBuyPackage: function() {
        // Show autoRenew checkbox and buy package button.
        $("input[id$='cbxAutoRenew']").parent().show();
        $("input[id$='btnBuyPackage']").show();
    },

    buyPackage: function(objectID, adApplication) {
        // If objectID is 0 get it from the selected object in the objects drop down list.
        if (objectID == 0) {
            objectID = $("[id$='ddlPackageObjects']").val();
        }

        // Get packageID and check whether autoRenew is checked.
        adPackageID = $("[id$='rblAdPackages'] input:checked").val();
        autoRenew = $("[id$='cbxAutoRenew']").is(':checked');

        getJsonCI('UntypedAds', 'BuyPackage', function(data) {
            // If there is a redirect link, navigate to it, else refresh the page.
            if (data.RedirectLink) {
                setTimeout("window.location = '" + data.RedirectLink + "'", 3000);
            }
            else {
                window.location.reload();
            }
        }, { adPackageID: adPackageID, objectID: objectID, autoRenew: autoRenew, adApplication: adApplication });
    }
};

var ContentItemTwitterConfig = {

    save: function(menuID, uniqueName) {
        var screenName = $("input[id='ScreenName']").val();
        var count = $("input[id='Count']").val();
        var dateFormat = $("input[id='DateFormat']").val();
        var showHeader = $("input[id='ShowHeader']").is(':checked');
        getJsonCI('TwitterConfig',
            'Save',
            function() { window.location.reload(); },
            {
                menuID: menuID,
                uniqueName: uniqueName,
                screenName: screenName,
                count: count,
                dateFormat: dateFormat,
                showHeader: showHeader
            });
    }
};



var ContentItemText = {
    highLightContentItem: function(id) {
        var ci = $('#' + id);
        ci.highlightFade({ speed: 1500 });
    }
};


/* ContentItemTagSearch.cs.js */
var ContentItemTagSearch = {
    search: function(controlID, tagName, listUrl) {

        // get search tags.
        var searchTags = $("input[id$='" + controlID + "_TagBox']").val();

        var path = '';

        // redirect to list page if needed.
        if (listUrl != undefined) {
            path = listUrl;
        }
        else {
            // Add search terms to the query string.
            path = location.href.split('?')[0];
        }

        // if only one tag is being searched.
        if (tagName != '') {
            path = path + "?searchTags=" + encodeURIComponent(tagName);
        }
        else if (searchTags != '') {
            searchTags = encodeURIComponent($.trim(searchTags));

            // add search tags to the query string.
            path = path + "?searchTags=" + searchTags;
        }

        location.href = path;
    }
};



var ContentItemShoppingCart = {

    getOldValue: function(quantityInput) {
        var oldQuantity = toFloat(quantityInput.attr('oldValue'));
        if (isNaN(oldQuantity)) return;
        oldQuantity = Math.round(oldQuantity);
        return oldQuantity;
    },

    setOldValue: function(quantityInput) {
        quantityInput.attr('oldValue', quantityInput.val());
    },

    resetValue: function(quantityInput) {
        quantityInput.val(this.getOldValue(quantityInput));
    },
    
    updateQuantity: function(orderLineID, quantityInput) {
        var newQuantity = toFloat(quantityInput.val());
        if (isNaN(newQuantity)) return;
        newQuantity = Math.round(newQuantity);

        var oldQuantity = this.getOldValue(quantityInput);

        // check if value has changed at all
        if (oldQuantity == newQuantity) {
            return;
        }

        // check if the order line must me removed    
        if (newQuantity == 0) {
            // delete orderline
            this.deleteOrderLine(orderLineID, quantityInput);
            return;
        }

        // save quantity to the server
        getJsonCI(
            'ShoppingCart',
            'UpdateQuantity',
            function(data) {
                $("td[id$='subtotal_" + orderLineID + "']").html(data.ExtendedPrice);
                $("div[id$='shoppingCartTotals']").html(data.ShoppingCartTotals);
            },
            { orderLineID: orderLineID, quantity: newQuantity });
    },

    deleteOrderLine: function(orderLineID, quantityInput) {
        // Prompt to remove the item.
        var deleteConfirm = confirm(labels.areYouSure);

        // if cancelled, reset value and stop
        if (deleteConfirm == false) {
            if (quantityInput != null) {
                this.resetValue(quantityInput);
            }
            return;
        }

        // confirmed, delete from server
        getJsonCI(
            'ShoppingCart',
            'DeleteOrderLine',
            function(data) {
                if (data.OrderLineDeleted == true) {
                    $("tr[id$='OrderLine_" + data.OrderLineID + "']").remove();
                    $("div[id$='shoppingCartTotals']").html(data.ShoppingCartTotals);

                    var orderLinesCount = $('.shoppingCart tr.orderLine').length;
                    if (orderLinesCount == 0) {
                        $('.shoppingCart').hide();
                    }
                }
            },
            { orderLineID: orderLineID });
    }
};

$(document).ready(function() {
    if ($('.shoppingCart').length == 0) return;

    $('.shoppingCart .quantity input').focus(function() {
        ContentItemShoppingCart.setOldValue($(this));
    });

    $('.shoppingCart .quantity input').blur(function() {
        ContentItemShoppingCart.updateQuantity($(this).attr('orderLineID'), $(this));
    });

    $('.shoppingCart .remove').click(function() {
        ContentItemShoppingCart.deleteOrderLine($(this).attr('orderLineID'));
    });
});


var ContentItemSettings = {

    showEdit: function(controlID) {
        // Reset all other divs.
        $(".divEdit").hide();
        $(".divList").show();

        // Toggle list and edit views
        $("#divList_" + controlID).toggle();
        $("#divEdit_" + controlID).toggle();
    },

    cancel: function() {
        // Reset all other divs.
        $(".divEdit").hide();
        $(".divList").show();
    },

    save: function(menuSettingProperty, controlID, settingType, clickedMenuID) {
        var value = '';

        if (settingType == 'bln') {
            // Find the checked radio button and get its value.
            var rblName = "menuSetting_" + controlID;
            var radioButtons = document.getElementsByName(rblName);
            for (var x = 0; x < radioButtons.length; x++) {
                if (radioButtons[x].checked) {
                    value = radioButtons[x].value;
                }
            }
        }
        else {
            // If it is an integer or a string value take it from the input field.
            value = $("#menuSetting_" + controlID).val();
        }

        // Update label in list view.
        // Replace any start tags with &lt.
        $("#divList_label_" + controlID).html(value.replace(/</g, '&lt;'));

        // Show revert button
        $("#revert_" + controlID).show();

        // Save setting
        getJsonCI('Settings', 'Save', null, { menuSettingProperty: menuSettingProperty, menuSettingValue: value, clickedMenuID: clickedMenuID });
    },

    saveMultilingualText: function(menuSettingProperty, controlID, activeLanguages, clickedMenuID) {

        // Get languages
        var languages = JSON.parse(activeLanguages);

        var valuesArray = new Array(languages.length);
        // For each active language find the control and save the new value and add it to JSON obect.
        for (var index = 0; index < languages.length; index++) {
            // Add value array
            valuesArray[index] = $("#menuSetting_" + controlID + "_" + languages[index]).val();
        }

        // Update list view with new value
        // Replace any start tags with &lt.
        $("#divList_label_" + controlID)[0].innerHTML = valuesArray[0].replace(/</g, '&lt;');

        // Show revert button
        $("#revert_" + controlID).show();

        // Convert array to JSON object.
        var valuesJSONText = JSON.stringify(valuesArray);

        // Save setting
        getJsonCI('Settings', 'SaveMultilingualText', null, { menuSettingProperty: menuSettingProperty, menuSettingJSONValues: valuesJSONText, clickedMenuID: clickedMenuID });
    },

    revert: function(menuSettingProperty, controlID, settingType, activeLanguages, clickedMenuID) {
        // Hide revert button as default setting is being requested.
        $("#revert_" + controlID).hide();

        // Use handler to delete setting from database, also update the label value with that of the default setting.
        getJsonCI('Settings', 'Revert', function(data) {

            // Update input boxes with default values.
            if (settingType == 'bln') {
                // Find the checked radio button and get its value.
                var rblName = "menuSetting_" + controlID;

                $("#divList_label_" + controlID).html(String(data.DefaultMenuSettingValue));
                $("input[name='" + rblName + "']:first").attr("checked", data.DefaultMenuSettingValue);
                $("input[name='" + rblName + "']:last").attr("checked", (data.DefaultMenuSettingValue == false));
            }
            else if (settingType == 'txt') {

                var values = JSON.parse(data.DefaultMenuSettingValue);
                var languages = JSON.parse(activeLanguages);

                // For each active language update the value in the input box.
                for (var index = 0; index < languages.length; index++) {
                    // Add value array
                    $("#menuSetting_" + controlID + "_" + languages[index]).val(values[index]);
                }

                // Update label in list
                $("#divList_label_" + controlID).html(values[0]);
            }
            else {
                // Update label in list and input in edit with default value.
                $("#divList_label_" + controlID).html(data.DefaultMenuSettingValue);
                $("#menuSetting_" + controlID).val(data.DefaultMenuSettingValue);
            }

        }, { menuSettingProperty: menuSettingProperty, clickedMenuID: clickedMenuID });
    },

    getNewSettingValueCell: function() {
        var settingType = '';

        // Find the checked setting type and get its value.
        var rblName = 'NewSettingTypeRadioButtonList'
        var radioButtons = document.getElementsByName(rblName);
        for (var x = 0; x < radioButtons.length; x++) {
            if (radioButtons[x].checked) {
                settingType = radioButtons[x].value;
            }
        }

        // Get new setting cell by type.
        getJsonCI('Settings', 'GetNewSettingValueCell', function(data) {
            // Replace cell
            if (data != undefined) {
                var newSettingValueCell = $("[id$='NewSettingValueCell']");
                newSettingValueCell.after(data.NewSettingValueCell).remove();
            }
        }
        , { settingType: settingType });
    },

    addNewSetting: function(controlID, activeLanguages, clickedMenuID) {
        // Get languages
        var languages = JSON.parse(activeLanguages);

        var settingType = '';

        // Find the checked setting type and get its value.
        var newSettingTypeRadioButtonList = 'NewSettingTypeRadioButtonList'
        var radioButtons = document.getElementsByName(newSettingTypeRadioButtonList);
        for (var x = 0; x < radioButtons.length; x++) {
            if (radioButtons[x].checked) {
                settingType = radioButtons[x].value;
            }
        }

        // Get the new setting property name.
        var menuSettingProperty = $("#NewSettingProperty").val();

        if (settingType == 'txt') {
            var valuesArray = new Array(languages.length);

            // For each active language find the control and save the new value and add it to JSON obect.
            for (var index = 0; index < languages.length; index++) {

                // Add value toarray
                valuesArray[index] = $("#menuSetting_" + controlID + "_" + languages[index]).val();
            }

            // Convert value array to JSON object.
            var menuSettingValues = JSON.stringify(valuesArray);
        }
        else {
            var value = '';

            if (settingType == 'bln') {
                // Find the checked radio button and get its value.
                var rblName = "menuSetting_" + controlID;
                var radioButtons = document.getElementsByName(rblName);
                for (var x = 0; x < radioButtons.length; x++) {
                    if (radioButtons[x].checked) {
                        value = radioButtons[x].value;
                    }
                }
            }
            else {
                // If it is an integer or a string value take it from the input field.
                value = $("#menuSetting_" + controlID).val();
            }

        }
        var descriptionArray = new Array(languages.length);
        // For each active language find the control and save the description value and add it to JSON obect.
        for (var index = 0; index < languages.length; index++) {

            // Add description to array
            descriptionArray[index] = $("#menuSetting_" + "NewSettingDescription" + "_" + languages[index]).val();
        }

        // Convert description array to JSON object.
        var menuSettingDescription = JSON.stringify(descriptionArray);

        // Add new setting
        getJsonCI('Settings', 'AddNewSetting', function(data) {
            // Close thick box
            tb_remove();
        }, { menuSettingProperty: menuSettingProperty, menuSettingValue: value, clickedMenuID: clickedMenuID, menuSettingDescription: menuSettingDescription, menuSettingType: settingType, menuSettingValues: menuSettingValues });

    }
};


/* ContentItemSendMail.cs.js */

var ContentItemSendMail = {
    create: function (httpBaseUrl, subject, body, recipients, windowHeader) {

        // Show the create mail form.
        var url = httpBaseUrl + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?ID=' + menuID +
            '&name=SendMail&action=Create&width=600&height=430&pageUrl=' + document.location.href;
        tb_show(windowHeader, url, null, { subject: subject, body: body, recipients: recipients });

        // Set focus on recipients.
        $("#Recipients").focus();

    },

    send: function () {
        // Get the details from the form and send the mail.
        var recipients = $("#Recipients").val();
        var sender = $("#Sender").val();
        var subject = $("#Subject").val();
        var body = $("#Body").val();

        getJsonCI('SendMail',
        'Send',
        function (data) {
            if (data.messageToPerson == '') {
                tb_remove();
            }
            else {
                // Show the returned message.
                var message = $(".sendMailMessage");
                message.html(data.messageToPerson);
            }
        }
        , { recipients: recipients, sender: sender, subject: subject, body: body });
    }
};

/* ContentItemSearchInput.cs.js */

var ContentItemSearchInput = {
    search: function (searchBoxID, url, separator) {

        // get the search term from the search box.
        var searchBox = $("input[id$='" + searchBoxID + "']");
        var searchTerm = searchBox.val();

        // add the search term to the query string.
        if (searchTerm.length > 0) {
            window.location.href = url + separator + 'searchTerm=' + escape(searchTerm);
        } else {
            window.location.href = url;
            searchBox.focus();
        }

        // reset the search term in the search box.
        searchBox.val(searchTerm);

        return false;
    }
};

var ContentItemProductSubscriptionList = {
    checkbox: null,
    uniqueName: null,

    onChange: function(obj, productSubscriptionID, unqiueName, message) {
        this.checkbox = obj;
        this.uniqueName = unqiueName;

        if (obj.checked) {
            ContentItemProductSubscriptionList.autoRenew(productSubscriptionID);
        } else {
            ContentItemProductSubscriptionList.unsubscribe(productSubscriptionID, message);
        }
    },

    autoRenew: function(productSubscriptionID) {
    getJsonCI('ProductSubscriptionList', 'AutoRenew', function(data) {
        }, { productSubscriptionID: productSubscriptionID, unqiueName: this.uniqueName, menuID: menuID });
    },

    unsubscribe: function(productSubscriptionID, message) {
        if (confirm(labels.areYouSure + '\n' + message)) {
            getJsonCI('ProductSubscriptionList', 'Unsubscribe', function(data) {
        }, { productSubscriptionID: productSubscriptionID, unqiueName: this.uniqueName, menuID: menuID });
        } else {
            this.checkbox.checked = true;
        }
    }
};

var ContentItemProductSubscriptionListConfig = {
    save: function(menuID, uniqueName) {
        var postData = { menuID: menuID, uniqueName: uniqueName };
        $("#TB_ajaxContent input, #TB_ajaxContent select, #TB_ajaxContent textarea").each(function() {
            var field = $(this);
            // Get value for a radio button
            if (field.attr('type') == 'radio' || field.attr('type') == 'checkbox') {
                postData[field.attr('id')] = field.attr('checked');
            }
            else {
                postData[field.attr('id')] = field.val();
            }
        });

        getJsonCI('ProductSubscriptionListConfig', 'Save', function(data) {
            tb_remove();
        }, postData);
    }
}

var ContentItemProductDetails = {
    addProductToOrder: function(productID, defaultValue, labels, properties) {
        ContentItemProductList.addProductToOrder(productID, defaultValue, labels, properties);
    }
};

var ContentItemProductList = {
    addProductToOrder: function (productID, defaultValue, labels, postdata) {
        // get quantity and reset the input
        var quantityInput = $("input[id$='quantity_" + productID + "']");
        var quantity = toFloat(quantityInput.val());

        // if no quantity is entered, set it to 1.
        if (quantity == 0) {
            quantity = 1;
            quantityInput.val(defaultValue);
        }

        // if the quantity is not a number
        if (isNaN(quantity)) {
            quantityInput.val(defaultValue);
            return;
        }

        var attributesDescription = '';

        // add productcolor
        var color = $("input[id$='" + productID + "_color']");
        if (color.length > 0) {
            var value = color.val();
            if (!value || value.length == 0) {
                alert(labels.color);
                return;
            }

            attributesDescription = value;
        }

        // get attributes, if any exist
        var attributes = $("select[id*='Product_" + productID + "_attribute'],input[id*='Product_" + productID + "_attribute']")

        // create an object to store the selected attributes
        var selectedAttributes = {};
        var attributeIDRegex = new RegExp("^(.*)(attribute_)([0-9]+)(.*)$", "i");
        attributes.each(function (i) {

            // add the attribute ID and value for each selected attribute to the selectedAttributes object.
            var attributeIDParts = this.id.match(attributeIDRegex);
            var key = attributeIDParts[3];
            selectedAttributes[key] = this.value;

            // format the product attribute description.
            if (attributesDescription.length == 0) {
                attributesDescription += this.value;
            }
            else {
                attributesDescription += (', ' + this.value);
            }
        });

        var orderInformation = $("textarea[id$='orderInformation_" + productID + "']");
        var orderInformationLength = orderInformation.length;

        if (orderInformationLength != 0) {
            if (orderInformation.val() != '') {
                attributesDescription += (', ' + orderInformation.val());
            }
        }

        // save quantity and price to the server
        quantity = Math.round(quantity);

        if (!postdata) postdata = {};
        postdata.productID = productID;
        postdata.quantity = quantity;
        postdata.attributesDescription = attributesDescription;
        postdata.selectedAttributes = JSON.stringify(selectedAttributes);

        getJsonCI('ProductList', 'AddProductToOrder',
        function (data) {
            var messageDiv = $("div[id$='message_" + productID + "']");
            messageDiv.show();
            messageDiv.html(data.messages.success[0]);

            function hide() {
                $("div[id$='message_" + productID + "']").slideUp(3000);
            }

            setTimeout(hide, 3000);

        }, postdata);

        quantityInput.val(defaultValue);
    },

    updateProductPrice: function (productID, productPrice) {
        // ensure that the product price is culturally invariant.
        productPrice = toCultureInvariantNumber(productPrice);

        // get the current product price
        var priceSpan = $("span[id$='price_" + productID + "']");
        var currentProductPrice = priceSpan[0].innerHTML;

        var priceChange = 0.00;

        // get the attribute values from the drop down lists
        $("tr[id*='Product_" + productID + "_attribute'] option:selected").each(function () {
            var price = toFloat($(this).attr('number'));
            if (!isNaN(price)) {
                priceChange = priceChange + price;
            }
        });

        // calculate the new price using the change in price.
        var newProductPrice = (productPrice + priceChange).toFixed(2);

        // convert the new price to a string.
        newProductPrice = newProductPrice.toString();

        // display the new price with the correct decimal separator
        if (currentProductPrice.charAt(currentProductPrice.length - 3) == ',') {
            newProductPrice = newProductPrice.replace('.', ',')
        }

        // update the product price with the new price.
        priceSpan[0].innerHTML = "&euro; " + newProductPrice;
    }
};

$(document).ready(function() {

    // select all products and update them on page load.
    var productIDRegex = new RegExp("^.*product_", "gi");

    $("div[id*='product']").each(function() {
        var productID = ($(this)[0].id).replace(productIDRegex, "");
        var productPriceSpan = $("span[id$='price_" + productID + "']");

        if (productPriceSpan[0] != null) {
            var productPrice = productPriceSpan[0].innerHTML;
            ContentItemProductList.updateProductPrice(productID, productPrice);
        }
    });
});




/* ContentItemProductListNextSubCategory.cs.js */

var ContentItemProductListNextSubCategory = {
};

/* ContentItemProductListNextSubCategoryConfig.cs.js */

var ContentItemProductListNextSubCategoryConfig = {

    save: function(menuID, uniqueName) {
        var text = $("input[id='Text']").val();
        getJsonCI('ProductListNextSubCategoryConfig',
            'Save',
            function() { window.location.reload(); },
            {
                menuID: menuID,
                uniqueName: uniqueName,
                text: text
            });
    }
};

var ContentItemProductColorPicker = {
    instances: new Array(),

    // insert the choosen color
    insert: function(instanceID, seriesName, color, colorName) {
        var instance = this.getInstance(instanceID);

        // set the params
        var params = instance.params;
        params.productID = instance.productID;
        params.color = color;
        params.colorName = colorName;
        params.seriesName = seriesName;

        // call the callback function
        if ($.isFunction(instance.callback)) {
            instance.callback.call(this, params);
        }

        // close the popup
        tb_remove();
    },

    callback: function(data) {
        $("#" + data.clientID + " .sample").css("background-color", '#' + data.color);
        $("#" + data.clientID + " .seriesname").text(data.seriesName);
        $("#" + data.clientID + " .colorname").text(data.colorName);
        $("#" + data.clientID + " input[type=hidden]").val(data.seriesName + ' ' + data.colorName);
        $("#" + data.clientID).show();
    },

    // load the colors
    load: function(instanceID, colorsClientID, productColorSeriesID) {
        $("div[id$='" + colorsClientID + "']").load(
            baseURL + "valentnet/views/shared/handlers/ContentItemHandler.ashx",
            { name: 'ProductColorPicker', action: 'GetColors', ID: menuID, productColorSeriesID: productColorSeriesID, instanceID: instanceID }
        );
    },

    // open the color picker popup
    open: function(productID, callback, params) {
        var instance = this.getInstance();
        instance.productID = productID;
        instance.callback = callback;
        instance.params = params || {};

        // opens the popup with the color picker
        tb_show('Kies een kleur', baseURL + "valentnet/views/shared/handlers/ContentItemHandler.ashx", null,
            { productID: productID, name: 'ProductColorPicker', action: 'Show', ID: menuID, instanceID: instance.id });
    },

    // search within the colors
    search: function(instanceID, colorPlaceHolderID, value) {
        $("#" + colorPlaceHolderID + " .color").hide();
        $("#" + colorPlaceHolderID + " .color:search('" + value + "')").show();
    },

    // get an instance
    getInstance: function(instanceID) {
        // check if the instance exists
        if (instanceID != undefined) {
            return this.instances[instanceID];
        }

        // create new instance
        instanceID = this.instances.length;
        this.instances[instanceID] = new Object();
        this.instances[instanceID].id = instanceID;
        return this.instances[instanceID];
    }
};

var ContentItemProductCatalogListConfig = {

    save: function(menuID, uniqueName) {
    var productCatalogIDs = $("input[id='ProductCatalogIDs']").val();
        var hasHyperlinks = $("input[id='HasHyperlinks']").val();
        var showCaption = $("input[id='ShowCaption']").val();
        var showProductCatalogHeader = $("input[id='ShowProductCatalogHeader']").val();
        var hideCatalogBySelect = $("input[id='HideCatalogBySelect']").val();
        var navigateUrlPrefix = $("input[id='NavigateUrlPrefix']").val();
        
        getJsonCI('ProductCatalogListConfig',
            'Save',
            function() { window.location.reload(); },
            {
                menuID: menuID,
                uniqueName: uniqueName,
                productCatalogIDs: productCatalogIDs,
                hasHyperlinks: hasHyperlinks,
                showCaption: showCaption,
                showProductCatalogHeader: showProductCatalogHeader,
                hideCatalogBySelect: hideCatalogBySelect,
                navigateUrlPrefix: navigateUrlPrefix
            });
    }
};


/* ContentItemProductBrowserShowProduct.cs.js */

var ContentItemProductBrowserShowProduct = {
};

/* ContentItemProductBrowserShowProductConfig.cs.js */

var ContentItemProductBrowserShowProductConfig = {

    save: function(menuID, uniqueName) {
        var text = $("input[id='Text']").val();
        getJsonCI('ProductBrowserShowProductConfig',
            'Save',
            function() { window.location.reload(); },
            {
                menuID: menuID,
                uniqueName: uniqueName,
                text: text
            });
    }
};

/* ContentItemProductBrowserProductList.cs.js */

var ContentItemProductBrowserProductList = {
};

/* ContentItemProductBrowserProductListConfig.cs.js */

var ContentItemProductBrowserProductListConfig = {

    save: function(menuID, uniqueName) {
        var text = $("input[id='Text']").val();
        getJsonCI('ProductBrowserProductListConfig',
            'Save',
            function() { window.location.reload(); },
            {
                menuID: menuID,
                uniqueName: uniqueName,
                text: text
            });
    }
};

/* ContentItemProductBrowser.cs.js */

var ContentItemProductBrowser = {
};

/* ContentItemPopup.cs.js */

var ContentItemPopup = {
    show: function(inlineID, width, height, caption) {
        // Load the popup text in a light box.
        var url = '#TB_inline?height=' + height + '&width=' + width + '&inlineId=' + inlineID;
        tb_show(caption, url);

        $('#TB_window a').one('click', function(ev) {
            tb_remove();
        });

    }
};



/* ContentItemPopupConfig.cs.js */

var ContentItemPopupConfig = {

    save: function(menuID, uniqueName) {
        var width = $("input[id='Width']").val();
        var height = $("input[id='Height']").val();
        
        getJsonCI('PopupConfig',
            'Save',
            function() {},
            {
                menuID: menuID,
                uniqueName: uniqueName,
                width: width,
                height: height
            });
    }
};

/* ContentItemPhotoGallery.cs.js */

var ContentItemPhotoGallery = {
};

var ContentItemPersonLanguageSelector = {
    Init: function() {
        // On page load if a language is not selected in CheckBoxList, hide the associated fieds.
        $(".personLanguageSelector input:not(:checked)").each(function() {
            $("." + $(this).parent().attr("language")).hide();
        });
    },

    ToggleLanguage: function(show, language) {
        if (show) {
            $("." + language).show();
        }
        else {
            $("." + language).hide();
        }
        // Call method in Content Item to set language on or off and record in database.
        getJsonCI('PersonLanguageSelector', 'ToggleLanguage', function(data) { }, { language: language });
    }
};

/* ContentItemPeopleViewer.cs.js */

var ContentItemPeopleViewer = {
};

/* ContentItemPeopleViewerConfig.cs.js */

var ContentItemPeopleViewerConfig = {

    save: function (menuID, uniqueName) {
        var organizationID = $("select[id$='OrganizationID']").val();
        getJsonCI('PeopleViewerConfig',
            'Save',
            function () { window.location.reload(); },
            {
                menuID: menuID,
                uniqueName: uniqueName,
                organizationID: organizationID
            });
    }
};

var ContentItemPageTemplate = {
    Save: function(uniqueName, pageTemplateID) {
        getJsonCI('PageTemplate', 'Save', function(data) { }, 
        { uniqueName: uniqueName, pageTemplateID: pageTemplateID });
    }
};

var ContentItemPageMenuTabsConfig = {
    ToggleActive: function(tabID) {
        getJsonCI("PageMenuTabsConfig", "ToggleActive", function(data) {
            $(".submenu #li" + tabID).toggleClass("hidden");
        }, { tabID: tabID });
    },
    setAlternateTitle: function(tabID, alternateTitle, menuID) {
        getJsonCI('PageMenuTabsConfig', 'SetAlternateTitle', function(data) {
            $('.submenu #li' + tabID + ' .title').html(data.Title);
        }, { tabID: tabID, alternateTitle: alternateTitle, menuID: menuID });
    }
};

/* ContentItemNewsSenderUnsubscribe.cs.js */

var ContentItemNewsSenderUnsubscribe = {
    unsubscribe: function(controlID) {

        // Get email addresses.
        var emailAddresses = $("[id$='" + controlID + "_EmailAddressesTextArea']").val();

        getJsonCI('NewsSenderUnsubscribe', 'Unsubscribe', function(data) {

            // Replace content item html with status list.
            if (data.StatusList != undefined) {
                $("[id$='" + controlID + "']").html(data.StatusList);
            }

        }, { emailAddresses: emailAddresses });
    }
};

/* ContentItemNewsSenderSubscribe.cs.js */

var ContentItemNewsSenderSubscribe = {
    subscribe: function(controlID) {

        // Get email addresses.
        var emailAddresses = $("[id$='" + controlID + "_EmailAddressesTextArea']").val();

        getJsonCI('NewsSenderSubscribe', 'Subscribe', function(data) {

            // Replace content item html with status list.
            if (data.StatusList != undefined) {
                $("[id$='" + controlID + "']").html(data.StatusList);
            }

        }, { emailAddresses: emailAddresses });
    }
};

var ContentItemNews = {
    markAsRead: function(newsItemID) {
        getJsonCI('News', 'SetStatusAsRead',
            function(data) {
                var newsitem = $("[id$='newsitem" + newsItemID + "']");
                var hidden = $("input[id$='hddMarkAsRead" + newsItemID + "']");
                if (data.read) {
                    newsitem.addClass('crossed');
                    hidden.val(newsItemID);
                } else {
                    newsitem.removeClass('crossed');
                    hidden.val('');
                }
            },
            { menuID: menuID, newsitemID: newsItemID });
    },

    markAsReadOnReturn: function() {
        $("input[id*='hddMarkAsRead']").each(function() {
            var value = $(this).val();
            if (value.length > 0) {
                $("[id$='newsitem" + value + "']").addClass('crossed');
            }
        });
    }
};

$(document).ready(function() {
    ContentItemNews.markAsReadOnReturn();
});

var ContentItemMenuRelations = {
    Toggle: function(menuID1, menuID2) {
    getJsonCI('MenuRelations', 'Toggle', null, {menuID1: menuID1, menuID2: menuID2});
    }
};

/* ContentItemMenuRecycleBin.cs.js */

var ContentItemMenuRecycleBin = {
    show: function(httpBaseUrl) {
        // Load the list of recyclebin menu items in a light box.
        var url = httpBaseUrl + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?ID=' + menuID +
            '&width=600&height=500&name=MenuRecycleBin&action=Show&pageUrl=' + document.location.href;
        tb_show('', url);
    },
    
    restore: function(menuID) {
        // Restore the menu item.
        getJsonCI('MenuRecycleBin', 'Restore', function(data) {
            if (data.Restored == true) {
                // Reload the window displaying the restored menu item.
                window.location.reload();
            }
        }
        , { menuID: menuID });
    }
};

/* ContentItemMenuManager.cs.js */

var ContentItemMenuManager = {

    unfoldMenuToolbar: function() {
        $.cookie('MenuToolbarState', 'UNFOLDED', { expires: 7, path: '/' });
        $('.contentItemMenuManagerToolbarCollapsed').hide('slide', { direction: 'left' }, 0, function() { $('.contentItemMenuManagerToolbarUnfolded').show('slide', { direction: 'left' }, 100); });
    },

    collapseMenuToolbar: function() {
        $.cookie('MenuToolbarState', 'COLLAPSED', { expires: 7, path: '/' });
        $('.contentItemMenuManagerToolbarUnfolded').hide('slide', {}, 100, function() { $('.contentItemMenuManagerToolbarCollapsed').show('slide', {}, 0); });
    },

    unfoldContextMenu: function() {
        $.cookie('ContextMenuState', 'UNFOLDED', { expires: 7, path: '/' });
        $('.contentItemMenuManagerContextMenuUnfolded').show();
        $('.contentItemMenuManagerContextMenuCollapsed').hide();
    },

    collapseContextMenu: function() {
        $.cookie('ContextMenuState', 'COLLAPSED', { expires: 7, path: '/' });
        $('.contentItemMenuManagerContextMenuUnfolded').hide();
        $('.contentItemMenuManagerContextMenuCollapsed').show();
    },

    handleEdit: function(httpBaseUrl, clickedMenuID) {
        var url = httpBaseUrl + 'ValentNet/Views/Menu/Popup.aspx?ID=' + clickedMenuID +
            '&action=Edit&width=600&height=500&TB_iframe=true';
        tb_show(labels.menuItem, url);
    },
    handleCreateAfter: function(httpBaseUrl, position, clickedMenuID) {
        var url = httpBaseUrl + 'ValentNet/Views/Menu/Popup.aspx?ID=' + clickedMenuID +
            '&action=Create&position=After&width=600&height=500&TB_iframe=true';
        tb_show('', url);
    },
    handleCreateBefore: function(httpBaseUrl, position, clickedMenuID) {
        var url = httpBaseUrl + 'ValentNet/Views/Menu/Popup.aspx?ID=' + clickedMenuID +
                '&action=Create&position=Before&width=600&height=500&TB_iframe=true';
        tb_show('', url);
    },
    handleCreateLower: function(httpBaseUrl, position, clickedMenuID) {
        var url = httpBaseUrl + 'ValentNet/Views/Menu/Popup.aspx?ID=' + clickedMenuID +
                '&action=Create&position=Lower&width=600&height=500&TB_iframe=true';
        tb_show('', url);
    },

    handleEditRights: function(httpBaseUrl, clickedMenuID) {
        var url = httpBaseUrl + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?clickedMenuID=' + clickedMenuID +
            '&width=600&height=500&name=MenuManager&action=EditRights&pageUrl=' + document.location.href;
        tb_show('', url);
    },

    handleSetRights: function(groupID, rights, clickedMenuID) {
        // call server to update
        getJsonCI('MenuManager', 'SetRights', null, { groupID: groupID, rights: rights, clickedMenuID: clickedMenuID });
    },

    handleDelete: function(clickedMenuID) {
        // ask confirmation for this scary action
        if (confirm(labels.confirmDeleteItem)) {
            // call server to update
            getJsonCI('MenuManager', 'Delete', function(data) {
                $clickedItem = $('#ctl00_mtMaster_li' + data.ClickedMenuID)
                if ($clickedItem.hasClass("selected")) {
                    // Deleted item was selected. Navigate to previous, next or parent item in list.
                    $new = $clickedItem.next();
                    if ($new.length == 0) $new = $clickedItem.prev();
                    if ($new.length == 0) $new = $clickedItem.parent();
                    window.location = $new.find('a').attr('href');
                    window.location.reload();
                }
                else {
                    // The deleted item is not the current page, so just remove it from the menu.
                    $clickedItem.remove();
                }
            }, { clickedMenuID: clickedMenuID });
        }
    },

    handleSetVisibility: function(clickedMenuID) {
        getJsonCI('MenuManager', 'SetVisibility', function(data) {
            // Select the link of the menu item
            var $curr = $('#ctl00_mtMaster_li' + data.ClickedMenuID + ' a:first');

            var toolbarVisibilityToggle = $(".visibilityToggle");

            if (data.Hidden) {
                // Grey out menu item
                $curr.addClass('invisible');

                if (data.ClickedMenuID == menuID) {
                    toolbarVisibilityToggle.attr({ title: data.Title });
                    toolbarVisibilityToggle.children().attr({ src: baseURL + 'ValentNet/Content/icons/16x16/eye.png' });
                }
            }
            else {
                // Remove grey out.
                $curr.removeClass('invisible');
                if (data.ClickedMenuID == menuID) {
                    toolbarVisibilityToggle.attr({ title: data.Title });
                    toolbarVisibilityToggle.children().attr({ src: baseURL + 'ValentNet/Content/icons/16x16/eyeCross.png' });
                }
            }
        }, { clickedMenuID: clickedMenuID });
    },

    handleLink: function(httpBaseUrl, clickedMenuID) {
        var url = httpBaseUrl + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?clickedMenuID=' + clickedMenuID +
            '&width=600&height=500&name=MenuLinkTo&action=ShowLinkableMenus&pageUrl=' + document.location.href;
        tb_show('', url);
    },

    handleUnlinkCopyContentConfirm: function(httpBaseUrl, clickedMenuID) {
        var url = httpBaseUrl + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?clickedMenuID=' + clickedMenuID +
            '&width=350&height=70&modal=true&name=MenuLinkTo&action=UnlinkCopyContentConfirm&pageUrl=' + document.location.href;
        tb_show('', url);
    },

    handleMoveUp: function(clickedMenuID) {
        // check if there is a previous menu item
        var $curr = $('#ctl00_mtMaster_li' + clickedMenuID);
        if ($curr.prev().length == 0) return;
        if ($curr.hasClass('content') && $curr.prev().hasClass('admin')) return;

        // call server to update
        getJsonCI('MenuManager', 'MoveUp', function(data) {
            if (data.Moved == false) return;
            var $curr = $('#ctl00_mtMaster_li' + data.ClickedMenuID);
            $curr.swap($curr.prev());
        }, { clickedMenuID: clickedMenuID });
    },

    handleMoveDown: function(clickedMenuID) {
        // check if there is a next menu item
        var $curr = $('#ctl00_mtMaster_li' + clickedMenuID);
        if ($curr.hasClass('admin') && $curr.next().hasClass('content')) return;
        if ($curr.next().length == 0) return;

        // call server to update
        getJsonCI('MenuManager', 'MoveDown', function(data) {
            if (data.Moved == false) return;
            var $curr = $('#ctl00_mtMaster_li' + data.ClickedMenuID);
            $curr.swap($curr.next());
        }, { clickedMenuID: clickedMenuID });
    },

    handleSetMenuLanguages: function(httpBaseUrl, clickedMenuID) {
        var url = httpBaseUrl + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?clickedMenuID=' + clickedMenuID +
            '&width=600&height=500&name=MenuLanguages&action=List&pageUrl=' + document.location.href;
        tb_show('', url);
    },

    handleEditMenuRelations: function(httpBaseUrl, clickedMenuID) {
        var url = httpBaseUrl + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?clickedMenuID=' + clickedMenuID +
            '&width=600&height=500&name=MenuRelations&action=Edit&pageUrl=' + document.location.href;
        tb_show('', url);
    },

    handleEditPageMenuTabs: function(httpBaseUrl, selectedTabID, clickedMenuID) {
        var url = httpBaseUrl + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?clickedMenuID=' + clickedMenuID +
            '&width=600&height=500&name=PageMenuTabsConfig&action=Edit&selectedTabID=' + selectedTabID + '&pageUrl=' + document.location.href;
        tb_show('', url);
    },

    handleSettings: function(httpBaseUrl, clickedMenuID) {
        var url = httpBaseUrl + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?clickedMenuID=' + clickedMenuID +
            '&width=600&height=500&name=Settings&action=List&pageUrl=' + document.location.href;
        tb_show('', url);
    },

    contextMenuEventHandler: function(event, clickedMenuID, currentTabID) {

        // IE doesn't pass the event object, rather it sets it globally on the window. Get that instead.
        if (event == null) {
            event = window.event;
        }

        // For IE
        var target = event.target != null ? event.target : event.srcElement;

        getJsonCI('MenuManager', 'BuildMenu', this.showContextMenu, { clickedMenuID: clickedMenuID, currentTabID: currentTabID, clientX: event.clientX, clientY: event.clientY });

        // Cancel event bubbling, so that this event doesn't get handled again for any parent elements in the tree.
        event.cancelBubble = true; // IE
        if (event.stopPropagation) event.stopPropagation(); // W3C

        return false;
    },

    showContextMenu: function(data) {
        // Find the context menu's div.
        var contextRootDiv = $("#" + data.ControlID);

        // Re-fill with HTML returned by the server.
        contextRootDiv.html(data.ContextMenu);

        var contextDiv = $(".contentItemMenuManagerContextMenu");

        // Determine click position (with IE workaround)
        var scrollTop = document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop;
        var scrollLeft = document.body.scrollLeft ? document.body.scrollLeft : document.documentElement.scrollLeft;

        var leftPos = data.ClientX + scrollLeft;
        var topPos = data.ClientY + scrollTop;

        // Expand or collapse the extra info panel, according to the user's cookie.
        var extraInfoCollapsed = $.cookie('ContextMenuState') == "COLLAPSED";
        if (extraInfoCollapsed) {
            ContentItemMenuManager.collapseContextMenu();
        } else {
            ContentItemMenuManager.unfoldContextMenu();
        }

        // How tall is the context menu?
        contextDiv.css({ top: "-10000px", left: leftPos + "0px" }); // Needed cause JQuery will temporarily render the div to determine its height.
        var contextMenuHeight = contextDiv.height();

        // How tall is the window?
        var ieHeight = (!document.documentElement.clientHeight || document.documentElement.clientHeight == 0) ? document.body.clientHeight : document.documentElement.clientHeight;
        var windowHeight = window.innerHeight || ieHeight;

        // Should the context menu cross the bottom edge of the window?
        if ((topPos + contextMenuHeight) > (scrollTop + windowHeight)) {
            // It would, so see if it's better to popup above (instead of below) the mouse cursor
            var hiddenHeightPopDown = (topPos + contextMenuHeight) - (scrollTop + windowHeight);
            var hiddenHeightPopUp = scrollTop - (topPos - contextMenuHeight);
            if ((hiddenHeightPopUp < hiddenHeightPopDown) && ((topPos - contextMenuHeight) >= 0)) {
                // The largest area of the context menu will be visible if we pop up instead of down.
                topPos = topPos - contextMenuHeight;
            }
        }

        // Position the context menu correctly, and show it.
        contextDiv.css({ top: topPos + "px", left: leftPos + "px" });

        // Force IE7 to set the width of the menu items.
        var menuWidth = contextDiv.width();
        contextDiv.children().css({ width: menuWidth + "px" });

        contextDiv.show();

        // Make sure to hide again once a click is registered on the document.
        $(document).one('click', function(ev) {
            //contextDiv.html("");
            contextDiv.hide();
        });

        $(".preventContextMenuHide").click(function(event) {
            // Cancel event bubbling, so that this event doesn't get handled again for any parent elements in the tree.
            // Makes sure the onclick event for the element marked with the preventContextMenuHide class doesn't
            // propagate up to the document level where it would get handled by the onclick event handler we just 
            // registered.
            event.cancelBubble = true; // IE
            if (event.stopPropagation) event.stopPropagation(); // W3C
        });
    }
};


/* ContentItemMenuManagerConfig.cs.js */

var ContentItemMenuManagerConfig = {

    save: function(menuID, uniqueName) {
        var text = $("input[id='Text']").val();
        getJsonCI('MenuManagerConfig',
            'Save',
            function() { window.location.reload(); },
            {
                menuID: menuID,
                uniqueName: uniqueName,
                text: text
            });
    }
};

/* ContentItemMenuLinkTo.cs.js */

var ContentItemMenuLinkTo = {
    link: function(menuID, sourceID) {
        // Call the link method passing the menuID and the ID of menu to be linked to.
        getJsonCI('MenuLinkTo', 'Link', function(data) {
            tb_remove();

            // reload the page
            window.location.reload();
        }, { clickedMenuID: menuID, sourceID: sourceID });
    },

    unlink: function(clickedMenuID, copyContent) {
        // Call the unlink method passing the menuID and bool to indicate whether to copy the content.
        getJsonCI('MenuLinkTo', 'Unlink', function(data) {
            tb_remove();
            
            // reload the page
            window.location.reload();
        },
            { clickedMenuID: clickedMenuID, copyContent: copyContent });
    }
};

/* ContentItemMenuLanguages.cs.js */

var ContentItemMenuLanguages = {
    toggleLanguage: function(language, menuID) {
    // Call method in Content Item to set language on or off and record in database.
        getJsonCI('MenuLanguages', 'ToggleLanguage', function(data) { }, { language: language, menuID: menuID });
    }
};

/* ContentItemMailingSubscriptions.cs.js */

var ContentItemMailingSubscriptions = {
    toggleSubscription: function(mailingMenuID, mailingName, personID, subscribed) {
        getJsonCI('MailingSubscriptions', 'ToggleSubscription', function(data) {
        }, { mailingMenuID: mailingMenuID, mailingName: mailingName, personID: personID, subscribed: subscribed });
    }
};

/* ContentItemLogin.cs.js */

var ContentItemLogin = {
    keyEnter: function(e) {
        var keynum = 0;
        if (window.event) { keynum = e.keyCode; }
        else if (e.which) { keynum = e.which; }

        // enter
        return keynum == 13;
    },

    keySubmit: function(e) {
        var keynum = 0;
        if (window.event) { keynum = e.keyCode; }
        else if (e.which) { keynum = e.which; }

        // enter || space
        return keynum == 13 || keynum == 32;
    },

    focus: function(controlID) {
        var fld = $("#" + controlID);
        if (fld.length) {
            fld.focus();
        }
    },

    doLogin: function(controlID, suffix) {
        if (!suffix) {
            suffix = '';
        }

        // find the login name field
        var fld = $("input[id$='" + controlID + "_txtLoginName" + suffix + "']");
        if (!fld.length || fld.length == 0) {
            return;
        }

        // check the login name
        var loginName = fld.val();
        if (loginName.length == 0) {
            fld.focus();
            return;
        }

        // find the password field
        fld = $("input[id$='" + controlID + "_txtLoginPassword" + suffix + "']");
        if (!fld.length || fld.length == 0) {
            return;
        }

        // check the password
        var password = fld.val();
        if (password.length == 0) {
            fld.focus();
            return;
        }

        // find and check the login type
        var loginType = $("#" + controlID + " input:checked").val();
        if (loginType.length == 0) {
            return;
        }

        // login
        getJsonCI('Login', 'Login', function(data) {
            if (!data.loginResponse) {
                if (data.focus) {
                    $("input[id$='" + controlID + "_" + data.focus + "']").focus();
                }
            } else if (data.returnUrl && data.returnUrl.length > 0) {
                document.location.href = data.returnUrl;
            } else if (data.loginResponse == 'Success') {
                window.location.reload(true);
            }
        },
            { uniqueName: controlID, loginName: loginName, password: password, loginType: loginType });
    }
};

/* ContentItemDisplayLanguageSwitch.cs.js */

var ContentItemDisplayLanguageSwitch = {
};

$(document).ready(function() {

    if ($('.displayLanguageSwitch').length > 0) {
        $('.displayLanguageSwitch .dropDownArrow').click(function() {
            $('.displayLanguageSwitch .otherLanguages').toggle();
        });

        $('.displayLanguageSwitch .otherLanguages li').click(function() {

            var newDisplayLanguage = $(this).attr('displayLanguage');
            if (newDisplayLanguage != null) {

                // save new display language on the server and reload this window
                getJsonCI('DisplayLanguageSwitch',
                    'SwitchLanguage',
                    function() { window.location.reload(); },
                    {
                        lan: newDisplayLanguage
                    });

            } else {
                $('.displayLanguageSwitch .otherLanguages').hide();
            }
        });
    }
});

var ContentItemLanguageSelector = {
    switchLanguage: function (language) {
        getJsonCI('LanguageSelector', 'SwitchLanguage',
        function (data) {
            if (data.languageID != '0') {
                window.location.href = window.location.href.replace(new RegExp('/[A-Za-z]{2}/'), '/' + data.languageID + '/');
            }
        },
        { lan: language });
    }
};

var ContentItemKeepSessionAlive = {

    intervalID: null,

    setKeepSessionAlive: function(keepSessionAlive) {
        getJsonCI('KeepSessionAlive',
            'SetKeepSessionAlive',
            function(data) {
                if (data.KeepSessionAlive) {
                    $('.sessionTimesOut').hide();
                    $('.sessionIsKeptAlive').show();
                    ContentItemKeepSessionAlive.keepSessionAliveHeartBeat();
                    ContentItemKeepSessionAlive.startKeepSessionAlive();
                }
                else {
                    $('.sessionIsKeptAlive').hide();
                    $('.sessionTimesOut').show();
                    ContentItemKeepSessionAlive.stopKeepSessionAlive();
                }
            },
            { KeepSessionAlive: keepSessionAlive.toString() });
    },

    startKeepSessionAlive: function() {
        ContentItemKeepSessionAlive.intervalID = setInterval('ContentItemKeepSessionAlive.keepSessionAliveHeartBeat();', 300000);
    },

    stopKeepSessionAlive: function() {
        clearInterval(this.intervalID);
    },

    keepSessionAliveHeartBeat: function() {
        getJsonCI('KeepSessionAlive', 'KeepSessionAliveHeartBeat', null, { random: Math.random() });
    }
};

var ContentItemInvoiceListConfig = {
    save: function(menuID, uniqueName) {
        var postData = { menuID: menuID, uniqueName: uniqueName };
        $("#TB_ajaxContent input, #TB_ajaxContent select, #TB_ajaxContent textarea").each(function() {
            var field = $(this);
            // Get value for a radio button
            if (field.attr('type') == 'radio' || field.attr('type') == 'checkbox') {
                postData[field.attr('id')] = field.attr('checked');
            }
            else {
                postData[field.attr('id')] = field.val();
            }
        });

        getJsonCI('InvoiceListConfig', 'Save', function(data) {
            tb_remove();
        }, postData);
    }
}

/* ContentItemInvoicePayment.cs.js */

var ContentItemInvoicePayment = {
    pay: function(controlID, associatedPaymentItemID, waitingMessage) {
        // show waiting box
        tb_waiting(waitingMessage);

        var bankaccount = '';

        var accountholder = '';

        var paymentMethod = ContentItemEventsCalendarSubscribePayment.getPaymentMethod(associatedPaymentItemID);

        if ($('#bankrekening_error')) { $('#bankrekening_error').remove(); }
        if ($('#accountholder_error')) { $('#accountholder_error').remove(); }

        // direct Debit
        if (paymentMethod == "32") {

            /* check values */
            bankaccount = ContentItemEventsCalendarSubscribePayment.getBankaccount(associatedPaymentItemID);
            var fault = false;
            if (bankaccount === "") {
                var error = '<span id="bankrekening_error" class="warning" style="color: rgb(255, 0, 0);"><img style="" src="/personeelsdocumenten/ValentNet/Content/icons/warning.gif" alt="*" title="Bankrekening is verplicht" class="warning" width="16" height="16"></span>';
                $("input[name$='bankaccount']").after(error);
                fault = true;
            }

            accountholder = ContentItemEventsCalendarSubscribePayment.getAccountholder(associatedPaymentItemID);

            if (accountholder === "") {
                var error = '<span id="accountholder_error" class="warning" style="color: rgb(255, 0, 0);"><img style="" src="/personeelsdocumenten/ValentNet/Content/icons/warning.gif" alt="*" title="Rekeninghouder is verplicht" class="warning" width="16" height="16"></span>';
                $("input[name$='accountholder']").after(error);
                fault = true;
            }
            if (fault) return false;
        }

        getJsonCI('InvoicePayment',
        'Pay',
        function(data) {

            // close waiting box
            tb_remove();

            // If there is a redirect url.
            if (data.afterPaymentUrl) {

                // disable pay button
                var payButton = $("[id$='PayButton']");
                payButton.attr("disabled", "true");

                setTimeout("window.location = '" + data.afterPaymentUrl + "'", 3000);
            }
            if (data.html) {
                document.close();
                document.open();
                document.write(data.html);
            }
        }
        , { controlID: controlID, paymentMethod: paymentMethod, bankaccount: bankaccount, accountholder: accountholder });
    }
};

/* ContentItemInvoicePaymentConfig.cs.js */

var ContentItemInvoicePaymentConfig = {

    save: function(menuID, uniqueName) {
        var postData = { menuID: menuID, uniqueName: uniqueName };
        $("#TB_ajaxContent input, #TB_ajaxContent select, #TB_ajaxContent textarea").each(function() {
            var field = $(this);
            // Get value for a radio button
            if (field.attr('type') == 'radio' || field.attr('type') == 'checkbox') {
                postData[field.attr('id')] = field.attr('checked');
            }
            else {
                postData[field.attr('id')] = field.val();
            }
        });

        getJsonCI('InvoicePaymentConfig', 'Save', function(data) {
            tb_remove();
        }, postData);
    }
};

/* ContentItemTimeRegistrationOverview.cs.js */
var ContentItemHoursWeekOverview = {
    getRows: function (offSet, callback) {
        getJsonCI('HoursWeekOverview',
                'GetRows',
                callback,
                { offSet: offSet });
    },

    setOffSet: function (newOffSet) {
        $('.hoursWeekOverview [id$=OffSet]').val(newOffSet);

        if (newOffSet < 0) {
            $('.hoursWeekOverview [id$=next]').show()
            $('.hoursWeekOverview [id$=current]').show()
        } else {
            $('.hoursWeekOverview [id$=next]').hide()
            $('.hoursWeekOverview [id$=current]').hide()
        }
    },

    move: function (offSet) {
        this.getRows(offSet, function (data) {
            $('.hoursWeekOverview .heading').html(data.headingText);

            $('.hoursWeekOverview table.list td').remove();
            $('.hoursWeekOverview table.list').append(data.tableRows);

            ContentItemHoursWeekOverview.setOffSet(offSet);
        });
    }
};

$(document).ready(function () {
    if ($('.hoursWeekOverview').length > 0) {
        ContentItemHoursWeekOverview.move(0);

        $("[id$=previous]").click(function () {
            ContentItemHoursWeekOverview.move($('.hoursWeekOverview [id$=OffSet]').val() - 1);
        });
        $("[id$=next]").click(function () {
            ContentItemHoursWeekOverview.move(parseInt($('.hoursWeekOverview [id$=OffSet]').val()) + 1);
        });
        $("[id$=current]").click(function () {
            ContentItemHoursWeekOverview.move(0);
        });
    }
});

var ContentItemHostHeader = {
    save: function(menusClientID, domainsClientID) {
        var menus = $("#" + menusClientID).val();
        var domains = $("#" + domainsClientID).val();

        getJsonCI('HostHeader', 'Save', function(data) { }, { menus: menus, domains: domains, menuID: menuID });
    }
};

var ContentItemHelpHint = {

    showHint: function(controlID) {

        var container = $("div[id$='" + controlID + "']");

        // check if the help hint is already filled from the server
        if (container.children().length == 0) {
            // retrieve text from the server
            getJsonCI('HelpHint', 'ShowHelpHint', function(data) {
                var container = $("div[id$='" + controlID + "']");
                container.html(data.html);
                container.show();
                container.parent().children('.adminToolbar').show();
                container.parent().children('.showLink').hide();
            }, { controlID: controlID });
        }
        else {
            // just show help hint
            container.slideDown();
        }
    },

    globalHelpHintEdit: function(applicationName, controlID) {
        $('.globalHelpHintText').hide();
        $('.globalHelpHintEdit').show();
        $('.globalHelpHintEditButton').hide();
        $('.globalHelpHintSaveButton').show();
        $('.globalHelpHintCancelButton').show();
        $('.globalHelpHintHideButton').hide();
    },

    globalHelpHintSave: function(applicationName, controlID) {
        getJsonCI('HelpHint', 'SaveGlobalHint', function(data) {
            $('.globalHelpHintText').html(Trim($('.globalHelpHintEdit').val()));
            $('.globalHelpHintText').show();
            $('.globalHelpHintEdit').hide();
            $('.globalHelpHintEditButton').show();
            $('.globalHelpHintSaveButton').hide();
            $('.globalHelpHintCancelButton').hide();
            $('.globalHelpHintHideButton').show();
            ContentItemHelpHint.showNoHelpHintAvailable();
        },
        {
            applicationName: applicationName,
            controlID: controlID,
            text: Trim($('.globalHelpHintEdit').val())
        });
    },

    globalHelpHintCancel: function(applicationName, controlID) {
        $('.globalHelpHintEdit').val(Trim($('.globalHelpHintText').html()));

        $('.globalHelpHintText').show();
        $('.globalHelpHintEdit').hide();
        $('.globalHelpHintEditButton').show();
        $('.globalHelpHintSaveButton').hide();
        $('.globalHelpHintCancelButton').hide();
        $('.globalHelpHintHideButton').show();
    },

    globalHelpHintHide: function(applicationName, controlID) {
        getJsonCI('HelpHint', 'SetGlobalVisible', function(data) {
            $('.globalHelpHintText').hide();
            $('.globalHelpHintEdit').hide();
            $('.globalHelpHintEditButton').hide();
            $('.globalHelpHintHideButton').hide();
            $('.globalHelpHintShowButton').show();
            ContentItemHelpHint.showNoHelpHintAvailable();
        },
        {
            applicationName: applicationName,
            controlID: controlID,
            globalVisible: false
        });
    },

    globalHelpHintShow: function(applicationName, controlID) {
        getJsonCI('HelpHint', 'SetGlobalVisible', function(data) {
            $('.globalHelpHintText').show();
            $('.globalHelpHintEditButton').show();
            $('.globalHelpHintHideButton').show();
            $('.globalHelpHintShowButton').hide();
            ContentItemHelpHint.showNoHelpHintAvailable();
        },
        {
            applicationName: applicationName,
            controlID: controlID,
            globalVisible: true
        });
    },

    localHelpHintEdit: function(applicationName, controlID) {
        $('.localHelpHintText').hide();
        $('.localHelpHintEdit').show();
        $('.localHelpHintEditButton').hide();
        $('.localHelpHintSaveButton').show();
        $('.localHelpHintCancelButton').show();
    },

    localHelpHintSave: function(applicationName, controlID) {

        getJsonCI('HelpHint', 'SaveLocalHint', function(data) {
            $('.localHelpHintText').html(Trim($('.localHelpHintEdit').val()));
            $('.localHelpHintText').show();
            $('.localHelpHintEdit').hide();
            $('.localHelpHintEditButton').show();
            $('.localHelpHintSaveButton').hide();
            $('.localHelpHintCancelButton').hide();
            ContentItemHelpHint.showNoHelpHintAvailable();
        },
        {
            applicationName: applicationName,
            controlID: controlID,
            text: Trim($('.localHelpHintEdit').val())
        });
    },

    localHelpHintCancel: function(applicationName, controlID) {
        $('.localHelpHintEdit').val(Trim($('.localHelpHintText').html()));

        $('.localHelpHintText').show();
        $('.localHelpHintEdit').hide();
        $('.localHelpHintEditButton').show();
        $('.localHelpHintSaveButton').hide();
        $('.localHelpHintCancelButton').hide();
    },

    showNoHelpHintAvailable: function() {
        var globalText = Trim($('.globalHelpHintText').html());
        var globalVisible = $('.globalHelpHintText:visible').length > 0;
        var localText = Trim($('.localHelpHintText').html());
        if ((globalText.length == 0 || globalVisible == false) && localText == 0) {
            $('.noHelpHintAvailable').show();
        } else {
            $('.noHelpHintAvailable').hide();
        }
    }
};

var ContentItemGoogleSearch = {

    Init: function() {
    var f = document.getElementById('cse-search-box');
    if (f) {

        var q = document.getElementById('q');
        var n = navigator;
        var l = location;
        if (n.platform == 'Win32') {
            q.style.cssText = 'border: 1px solid #7e9db9; padding: 2px;';
        }

        var b = function() { if (q.value == '') q.className = 'watermark'; };
        var f = function() { q.className = 'search'; };

        q.onfocus = f;
        q.onblur = b;

        if (!/[&?]q=[^&]/.test(l.search)) {
            b();
        }
    }
},

    Keydown: function() {
        if (window.event) {
            key = window.event.keyCode;     //IE
        }
        else {
            key = e.which;     //firefox
        }

        if (key == 13) {
            event.returnValue = false;
            event.cancel = true;
            document.getElementById('cse-search-button').click();
        }
    },

    Search: function(ie, cx) {
        location.href = 'http://www.google.com/cse?q=' + escape(document.getElementById('q').value) +
        '&ie=' + ie + '&cx=' + cx;
    }
};

$(document).ready(function() {
    ContentItemGoogleSearch.Init();
});

/* ContentItemForumQuestionView.cs.js */

var ContentItemForumQuestionView = {
    deleteQuestion: function(forumQuestionID, redirectUrl) {
        ContentItemForumQuestion.deleteQuestion(forumQuestionID, redirectUrl)
    }
};

/* ContentItemForumQuestionFaqConfig.cs.js */

var ContentItemForumQuestionFaqConfig = {

    save: function(menuID, uniqueName) {
        var questionLimit = $("input[id='QuestionLimit']").val();
        getJsonCI('ForumQuestionFaqConfig',
            'Save',
            function() { window.location.reload(); },
            {
                menuID: menuID,
                uniqueName: uniqueName,
                questionLimit: questionLimit
            });
    }
};


/* ContentItemForumQuestion.cs.js */

var ContentItemForumQuestion = {
    save: function(menuID, controlID, redirectUrl) {
        var editor = tinyMCE.get('ctl00_cs1_' + controlID + '_Description_editor') || tinyMCE.get('ctl01_Cs1_' + controlID + '_Description_editor');

        // Get data.
        var forumQuestionID = $(document).getUrlParam('forumQuestionID');
        var question = $("input[id$='Question_" + controlID + "']").val();
        var description = editor.getContent();
        var tags = $("input[id$='ContentItemUntypedTags_TagBox']").val();

        // Post question.
        getJsonCI('ForumQuestion', 'Save', function(data) {
            if (data.RedirectUrl != undefined) {
                // Redirect to new question page.
                window.location = data.RedirectUrl;
            }
        }, { question: question, description: description, tags: tags, menuID: menuID, redirectUrl: redirectUrl, forumQuestionID: forumQuestionID });
    },

    deleteQuestion: function(forumQuestionID, redirectUrl) {
        getJsonCI('ForumQuestion', 'Delete', function(data) {
            if (data.Deleted == true) {
                window.location = data.RedirectUrl;
            }
        }, { forumQuestionID: forumQuestionID, redirectUrl: redirectUrl });
    }
};



var ContentItemForm = {

    PageIndex: 1,

    PreviousPage: function(clientID, pageCount) {
        this.GotoPage(clientID, this.PageIndex - 1, pageCount);
    },

    NextPage: function(clientID, pageCount) {
        // validate the current page
        if (this.Validate(clientID) == false) return false;

        this.GotoPage(clientID, this.PageIndex + 1, pageCount);
    },

    GotoPage: function(clientID, index, pageCount) {
        // hide the current page and show the new one
        $("tr.Page" + this.PageIndex).hide();
        $("tr.Page" + index + ":not(.disabled)").show();

        var previous = $("input[id$='" + clientID + "_Previous']");
        var next = $("input[id$='" + clientID + "_Next']");
        var submit = $("input[id$='" + clientID + "_Submit']");

        // hide the previus button on the first page
        if (index == 1) { previous.hide(); } else { previous.show(); }

        // hide the next button on the last page
        if (index == pageCount) { next.hide(); } else { next.show(); }

        // hide the submit button except on the last page
        if (index != pageCount) { submit.hide(); } else { submit.show(); }

        // set the page index to the new page
        this.PageIndex = index;

        // show the current pageindex
        $("#" + clientID + "_CurrentPageIndex").html(index);

        // show or hide the required fields message
        var row = $("tr[id$='" + clientID + "_requiredFields']");
        var rows = $("tr.Page" + this.PageIndex + ":not(.disabled)");
        var length = rows.find("[id*=" + clientID + "].required").length;
        if (length > 0) { row.show(); } else { row.hide(); }
    },

    Post: function(clientID, postJS, postbackJS) {
        if (this.Validate(clientID) == false) return false;

        // get the post data
        var postData = {};
        var tableID = '';
        $("[id*=" + clientID + "]").each(function() {
            var field = $(this);
            var id = field.attr('id');

            if ((tableID == '' || id.indexOf(tableID) == -1) && id.indexOf('_error') == -1 && id.indexOf('_invalid') == -1) {

                if (field.attr('type') == 'checkbox') {
                    postData[id] = field.attr('checked');
                } else {
                    postData[id] = field.val();
                }

                tableID = '';

                if (field.get(0).tagName == 'TABLE') {
                    postData[id] = Array();
                    field.find("input:checked").each(function() { postData[id].push($(this).val()); });
                    tableID = id;
                }
            }
        });

        var action = 'Save';
        var typeName = 'Form';

        // before post
        if (postJS.length > 0) {
            eval(postJS);
        }

        // add loading image
        var timeoutID = setTimeout("ContentItemForm.Loading('" + clientID + "');", 500);

        // post the form
        getJsonCI(typeName, action,
            function(data) {
                // remove loading image
                clearTimeout(timeoutID);
                tb_remove();

                var redirectUrl = '';
                if (data.redirectUrl) {
                    redirectUrl = data.redirectUrl;
                }

                if (!data.error) {
                    var removeFormData = true;

                    // after post
                    if (postbackJS.length > 0) {
                        eval(postbackJS);
                    }

                    // eval data javascript
                    if (data.javascript && data.javascript.length > 0) {
                        eval(data.javascript);
                    }

                    // remove the form data
                    if (removeFormData) {
                        $("tr.Body input[id*='" + clientID + "']").each(function() {
                            var type = $(this).attr('type');
                            switch (type.toLowerCase()) {
                                case 'text':
                                case 'password':
                                    $(this).val('');
                                    break;
                                case 'radio':
                                case 'checkbox':
                                    $(this).removeAttr('checked');
                                    break;
                            }
                        });

                        $("tr.Body select[id*='" + clientID + "']").val('');
                        $("tr.Body textarea[id*='" + clientID + "']").val('');
                    }
                }

                // redirect to the new url
                if (redirectUrl && redirectUrl.length > 0) {
                    location.href = redirectUrl;
                }

                window.scroll(0, 0);

                // hide the form and show the message
                if (data.message && data.message.length > 0) {
                    $("div[id$='" + $("input[id$='" + clientID + "_ControlID']").val() + "']").html(data.message);
                }

            }, postData);

        return false;
    },

    Validate: function(clientID) {
        var isValid = true;
        var messages = { warning: Array() };

        // find the rows of the current page
        var rows = $("tr.Page" + this.PageIndex + ":not(.disabled)");

        rows.find("[id*=" + clientID + "].required").each(function() {
            var valid = true;
            var field = $(this);
            var span = $("#" + field.attr('id') + "_error");

            // check of the field has a value
            if (field.get(0).tagName == 'TABLE') {
                valid = field.find("input:checked").length > 0;
            }
            else if (field.val().length == 0 || serverValidate(field.val(), 'ShouldHaveValue', 1) == false) {
                valid = false;
            };

            // hide or show the error
            if (valid) {
                field.attr('valid', "yes");
                span.hide();
            } else {
                field.attr('valid', "no");
                span.show();
                messages.warning.push('<p>' + span.find("img").attr('title') + '</p>');
            }

            if (valid == false) isValid = false;
        });

        rows.find("[id*=" + clientID + "]").each(function() {
            var field = $(this);
            // check of the field is valid
            var className = field.attr('class');
            var index = className.indexOf('validate');
            var test = field.attr('valid') || "yes";
            if (index != -1 && test == "yes") {
                var span = $("#" + field.attr('id') + "_invalid");
                var required = field.hasClass('required') ? 1 : 0;

                if (className.indexOf('validateRange') != -1) {
                    var minimum = $("#" + field.attr('id') + "_minimum").val();
                    var maximum = $("#" + field.attr('id') + "_maximum").val();
                    var value = field.get(0).tagName == 'TABLE' ? field.find("input:checked").length : toFloat(field.val());

                    if ((value < minimum && minimum != 0) || (value > maximum && maximum != 0)) {
                        span.show();
                        messages.warning.push('<p>' + span.find("img").attr('title') + '</p>');
                        isValid = false;
                    } else {
                        span.hide();
                    }
                }
                else {
                    if (serverValidate(field.val(), 'ShouldBeValid' + className.substr(index + 8), required) == false) {
                        span.show();
                        messages.warning.push('<p>' + span.find("img").attr('title') + '</p>');
                        isValid = false;
                    } else {
                        span.hide();
                    }
                }
            }
        });

        // set messages
        if (messages && messages.warning.length > 0) {
            showMessages(messages);
        }

        // return status
        return isValid;
    },

    Loading: function(clientID) {
        var id = clientID.split('_')[0];
        if (typeof document.body.style.maxHeight === "undefined") {//if IE 6
            //$("body", "html").css({ height: "100%", width: "100%" });
            $("#" + id).css("overflow", "hidden");
            if (document.getElementById("TB_HideSelect") === null) {//iframe to hide select elements in ie6
                $("#" + id).append("<iframe id='TB_HideSelect'></iframe><div id='TB_overlay'></div><div id='TB_window'></div>");
                $("#TB_overlay").click(tb_remove);
            }
        } else {//all others
            if (document.getElementById("TB_overlay") === null) {
                $("#" + id).append("<div id='TB_overlay'></div><div id='TB_window'></div>");
                $("#TB_overlay").click(tb_remove);
            }
        }

        $("#TB_overlay").css("position", "absolute");
        $("#TB_window").css("position", "absolute");

        if (tb_detectMacXFF()) {
            $("#TB_overlay").addClass("TB_overlayMacFFBGHack"); //use png overlay so hide flash
        } else {
            $("#TB_overlay").addClass("TB_overlayBG"); //use background and opacity
        }

        //show loader
        $("#" + id).append("<div id='TB_load'><img src='" + imgLoader.src + "' /></div>"); //add loader to the page
        $('#TB_load')
            .css("position", "absolute")
            .show();
    }
};

var ContentItemFormConfig = {

    save: function(menuID, uniqueName) {
        var postData = { menuID: menuID, uniqueName: uniqueName };
        $("#TB_ajaxContent input, #TB_ajaxContent select, #TB_ajaxContent textarea").each(function() {
            var field = $(this);
            // Get value for a radio button
            if (field.attr('type') == 'radio' || field.attr('type') == 'checkbox') {
                postData[field.attr('id')] = field.attr('checked');
            }
            else {
                postData[field.attr('id')] = field.val();
            }
        });

        getJsonCI('FormConfig', 'Save', function(data) {
            tb_remove();
        }, postData);
    },

    getEmailFromCell: function(formDefinitionID, uniqueName) {
        // Get replacement email from cell html. 
        getJsonCI('FormConfig', 'GetEmailFromCell', function(data) {
            if (data != undefined) {
                $("[id$='EmailTable']").html(data.EmailTable);
            }
        }, { formDefinitionID: formDefinitionID, uniqueName: uniqueName });
    },

    toggleEmailFromSource: function(clickedControlID) {
        // Get controls
        var emailFromFieldsRadioButton = $("[id$='ManagerFromRadioButtonField']");
        var emailFieldsDropDownList = $("[id$='ManagerFromFieldID']");
        var emailFromRadioButton = $("[id$='ManagerFromRadioButtonFrom']");
        var emailFrom = $("[id$='ManagerFrom']");

        // Toggle controls between email from textbox and email fields drop down list.
        if (clickedControlID == 'ManagerFromRadioButtonField' && emailFromRadioButton.attr('checked') == true) {
            emailFromRadioButton.removeAttr('checked');
            emailFieldsDropDownList.removeAttr('disabled');
            emailFrom.attr('disabled', 'disabled');
        }

        if (clickedControlID == 'ManagerFromRadioButtonFrom' && emailFromFieldsRadioButton.attr('checked') == true) {
            emailFromFieldsRadioButton.removeAttr('checked');
            emailFrom.removeAttr('disabled');
            emailFieldsDropDownList.attr('disabled', 'disabled');
        }
    }
};

 

/* ContentItemFileUpload.cs.js */

var ContentItemFileUpload = {
    sfwUpload: {},

    swfUploadPreLoad: function () {
        var self = this;
        var loading = function () {
            $("div[id$='divLoadingContent']").show();

            var longLoad = function () {
                $("div[id$='divLoadingContent']").hide();
                $("div[id$='divLongLoading']").show();
            };
            this.customSettings.loadingTimeout = setTimeout(function () {
                longLoad.call(self)
            },
			15 * 1000);
        };

        this.javascriptObject = null;
        if (eval("typeof " + this.customSettings.javascriptObjectName + " != 'undefined'")) {
            this.javascriptObject = eval(this.customSettings.javascriptObjectName);
        }

        this.customSettings.loadingTimeout = setTimeout(function () {
            loading.call(self);
        },
		1 * 1000);
    },

    swfUploadLoaded: function () {
        var self = this;
        clearTimeout(this.customSettings.loadingTimeout);

        $("div[id$='divLoadingContent']").hide();
        $("div[id$='divLongLoading']").hide();
        $("div[id$='divAlternateContent']").hide();

        $("input[id$='btnCancel']").click(function () { self.cancelQueue(); });
    },

    swfUploadLoadFailed: function () {
        clearTimeout(this.customSettings.loadingTimeout);

        $("div[id$='divLoadingContent']").hide();
        $("div[id$='divLongLoading']").hide();
        $("div[id$='UploadProgress']").hide();
        $("div[id$='divAlternateContent']").show();
    },

    fileQueued: function (file) {
        try {
            if (this.javascriptObject && this.javascriptObject.fileQueued) {
                if (this.javascriptObject.fileQueued(this, file) == false) {
                    return false;
                };
            }

            var progress = new FileProgress(file, this.customSettings.progressTarget);
            if (this.customSettings.autoStartUpload == false) {
                progress.setStatus("Click save to upload...");
            } else {
                progress.setStatus("Pending...");
            }
            progress.toggleCancel(true, this);
        } catch (ex) {
            this.debug(ex);
        }
    },

    fileQueueError: function (file, errorCode, message) {
        try {
            if (errorCode === SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) {
                alert("You have attempted to queue too many files.\n" + (message === 0 ? "You have reached the upload limit." : "You may select " + (message > 1 ? "up to " + message + " files." : "one file.")));
                return;
            }

            var progress = new FileProgress(file, this.customSettings.progressTarget);
            progress.setError();
            progress.toggleCancel(false);

            switch (errorCode) {
                case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
                    progress.setStatus("File is too big.");
                    this.debug("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
                    break;
                case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
                    progress.setStatus("Cannot upload Zero Byte files.");
                    this.debug("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
                    break;
                case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
                    progress.setStatus("Invalid File Type.");
                    this.debug("Error Code: Invalid File Type, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
                    break;
                default:
                    if (file !== null) {
                        progress.setStatus("Unhandled Error");
                    }
                    this.debug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
                    break;
            }
        } catch (ex) {
            this.debug(ex);
        }
    },

    fileDialogComplete: function (numFilesSelected, numFilesQueued) {
        try {
            if (numFilesSelected > 0) {
                $("input[id$='" + this.customSettings.cancelButtonId + "']").attr("disabled", false);
            }

            /* I want auto start the upload and I can do that here */
            if (this.customSettings.autoStartUpload) {
                this.startUpload();
            }
        } catch (ex) {
            this.debug(ex);
        }
    },

    uploadStart: function (file) {
        try {
            /* I don't want to do any file validation or anything,  I'll just update the UI and
            return true to indicate that the upload should start.
            It's important to update the UI here because in Linux no uploadProgress events are called. The best
            we can do is say we are uploading.
            */
            if (this.javascriptObject && this.javascriptObject.uploadStart) {
                if (this.javascriptObject.uploadStart(this, file) == false) {
                    return false;
                };
            }

            var progress = new FileProgress(file, this.customSettings.progressTarget);
            progress.setStatus("Uploading...");
            progress.toggleCancel(true, this);
        }
        catch (ex) { }

        return true;
    },

    uploadProgress: function (file, bytesLoaded, bytesTotal) {
        try {
            if (this.javascriptObject && this.javascriptObject.uploadProgress) {
                this.javascriptObject.uploadProgress(this, file, bytesLoaded, bytesTotal);
            }

            var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);
            var progress = new FileProgress(file, this.customSettings.progressTarget);
            progress.setProgress(percent);
            progress.setStatus("Uploading...");
        } catch (ex) {
            this.debug(ex);
        }
    },

    uploadSuccess: function (file, serverData) {
        try {
            if (this.javascriptObject && this.javascriptObject.uploadSuccess) {
                this.javascriptObject.uploadSuccess(this, file, serverData);
            }

            var progress = new FileProgress(file, this.customSettings.progressTarget);
            progress.setComplete();
            progress.setStatus("Complete.");
            progress.toggleCancel(false);
        } catch (ex) {
            this.debug(ex);
        }
    },

    uploadError: function (file, errorCode, message) {
        try {
            if (this.javascriptObject && this.javascriptObject.uploadError) {
                this.javascriptObject.uploadError(this, file, errorCode, message);
            }

            var progress = new FileProgress(file, this.customSettings.progressTarget);
            progress.setError();
            progress.toggleCancel(false);

            switch (errorCode) {
                case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
                    progress.setStatus("Upload Error: " + message);
                    this.debug("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message);
                    break;
                case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
                    progress.setStatus("Upload Failed.");
                    this.debug("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
                    break;
                case SWFUpload.UPLOAD_ERROR.IO_ERROR:
                    progress.setStatus("Server (IO) Error");
                    this.debug("Error Code: IO Error, File name: " + file.name + ", Message: " + message);
                    break;
                case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
                    progress.setStatus("Security Error");
                    this.debug("Error Code: Security Error, File name: " + file.name + ", Message: " + message);
                    break;
                case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
                    progress.setStatus("Upload limit exceeded.");
                    this.debug("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
                    break;
                case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:
                    progress.setStatus("Failed Validation.  Upload skipped.");
                    this.debug("Error Code: File Validation Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
                    break;
                case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
                    // If there aren't any files left (they were all cancelled) disable the cancel button
                    if (this.getStats().files_queued === 0) {
                        $("input[id$='" + this.customSettings.cancelButtonId + "']").attr("disabled", true);
                    }
                    progress.setStatus("Cancelled");
                    progress.setCancelled();
                    break;
                case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
                    progress.setStatus("Stopped");
                    break;
                default:
                    progress.setStatus("Unhandled Error: " + errorCode);
                    this.debug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
                    break;
            }
        } catch (ex) {
            this.debug(ex);
        }
    },

    uploadComplete: function (file) {
        if (this.javascriptObject && this.javascriptObject.uploadComplete) {
            this.javascriptObject.uploadComplete(this, file);
        }

        if (this.getStats().files_queued === 0) {
            $("input[id$='" + this.customSettings.cancelButtonId + "']").attr("disabled", true);
        }
    },

    startUpload: function (saveID) {
        this.sfwUpload.customSettings.saveButtonID = '#' + this.sfwUpload.customSettings[saveID];
        if (this.sfwUpload.getStats().files_queued > 0) {
            // start the upload
            this.sfwUpload.startUpload();
        } else if (this.sfwUpload.customSettings.isRequired) {
            var message = '<div style="position: absolute; width: 16px; heigth:16px;top:0px;left:100px;"><img src="' + baseURL +
                'ValentNet/Content/icons/warning.gif" class="warning" width="16" height="16" alt="*" title="' +
                this.sfwUpload.customSettings.requiredMessage + '" /></div>';
            $("#" + this.sfwUpload.customSettings.progressTarget)
                .html(message);
            var messages = { warning: Array() };
            messages.warning.push('<p>' + this.sfwUpload.customSettings.requiredMessage + '</p>');
            showMessages(messages);
        } else {
            // save the object
            tb_waiting(this.sfwUpload.customSettings.saveMessage);
            eval($(this.sfwUpload.customSettings.saveButtonID).attr('href').replace('javascript:', ''));
        }
    },

    // This event comes from the Queue Plugin
    queueComplete: function (numFilesUploaded) {
        $("div[id$='divStatus']").html(numFilesUploaded + " file" + (numFilesUploaded === 1 ? "" : "s") + " uploaded.");

        if (this.customSettings.autoStartUpload == false) {
            tb_waiting(this.customSettings.saveMessage);
            eval($(this.customSettings.saveButtonID).attr('href').replace('javascript:', ''));
        }
    }
};

/* ContentItemFileUploadConfig.cs.js */

var ContentItemFileUploadConfig = {

    save: function(menuID, uniqueName) {
        var postData = { menuID: menuID, uniqueName: uniqueName };
        $("#TB_ajaxContent input, #TB_ajaxContent select").each(function() {
            var field = $(this);
            postData[field.attr('id')] = field.val();
        });

        if (postData.ObjectTypeName.length == 0) {
            alert('Objecttypename is verplicht\nTODO ECH translate this alert');
            return;
        }

        getJsonCI('FileUploadConfig', 'Save', function() { tb_remove(); }, postData);
    },

    getProperties: function(menuId, uniqueName, objectTypeName) {
        var postData = { menuID: menuId, uniqueName: uniqueName, objectTypeName: objectTypeName };

        getJsonCI('FileUploadConfig', 'GetDefaultProperties',
            function(data) {
                $.each(data, function(key, obj) {
                    if (key != "messages") {
                        $("input[id$='" + key + "']")
                            .val(obj.value)
                            .attr('disabled', obj.disable);
                    }
                });
            },
            postData);
    }
};

/*
	A simple class for displaying file information and progress
	Note: This is a demonstration only and not part of SWFUpload.
	Note: Some have had problems adapting this class in IE7. It may not be suitable for your application.
*/

// Constructor
// file is a SWFUpload file object
// targetID is the HTML element id attribute that the FileProgress HTML structure will be added to.
// Instantiating a new FileProgress object with an existing file will reuse/update the existing DOM elements
function FileProgress(file, targetID) {
	this.fileProgressID = file.id;

	this.opacity = 100;
	this.height = 0;

	this.fileProgressWrapper = document.getElementById(this.fileProgressID);
	if (!this.fileProgressWrapper) {
		this.fileProgressWrapper = document.createElement("div");
		this.fileProgressWrapper.className = "progressWrapper";
		this.fileProgressWrapper.id = this.fileProgressID;

		this.fileProgressElement = document.createElement("div");
		this.fileProgressElement.className = "progressContainer";

		var progressCancel = document.createElement("a");
		progressCancel.className = "progressCancel";
		progressCancel.href = "#";
		progressCancel.style.visibility = "hidden";
		progressCancel.appendChild(document.createTextNode(" "));

		var progressText = document.createElement("div");
		progressText.className = "progressName";
		progressText.appendChild(document.createTextNode(file.name));

		var progressBar = document.createElement("div");
		progressBar.className = "progressBarInProgress";

		var progressStatus = document.createElement("div");
		progressStatus.className = "progressBarStatus";
		progressStatus.innerHTML = "&nbsp;";

		this.fileProgressElement.appendChild(progressCancel);
		this.fileProgressElement.appendChild(progressText);
		this.fileProgressElement.appendChild(progressStatus);
		this.fileProgressElement.appendChild(progressBar);

		this.fileProgressWrapper.appendChild(this.fileProgressElement);

		document.getElementById(targetID).appendChild(this.fileProgressWrapper);
	} else {
		this.fileProgressElement = this.fileProgressWrapper.firstChild;
		this.reset();
	}

	this.height = this.fileProgressWrapper.offsetHeight;
	this.setTimer(null);
}

FileProgress.prototype.setTimer = function (timer) {
	this.fileProgressElement["FP_TIMER"] = timer;
};
FileProgress.prototype.getTimer = function (timer) {
	return this.fileProgressElement["FP_TIMER"] || null;
};

FileProgress.prototype.reset = function () {
	this.fileProgressElement.className = "progressContainer";

	this.fileProgressElement.childNodes[2].innerHTML = "&nbsp;";
	this.fileProgressElement.childNodes[2].className = "progressBarStatus";
	
	this.fileProgressElement.childNodes[3].className = "progressBarInProgress";
	this.fileProgressElement.childNodes[3].style.width = "0%";
	
	this.appear();	
};

FileProgress.prototype.setProgress = function (percentage) {
	this.fileProgressElement.className = "progressContainer green";
	this.fileProgressElement.childNodes[3].className = "progressBarInProgress";
	this.fileProgressElement.childNodes[3].style.width = percentage + "%";

	this.appear();	
};
FileProgress.prototype.setComplete = function () {
	this.fileProgressElement.className = "progressContainer blue";
	this.fileProgressElement.childNodes[3].className = "progressBarComplete";
	this.fileProgressElement.childNodes[3].style.width = "";

	var oSelf = this;
	this.setTimer(setTimeout(function () {
		oSelf.disappear();
	}, 10000));
};
FileProgress.prototype.setError = function () {
	this.fileProgressElement.className = "progressContainer red";
	this.fileProgressElement.childNodes[3].className = "progressBarError";
	this.fileProgressElement.childNodes[3].style.width = "";

	var oSelf = this;
	this.setTimer(setTimeout(function () {
		oSelf.disappear();
	}, 5000));
};
FileProgress.prototype.setCancelled = function () {
	this.fileProgressElement.className = "progressContainer";
	this.fileProgressElement.childNodes[3].className = "progressBarError";
	this.fileProgressElement.childNodes[3].style.width = "";

	var oSelf = this;
	this.setTimer(setTimeout(function () {
		oSelf.disappear();
	}, 2000));
};
FileProgress.prototype.setStatus = function (status) {
	this.fileProgressElement.childNodes[2].innerHTML = status;
};

// Show/Hide the cancel button
FileProgress.prototype.toggleCancel = function (show, swfUploadInstance) {
	this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden";
	if (swfUploadInstance) {
		var fileID = this.fileProgressID;
		this.fileProgressElement.childNodes[0].onclick = function () {
			swfUploadInstance.cancelUpload(fileID);
			return false;
		};
	}
};

FileProgress.prototype.appear = function () {
	if (this.getTimer() !== null) {
		clearTimeout(this.getTimer());
		this.setTimer(null);
	}
	
	if (this.fileProgressWrapper.filters) {
		try {
			this.fileProgressWrapper.filters.item("DXImageTransform.Microsoft.Alpha").opacity = 100;
		} catch (e) {
			// If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
			this.fileProgressWrapper.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=100)";
		}
	} else {
		this.fileProgressWrapper.style.opacity = 1;
	}
		
	this.fileProgressWrapper.style.height = "";
	
	this.height = this.fileProgressWrapper.offsetHeight;
	this.opacity = 100;
	this.fileProgressWrapper.style.display = "";
	
};

// Fades out and clips away the FileProgress box.
FileProgress.prototype.disappear = function () {

	var reduceOpacityBy = 15;
	var reduceHeightBy = 4;
	var rate = 30;	// 15 fps

	if (this.opacity > 0) {
		this.opacity -= reduceOpacityBy;
		if (this.opacity < 0) {
			this.opacity = 0;
		}

		if (this.fileProgressWrapper.filters) {
			try {
				this.fileProgressWrapper.filters.item("DXImageTransform.Microsoft.Alpha").opacity = this.opacity;
			} catch (e) {
				// If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
				this.fileProgressWrapper.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + this.opacity + ")";
			}
		} else {
			this.fileProgressWrapper.style.opacity = this.opacity / 100;
		}
	}

	if (this.height > 0) {
		this.height -= reduceHeightBy;
		if (this.height < 0) {
			this.height = 0;
		}

		this.fileProgressWrapper.style.height = this.height + "px";
	}

	if (this.height > 0 || this.opacity > 0) {
		var oSelf = this;
		this.setTimer(setTimeout(function () {
			oSelf.disappear();
		}, rate));
	} else {
		this.fileProgressWrapper.style.display = "none";
		this.setTimer(null);
	}
};

/**
 * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
 *
 * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/,  http://www.vinterwebb.se/
 *
 * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilz�n and Mammon Media and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 */


/* ******************* */
/* Constructor & Init  */
/* ******************* */
var SWFUpload;

if (SWFUpload == undefined) {
	SWFUpload = function (settings) {
		this.initSWFUpload(settings);
	};
}

SWFUpload.prototype.initSWFUpload = function(settings) {
    try {
        this.customSettings = {}; // A container where developers can place their own settings associated with this instance.
        this.settings = settings;
        this.eventQueue = [];
        this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
        this.movieElement = null;


        // Setup global control tracking
        SWFUpload.instances[this.movieName] = this;

        // Load the settings.  Load the Flash movie.
        this.initSettings();
        this.loadFlash();
        this.displayDebugInfo();
    } catch (ex) {
        delete SWFUpload.instances[this.movieName];
        throw ex;
    }
};

/* *************** */
/* Static Members  */
/* *************** */
SWFUpload.instances = {};
SWFUpload.movieCount = 0;
SWFUpload.version = "2.2.0 2009-03-25";
SWFUpload.QUEUE_ERROR = {
	QUEUE_LIMIT_EXCEEDED	  		: -100,
	FILE_EXCEEDS_SIZE_LIMIT  		: -110,
	ZERO_BYTE_FILE			  		: -120,
	INVALID_FILETYPE		  		: -130
};
SWFUpload.UPLOAD_ERROR = {
	HTTP_ERROR				  		: -200,
	MISSING_UPLOAD_URL	      		: -210,
	IO_ERROR				  		: -220,
	SECURITY_ERROR			  		: -230,
	UPLOAD_LIMIT_EXCEEDED	  		: -240,
	UPLOAD_FAILED			  		: -250,
	SPECIFIED_FILE_ID_NOT_FOUND		: -260,
	FILE_VALIDATION_FAILED	  		: -270,
	FILE_CANCELLED			  		: -280,
	UPLOAD_STOPPED					: -290
};
SWFUpload.FILE_STATUS = {
	QUEUED		 : -1,
	IN_PROGRESS	 : -2,
	ERROR		 : -3,
	COMPLETE	 : -4,
	CANCELLED	 : -5
};
SWFUpload.BUTTON_ACTION = {
	SELECT_FILE  : -100,
	SELECT_FILES : -110,
	START_UPLOAD : -120
};
SWFUpload.CURSOR = {
	ARROW : -1,
	HAND : -2
};
SWFUpload.WINDOW_MODE = {
	WINDOW : "window",
	TRANSPARENT : "transparent",
	OPAQUE : "opaque"
};

// Private: takes a URL, determines if it is relative and converts to an absolute URL
// using the current site. Only processes the URL if it can, otherwise returns the URL untouched
SWFUpload.completeURL = function(url) {
	if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) {
		return url;
	}
	
	var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : "");
	
	var indexSlash = window.location.pathname.lastIndexOf("/");
	if (indexSlash <= 0) {
		path = "/";
	} else {
		path = window.location.pathname.substr(0, indexSlash) + "/";
	}
	
	return /*currentURL +*/ path + url;
	
};


/* ******************** */
/* Instance Members  */
/* ******************** */

// Private: initSettings ensures that all the
// settings are set, getting a default value if one was not assigned.
SWFUpload.prototype.initSettings = function () {
	this.ensureDefault = function (settingName, defaultValue) {
		this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
	};
	
	// Upload backend settings
	this.ensureDefault("upload_url", "");
	this.ensureDefault("preserve_relative_urls", false);
	this.ensureDefault("file_post_name", "Filedata");
	this.ensureDefault("post_params", {});
	this.ensureDefault("use_query_string", false);
	this.ensureDefault("requeue_on_error", false);
	this.ensureDefault("http_success", []);
	this.ensureDefault("assume_success_timeout", 0);
	
	// File Settings
	this.ensureDefault("file_types", "*.*");
	this.ensureDefault("file_types_description", "All Files");
	this.ensureDefault("file_size_limit", 0);	// Default zero means "unlimited"
	this.ensureDefault("file_upload_limit", 0);
	this.ensureDefault("file_queue_limit", 0);

	// Flash Settings
	this.ensureDefault("flash_url", "swfupload.swf");
	this.ensureDefault("prevent_swf_caching", true);
	
	// Button Settings
	this.ensureDefault("button_image_url", "");
	this.ensureDefault("button_width", 1);
	this.ensureDefault("button_height", 1);
	this.ensureDefault("button_text", "");
	this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;");
	this.ensureDefault("button_text_top_padding", 0);
	this.ensureDefault("button_text_left_padding", 0);
	this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES);
	this.ensureDefault("button_disabled", false);
	this.ensureDefault("button_placeholder_id", "");
	this.ensureDefault("button_placeholder", null);
	this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW);
	this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW);
	
	// Debug Settings
	this.ensureDefault("debug", false);
	this.settings.debug_enabled = this.settings.debug;	// Here to maintain v2 API
	
	// Event Handlers
	this.settings.return_upload_start_handler = this.returnUploadStart;
	this.ensureDefault("swfupload_loaded_handler", null);
	this.ensureDefault("file_dialog_start_handler", null);
	this.ensureDefault("file_queued_handler", null);
	this.ensureDefault("file_queue_error_handler", null);
	this.ensureDefault("file_dialog_complete_handler", null);
	
	this.ensureDefault("upload_start_handler", null);
	this.ensureDefault("upload_progress_handler", null);
	this.ensureDefault("upload_error_handler", null);
	this.ensureDefault("upload_success_handler", null);
	this.ensureDefault("upload_complete_handler", null);
	
	this.ensureDefault("debug_handler", this.debugMessage);

	this.ensureDefault("custom_settings", {});

	// Other settings
	this.customSettings = this.settings.custom_settings;
	
	// Update the flash url if needed
	if (!!this.settings.prevent_swf_caching) {
		this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime();
	}
	
	if (!this.settings.preserve_relative_urls) {
		//this.settings.flash_url = SWFUpload.completeURL(this.settings.flash_url);	// Don't need to do this one since flash doesn't look at it
		this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url);
		this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url);
	}
	
	delete this.ensureDefault;
};

// Private: loadFlash replaces the button_placeholder element with the flash movie.
SWFUpload.prototype.loadFlash = function () {
	var targetElement, tempParent;

	// Make sure an element with the ID we are going to use doesn't already exist
	if (document.getElementById(this.movieName) !== null) {
		throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
	}

	// Get the element where we will be placing the flash movie
	targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder;

	if (targetElement == undefined) {
		throw "Could not find the placeholder element: " + this.settings.button_placeholder_id;
	}

	// Append the container and load the flash
	tempParent = document.createElement("div");
	tempParent.innerHTML = this.getFlashHTML();	// Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
	targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);

	// Fix IE Flash/Form bug
	if (window[this.movieName] == undefined) {
		window[this.movieName] = this.getMovieElement();
	}
	
};

// Private: getFlashHTML generates the object tag needed to embed the flash in to the document
SWFUpload.prototype.getFlashHTML = function () {
	// Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
	return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">',
				'<param name="wmode" value="', this.settings.button_window_mode, '" />',
				'<param name="movie" value="', this.settings.flash_url, '" />',
				'<param name="quality" value="high" />',
				'<param name="menu" value="false" />',
				'<param name="allowScriptAccess" value="always" />',
				'<param name="flashvars" value="' + this.getFlashVars() + '" />',
				'</object>'].join("");
};

// Private: getFlashVars builds the parameter string that will be passed
// to flash in the flashvars param.
SWFUpload.prototype.getFlashVars = function () {
	// Build a string from the post param object
	var paramString = this.buildParamString();
	var httpSuccessString = this.settings.http_success.join(",");
	
	// Build the parameter string
	return ["movieName=", encodeURIComponent(this.movieName),
			"&amp;uploadURL=", encodeURIComponent(this.settings.upload_url),
			"&amp;useQueryString=", encodeURIComponent(this.settings.use_query_string),
			"&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
			"&amp;httpSuccess=", encodeURIComponent(httpSuccessString),
			"&amp;assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout),
			"&amp;params=", encodeURIComponent(paramString),
			"&amp;filePostName=", encodeURIComponent(this.settings.file_post_name),
			"&amp;fileTypes=", encodeURIComponent(this.settings.file_types),
			"&amp;fileTypesDescription=", encodeURIComponent(this.settings.file_types_description),
			"&amp;fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit),
			"&amp;fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit),
			"&amp;fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit),
			"&amp;debugEnabled=", encodeURIComponent(this.settings.debug_enabled),
			"&amp;buttonImageURL=", encodeURIComponent(this.settings.button_image_url),
			"&amp;buttonWidth=", encodeURIComponent(this.settings.button_width),
			"&amp;buttonHeight=", encodeURIComponent(this.settings.button_height),
			"&amp;buttonText=", encodeURIComponent(this.settings.button_text),
			"&amp;buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding),
			"&amp;buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding),
			"&amp;buttonTextStyle=", encodeURIComponent(this.settings.button_text_style),
			"&amp;buttonAction=", encodeURIComponent(this.settings.button_action),
			"&amp;buttonDisabled=", encodeURIComponent(this.settings.button_disabled),
			"&amp;buttonCursor=", encodeURIComponent(this.settings.button_cursor)
		].join("");
};

// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload
// The element is cached after the first lookup
SWFUpload.prototype.getMovieElement = function () {
	if (this.movieElement == undefined) {
		this.movieElement = document.getElementById(this.movieName);
	}

	if (this.movieElement === null) {
		throw "Could not find Flash element";
	}
	
	return this.movieElement;
};

// Private: buildParamString takes the name/value pairs in the post_params setting object
// and joins them up in to a string formatted "name=value&amp;name=value"
SWFUpload.prototype.buildParamString = function () {
	var postParams = this.settings.post_params; 
	var paramStringPairs = [];

	if (typeof(postParams) === "object") {
		for (var name in postParams) {
			if (postParams.hasOwnProperty(name)) {
				paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString()));
			}
		}
	}

	return paramStringPairs.join("&amp;");
};

// Public: Used to remove a SWFUpload instance from the page. This method strives to remove
// all references to the SWF, and other objects so memory is properly freed.
// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state.
// Credits: Major improvements provided by steffen
SWFUpload.prototype.destroy = function () {
	try {
		// Make sure Flash is done before we try to remove it
		this.cancelUpload(null, false);
		

		// Remove the SWFUpload DOM nodes
		var movieElement = null;
		movieElement = this.getMovieElement();
		
		if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
			// Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround)
			for (var i in movieElement) {
				try {
					if (typeof(movieElement[i]) === "function") {
						movieElement[i] = null;
					}
				} catch (ex1) {}
			}

			// Remove the Movie Element from the page
			try {
				movieElement.parentNode.removeChild(movieElement);
			} catch (ex) {}
		}
		
		// Remove IE form fix reference
		window[this.movieName] = null;

		// Destroy other references
		SWFUpload.instances[this.movieName] = null;
		delete SWFUpload.instances[this.movieName];

		this.movieElement = null;
		this.settings = null;
		this.customSettings = null;
		this.eventQueue = null;
		this.movieName = null;
		
		
		return true;
	} catch (ex2) {
		return false;
	}
};


// Public: displayDebugInfo prints out settings and configuration
// information about this SWFUpload instance.
// This function (and any references to it) can be deleted when placing
// SWFUpload in production.
SWFUpload.prototype.displayDebugInfo = function () {
	this.debug(
		[
			"---SWFUpload Instance Info---\n",
			"Version: ", SWFUpload.version, "\n",
			"Movie Name: ", this.movieName, "\n",
			"Settings:\n",
			"\t", "upload_url:               ", this.settings.upload_url, "\n",
			"\t", "flash_url:                ", this.settings.flash_url, "\n",
			"\t", "use_query_string:         ", this.settings.use_query_string.toString(), "\n",
			"\t", "requeue_on_error:         ", this.settings.requeue_on_error.toString(), "\n",
			"\t", "http_success:             ", this.settings.http_success.join(", "), "\n",
			"\t", "assume_success_timeout:   ", this.settings.assume_success_timeout, "\n",
			"\t", "file_post_name:           ", this.settings.file_post_name, "\n",
			"\t", "post_params:              ", this.settings.post_params.toString(), "\n",
			"\t", "file_types:               ", this.settings.file_types, "\n",
			"\t", "file_types_description:   ", this.settings.file_types_description, "\n",
			"\t", "file_size_limit:          ", this.settings.file_size_limit, "\n",
			"\t", "file_upload_limit:        ", this.settings.file_upload_limit, "\n",
			"\t", "file_queue_limit:         ", this.settings.file_queue_limit, "\n",
			"\t", "debug:                    ", this.settings.debug.toString(), "\n",

			"\t", "prevent_swf_caching:      ", this.settings.prevent_swf_caching.toString(), "\n",

			"\t", "button_placeholder_id:    ", this.settings.button_placeholder_id.toString(), "\n",
			"\t", "button_placeholder:       ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n",
			"\t", "button_image_url:         ", this.settings.button_image_url.toString(), "\n",
			"\t", "button_width:             ", this.settings.button_width.toString(), "\n",
			"\t", "button_height:            ", this.settings.button_height.toString(), "\n",
			"\t", "button_text:              ", this.settings.button_text.toString(), "\n",
			"\t", "button_text_style:        ", this.settings.button_text_style.toString(), "\n",
			"\t", "button_text_top_padding:  ", this.settings.button_text_top_padding.toString(), "\n",
			"\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n",
			"\t", "button_action:            ", this.settings.button_action.toString(), "\n",
			"\t", "button_disabled:          ", this.settings.button_disabled.toString(), "\n",

			"\t", "custom_settings:          ", this.settings.custom_settings.toString(), "\n",
			"Event Handlers:\n",
			"\t", "swfupload_loaded_handler assigned:  ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n",
			"\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n",
			"\t", "file_queued_handler assigned:       ", (typeof this.settings.file_queued_handler === "function").toString(), "\n",
			"\t", "file_queue_error_handler assigned:  ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n",
			"\t", "upload_start_handler assigned:      ", (typeof this.settings.upload_start_handler === "function").toString(), "\n",
			"\t", "upload_progress_handler assigned:   ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n",
			"\t", "upload_error_handler assigned:      ", (typeof this.settings.upload_error_handler === "function").toString(), "\n",
			"\t", "upload_success_handler assigned:    ", (typeof this.settings.upload_success_handler === "function").toString(), "\n",
			"\t", "upload_complete_handler assigned:   ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n",
			"\t", "debug_handler assigned:             ", (typeof this.settings.debug_handler === "function").toString(), "\n"
		].join("")
	);
};

/* Note: addSetting and getSetting are no longer used by SWFUpload but are included
	the maintain v2 API compatibility
*/
// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used.
SWFUpload.prototype.addSetting = function (name, value, default_value) {
    if (value == undefined) {
        return (this.settings[name] = default_value);
    } else {
        return (this.settings[name] = value);
	}
};

// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found.
SWFUpload.prototype.getSetting = function (name) {
    if (this.settings[name] != undefined) {
        return this.settings[name];
	}

    return "";
};



// Private: callFlash handles function calls made to the Flash element.
// Calls are made with a setTimeout for some functions to work around
// bugs in the ExternalInterface library.
SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
	argumentArray = argumentArray || [];
	
	var movieElement = this.getMovieElement();
	var returnValue, returnString;

	// Flash's method if calling ExternalInterface methods (code adapted from MooTools).
	try {
		returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>');
		returnValue = eval(returnString);
	} catch (ex) {
		throw "Call to " + functionName + " failed";
	}
	
	// Unescape file post param values
	if (returnValue != undefined && typeof returnValue.post === "object") {
		returnValue = this.unescapeFilePostParams(returnValue);
	}

	return returnValue;
};

/* *****************************
	-- Flash control methods --
	Your UI should use these
	to operate SWFUpload
   ***************************** */

// WARNING: this function does not work in Flash Player 10
// Public: selectFile causes a File Selection Dialog window to appear.  This
// dialog only allows 1 file to be selected.
SWFUpload.prototype.selectFile = function () {
	this.callFlash("SelectFile");
};

// WARNING: this function does not work in Flash Player 10
// Public: selectFiles causes a File Selection Dialog window to appear/ This
// dialog allows the user to select any number of files
// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names.
// If the selection name length is too long the dialog will fail in an unpredictable manner.  There is no work-around
// for this bug.
SWFUpload.prototype.selectFiles = function () {
	this.callFlash("SelectFiles");
};


// Public: startUpload starts uploading the first file in the queue unless
// the optional parameter 'fileID' specifies the ID 
SWFUpload.prototype.startUpload = function (fileID) {
	this.callFlash("StartUpload", [fileID]);
};

// Public: cancelUpload cancels any queued file.  The fileID parameter may be the file ID or index.
// If you do not specify a fileID the current uploading file or first file in the queue is cancelled.
// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter.
SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) {
	if (triggerErrorEvent !== false) {
		triggerErrorEvent = true;
	}
	this.callFlash("CancelUpload", [fileID, triggerErrorEvent]);
};

// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue.
// If nothing is currently uploading then nothing happens.
SWFUpload.prototype.stopUpload = function () {
	this.callFlash("StopUpload");
};

/* ************************
 * Settings methods
 *   These methods change the SWFUpload settings.
 *   SWFUpload settings should not be changed directly on the settings object
 *   since many of the settings need to be passed to Flash in order to take
 *   effect.
 * *********************** */

// Public: getStats gets the file statistics object.
SWFUpload.prototype.getStats = function () {
	return this.callFlash("GetStats");
};

// Public: setStats changes the SWFUpload statistics.  You shouldn't need to 
// change the statistics but you can.  Changing the statistics does not
// affect SWFUpload accept for the successful_uploads count which is used
// by the upload_limit setting to determine how many files the user may upload.
SWFUpload.prototype.setStats = function (statsObject) {
	this.callFlash("SetStats", [statsObject]);
};

// Public: getFile retrieves a File object by ID or Index.  If the file is
// not found then 'null' is returned.
SWFUpload.prototype.getFile = function (fileID) {
	if (typeof(fileID) === "number") {
		return this.callFlash("GetFileByIndex", [fileID]);
	} else {
		return this.callFlash("GetFile", [fileID]);
	}
};

// Public: addFileParam sets a name/value pair that will be posted with the
// file specified by the Files ID.  If the name already exists then the
// exiting value will be overwritten.
SWFUpload.prototype.addFileParam = function (fileID, name, value) {
	return this.callFlash("AddFileParam", [fileID, name, value]);
};

// Public: removeFileParam removes a previously set (by addFileParam) name/value
// pair from the specified file.
SWFUpload.prototype.removeFileParam = function (fileID, name) {
	this.callFlash("RemoveFileParam", [fileID, name]);
};

// Public: setUploadUrl changes the upload_url setting.
SWFUpload.prototype.setUploadURL = function (url) {
	this.settings.upload_url = url.toString();
	this.callFlash("SetUploadURL", [url]);
};

// Public: setPostParams changes the post_params setting
SWFUpload.prototype.setPostParams = function (paramsObject) {
	this.settings.post_params = paramsObject;
	this.callFlash("SetPostParams", [paramsObject]);
};

// Public: addPostParam adds post name/value pair.  Each name can have only one value.
SWFUpload.prototype.addPostParam = function (name, value) {
	this.settings.post_params[name] = value;
	this.callFlash("SetPostParams", [this.settings.post_params]);
};

// Public: removePostParam deletes post name/value pair.
SWFUpload.prototype.removePostParam = function (name) {
	delete this.settings.post_params[name];
	this.callFlash("SetPostParams", [this.settings.post_params]);
};

// Public: setFileTypes changes the file_types setting and the file_types_description setting
SWFUpload.prototype.setFileTypes = function (types, description) {
	this.settings.file_types = types;
	this.settings.file_types_description = description;
	this.callFlash("SetFileTypes", [types, description]);
};

// Public: setFileSizeLimit changes the file_size_limit setting
SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) {
	this.settings.file_size_limit = fileSizeLimit;
	this.callFlash("SetFileSizeLimit", [fileSizeLimit]);
};

// Public: setFileUploadLimit changes the file_upload_limit setting
SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) {
	this.settings.file_upload_limit = fileUploadLimit;
	this.callFlash("SetFileUploadLimit", [fileUploadLimit]);
};

// Public: setFileQueueLimit changes the file_queue_limit setting
SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) {
	this.settings.file_queue_limit = fileQueueLimit;
	this.callFlash("SetFileQueueLimit", [fileQueueLimit]);
};

// Public: setFilePostName changes the file_post_name setting
SWFUpload.prototype.setFilePostName = function (filePostName) {
	this.settings.file_post_name = filePostName;
	this.callFlash("SetFilePostName", [filePostName]);
};

// Public: setUseQueryString changes the use_query_string setting
SWFUpload.prototype.setUseQueryString = function (useQueryString) {
	this.settings.use_query_string = useQueryString;
	this.callFlash("SetUseQueryString", [useQueryString]);
};

// Public: setRequeueOnError changes the requeue_on_error setting
SWFUpload.prototype.setRequeueOnError = function (requeueOnError) {
	this.settings.requeue_on_error = requeueOnError;
	this.callFlash("SetRequeueOnError", [requeueOnError]);
};

// Public: setHTTPSuccess changes the http_success setting
SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) {
	if (typeof http_status_codes === "string") {
		http_status_codes = http_status_codes.replace(" ", "").split(",");
	}
	
	this.settings.http_success = http_status_codes;
	this.callFlash("SetHTTPSuccess", [http_status_codes]);
};

// Public: setHTTPSuccess changes the http_success setting
SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) {
	this.settings.assume_success_timeout = timeout_seconds;
	this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]);
};

// Public: setDebugEnabled changes the debug_enabled setting
SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
	this.settings.debug_enabled = debugEnabled;
	this.callFlash("SetDebugEnabled", [debugEnabled]);
};

// Public: setButtonImageURL loads a button image sprite
SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) {
	if (buttonImageURL == undefined) {
		buttonImageURL = "";
	}
	
	this.settings.button_image_url = buttonImageURL;
	this.callFlash("SetButtonImageURL", [buttonImageURL]);
};

// Public: setButtonDimensions resizes the Flash Movie and button
SWFUpload.prototype.setButtonDimensions = function (width, height) {
	this.settings.button_width = width;
	this.settings.button_height = height;
	
	var movie = this.getMovieElement();
	if (movie != undefined) {
		movie.style.width = width + "px";
		movie.style.height = height + "px";
	}
	
	this.callFlash("SetButtonDimensions", [width, height]);
};
// Public: setButtonText Changes the text overlaid on the button
SWFUpload.prototype.setButtonText = function (html) {
	this.settings.button_text = html;
	this.callFlash("SetButtonText", [html]);
};
// Public: setButtonTextPadding changes the top and left padding of the text overlay
SWFUpload.prototype.setButtonTextPadding = function (left, top) {
	this.settings.button_text_top_padding = top;
	this.settings.button_text_left_padding = left;
	this.callFlash("SetButtonTextPadding", [left, top]);
};

// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button
SWFUpload.prototype.setButtonTextStyle = function (css) {
	this.settings.button_text_style = css;
	this.callFlash("SetButtonTextStyle", [css]);
};
// Public: setButtonDisabled disables/enables the button
SWFUpload.prototype.setButtonDisabled = function (isDisabled) {
	this.settings.button_disabled = isDisabled;
	this.callFlash("SetButtonDisabled", [isDisabled]);
};
// Public: setButtonAction sets the action that occurs when the button is clicked
SWFUpload.prototype.setButtonAction = function (buttonAction) {
	this.settings.button_action = buttonAction;
	this.callFlash("SetButtonAction", [buttonAction]);
};

// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button
SWFUpload.prototype.setButtonCursor = function (cursor) {
	this.settings.button_cursor = cursor;
	this.callFlash("SetButtonCursor", [cursor]);
};

/* *******************************
	Flash Event Interfaces
	These functions are used by Flash to trigger the various
	events.
	
	All these functions a Private.
	
	Because the ExternalInterface library is buggy the event calls
	are added to a queue and the queue then executed by a setTimeout.
	This ensures that events are executed in a determinate order and that
	the ExternalInterface bugs are avoided.
******************************* */

SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) {
	// Warning: Don't call this.debug inside here or you'll create an infinite loop
	
	if (argumentArray == undefined) {
		argumentArray = [];
	} else if (!(argumentArray instanceof Array)) {
		argumentArray = [argumentArray];
	}
	
	var self = this;
	if (typeof this.settings[handlerName] === "function") {
		// Queue the event
		this.eventQueue.push(function () {
			this.settings[handlerName].apply(this, argumentArray);
		});
		
		// Execute the next queued event
		setTimeout(function () {
			self.executeNextEvent();
		}, 0);
		
	} else if (this.settings[handlerName] !== null) {
		throw "Event handler " + handlerName + " is unknown or is not a function";
	}
};

// Private: Causes the next event in the queue to be executed.  Since events are queued using a setTimeout
// we must queue them in order to garentee that they are executed in order.
SWFUpload.prototype.executeNextEvent = function () {
	// Warning: Don't call this.debug inside here or you'll create an infinite loop

	var  f = this.eventQueue ? this.eventQueue.shift() : null;
	if (typeof(f) === "function") {
		f.apply(this);
	}
};

// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have
// properties that contain characters that are not valid for JavaScript identifiers. To work around this
// the Flash Component escapes the parameter names and we must unescape again before passing them along.
SWFUpload.prototype.unescapeFilePostParams = function (file) {
	var reg = /[$]([0-9a-f]{4})/i;
	var unescapedPost = {};
	var uk;

	if (file != undefined) {
		for (var k in file.post) {
			if (file.post.hasOwnProperty(k)) {
				uk = k;
				var match;
				while ((match = reg.exec(uk)) !== null) {
					uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16)));
				}
				unescapedPost[uk] = file.post[k];
			}
		}

		file.post = unescapedPost;
	}

	return file;
};

// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working)
SWFUpload.prototype.testExternalInterface = function () {
	try {
		return this.callFlash("TestExternalInterface");
	} catch (ex) {
		return false;
	}
};

// Private: This event is called by Flash when it has finished loading. Don't modify this.
// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded.
SWFUpload.prototype.flashReady = function () {
	// Check that the movie element is loaded correctly with its ExternalInterface methods defined
	var movieElement = this.getMovieElement();

	if (!movieElement) {
		this.debug("Flash called back ready but the flash movie can't be found.");
		return;
	}

	this.cleanUp(movieElement);
	
	this.queueEvent("swfupload_loaded_handler");
};

// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE.
// This function is called by Flash each time the ExternalInterface functions are created.
SWFUpload.prototype.cleanUp = function (movieElement) {
	// Pro-actively unhook all the Flash functions
	try {
		if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
			this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");
			for (var key in movieElement) {
				try {
					if (typeof(movieElement[key]) === "function") {
						movieElement[key] = null;
					}
				} catch (ex) {
				}
			}
		}
	} catch (ex1) {
	
	}

	// Fix Flashes own cleanup code so if the SWFMovie was removed from the page
	// it doesn't display errors.
	window["__flash__removeCallback"] = function (instance, name) {
		try {
			if (instance) {
				instance[name] = null;
			}
		} catch (flashEx) {
		
		}
	};

};


/* This is a chance to do something before the browse window opens */
SWFUpload.prototype.fileDialogStart = function () {
	this.queueEvent("file_dialog_start_handler");
};


/* Called when a file is successfully added to the queue. */
SWFUpload.prototype.fileQueued = function (file) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("file_queued_handler", file);
};


/* Handle errors that occur when an attempt to queue a file fails. */
SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("file_queue_error_handler", [file, errorCode, message]);
};

/* Called after the file dialog has closed and the selected files have been queued.
	You could call startUpload here if you want the queued files to begin uploading immediately. */
SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) {
	this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]);
};

SWFUpload.prototype.uploadStart = function (file) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("return_upload_start_handler", file);
};

SWFUpload.prototype.returnUploadStart = function (file) {
	var returnValue;
	if (typeof this.settings.upload_start_handler === "function") {
		file = this.unescapeFilePostParams(file);
		returnValue = this.settings.upload_start_handler.call(this, file);
	} else if (this.settings.upload_start_handler != undefined) {
		throw "upload_start_handler must be a function";
	}

	// Convert undefined to true so if nothing is returned from the upload_start_handler it is
	// interpretted as 'true'.
	if (returnValue === undefined) {
		returnValue = true;
	}
	
	returnValue = !!returnValue;
	
	this.callFlash("ReturnUploadStart", [returnValue]);
};



SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]);
};

SWFUpload.prototype.uploadError = function (file, errorCode, message) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("upload_error_handler", [file, errorCode, message]);
};

SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("upload_success_handler", [file, serverData, responseReceived]);
};

SWFUpload.prototype.uploadComplete = function (file) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("upload_complete_handler", file);
};

/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
   internal debug console.  You can override this event and have messages written where you want. */
SWFUpload.prototype.debug = function (message) {
	this.queueEvent("debug_handler", message);
};


/* **********************************
	Debug Console
	The debug console is a self contained, in page location
	for debug message to be sent.  The Debug Console adds
	itself to the body if necessary.

	The console is automatically scrolled as messages appear.
	
	If you are using your own debug handler or when you deploy to production and
	have debug disabled you can remove these functions to reduce the file size
	and complexity.
********************************** */
   
// Private: debugMessage is the default debug_handler.  If you want to print debug messages
// call the debug() function.  When overriding the function your own function should
// check to see if the debug setting is true before outputting debug information.
SWFUpload.prototype.debugMessage = function (message) {
	if (this.settings.debug) {
		var exceptionMessage, exceptionValues = [];

		// Check for an exception object and print it nicely
		if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") {
			for (var key in message) {
				if (message.hasOwnProperty(key)) {
					exceptionValues.push(key + ": " + message[key]);
				}
			}
			exceptionMessage = exceptionValues.join("\n") || "";
			exceptionValues = exceptionMessage.split("\n");
			exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: ");
			SWFUpload.Console.writeLine(exceptionMessage);
		} else {
			SWFUpload.Console.writeLine(message);
		}
	}
};

SWFUpload.Console = {};
SWFUpload.Console.writeLine = function (message) {
	var console, documentForm;

	try {
		console = document.getElementById("SWFUpload_Console");

		if (!console) {
			documentForm = document.createElement("form");
			document.getElementsByTagName("body")[0].appendChild(documentForm);

			console = document.createElement("textarea");
			console.id = "SWFUpload_Console";
			console.style.fontFamily = "monospace";
			console.setAttribute("wrap", "off");
			console.wrap = "off";
			console.style.overflow = "auto";
			console.style.width = "700px";
			console.style.height = "350px";
			console.style.margin = "5px";
			documentForm.appendChild(console);
		}

		console.value += message + "\n";

		console.scrollTop = console.scrollHeight - console.clientHeight;
	} catch (ex) {
		alert("Exception: " + ex.name + " Message: " + ex.message);
	}
};


/*
	Queue Plug-in
	
	Features:
		*Adds a cancelQueue() method for cancelling the entire queue.
		*All queued files are uploaded when startUpload() is called.
		*If false is returned from uploadComplete then the queue upload is stopped.
		 If false is not returned (strict comparison) then the queue upload is continued.
		*Adds a QueueComplete event that is fired when all the queued files have finished uploading.
		 Set the event handler with the queue_complete_handler setting.
		
	*/

var SWFUpload;
if (typeof(SWFUpload) === "function") {
	SWFUpload.queue = {};
	
	SWFUpload.prototype.initSettings = (function (oldInitSettings) {
		return function () {
			if (typeof(oldInitSettings) === "function") {
				oldInitSettings.call(this);
			}
			
			this.queueSettings = {};
			
			this.queueSettings.queue_cancelled_flag = false;
			this.queueSettings.queue_upload_count = 0;
			
			this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler;
			this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler;
			this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler;
			this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler;
			
			this.settings.queue_complete_handler = this.settings.queue_complete_handler || null;
		};
	})(SWFUpload.prototype.initSettings);

	SWFUpload.prototype.startUpload = function (fileID) {
		this.queueSettings.queue_cancelled_flag = false;
		this.callFlash("StartUpload", [fileID]);
	};

	SWFUpload.prototype.cancelQueue = function () {
		this.queueSettings.queue_cancelled_flag = true;
		this.stopUpload();
		
		var stats = this.getStats();
		while (stats.files_queued > 0) {
			this.cancelUpload();
			stats = this.getStats();
		}
	};
	
	SWFUpload.queue.uploadStartHandler = function (file) {
		var returnValue;
		if (typeof(this.queueSettings.user_upload_start_handler) === "function") {
			returnValue = this.queueSettings.user_upload_start_handler.call(this, file);
		}
		
		// To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value.
		returnValue = (returnValue === false) ? false : true;
		
		this.queueSettings.queue_cancelled_flag = !returnValue;

		return returnValue;
	};
	
	SWFUpload.queue.uploadCompleteHandler = function (file) {
		var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler;
		var continueUpload;
		
		if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) {
			this.queueSettings.queue_upload_count++;
		}

		if (typeof(user_upload_complete_handler) === "function") {
			continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true;
		} else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) {
			// If the file was stopped and re-queued don't restart the upload
			continueUpload = false;
		} else {
			continueUpload = true;
		}
		
		if (continueUpload) {
			var stats = this.getStats();
			if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) {
				this.startUpload();
			} else if (this.queueSettings.queue_cancelled_flag === false) {
				this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]);
				this.queueSettings.queue_upload_count = 0;
			} else {
				this.queueSettings.queue_cancelled_flag = false;
				this.queueSettings.queue_upload_count = 0;
			}
		}
	};
}

/*
	SWFUpload.SWFObject Plugin

	Summary:
		This plugin uses SWFObject to embed SWFUpload dynamically in the page.  SWFObject provides accurate Flash Player detection and DOM Ready loading.
		This plugin replaces the Graceful Degradation plugin.

	Features:
		* swfupload_load_failed_hander event
		* swfupload_pre_load_handler event
		* minimum_flash_version setting (default: "9.0.28")
		* SWFUpload.onload event for early loading

	Usage:
		Provide handlers and settings as needed.  When using the SWFUpload.SWFObject plugin you should initialize SWFUploading
		in SWFUpload.onload rather than in window.onload.  When initialized this way SWFUpload can load earlier preventing the UI flicker
		that was seen using the Graceful Degradation plugin.

		<script type="text/javascript">
			var swfu;
			SWFUpload.onload = function () {
				swfu = new SWFUpload({
					minimum_flash_version: "9.0.28",
					swfupload_pre_load_handler: swfuploadPreLoad,
					swfupload_load_failed_handler: swfuploadLoadFailed
				});
			};
		</script>
		
	Notes:
		You must provide set minimum_flash_version setting to "8" if you are using SWFUpload for Flash Player 8.
		The swfuploadLoadFailed event is only fired if the minimum version of Flash Player is not met.  Other issues such as missing SWF files, browser bugs
		 or corrupt Flash Player installations will not trigger this event.
		The swfuploadPreLoad event is fired as soon as the minimum version of Flash Player is found.  It does not wait for SWFUpload to load and can
		 be used to prepare the SWFUploadUI and hide alternate content.
		swfobject's onDomReady event is cross-browser safe but will default to the window.onload event when DOMReady is not supported by the browser.
		 Early DOM Loading is supported in major modern browsers but cannot be guaranteed for every browser ever made.
*/


/*	SWFObject v2.0 rc4 <http://code.google.com/p/swfobject/>
	Copyright (c) 2007 Geoff Stearns, Michael Williams, and Bobby van der Sluis
	This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
var swfobject=function(){var X="undefined",P="object",a="visibility:visible",e="visibility:hidden",B="Shockwave Flash",h="ShockwaveFlash.ShockwaveFlash",V="application/x-shockwave-flash",K="SWFObjectExprInst",G=window,g=document,N=navigator,f=[],H=[],Q=null,L=null,S=false,C=false;var Y=function(){var l=typeof g.getElementById!=X&&typeof g.getElementsByTagName!=X&&typeof g.createElement!=X&&typeof g.appendChild!=X&&typeof g.replaceChild!=X&&typeof g.removeChild!=X&&typeof g.cloneNode!=X,t=[0,0,0],n=null;if(typeof N.plugins!=X&&typeof N.plugins[B]==P){n=N.plugins[B].description;if(n){n=n.replace(/^.*\s+(\S+\s+\S+$)/,"$1");t[0]=parseInt(n.replace(/^(.*)\..*$/,"$1"),10);t[1]=parseInt(n.replace(/^.*\.(.*)\s.*$/,"$1"),10);t[2]=/r/.test(n)?parseInt(n.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof G.ActiveXObject!=X){var o=null,s=false;try{o=new ActiveXObject(h+".7")}catch(k){try{o=new ActiveXObject(h+".6");t=[6,0,21];o.AllowScriptAccess="always"}catch(k){if(t[0]==6){s=true}}if(!s){try{o=new ActiveXObject(h)}catch(k){}}}if(!s&&o){try{n=o.GetVariable("$version");if(n){n=n.split(" ")[1].split(",");t=[parseInt(n[0],10),parseInt(n[1],10),parseInt(n[2],10)]}}catch(k){}}}}var v=N.userAgent.toLowerCase(),j=N.platform.toLowerCase(),r=/webkit/.test(v)?parseFloat(v.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,i=false,q=j?/win/.test(j):/win/.test(v),m=j?/mac/.test(j):/mac/.test(v);/*@cc_on i=true;@if(@_win32)q=true;@elif(@_mac)m=true;@end@*/return{w3cdom:l,pv:t,webkit:r,ie:i,win:q,mac:m}}();var d=function(){if(!Y.w3cdom){return }J(I);if(Y.ie&&Y.win){try{g.write("<script id=__ie_ondomload defer=true src=//:><\/script>");var i=b("__ie_ondomload");if(i){i.onreadystatechange=function(){if(this.readyState=="complete"){this.parentNode.removeChild(this);U()}}}}catch(j){}}if(Y.webkit&&typeof g.readyState!=X){Q=setInterval(function(){if(/loaded|complete/.test(g.readyState)){U()}},10)}if(typeof g.addEventListener!=X){g.addEventListener("DOMContentLoaded",U,null)}M(U)}();function U(){if(S){return }if(Y.ie&&Y.win){var m=W("span");try{var l=g.getElementsByTagName("body")[0].appendChild(m);l.parentNode.removeChild(l)}catch(n){return }}S=true;if(Q){clearInterval(Q);Q=null}var j=f.length;for(var k=0;k<j;k++){f[k]()}}function J(i){if(S){i()}else{f[f.length]=i}}function M(j){if(typeof G.addEventListener!=X){G.addEventListener("load",j,false)}else{if(typeof g.addEventListener!=X){g.addEventListener("load",j,false)}else{if(typeof G.attachEvent!=X){G.attachEvent("onload",j)}else{if(typeof G.onload=="function"){var i=G.onload;G.onload=function(){i();j()}}else{G.onload=j}}}}}function I(){var l=H.length;for(var j=0;j<l;j++){var m=H[j].id;if(Y.pv[0]>0){var k=b(m);if(k){H[j].width=k.getAttribute("width")?k.getAttribute("width"):"0";H[j].height=k.getAttribute("height")?k.getAttribute("height"):"0";if(O(H[j].swfVersion)){if(Y.webkit&&Y.webkit<312){T(k)}}else{if(H[j].expressInstall&&!C&&O("6.0.65")&&(Y.win||Y.mac)){D(H[j])}else{c(k)}}}}A("#"+m,a)}}function T(m){var k=m.getElementsByTagName(P)[0];if(k){var p=W("embed"),r=k.attributes;if(r){var o=r.length;for(var n=0;n<o;n++){if(r[n].nodeName.toLowerCase()=="data"){p.setAttribute("src",r[n].nodeValue)}else{p.setAttribute(r[n].nodeName,r[n].nodeValue)}}}var q=k.childNodes;if(q){var s=q.length;for(var l=0;l<s;l++){if(q[l].nodeType==1&&q[l].nodeName.toLowerCase()=="param"){p.setAttribute(q[l].getAttribute("name"),q[l].getAttribute("value"))}}}m.parentNode.replaceChild(p,m)}}function F(i){if(Y.ie&&Y.win&&O("8.0.0")){G.attachEvent("onunload",function(){var k=b(i);for(var j in k){if(typeof k[j]=="function"){k[j]=function(){}}}k.parentNode.removeChild(k)})}}function D(j){C=true;var o=b(j.id);if(o){if(j.altContentId){var l=b(j.altContentId);if(l){L=l}}else{L=Z(o)}if(!(/%$/.test(j.width))&&parseInt(j.width,10)<310){j.width="310"}if(!(/%$/.test(j.height))&&parseInt(j.height,10)<137){j.height="137"}g.title=g.title.slice(0,47)+" - Flash Player Installation";var n=Y.ie&&Y.win?"ActiveX":"PlugIn",k=g.title,m="MMredirectURL="+G.location+"&MMplayerType="+n+"&MMdoctitle="+k,p=j.id;if(Y.ie&&Y.win&&o.readyState!=4){var i=W("div");p+="SWFObjectNew";i.setAttribute("id",p);o.parentNode.insertBefore(i,o);o.style.display="none";G.attachEvent("onload",function(){o.parentNode.removeChild(o)})}R({data:j.expressInstall,id:K,width:j.width,height:j.height},{flashvars:m},p)}}function c(j){if(Y.ie&&Y.win&&j.readyState!=4){var i=W("div");j.parentNode.insertBefore(i,j);i.parentNode.replaceChild(Z(j),i);j.style.display="none";G.attachEvent("onload",function(){j.parentNode.removeChild(j)})}else{j.parentNode.replaceChild(Z(j),j)}}function Z(n){var m=W("div");if(Y.win&&Y.ie){m.innerHTML=n.innerHTML}else{var k=n.getElementsByTagName(P)[0];if(k){var o=k.childNodes;if(o){var j=o.length;for(var l=0;l<j;l++){if(!(o[l].nodeType==1&&o[l].nodeName.toLowerCase()=="param")&&!(o[l].nodeType==8)){m.appendChild(o[l].cloneNode(true))}}}}}return m}function R(AE,AC,q){var p,t=b(q);if(typeof AE.id==X){AE.id=q}if(Y.ie&&Y.win){var AD="";for(var z in AE){if(AE[z]!=Object.prototype[z]){if(z=="data"){AC.movie=AE[z]}else{if(z.toLowerCase()=="styleclass"){AD+=' class="'+AE[z]+'"'}else{if(z!="classid"){AD+=" "+z+'="'+AE[z]+'"'}}}}}var AB="";for(var y in AC){if(AC[y]!=Object.prototype[y]){AB+='<param name="'+y+'" value="'+AC[y]+'" />'}}t.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+AD+">"+AB+"</object>";F(AE.id);p=b(AE.id)}else{if(Y.webkit&&Y.webkit<312){var AA=W("embed");AA.setAttribute("type",V);for(var x in AE){if(AE[x]!=Object.prototype[x]){if(x=="data"){AA.setAttribute("src",AE[x])}else{if(x.toLowerCase()=="styleclass"){AA.setAttribute("class",AE[x])}else{if(x!="classid"){AA.setAttribute(x,AE[x])}}}}}for(var w in AC){if(AC[w]!=Object.prototype[w]){if(w!="movie"){AA.setAttribute(w,AC[w])}}}t.parentNode.replaceChild(AA,t);p=AA}else{var s=W(P);s.setAttribute("type",V);for(var v in AE){if(AE[v]!=Object.prototype[v]){if(v.toLowerCase()=="styleclass"){s.setAttribute("class",AE[v])}else{if(v!="classid"){s.setAttribute(v,AE[v])}}}}for(var u in AC){if(AC[u]!=Object.prototype[u]&&u!="movie"){E(s,u,AC[u])}}t.parentNode.replaceChild(s,t);p=s}}return p}function E(k,i,j){var l=W("param");l.setAttribute("name",i);l.setAttribute("value",j);k.appendChild(l)}function b(i){return g.getElementById(i)}function W(i){return g.createElement(i)}function O(k){var j=Y.pv,i=k.split(".");i[0]=parseInt(i[0],10);i[1]=parseInt(i[1],10);i[2]=parseInt(i[2],10);return(j[0]>i[0]||(j[0]==i[0]&&j[1]>i[1])||(j[0]==i[0]&&j[1]==i[1]&&j[2]>=i[2]))?true:false}function A(m,j){if(Y.ie&&Y.mac){return }var l=g.getElementsByTagName("head")[0],k=W("style");k.setAttribute("type","text/css");k.setAttribute("media","screen");if(!(Y.ie&&Y.win)&&typeof g.createTextNode!=X){k.appendChild(g.createTextNode(m+" {"+j+"}"))}l.appendChild(k);if(Y.ie&&Y.win&&typeof g.styleSheets!=X&&g.styleSheets.length>0){var i=g.styleSheets[g.styleSheets.length-1];if(typeof i.addRule==P){i.addRule(m,j)}}}return{registerObject:function(l,i,k){if(!Y.w3cdom||!l||!i){return }var j={};j.id=l;j.swfVersion=i;j.expressInstall=k?k:false;H[H.length]=j;A("#"+l,e)},getObjectById:function(l){var i=null;if(Y.w3cdom&&S){var j=b(l);if(j){var k=j.getElementsByTagName(P)[0];if(!k||(k&&typeof j.SetVariable!=X)){i=j}else{if(typeof k.SetVariable!=X){i=k}}}}return i},embedSWF:function(n,u,r,t,j,m,k,p,s){if(!Y.w3cdom||!n||!u||!r||!t||!j){return }r+="";t+="";if(O(j)){A("#"+u,e);var q=(typeof s==P)?s:{};q.data=n;q.width=r;q.height=t;var o=(typeof p==P)?p:{};if(typeof k==P){for(var l in k){if(k[l]!=Object.prototype[l]){if(typeof o.flashvars!=X){o.flashvars+="&"+l+"="+k[l]}else{o.flashvars=l+"="+k[l]}}}}J(function(){R(q,o,u);A("#"+u,a)})}else{if(m&&!C&&O("6.0.65")&&(Y.win||Y.mac)){A("#"+u,e);J(function(){var i={};i.id=i.altContentId=u;i.width=r;i.height=t;i.expressInstall=m;D(i);A("#"+u,a)})}}},getFlashPlayerVersion:function(){return{major:Y.pv[0],minor:Y.pv[1],release:Y.pv[2]}},hasFlashPlayerVersion:O,createSWF:function(k,j,i){if(Y.w3cdom&&S){return R(k,j,i)}else{return undefined}},createCSS:function(j,i){if(Y.w3cdom){A(j,i)}},addDomLoadEvent:J,addLoadEvent:M,getQueryParamValue:function(m){var l=g.location.search||g.location.hash;if(m==null){return l}if(l){var k=l.substring(1).split("&");for(var j=0;j<k.length;j++){if(k[j].substring(0,k[j].indexOf("="))==m){return k[j].substring((k[j].indexOf("=")+1))}}}return""},expressInstallCallback:function(){if(C&&L){var i=b(K);if(i){i.parentNode.replaceChild(L,i);L=null;C=false}}}}}();

	
var SWFUpload;
if (typeof(SWFUpload) === "function") {
	SWFUpload.onload = function () {};
	
	swfobject.addDomLoadEvent(function () {
		if (typeof(SWFUpload.onload) === "function") {
			SWFUpload.onload.call(window);
		}
	});
	
	SWFUpload.prototype.initSettings = (function (oldInitSettings) {
		return function () {
			if (typeof(oldInitSettings) === "function") {
				oldInitSettings.call(this);
			}

			this.ensureDefault = function (settingName, defaultValue) {
				this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
			};

			this.ensureDefault("minimum_flash_version", "9.0.28");
			this.ensureDefault("swfupload_load_failed_handler", null);

			delete this.ensureDefault;

		};
	})(SWFUpload.prototype.initSettings);


	SWFUpload.prototype.loadFlash = function (oldLoadFlash) {
		return function () {
			var hasFlash = swfobject.hasFlashPlayerVersion(this.settings.minimum_flash_version);
			
			if (hasFlash) {
				this.queueEvent("swfupload_pre_load_handler");
				if (typeof(oldLoadFlash) === "function") {
					oldLoadFlash.call(this);
				}
			} else {
				this.queueEvent("swfupload_load_failed_handler");
			}
		};
		
	}(SWFUpload.prototype.loadFlash);
			
	SWFUpload.prototype.displayDebugInfo = function (oldDisplayDebugInfo) {
		return function () {
			if (typeof(oldDisplayDebugInfo) === "function") {
				oldDisplayDebugInfo.call(this);
			}
			
			this.debug(
				[
					"SWFUpload.SWFObject Plugin settings:", "\n",
					"\t", "minimum_flash_version:                      ", this.settings.minimum_flash_version, "\n",
					"\t", "swfupload_load_failed_handler assigned:     ", (typeof(this.settings.swfupload_load_failed_handler) === "function").toString(), "\n",
				].join("")
			);
		};	
	}(SWFUpload.prototype.displayDebugInfo);
}


/* ContentItemFileList.cs.js */

var ContentItemFileList = {
};

/* ContentItemFileListConfig.cs.js */

var ContentItemFileListConfig = {

    save: function(menuID, uniqueName) {
    var showicons = $("input[id='ShowIcons']").is(':checked');
    var showfilesize = $("input[id='ShowFileSize']").is(':checked');
    var loginRequired = $("input[id='ShowIcons']").is(':checked');
    var loginUrl = $("input[id='LoginUrl']").val();
    var invoiceRequired = $("input[id='InvoiceRequired']").is(':checked');
    var registrationUrl = $("input[id='RegistrationUrl']").val();
        getJsonCI('FileListConfig',
            'Save',
            function() { window.location.reload(); },
            {
                menuID: menuID,
                uniqueName: uniqueName,
                showicons: showicons,
                showfilesize: showfilesize,
                loginRequired: loginRequired,
                loginUrl: loginUrl,
                invoiceRequired: invoiceRequired,
                registrationUrl: registrationUrl
            });
    }
};

/* ContentItemEventSubscriptions.cs.js */

var ContentItemEventSubscriptions = {
    saveSubscription: function(element) {
        getJsonCI('EventSubscriptions',
            'SaveSubscription',
            function(data) {
            },
            {
                eventID: element.attr('eventid'),
                menuID: menuID,
                subscribed: element.attr('checked')
            });

    }
};


/* ContentItemEventsCalendarSubscribeSummary.cs.js */

var ContentItemEventsCalendarSubscribeSummary = {
    addPromoCode: function(controlID, orderID, calendarItemID) {
        // get inserted promo code.
        var promoCode = $("input[id$='" + controlID + "_PromoCodeTextBox']").val();
        
        // do nothing if no promocode has been entered.
        if (!promoCode) {
            return false;
        }

        getJsonCI('EventsCalendarSubscribeSummary',
        'AddPromoCode',
        function(data) {
            if (data.totalsTable != '') {
                // update totals
                $("td[id$='" + controlID + "_TotalsCell']").html(data.totalsTable);

                // clear text box
                $("input[id$='" + controlID + "_PromoCodeTextBox']").val('');
            }
        }
        , { promoCode: promoCode, orderID: orderID, calendarItemID: calendarItemID });
    }
};

/* ContentItemEventsCalendarSubscribePayment.cs.js */

var ContentItemEventsCalendarSubscribePayment = {
    // gets the payment method selected on the radio button list.
    getPaymentMethod: function(controlID) {
        var input = $("[id$='" + controlID + "_PaymentMethodRadioButtonList'] input:checked");
        return input.val();
    },
    // gets the payment method selected on the radio button list.
    getBankaccount: function(controlID) {
        var input = $("input[id='" + controlID + "_bankaccount']");
        return input.val();
    },
    getAccountholder: function(controlID) {
        var input = $("input[id='" + controlID + "_accountholder']");
        return input.val();
    }
};

$(document).ready(function() {
    // reselect payment method.
    var value = $(document).getUrlParam('paymentmethod');
    if (value) {
        var radiobutton = $("input[name$='_PaymentMethodRadioButtonList'][value='" + value + "']");
        radiobutton.attr('checked', 'checked');
    }
    //refill bankaccount / accountholder
});

/* ContentItemEventsCalendarSubscribe.cs.js */

var ContentItemEventsCalendarSubscribe = {
    createStepTwoPanel: function(controlID, personID) {
        var calendarItemID = (location.href.split('?')[1]).split('=')[1];
        getJsonCI('EventsCalendarSubscribe',
        'CreateStepTwoPanel',
        function(data) {
            if (data.stepTwoPanel != null) {
                $("[id$='" + controlID + "']").html(data.stepTwoPanel);
            }
        }
        , { controlID: controlID, personID: personID, calendarItemID: calendarItemID });
    },

    enroll: function(controlID, personID, calendarItemID, orderID, associatedPaymentItemID, waitingMessage) {
        // show waiting box
        tb_waiting(waitingMessage);
        var bankaccount = '';
        var accountholder = '';
        var paymentMethod = ContentItemEventsCalendarSubscribePayment.getPaymentMethod(associatedPaymentItemID);
        if ($('#bankrekening_error')) { $('#bankrekening_error').remove(); }
        if ($('#accountholder_error')) { $('#accountholder_error').remove(); }
        if (paymentMethod == "32")//Direct Debit
        {
            /* check values */
            bankaccount = ContentItemEventsCalendarSubscribePayment.getBankaccount(associatedPaymentItemID);
            var fault = false;
            if (bankaccount === "") {
                var error = '<span id="bankrekening_error" class="warning" style="color: rgb(255, 0, 0);"><img style="" src="/personeelsdocumenten/ValentNet/Content/icons/warning.gif" alt="*" title="Bankrekening is verplicht" class="warning" width="16" height="16"></span>';
                $("input[name$='bankaccount']").after(error);
                fault = true;
            }
            accountholder = ContentItemEventsCalendarSubscribePayment.getAccountholder(associatedPaymentItemID);

            if (accountholder === "") {
                var error = '<span id="accountholder_error" class="warning" style="color: rgb(255, 0, 0);"><img style="" src="/personeelsdocumenten/ValentNet/Content/icons/warning.gif" alt="*" title="Rekeninghouder is verplicht" class="warning" width="16" height="16"></span>';
                $("input[name$='accountholder']").after(error);
                fault = true;
            }
            if (fault) return false;
        }
        getJsonCI('EventsCalendarSubscribe',
        'Enroll',
        function(data) {

            // close waiting box
            tb_remove();

            // If there is a redirect url.
            if (data.enrollRedirectUrl) {

                // disable finish button
                var finishButton = $("[id$='FinishButton']");
                finishButton.attr("disabled", "true");

                setTimeout("window.location = '" + data.enrollRedirectUrl + "'", 0);
            }
            if (data.html) {
                document.close();
                document.open();
                document.write(data.html);
            }
        }
        , { controlID: controlID, personID: personID, calendarItemID: calendarItemID, orderID: orderID, paymentMethod: paymentMethod, bankaccount: bankaccount, accountholder: accountholder });
    },

    toggleMember: function(clickedControlID) {
        // Get controls
        var memberRadioButton = $("[id$='MemberRadioButton']");
        var loginForm = $("[id$='EventsCalendarSubscribe_Login']");
        var notMemberRadioButton = $("[id$='MemberRadioButtonNot']");
        var registrationForm = $("[id$='EventsCalendarSubscribe_FormEventRegister']");

        if (clickedControlID == 'MemberRadioButton' && notMemberRadioButton.attr('checked') == true) {
            notMemberRadioButton.removeAttr('checked');
            loginForm.show();
            registrationForm.hide();
        }

        if (clickedControlID == 'MemberRadioButtonNot' && memberRadioButton.attr('checked') == true) {
            memberRadioButton.removeAttr('checked');
            registrationForm.show();
            loginForm.hide();
        }
    }
};

$(document).ready(function() {
    if ($("[id$='EventsCalendarSubscribe_FormEventRegister']").length > 0) {
        $("[id$='EventsCalendarSubscribe_Login']").hide();
    }
});

/* ContentItemEventsCalendar.cs.js */

var ContentItemEventsCalendar = {
    changeSpotlight: function(controlID, calendarItemID) {

        // Hide all images not in the spotlight.
        $("[id^='" + controlID + "_Image_']").hide();

        // Remove 'spotlightButtonSelected' class from all spotlight buttons.
        $("[id^='" + controlID + "_SpotlightButton_']").removeClass('spotlightButtonSelected');

        // Show spotlight image.
        $("[id$='" + controlID + "_Image_" + calendarItemID + "']").show(); ;

        // Add 'spotlightButtonSelected' class to spotlight button.
        $("[id$='" + controlID + "_SpotlightButton_" + calendarItemID + "']").addClass('spotlightButtonSelected');
    }
};

/* ContentItemCsvImport.cs.js */

var ContentItemCsvImport = {
    importCsv: function(contentItemID) {

        tb_waiting();
        
        // Get email addresses.
        var csvData = $("[id$='" + contentItemID + "_csvDataTextArea']");

        getJsonCI('CsvImport', 'Import', function(data) {

            // Replace content item html with status list.
            if (data.Success == true) 
            {
                csvData.val(data.headers); 
            }
            tb_remove();
        }, { csvData: csvData.val() ,menuID: menuID, uniqueName: contentItemID});
    }
};

/* ContentItemTagSearch.cs.js */
var CostObject = {
    GetGraphAjax: function(perweeks, begindate) {
        getJsonCI('CostObject',
                'GetGraphAjax',
                function(data) {
                    $("[id$=costobjectgraph]").attr("src",data.html);
                },
                {
                    perweeks: perweeks,
                    begindate: begindate
                });
    }
};

$(document).ready(function() {
    $("[id$=binladen]").click(function() {
      CostObject.GetGraphAjax($("[id$=selectWeek]").val(), $("[id$=weekpicker]").val());  
    });
});

var ContentItemCopyWizard = {
    CurrentStep: 1,
    Container: null,

    Init: function(clientID) {
        this.Container = $("div[id$='" + clientID + "']");
        getJsonCI('CopyWizard', 'Initialize', function(data) {
            ContentItemCopyWizard.Container.append(data.html);
            ContentItemCopyWizard.Load(1);
        }, {});
    },

    Load: function(step) {
        var postData = {};
        postData['previousStep'] = this.CurrentStep;

        this.Container.find("input, select").each(function() {
            var field = $(this);
            var id = field.attr('id');

            if(field.attr('type') == 'radio') {
                 if(field.attr('checked')) {
                    postData[field.attr('name')] = field.val();
                 }
            } else {
                postData[id] = field.val();
            }

            if (field.attr('type') == "checkbox" && postData[id] != "true")
                postData[id] = field.attr('checked');
        });

        getJsonCI('CopyWizard', 'Step' + step, function(data) {
            if (data.loaded) {
                ContentItemCopyWizard.Container.find("table[id$='tableStep" + data.step + "']").html(data.html);
            }
            ContentItemCopyWizard.Show(data.step, true);
        }, postData);
    },

    Show: function(step, loaded) {
        if (!loaded) {
            this.Load(step);
            return;
        }

        $("table[id^='tableStep']").each(function(i) {
            if (i != (step - 1)) {
                $(this).find("tbody").hide();
                $(this).find("thead th").css("color", i < (step - 1) ? "#BBB" : "#DDD");
            }
        });
        $("table[id^='tableStep" + step + "'] tbody").show();
        $("table[id^='tableStep" + step + "'] thead th").css("color", "#880000");

        this.CurrentStep = step;
    }
};

/* ContentItemCopyObjects.cs.js */

var ContentItemCopyObjects = {
    show: function(httpBaseUrl, objectID, objectTypeName, moduleName) {
        // Show the copy objects form.
        var url = httpBaseUrl + 'ValentNet/Views/Shared/Handlers/ContentItemHandler.ashx?ID=' + menuID +
            '&name=CopyObjects&action=Show&width=600&height=450&pageUrl=' + document.location.href;
        tb_show('', url, null, { objectID: objectID, objectTypeName: objectTypeName, moduleName: moduleName });
    },

    copy: function(objectID, objectTypeName) {

        // Get the selected module menu IDs.
        var moduleMenuIDs = "";
        $("table.modulesTable input").each(function(index) {
            if (this.checked) {
                if (moduleMenuIDs.length > 0) moduleMenuIDs += ';';
                moduleMenuIDs += $(this).attr("id").match(/[^_]*$/)[0];
            }
        });

        getJsonCI('CopyObjects',
        'Copy',
             function(data) {
                 if (data.message == '') {
                     tb_remove();
                 }
                 else {
                     // Show the returned message.
                     var message = $(".copyObjectsMessage");
                     message.text(data.message);
                 }
             }
        , { objectID: objectID, objectTypeName: objectTypeName, moduleMenuIDs: moduleMenuIDs });
    }
};

var ContentItemConfig = {
    save: function (ciname, postData) {
        if (!postData) postData = {};
        $("#TB_ajaxContent input, #TB_ajaxContent select, #TB_ajaxContent textarea").each(function () {
            var field = $(this);
            // Get value for a radio button
            if (field.attr('type') == 'radio' || field.attr('type') == 'checkbox') {
                postData[field.attr('id')] = field.attr('checked');
            }
            else {
                postData[field.attr('id')] = field.val();
            }
        });

        // handle the save in the contentitem self
        if (eval("typeof ContentItem" + ciname + " != 'undefined'")) {
            var contentitem = eval("ContentItem" + ciname);
            if (contentitem.save) {
                contentitem.save(postData);
                return;
            }
        }

        // call the save method
        getJsonCI(ciname, 'Save', function () { window.location.reload(); }, postData);
    }
};

/* ContentItemCmsOverview.cs.js */

var ContentItemCmsOverview = {
};

var ContentItemCmsCleanup = {
    toggleCheckbox: function(obj) {
        $(obj).parent().parent().find("table input:checkbox").attr('checked', $(obj).attr('checked'));
    },

    toggleChilds: function(obj) {
        var img = $(obj).find("img");
        var src = img.attr('src');
        var table = $(obj).parent().parent().parent().find("table");
        if (src.indexOf('trvmin.gif') != -1) {
            // hide
            table.hide();
            img.attr('src', src.replace('trvmin.gif', 'trvplus.gif'));
        } else {
            // show
            table.show();
            img.attr('src', src.replace('trvplus.gif', 'trvmin.gif'));
        }
    },

    show: function() {
        var selectedOption = $("select[id$='cboSites'] option:selected");

        tb_waiting();

        getJsonCI('CmsCleanup', 'Show', function(data) {
            $("div[id$='divChanges']").html(data.html);
            tb_remove();
        }, { siteID: selectedOption.val(), siteName: selectedOption.html() });
    },

    cleanup: function() {
        var selectedOption = $("select[id$='cboSites'] option:selected");
        var postData = { siteID: selectedOption.val(), siteName: selectedOption.html() };

        tb_waiting();

        $("div[id$='divChanges']").find("input:checkbox:checked").each(function() {
            var id = $(this).attr('id');
            postData[id] = 'true';
        });

        getJsonCI('CmsCleanup', 'Cleanup', function(data) {
            $("div[id$='divChanges']").html(data.html);
            tb_remove();
        }, postData);
    }
};

/* ContentItemCmsApplicationList.cs.js */

var ContentItemCmsApplicationList = {
};

$(document).ready(function() {

    if ($('input.cmsApplication').length > 0) {
        $('input.cmsApplication').click(function() {
            if (this.checked) {
                getJsonCI('CmsApplicationList',
                    'AddApplication',
                    null,
                    {
                        applicationID: $(this).attr('applicationID')
                    });
            } else {
            getJsonCI('CmsApplicationList',
                    'RemoveApplication',
                    null,
                    {
                        applicationID: $(this).attr('applicationID')
                    });
        }
        });
    }


});

/* ContentItemChangePasswordRequest.cs.js */

var ContentItemChangePasswordRequest = {
    request: function(controlID) {
        // get the email address
        var emailAddress = $("input[id$='" + controlID + "_emailAddressTextBox']").val();
        getJsonCI('ChangePasswordRequest',
        'Request',
        function(data) {
            // redirect to the redirect url if it exists.
            if (data.RedirectUrl) {
                setTimeout("window.location = '" + data.RedirectUrl + "'", 3000);
            }
        }
        , { controlID: controlID, emailAddress: emailAddress });
    }
};

/* ContentItemChangePasswordForm.cs.js */

var ContentItemChangePasswordForm = {
    changePassword: function(controlID, identifier) {
        // get the passwords
        var password = $("input[id$='" + controlID + "_passwordTextBox']").val();
        var confirmationPassword = $("input[id$='" + controlID + "_confirmationPasswordTextBox']").val();
        getJsonCI('ChangePasswordForm',
        'ChangePassword',
        function(data) {

            // redirect to the redirect url if it exists.
            if (data.redirectUrl && data.redirectUrl != '') {
                setTimeout("window.location = '" + data.redirectUrl + "'", 3000);
            }
        }

        , { controlID: controlID, password: password, confirmationPassword: confirmationPassword, identifier: identifier });
    }
};

var ContentItemAdSearch = {
    cascadeSettingsToString: function(cascadeSettings) {
        return '{ filter2: ' + cascadeSettings.filter2 + ', filter3: ' + cascadeSettings.filter3 + ', filter4: ' + cascadeSettings.filter4 + ' }';
    },

    getFilter2Items: function(filtersTableClientID, adType, cascadeSettings) {
        // Get drop down list values for filtering.
        var selectedFilter1 = $("[id$='Filter1DropDownList']").val() || '';
        var selectedFilter2 = $("[id$='Filter2DropDownList']").val() || '';

        // As filter1 has been changed, hide the filter3 and filter4 drop down lists, if cascade is true.
        if (cascadeSettings.filter3) {
            $("table[id$='" + filtersTableClientID + "'] tr[id$='SelectFilter3Header']").hide();
        }

        if (cascadeSettings.filter4 == 'True') {
            $("table[id$='" + filtersTableClientID + "'] tr[id$='SelectFilter4Header']").hide();
        }

        var filter = this.cascadeSettingsToString(cascadeSettings);

        getJsonCI('AdSearch', 'GetFilter2Items', function(data) {
            if (data != undefined) {
                // Remove current filter2, filter3 and filter4 drop down lists, if cascade is true.
                if (cascadeSettings.filter2) {
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='Filter2Row']").remove();
                }

                if (cascadeSettings.filter3) {
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='Filter3Row']").remove();
                }

                if (cascadeSettings.filter4) {
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='Filter4Row']").remove();
                }

                // If there isn't a selected filter1, don't show the filter1 drop down list.
                if (selectedFilter1 == '') {
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='SelectFilter2Header']").hide();
                }
                else {
                    // Add the filter2 row.
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='SelectFilter2Header']").show();
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='SelectFilter2Header']").after(data.NewRow);
                }
            }
        }, { selectedFilter1: selectedFilter1, filtersTableClientID: filtersTableClientID, adType: adType, cascadeSettings: filter });
    },

    getFilter3Items: function(filtersTableClientID, adType, cascadeSettings) {
        // Get drop down list values for filtering.
        var selectedFilter1 = $("[id$='Filter1DropDownList']").val() || '';
        var selectedFilter2 = $("[id$='Filter2DropDownList']").val() || '';

        if (cascadeSettings.filter4) {
            $("table[id$='" + filtersTableClientID + "'] tr[id$='SelectFilter4Header']").hide();
        }
        var filter = this.cascadeSettingsToString(cascadeSettings);

        getJsonCI('AdSearch', 'GetFilter3Items', function(data) {
            if (data != undefined) {
                // Remove current filter3 and filter4 drop down lists, if true.
                if (cascadeSettings.filter3) {
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='Filter3Row']").remove();
                }

                if (cascadeSettings.filter4) {
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='Filter4Row']").remove();
                }

                // If there isn't a selected filter2, don't show the filter3 drop down list.
                if (selectedFilter2 == '') {
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='SelectFilter3Header']").hide();
                }
                else {
                    // Add the filter3 row.
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='SelectFilter3Header']").show();
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='SelectFilter3Header']").after(data.NewRow);
                }
            }
        }, { selectedFilter1: selectedFilter1, selectedFilter2: selectedFilter2, filtersTableClientID: filtersTableClientID, adType: adType, cascadeSettings: filter });
    },

    getFilter4Items: function(filtersTableClientID, adType, cascadeSettings) {
        // Get drop down list values for filtering.
        var selectedFilter1 = $("[id$='Filter1DropDownList']").val() || '';
        var selectedFilter2 = $("[id$='Filter2DropDownList']").val() || '';
        var selectedFilter3 = $("[id$='Filter3DropDownList']").val() || '';
        var filter = this.cascadeSettingsToString(cascadeSettings);

        getJsonCI('AdSearch', 'GetFilter4Items', function(data) {
            if (data != undefined) {
                // Remove the current filter4 drop down list, if true.
                if (cascadeSettings.filter4) {
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='Filter4Row']").remove();
                }

                // If there isn't a selected filter3, don't show the filter4 drop down list.
                if (selectedFilter3 == '') {
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='SelectFilter4Header']").hide();
                }
                else {
                    // Add the filter4 row.
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='SelectFilter4Header']").show();
                    $("table[id$='" + filtersTableClientID + "'] tr[id$='SelectFilter4Header']").after(data.NewRow);
                }
            }
        }, { selectedFilter1: selectedFilter1, selectedFilter2: selectedFilter2, selectedFilter3: selectedFilter3, filtersTableClientID: filtersTableClientID, adType: adType, cascadeSettings: filter });
    },

    search: function(args) {
        var controlID = args.controlID;
        var associatedList = args.associatedList;
        var associatedControlID = args.associatedControlID;
        var search = $("[id$='" + controlID + "']");

        // Get valus from drop down lists
        var selectedFilter1 = $("[id$='Filter1DropDownList']").val() || '';
        var selectedFilter2 = $("[id$='Filter2DropDownList']").val() || '';
        var selectedFilter3 = $("[id$='Filter3DropDownList']").val() || '';
        var selectedFilter4 = $("[id$='Filter4DropDownList']").val() || '';

        // Call search method in AdList ContentItem
        var data = { controlID: associatedControlID, selectedFilter1: selectedFilter1, selectedFilter2: selectedFilter2, selectedFilter3: selectedFilter3, selectedFilter4: selectedFilter4 };
        eval(associatedList).search(data);
    }
};

var ContentItemAdSearchConfig = {

    save: function(menuID, uniqueName, activeLanguages) {
        var associatedList = $("input[id='AssociatedList']").val();
        var associatedControlID = $("input[id='AssociatedControlID']").val();
        var adType = $("input[id='AdType']").val();

        // Get active languages
        var languages = JSON.parse(activeLanguages);
        
        // Get textbox values and cascade boolean for each filter label.
        var filter1Label = this.getValues(1, languages);
        
        var filter2Label = this.getValues(2, languages);
        var cascadeFilter2 = $("input[id='CascadeFilter2']").is(':checked');

        var filter3Label = this.getValues(3, languages);
        var cascadeFilter3 = $("input[id='CascadeFilter3']").is(':checked');
        
        var filter4Label = this.getValues(4, languages);
        var cascadeFilter4 = $("input[id='CascadeFilter4']").is(':checked');

        getJsonCI('AdSearchConfig',
            'Save',
            function() { window.location.reload(); },
            {
                menuID: menuID,
                uniqueName: uniqueName,
                associatedList: associatedList,
                associatedControlID: associatedControlID,
                adType: adType,
                filter1Label: filter1Label,
                filter2Label: filter2Label,
                cascadeFilter2: cascadeFilter2,
                filter3Label: filter3Label,
                cascadeFilter3: cascadeFilter3,
                filter4Label: filter4Label,
                cascadeFilter4: cascadeFilter4
            });
    },

    getValues: function(filterNumber, languages) {
        var valuesArray = new Array(languages.length);
        
        // For each active language find the control and save the value in the array.
        for (var index = 0; index < languages.length; index++) {
            // Add to value array
            valuesArray[index] = $("#Filter" + filterNumber + "Label" + "_" + languages[index]).val();
        }
        // Convert array of values to JSON object.
        return JSON.stringify(valuesArray);
    }
};


var ContentItemAdList = {
    getAds: function(controlID, pageIndex, data) {
        // Get ads by list controlID, requested page index and filter options.
        getJsonCI('AdList', 'GetAds', function(data) {
            $("[id$='" + controlID + "']").html(data.AdsList);
        }, { uniqueName: controlID, pageIndex: pageIndex, selectedFilter1: data.selectedFilter1, selectedFilter2: data.selectedFilter2,
            selectedFilter3: data.selectedFilter3, selectedFilter4: data.selectedFilter4
        });

        void (0);
    },
    search: function(data) {
        // When searched is clicked, first page index is always zero.
        this.getAds(data.controlID, 0, data);
    }
};


function JOrder() {
    this._orderID = 0;
    this.menuID = 0;
    this.handler = '';
    this.types = new Array();
    this.simple = false;
    this.tracing = false;
}
JOrder.prototype = {
    // INTERNAL FUNCTIONS

    orderID: function() {
        if (this._orderID > 0) return this._orderID;
        _orderID = $(document).getUrlParam('orderID') || $(document).getUrlParam('OrderID') || 0;
        return _orderID;
    },

    getParent: function(obj, tagname) {
        if (!tagname) return null;
        tagname = tagname.toLowerCase();
        obj = $(obj);
        while (obj && obj.get(0).tagName && obj.get(0).tagName.toLowerCase() != tagname) obj = obj.parent();
        return obj;
    },

    setType: function(orderLineType) {
        this.types[orderLineType] = {
            name: orderLineType,
            loadAction: 'ShowProducts',
            selector: '#div' + orderLineType,
            table: function() { return $("table[id$='" + orderLineType + "']"); },
            timer: null,
            hasFocus: false,
            isChanged: false,
            changedProperty: '',

            addProduct: function() { },
            load: function() { $(this.selector).load(jOrder.handler, { action: this.loadAction, ID: jOrder.menuID, orderID: jOrder.orderID(), type: this.name }, this.onloaded); },
            focus: function() {
                $(this.selector + " input")
                    .attr("orderLineType", this.name)
                    .focus(function() {
                        var type = jOrder.getType($(this).attr("orderLineType"));
                        jOrder.trace("Focus", $(this).attr("id") + ': ' + type.timer);

                        type.hasFocus = true;
                        clearTimeout(type.timer);

                        if ($(this).val() == 0) $(this).val('');
                    });
            },
            onloaded: function() { },
            onposted: function(input, data, fixedProperty) { this.isChanged = false; },
            setExtendedPrice: function(row, extendedPrice) { },
            setHints: function(row, fixedProperty) { },
            setHours: function(orderLineID, val) { },
            setItemsPerUnit: function(orderLineID, val) { },
            setPrice: function(orderLineID, val) { },
            setQuantity: function(orderLineID, val) { },
            setTotals: function(totals) { },
            setUnitsPerContainer: function(orderLineID, val) { },
            removeOrderLine: function(orderLineID, obj) { }
        };
    },

    getType: function(orderLineType) {
        if (!this.types[orderLineType]) this.setType(orderLineType);
        return this.types[orderLineType];
    },

    alert: function(message, func) {
        alert(message + '\nOrder.js\n' + func);
    },

    trace: function(title, message) {
        if (this.tracing == false) return;

        if (!$("#trace_order_js").length) {
            $("form").append("<div id='trace_order_js' style='position:fixed;top:0;left:0;width:250px;height:400px;overflow:auto;border:solid 1px #000;zIndex:5;'></div>");
        }

        $("#trace_order_js").append("<strong>" + title + "</strong>: " + message + "<br />");
    },

    // PUBLIC FUNCTIONS
    init: function() {
        this.extendProduction();
        this.extendProductivity();
        this.extendCosts();
        this.extendSummary();
        this.extendAlternative();
        return this;
    },

    show: function(menuID, simple) {
        this.menuID = jOrder.menuID = menuID;
        this.simple = simple;
        this.handler = baseURL + 'ValentNet/Views/OrderProcessor/Orders/AjaxHandler.ashx';
        this.load('Production');
    },

    load: function(orderLineType, var1, var2) {
        this.trace("Load", orderLineType);
        this.getType(orderLineType).load(var1, var2);
    },

    // orderline functions
    addProduct: function(orderLineType, selectboxID) {
        var type = this.getType(orderLineType);
        var productID = $("select[id$='" + selectboxID + "']").val();

        this.trace("Add product", "[" + productID + "] for " + orderLineType);
        $(type.selector).load(jOrder.handler, { action: 'AddProduct', ID: this.menuID, orderID: this.orderID(), productID: productID, type: orderLineType },
            function(responseText, textStatus, XMLHttpRequest) {
                var name = $("select[id$='" + selectboxID + "'] option:selected").html();
                $(type.selector).find("td:contains('" + name + "')").next().find("input:first").focus();
            });
    },

    post: function(orderLineType, orderLineID, input, fixedProperty) {
        var type = this.getType(orderLineType);
        type.hasFocus = false;

        input = $(input);
        var val = input.val() || '0';
        if (input.attr('originalValue') == val) {
            this.trace("Post", fixedProperty + " - not changed");

            if (type.isChanged && type.hasFocus == false)
                type.timer = setTimeout("jOrder.getType('" + orderLineType + "').onposted('', '','" + type.changedProperty + "')", 100);
            return;
        }

        var params = { ID: this.menuID, action: 'Set' + fixedProperty, orderLineType: orderLineType, orderLineID: orderLineID };
        params[fixedProperty] = toCultureNumber(input.val());

        this.trace("Post", fixedProperty + " [" + params[fixedProperty] + "] for " + orderLineType + " with id " + orderLineID);
        $.post(jOrder.handler, params, function(data) { jOrder.onposted(orderLineType, input, data, fixedProperty); }, 'json');
    },

    onposted: function(orderLineType, input, data, fixedProperty) {
        var type = this.getType(orderLineType);

        if (data.IsChanged == false) {
            input.val(input.attr('originalValue'));
            return;
        }

        this.trace("Onposted", fixedProperty + " [" + input.val() + "] for " + orderLineType);
        if (input.get(0).tagName && input.get(0).tagName.toLowerCase() == 'input') input.attr('originalValue', input.val());
        var row = this.getParent(input, 'tr');

        this.setExtendedPrice(orderLineType, row, data.ExtendedPrice);
        this.setHints(orderLineType, row, fixedProperty);
        this.setPricePerProductionHour(orderLineType, row, data.PricePerProductionHour);
        this.setPricePerUnit(orderLineType, row, data.PricePerUnit);
        this.setTotals(orderLineType, data.Totals);

        this.trace("Timer", "set timer for " + orderLineType);
        clearTimeout(type.timer);

        type.isChanged = true;
        type.changedProperty = fixedProperty;
        if (type.hasFocus == false)
            type.timer = setTimeout("jOrder.getType('" + orderLineType + "').onposted('', '','" + fixedProperty + "')", 100);

    },

    postContainersCount: function(orderLineType, orderLineID, input) {
        this.post(orderLineType, orderLineID, input, 'ContainersCount');
    },

    postHours: function(orderLineType, orderLineID, input) {
        this.post(orderLineType, orderLineID, input, 'Hours');
    },

    postItemsCount: function(orderLineType, orderLineID, input) {
        this.post(orderLineType, orderLineID, input, 'ItemsCount');
    },

    postItemsPerUnit: function(orderLineType, orderLineID, input) {
        this.post(orderLineType, orderLineID, input, 'ItemsPerUnit');
    },

    postPrice: function(orderLineType, orderLineID, input) {
        this.post(orderLineType, orderLineID, input, 'Price');
    },

    postProductionPrice: function(selector) {
        var price = toCultureNumber($("#" + selector).text());
        $.post(jOrder.handler, { ID: this.menuID, action: 'SetProductionPrice', orderID: this.orderID(), price: price },
            function(data) {
                if (data.IsChanged == false) return;
                jOrder.load('Production');
            }, 'json');
    },

    postQuantity: function(orderLineType, orderLineID, input) {
        this.post(orderLineType, orderLineID, input, 'Quantity');
    },

    postUnitsPerContainer: function(orderLineType, orderLineID, input) {
        this.post(orderLineType, orderLineID, input, 'UnitsPerContainer');
    },

    setExtendedPrice: function(orderLineType, row, extendedPrice) {
        row.find("td[id*='ExtendedPrice']").html(toEuro(extendedPrice, 2));
    },

    setHints: function(orderLineType, row, fixedProperty) {
        this.getType(orderLineType).setHints(row, fixedProperty);
    },

    setPricePerProductionHour: function(orderLineType, row, pricePerProductionHour) {
        row.find("td[id*='PricePerProductionHour']").html(toEuro(pricePerProductionHour, 2));
    },

    setPricePerUnit: function(orderLineType, row, pricePerUnit) {
        row.find("td[id*='PricePerUnit']").html(toEuro(pricePerUnit, 4));
    },

    setTotals: function(orderLineType, totals) {
        var table = this.getType(orderLineType).table();
        table.find("#" + orderLineType + "_TotalQuantity").html('<strong>' + roundNumber(totals.Quantity, -1) + '</strong>');
        table.find("#" + orderLineType + "_PriceAverage").html('<strong>' + toEuro(totals.PriceAverage, 2) + '</strong>');
        table.find("#" + orderLineType + "_TotalExtendedPrice").html('<strong>' + toEuro(totals.ExtendedPrice, 2) + '</strong>');
        table.find("#" + orderLineType + "_TotalPricePerProductionHour").html('<strong>' + toEuro(totals.PricePerProductionHour, 2) + '</strong>');
        table.find("#" + orderLineType + "_TotalPricePerUnit").html('<strong>' + toEuro(totals.PricePerUnit, 4) + '</strong>');
    },

    removeOrderLine: function(orderLineType, orderLineID, obj) {
        this.trace("Remove orderline [" + orderLineID + "] for " + orderLineType);
        $.post(jOrder.handler, { ID: this.menuID, action: 'RemoveOrderLine', orderLineType: orderLineType, orderLineID: orderLineID },
            function(data) {
                if (data.IsChanged == false) return;
                jOrder.getParent(obj, 'tr').hide();
                jOrder.onposted(orderLineType, $(obj), data, '');
            }, 'json');
    },


    // PRODUCTION FUNCTIONS
    extendProduction: function() {
        // get the production
        var production = this.getType('Production');

        production.reload = function() {
            jOrder.load('Productivity');
        };

        production.onloaded = function() {
            jOrder.getType('Production').focus('Production');
            if (jOrder.simple) return;
            jOrder.load('Productivity');
        };

        production.onposted = function(input, data, fixedProperty) {
            if (jOrder.simple) return;
            var call = "this.onposted" + fixedProperty + "();";
            eval(call);
        };

        production.onpostedItemsCount = function() { this.reload(); }
        production.onpostedItemsPerUnit = function() { }
        production.onpostedQuantity = function() { this.reload(); }
        production.onpostedUnitsPerContainer = function() { }
        production.onpostedContainersCount = function() { this.reload(); }
        production.onpostedPrice = function() { this.reload(); }

        // set hints
        production.getHint = function(number1, number2, standard) {
            var number = number2 > 0 ? number1 / number2 : standard;
            return roundNumber(number, -1);
        };
        production.setHints = function(row, fixedProperty) {
            // ignore in simple form
            if (jOrder.simple) return;

            // clear hints
            $("span[id*='productionHint']", this.table()).html('');

            var hint = 0;
            var itemsCount = toFloat(row.find("input[id*='ItemsCount']").val());
            var itemsPerUnit = toFloat(row.find("input[id*='ItemsPerUnit']").val());
            var quantity = toFloat(row.find("input[id*='Quantity']").val());
            var unitsPerContainer = toFloat(row.find("input[id*='UnitsPerContainer']").val());
            var containersCount = toFloat(row.find("input[id*='ContainersCount']").val());

            switch (fixedProperty) {
                case 'ItemsCount':
                    row.find("span[id*='productionHintItemsPerUnit']").html(this.getHint(itemsCount, quantity, itemsPerUnit));
                    row.find("span[id*='productionHintQuantity']").html(this.getHint(itemsCount, itemsPerUnit, quantity));
                    break;
                case 'ItemsPerUnit':
                    row.find("span[id*='productionHintItemsCount']").html(roundNumber(itemsPerUnit * quantity, -1));
                    row.find("span[id*='productionHintQuantity']").html(this.getHint(itemsCount, itemsPerUnit, quantity));
                    break;
                case 'Quantity':
                    row.find("span[id*='productionHintItemsCount']").html(roundNumber(quantity * itemsPerUnit, -1));
                    row.find("span[id*='productionHintItemsPerUnit']").html(this.getHint(itemsCount, quantity, itemsPerUnit));
                    row.find("span[id*='productionHintUnitsPerContainer']").html(this.getHint(quantity, containersCount, unitsPerContainer));
                    row.find("span[id*='productionHintContainersCount']").html(this.getHint(quantity, unitsPerContainer, containersCount));
                    break;
                case 'UnitsPerContainer':
                    row.find("span[id*='productionHintQuantity']").html(roundNumber(unitsPerContainer * containersCount, -1));
                    row.find("span[id*='productionHintContainersCount']").html(this.getHint(quantity, unitsPerContainer, containersCount));
                    break;
                case 'ContainersCount':
                    row.find("span[id*='productionHintQuantity']").html(roundNumber(containersCount * unitsPerContainer, -1));
                    row.find("span[id*='productionHintUnitsPerContainer']").html(this.getHint(quantity, containersCount, unitsPerContainer));
                    break;
            }

            // check hints
            $("span[id*='productionHint']", this.table()).each(function(i) {
                var firstInput = $(this).parent().find("input:first").val();
                if (firstInput == $(this).html()) {
                    $(this).html('');
                }
            });
        };
    },


    // PRODUCTIVITY FUNCTIONS
    extendProductivity: function() {
        // get the productivity
        var productivity = this.getType('Productivity');

        // set load action
        productivity.loadAction = 'ProductivitySetter';

        // set onloaded function
        productivity.onloaded = function() {
            jOrder.getType('Productivity').focus('Productivity');

            $('#estimatedProductivity')
                .css("width", "100px")
                .focus(function() { $(this).attr('title', $(this).val()); })
                .blur(function() { jOrder.getType('Productivity').onchange(this); });
            jOrder.load('Costs');
        };

        // onchange function 
        productivity.onchange = function(input) {
            input = $(input);
            if (input.attr('title') == input.val()) return;

            $.getJSON(jOrder.handler + "?Action=SetEstimatedProductivity&OrderID=" + jOrder.orderID() + "&estimatedProductivity=" + toCultureNumber(input.val()),
                function(data) {
                    if (data.IsChanged == false) { input.val(input.attr('title')); return; }
                    jOrder.load('Productivity');
                });
        };
    },


    // COSTS FUNCTIONS
    extendCosts: function() {
        // get the costs
        var costs = this.getType('Costs');
        costs.loaded = 0;

        // shortcut for loading the different costs
        costs.load = function() {
            this.loaded = 0;
            jOrder.load('Labour');
            jOrder.load('FixedLabour');
            jOrder.load('MiscDay');
            jOrder.load('Misc');
        };

        // reload the summary and the alternatives
        costs.reload = function() {
            jOrder.load('Summary');
            jOrder.load('Alternative', 1, $("#alternativeMarginPercentage1").val() || 0);
            jOrder.load('Alternative', 2, $("#alternativeMarginPercentage2").val() || 0);
            jOrder.load('Alternative', 3, $("#alternativeMarginPercentage3").val() || 0);
        };

        // called after the costs are load
        costs.onloaded = function() {
            this.loaded++;
            // all different costs must be loaded
            if (this.loaded != 4) return;
            this.loaded = 0;

            // focus
            jOrder.getType('Labour').focus('Costs');
            jOrder.getType('FixedLabour').focus('Costs');
            jOrder.getType('MiscDay').focus('Costs');
            jOrder.getType('Misc').focus('Costs');

            this.reload();
        };

        // called after a property is posted
        costs.onposted = function(input, data, fixedProperty) {
            jOrder.trace("Costs", "onposted event for " + fixedProperty);
            this.reload();
        };

        this.extendCostsType('Labour');
        this.extendCostsType('FixedLabour');
        this.extendCostsType('MiscDay');
        this.extendCostsType('Misc');
    },
    extendCostsType: function(orderLineType) {
        var costType = this.getType(orderLineType);
        costType.onloaded = function() { jOrder.getType('Costs').onloaded(); };
        costType.onposted = function(input, data, fixedProperty) { jOrder.getType('Costs').onposted(input, data, fixedProperty); };
    },


    // SUMMARY FUNCTIONS
    extendSummary: function() {
        // get the summary
        var summary = this.getType('Summary');

        // set the load action
        summary.loadAction = 'Summary';
    },


    // ALTERNATIVES FUNCTIONS
    extendAlternative: function() {
        // get the alternative
        var alternative = this.getType('Alternative');

        alternative.load = function(number, marginPercentage) {
            $(alternative.selector + number).load(jOrder.handler + "?Action=AlternativeSetter&OrderID=" + jOrder.orderID() + "&alternativeNumber=" + number + "&alternativeMarginPercentage=" + marginPercentage,
                function() {
                    $('#alternativeMarginPercentage' + number)
                        .focus(function() { $(this).attr('title', $(this).val()); })
                        .blur(function() { if ($(this).val() != $(this).attr('title')) jOrder.load('Alternative', number, $(this).val()); });
                });
        };
    }
};
var jOrder = new JOrder().init();

var mailingsSend = {
    subscribers: 0,
    redirectUrl: '',
    sendMailing: function() {
        if (confirm(labels.areYouSure)) {
            tb_waiting(labels.emailsToSend + ' ' + mailingsSend.subscribers);
            var reqMailingID = $(document).getUrlParam('mailingID');
            $.getJSON(baseURL + "ValentNet/Views/NewsSender/Mailings/SendHandler.ashx",
                {
                    action: 'SendMailing',
                    mailingID: reqMailingID,
                    time: new Date().getMilliseconds()
                },
                function(data) {
                    if (data.success == true) {
                        tb_remove();
                        document.location = mailingsSend.redirectUrl;
                    }
                });
        }
    }
};

var GenericActionRights = {
    actionID: 0,
    handlerUrl: '',
    addGroup: function() {
        $.ajax({ type: 'POST', async: false, url: this.handlerUrl,
            data: { action: 'AddGroup', actionID: this.actionID, groupID: $('#cboGroups').val() },
            dataType: 'json',
            success: function(data) { GenericActionRights.updateScreen(data); }
        });
    },
    getGroups: function() {
        $.ajax({ type: 'POST', async: true, url: this.handlerUrl,
            data: { action: 'GetGroups', actionID: this.actionID },
            dataType: 'json',
            success: function(data) { GenericActionRights.updateScreen(data); }
        });
    },
    removeGroup: function(groupID) {
        if (confirm(labels.confirmDeleteItem) == false) return;

        $.ajax({ type: 'POST', async: false, url: this.handlerUrl,
            data: { action: 'RemoveGroup', actionID: this.actionID, groupID: groupID },
            dataType: 'json',
            success: function(data) { GenericActionRights.updateScreen(data); }
        });
    },
    updateScreen: function(data) {
        if (data.success) {
            $('#cboGroups').html(data.toAdd);
            var tb = $('#tbGroups');
            tb.html(data.added);
            tb.find('tbody tr:odd:not([class=header])').each(function() {
                var tr = $(this);
                if (tr.attr('class') != 'footer') {
                    tr.removeClass('rowEven').addClass('rowOdd')
                };
            });
            tb.find('tbody tr:even:not([class=header])').each(function() {
                var tr = $(this);
                if (tr.attr('class') != 'footer') {
                    tr.removeClass('rowOdd').addClass('rowEven')
                };
            });
        }
    }
};


var CmsWebshop = {
    tabId: '',
    handler: 'valentnet/views/cms/webshop/handler.ashx',

    checkPayment: function(input) {
        if (input.checked) {
            $(input).parent().parent().nextAll()
                .find("input, select").removeAttr("disabled");
        } else {
            $(input).parent().parent().nextAll()
                .find("input, select").attr("disabled", "disabled");
        }
    },

    showTab: function(li, id, className) {
        if (!className) className = 'tab';

        $(li).parent().find("li").removeClass('selected');
        $(li).addClass('selected');

        $(li).parent().parent().find("div." + className).hide();
        $('#' + id).show();
        this.loadData(id);
        this.tabId = id;
    },

    loadData: function(id) {
        if ('' == $('#' + id).html()) {
            $('#' + id).load(baseURL + this.handler, { ID: menuID, action: 'Get' + id }, function(responseText, textStatus, XMLHttpRequest) {
                tb_init('#' + id + ' a.thickbox');
            });
        }
    },

    save: function() {
        if ('' == this.tabId) return;

        var postData = { ID: menuID, action: 'Save' + this.tabId };
        $('#' + this.tabId).find("input, select, textarea").each(function() {
            var field = $(this);
            // Get value for a radio button
            if (field.attr('type') == 'checkbox' || field.attr('type') == 'radio') {
                postData[field.attr('id')] = field.attr('checked');
            }
            else {
                postData[field.attr('id')] = field.val();
            }
        });

        $.post(baseURL + this.handler, postData, function(data) { }, "json");
    }
};
