;// Beginning /res/js/os/jquery-1.7.1.min.js:
/*! jQuery v1.7.1 jquery.com | jquery.org/license */
(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.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|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
;// Beginning /res/js/os/jquery-ui-1.8.17.min.js:
/*!
 * jQuery UI 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI
 */(function(a,b){function d(b){return!a(b).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}function c(b,c){var e=b.nodeName.toLowerCase();if("area"===e){var f=b.parentNode,g=f.name,h;if(!b.href||!g||f.nodeName.toLowerCase()!=="map")return!1;h=a("img[usemap=#"+g+"]")[0];return!!h&&d(h)}return(/input|select|textarea|button|object/.test(e)?!b.disabled:"a"==e?b.href||c:c)&&d(b)}a.ui=a.ui||{};a.ui.version||(a.extend(a.ui,{version:"1.8.17",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}}),a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(b,c){return typeof b=="number"?this.each(function(){var d=this;setTimeout(function(){a(d).focus(),c&&c.call(d)},b)}):this._focus.apply(this,arguments)},scrollParent:function(){var b;a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?b=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):b=this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!b.length?a(document):b},zIndex:function(c){if(c!==b)return this.css("zIndex",c);if(this.length){var d=a(this[0]),e,f;while(d.length&&d[0]!==document){e=d.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){f=parseInt(d.css("zIndex"),10);if(!isNaN(f)&&f!==0)return f}d=d.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a.each(["Width","Height"],function(c,d){function h(b,c,d,f){a.each(e,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0,d&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0),f&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)});return c}var e=d==="Width"?["Left","Right"]:["Top","Bottom"],f=d.toLowerCase(),g={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){if(c===b)return g["inner"+d].call(this);return this.each(function(){a(this).css(f,h(this,c)+"px")})},a.fn["outer"+d]=function(b,c){if(typeof b!="number")return g["outer"+d].call(this,b);return this.each(function(){a(this).css(f,h(this,b,!0,c)+"px")})}}),a.extend(a.expr[":"],{data:function(b,c,d){return!!a.data(b,d[3])},focusable:function(b){return c(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var d=a.attr(b,"tabindex"),e=isNaN(d);return(e||d>=0)&&c(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),a.support.minHeight=c.offsetHeight===100,a.support.selectstart="onselectstart"in c,b.removeChild(c).style.display="none"}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e=a.ui[b].prototype;for(var f in d)e.plugins[f]=e.plugins[f]||[],e.plugins[f].push([c,d[f]])},call:function(a,b,c){var d=a.plugins[b];if(!!d&&!!a.element[0].parentNode)for(var e=0;e<d.length;e++)a.options[d[e][0]]&&d[e][1].apply(a.element,c)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(b,c){if(a(b).css("overflow")==="hidden")return!1;var d=c&&c==="left"?"scrollLeft":"scrollTop",e=!1;if(b[d]>0)return!0;b[d]=1,e=b[d]>0,b[d]=0;return e},isOverAxis:function(a,b,c){return a>b&&a<b+c},isOver:function(b,c,d,e,f,g){return a.ui.isOverAxis(b,d,f)&&a.ui.isOverAxis(c,e,g)}}))})(jQuery);/*!
 * jQuery UI Widget 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Widget
 */(function(a,b){if(a.cleanData){var c=a.cleanData;a.cleanData=function(b){for(var d=0,e;(e=b[d])!=null;d++)try{a(e).triggerHandler("remove")}catch(f){}c(b)}}else{var d=a.fn.remove;a.fn.remove=function(b,c){return this.each(function(){c||(!b||a.filter(b,[this]).length)&&a("*",this).add([this]).each(function(){try{a(this).triggerHandler("remove")}catch(b){}});return d.call(a(this),b,c)})}}a.widget=function(b,c,d){var e=b.split(".")[0],f;b=b.split(".")[1],f=e+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][f]=function(c){return!!a.data(c,b)},a[e]=a[e]||{},a[e][b]=function(a,b){arguments.length&&this._createWidget(a,b)};var g=new c;g.options=a.extend(!0,{},g.options),a[e][b].prototype=a.extend(!0,g,{namespace:e,widgetName:b,widgetEventPrefix:a[e][b].prototype.widgetEventPrefix||b,widgetBaseClass:f},d),a.widget.bridge(b,a[e][b])},a.widget.bridge=function(c,d){a.fn[c]=function(e){var f=typeof e=="string",g=Array.prototype.slice.call(arguments,1),h=this;e=!f&&g.length?a.extend.apply(null,[!0,e].concat(g)):e;if(f&&e.charAt(0)==="_")return h;f?this.each(function(){var d=a.data(this,c),f=d&&a.isFunction(d[e])?d[e].apply(d,g):d;if(f!==d&&f!==b){h=f;return!1}}):this.each(function(){var b=a.data(this,c);b?b.option(e||{})._init():a.data(this,c,new d(e,this))});return h}},a.Widget=function(a,b){arguments.length&&this._createWidget(a,b)},a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:!1},_createWidget:function(b,c){a.data(c,this.widgetName,this),this.element=a(c),this.options=a.extend(!0,{},this.options,this._getCreateOptions(),b);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()}),this._create(),this._trigger("create"),this._init()},_getCreateOptions:function(){return a.metadata&&a.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName),this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled "+"ui-state-disabled")},widget:function(){return this.element},option:function(c,d){var e=c;if(arguments.length===0)return a.extend({},this.options);if(typeof c=="string"){if(d===b)return this.options[c];e={},e[c]=d}this._setOptions(e);return this},_setOptions:function(b){var c=this;a.each(b,function(a,b){c._setOption(a,b)});return this},_setOption:function(a,b){this.options[a]=b,a==="disabled"&&this.widget()[b?"addClass":"removeClass"](this.widgetBaseClass+"-disabled"+" "+"ui-state-disabled").attr("aria-disabled",b);return this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_trigger:function(b,c,d){var e,f,g=this.options[b];d=d||{},c=a.Event(c),c.type=(b===this.widgetEventPrefix?b:this.widgetEventPrefix+b).toLowerCase(),c.target=this.element[0],f=c.originalEvent;if(f)for(e in f)e in c||(c[e]=f[e]);this.element.trigger(c,d);return!(a.isFunction(g)&&g.call(this.element[0],c,d)===!1||c.isDefaultPrevented())}}})(jQuery);/*!
 * jQuery UI Mouse 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Mouse
 *
 * Depends:
 *  jquery.ui.widget.js
 */(function(a,b){var c=!1;a(document).mouseup(function(a){c=!1}),a.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var b=this;this.element.bind("mousedown."+this.widgetName,function(a){return b._mouseDown(a)}).bind("click."+this.widgetName,function(c){if(!0===a.data(c.target,b.widgetName+".preventClickEvent")){a.removeData(c.target,b.widgetName+".preventClickEvent"),c.stopImmediatePropagation();return!1}}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(b){if(!c){this._mouseStarted&&this._mouseUp(b),this._mouseDownEvent=b;var d=this,e=b.which==1,f=typeof this.options.cancel=="string"&&b.target.nodeName?a(b.target).closest(this.options.cancel).length:!1;if(!e||f||!this._mouseCapture(b))return!0;this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){d.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(b)&&this._mouseDelayMet(b)){this._mouseStarted=this._mouseStart(b)!==!1;if(!this._mouseStarted){b.preventDefault();return!0}}!0===a.data(b.target,this.widgetName+".preventClickEvent")&&a.removeData(b.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(a){return d._mouseMove(a)},this._mouseUpDelegate=function(a){return d._mouseUp(a)},a(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),b.preventDefault(),c=!0;return!0}},_mouseMove:function(b){if(a.browser.msie&&!(document.documentMode>=9)&&!b.button)return this._mouseUp(b);if(this._mouseStarted){this._mouseDrag(b);return b.preventDefault()}this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b));return!this._mouseStarted},_mouseUp:function(b){a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,b.target==this._mouseDownEvent.target&&a.data(b.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(b));return!1},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(a){return this.mouseDelayMet},_mouseStart:function(a){},_mouseDrag:function(a){},_mouseStop:function(a){},_mouseCapture:function(a){return!0}})})(jQuery);/*
 * jQuery UI Position 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Position
 */(function(a,b){a.ui=a.ui||{};var c=/left|center|right/,d=/top|center|bottom/,e="center",f={},g=a.fn.position,h=a.fn.offset;a.fn.position=function(b){if(!b||!b.of)return g.apply(this,arguments);b=a.extend({},b);var h=a(b.of),i=h[0],j=(b.collision||"flip").split(" "),k=b.offset?b.offset.split(" "):[0,0],l,m,n;i.nodeType===9?(l=h.width(),m=h.height(),n={top:0,left:0}):i.setTimeout?(l=h.width(),m=h.height(),n={top:h.scrollTop(),left:h.scrollLeft()}):i.preventDefault?(b.at="left top",l=m=0,n={top:b.of.pageY,left:b.of.pageX}):(l=h.outerWidth(),m=h.outerHeight(),n=h.offset()),a.each(["my","at"],function(){var a=(b[this]||"").split(" ");a.length===1&&(a=c.test(a[0])?a.concat([e]):d.test(a[0])?[e].concat(a):[e,e]),a[0]=c.test(a[0])?a[0]:e,a[1]=d.test(a[1])?a[1]:e,b[this]=a}),j.length===1&&(j[1]=j[0]),k[0]=parseInt(k[0],10)||0,k.length===1&&(k[1]=k[0]),k[1]=parseInt(k[1],10)||0,b.at[0]==="right"?n.left+=l:b.at[0]===e&&(n.left+=l/2),b.at[1]==="bottom"?n.top+=m:b.at[1]===e&&(n.top+=m/2),n.left+=k[0],n.top+=k[1];return this.each(function(){var c=a(this),d=c.outerWidth(),g=c.outerHeight(),h=parseInt(a.curCSS(this,"marginLeft",!0))||0,i=parseInt(a.curCSS(this,"marginTop",!0))||0,o=d+h+(parseInt(a.curCSS(this,"marginRight",!0))||0),p=g+i+(parseInt(a.curCSS(this,"marginBottom",!0))||0),q=a.extend({},n),r;b.my[0]==="right"?q.left-=d:b.my[0]===e&&(q.left-=d/2),b.my[1]==="bottom"?q.top-=g:b.my[1]===e&&(q.top-=g/2),f.fractions||(q.left=Math.round(q.left),q.top=Math.round(q.top)),r={left:q.left-h,top:q.top-i},a.each(["left","top"],function(c,e){a.ui.position[j[c]]&&a.ui.position[j[c]][e](q,{targetWidth:l,targetHeight:m,elemWidth:d,elemHeight:g,collisionPosition:r,collisionWidth:o,collisionHeight:p,offset:k,my:b.my,at:b.at})}),a.fn.bgiframe&&c.bgiframe(),c.offset(a.extend(q,{using:b.using}))})},a.ui.position={fit:{left:function(b,c){var d=a(window),e=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft();b.left=e>0?b.left-e:Math.max(b.left-c.collisionPosition.left,b.left)},top:function(b,c){var d=a(window),e=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop();b.top=e>0?b.top-e:Math.max(b.top-c.collisionPosition.top,b.top)}},flip:{left:function(b,c){if(c.at[0]!==e){var d=a(window),f=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft(),g=c.my[0]==="left"?-c.elemWidth:c.my[0]==="right"?c.elemWidth:0,h=c.at[0]==="left"?c.targetWidth:-c.targetWidth,i=-2*c.offset[0];b.left+=c.collisionPosition.left<0?g+h+i:f>0?g+h+i:0}},top:function(b,c){if(c.at[1]!==e){var d=a(window),f=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop(),g=c.my[1]==="top"?-c.elemHeight:c.my[1]==="bottom"?c.elemHeight:0,h=c.at[1]==="top"?c.targetHeight:-c.targetHeight,i=-2*c.offset[1];b.top+=c.collisionPosition.top<0?g+h+i:f>0?g+h+i:0}}}},a.offset.setOffset||(a.offset.setOffset=function(b,c){/static/.test(a.curCSS(b,"position"))&&(b.style.position="relative");var d=a(b),e=d.offset(),f=parseInt(a.curCSS(b,"top",!0),10)||0,g=parseInt(a.curCSS(b,"left",!0),10)||0,h={top:c.top-e.top+f,left:c.left-e.left+g};"using"in c?c.using.call(b,h):d.css(h)},a.fn.offset=function(b){var c=this[0];if(!c||!c.ownerDocument)return null;if(b)return this.each(function(){a.offset.setOffset(this,b)});return h.call(this)}),function(){var b=document.getElementsByTagName("body")[0],c=document.createElement("div"),d,e,g,h,i;d=document.createElement(b?"div":"body"),g={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},b&&jQuery.extend(g,{position:"absolute",left:"-1000px",top:"-1000px"});for(var j in g)d.style[j]=g[j];d.appendChild(c),e=b||document.documentElement,e.insertBefore(d,e.firstChild),c.style.cssText="position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;",h=a(c).offset(function(a,b){return b}).offset(),d.innerHTML="",e.removeChild(d),i=h.top+h.left+(b?2e3:0),f.fractions=i>21&&i<22}()})(jQuery);/*
 * jQuery UI Draggable 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Draggables
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.mouse.js
 *  jquery.ui.widget.js
 */(function(a,b){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},destroy:function(){if(!!this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy();return this}},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle"))return!1;this.handle=this._getHandle(b);if(!this.handle)return!1;c.iframeFix&&a(c.iframeFix===!0?"iframe":c.iframeFix).each(function(){a('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(a(this).offset()).appendTo("body")});return!0},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b),this._cacheHelperProportions(),a.ui.ddmanager&&(a.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt),c.containment&&this._setContainment();if(this._trigger("start",b)===!1){this._clear();return!1}this._cacheHelperProportions(),a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.helper.addClass("ui-draggable-dragging"),this._mouseDrag(b,!0),a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,b);return!0},_mouseDrag:function(b,c){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute");if(!c){var d=this._uiHash();if(this._trigger("drag",b,d)===!1){this._mouseUp({});return!1}this.position=d.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";a.ui.ddmanager&&a.ui.ddmanager.drag(this,b);return!1},_mouseStop:function(b){var c=!1;a.ui.ddmanager&&!this.options.dropBehaviour&&(c=a.ui.ddmanager.drop(this,b)),this.dropped&&(c=this.dropped,this.dropped=!1);if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return!1;if(this.options.revert=="invalid"&&!c||this.options.revert=="valid"&&c||this.options.revert===!0||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var d=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){d._trigger("stop",b)!==!1&&d._clear()})}else this._trigger("stop",b)!==!1&&this._clear();return!1},_mouseUp:function(b){this.options.iframeFix===!0&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,b);return a.ui.mouse.prototype._mouseUp.call(this,b)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?!0:!1;a(this.options.handle,this.element).find("*").andSelf().each(function(){this==b.target&&(c=!0)});return c},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b])):c.helper=="clone"?this.element.clone().removeAttr("id"):this.element;d.parents("body").length||d.appendTo(c.appendTo=="parent"?this.element[0].parentNode:c.appendTo),d[0]!=this.element[0]&&!/(fixed|absolute)/.test(d.css("position"))&&d.css("position","absolute");return d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[b.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,b.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(b.containment=="document"?0:a(window).scrollLeft())+a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(b.containment=="document"?0:a(window).scrollTop())+(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)&&b.containment.constructor!=Array){var c=a(b.containment),d=c[0];if(!d)return;var e=c.offset(),f=a(d).css("overflow")!="hidden";this.containment=[(parseInt(a(d).css("borderLeftWidth"),10)||0)+(parseInt(a(d).css("paddingLeft"),10)||0),(parseInt(a(d).css("borderTopWidth"),10)||0)+(parseInt(a(d).css("paddingTop"),10)||0),(f?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(a(d).css("borderLeftWidth"),10)||0)-(parseInt(a(d).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(f?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(a(d).css("borderTopWidth"),10)||0)-(parseInt(a(d).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=c}else b.containment.constructor==Array&&(this.containment=b.containment)},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName),f=b.pageX,g=b.pageY;if(this.originalPosition){var h;if(this.containment){if(this.relative_container){var i=this.relative_container.offset();h=[this.containment[0]+i.left,this.containment[1]+i.top,this.containment[2]+i.left,this.containment[3]+i.top]}else h=this.containment;b.pageX-this.offset.click.left<h[0]&&(f=h[0]+this.offset.click.left),b.pageY-this.offset.click.top<h[1]&&(g=h[1]+this.offset.click.top),b.pageX-this.offset.click.left>h[2]&&(f=h[2]+this.offset.click.left),b.pageY-this.offset.click.top>h[3]&&(g=h[3]+this.offset.click.top)}if(c.grid){var j=c.grid[1]?this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY;g=h?j-this.offset.click.top<h[1]||j-this.offset.click.top>h[3]?j-this.offset.click.top<h[1]?j+c.grid[1]:j-c.grid[1]:j:j;var k=c.grid[0]?this.originalPageX+Math.round((f-this.originalPageX)/c.grid[0])*c.grid[0]:this.originalPageX;f=h?k-this.offset.click.left<h[0]||k-this.offset.click.left>h[2]?k-this.offset.click.left<h[0]?k+c.grid[0]:k-c.grid[0]:k:k}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:d.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:d.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(b,c,d){d=d||this._uiHash(),a.ui.plugin.call(this,b,[c,d]),b=="drag"&&(this.positionAbs=this._convertPositionTo("absolute"));return a.Widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(a){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),a.extend(a.ui.draggable,{version:"1.8.17"}),a.ui.plugin.add("draggable","connectToSortable",{start:function(b,c){var d=a(this).data("draggable"),e=d.options,f=a.extend({},c,{item:d.element});d.sortables=[],a(e.connectToSortable).each(function(){var c=a.data(this,"sortable");c&&!c.options.disabled&&(d.sortables.push({instance:c,shouldRevert:c.options.revert}),c.refreshPositions(),c._trigger("activate",b,f))})},stop:function(b,c){var d=a(this).data("draggable"),e=a.extend({},c,{item:d.element});a.each(d.sortables,function(){this.instance.isOver?(this.instance.isOver=0,d.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(b),this.instance.options.helper=this.instance.options._helper,d.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",b,e))})},drag:function(b,c){var d=a(this).data("draggable"),e=this,f=function(b){var c=this.offset.click.top,d=this.offset.click.left,e=this.positionAbs.top,f=this.positionAbs.left,g=b.height,h=b.width,i=b.top,j=b.left;return a.ui.isOver(e+c,f+d,i,j,g,h)};a.each(d.sortables,function(f){this.instance.positionAbs=d.positionAbs,this.instance.helperProportions=d.helperProportions,this.instance.offset.click=d.offset.click,this.instance._intersectsWith(this.instance.containerCache)?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=a(e).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return c.helper[0]},b.target=this.instance.currentItem[0],this.instance._mouseCapture(b,!0),this.instance._mouseStart(b,!0,!0),this.instance.offset.click.top=d.offset.click.top,this.instance.offset.click.left=d.offset.click.left,this.instance.offset.parent.left-=d.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=d.offset.parent.top-this.instance.offset.parent.top,d._trigger("toSortable",b),d.dropped=this.instance.element,d.currentItem=d.element,this.instance.fromOutside=d),this.instance.currentItem&&this.instance._mouseDrag(b)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",b,this.instance._uiHash(this.instance)),this.instance._mouseStop(b,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),d._trigger("fromSortable",b),d.dropped=!1)})}}),a.ui.plugin.add("draggable","cursor",{start:function(b,c){var d=a("body"),e=a(this).data("draggable").options;d.css("cursor")&&(e._cursor=d.css("cursor")),d.css("cursor",e.cursor)},stop:function(b,c){var d=a(this).data("draggable").options;d._cursor&&a("body").css("cursor",d._cursor)}}),a.ui.plugin.add("draggable","opacity",{start:function(b,c){var d=a(c.helper),e=a(this).data("draggable").options;d.css("opacity")&&(e._opacity=d.css("opacity")),d.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;d._opacity&&a(c.helper).css("opacity",d._opacity)}}),a.ui.plugin.add("draggable","scroll",{start:function(b,c){var d=a(this).data("draggable");d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML"&&(d.overflowOffset=d.scrollParent.offset())},drag:function(b,c){var d=a(this).data("draggable"),e=d.options,f=!1;if(d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML"){if(!e.axis||e.axis!="x")d.overflowOffset.top+d.scrollParent[0].offsetHeight-b.pageY<e.scrollSensitivity?d.scrollParent[0].scrollTop=f=d.scrollParent[0].scrollTop+e.scrollSpeed:b.pageY-d.overflowOffset.top<e.scrollSensitivity&&(d.scrollParent[0].scrollTop=f=d.scrollParent[0].scrollTop-e.scrollSpeed);if(!e.axis||e.axis!="y")d.overflowOffset.left+d.scrollParent[0].offsetWidth-b.pageX<e.scrollSensitivity?d.scrollParent[0].scrollLeft=f=d.scrollParent[0].scrollLeft+e.scrollSpeed:b.pageX-d.overflowOffset.left<e.scrollSensitivity&&(d.scrollParent[0].scrollLeft=f=d.scrollParent[0].scrollLeft-e.scrollSpeed)}else{if(!e.axis||e.axis!="x")b.pageY-a(document).scrollTop()<e.scrollSensitivity?f=a(document).scrollTop(a(document).scrollTop()-e.scrollSpeed):a(window).height()-(b.pageY-a(document).scrollTop())<e.scrollSensitivity&&(f=a(document).scrollTop(a(document).scrollTop()+e.scrollSpeed));if(!e.axis||e.axis!="y")b.pageX-a(document).scrollLeft()<e.scrollSensitivity?f=a(document).scrollLeft(a(document).scrollLeft()-e.scrollSpeed):a(window).width()-(b.pageX-a(document).scrollLeft())<e.scrollSensitivity&&(f=a(document).scrollLeft(a(document).scrollLeft()+e.scrollSpeed))}f!==!1&&a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(d,b)}}),a.ui.plugin.add("draggable","snap",{start:function(b,c){var d=a(this).data("draggable"),e=d.options;d.snapElements=[],a(e.snap.constructor!=String?e.snap.items||":data(draggable)":e.snap).each(function(){var b=a(this),c=b.offset();this!=d.element[0]&&d.snapElements.push({item:this,width:b.outerWidth(),height:b.outerHeight(),top:c.top,left:c.left})})},drag:function(b,c){var d=a(this).data("draggable"),e=d.options,f=e.snapTolerance,g=c.offset.left,h=g+d.helperProportions.width,i=c.offset.top,j=i+d.helperProportions.height;for(var k=d.snapElements.length-1;k>=0;k--){var l=d.snapElements[k].left,m=l+d.snapElements[k].width,n=d.snapElements[k].top,o=n+d.snapElements[k].height;if(!(l-f<g&&g<m+f&&n-f<i&&i<o+f||l-f<g&&g<m+f&&n-f<j&&j<o+f||l-f<h&&h<m+f&&n-f<i&&i<o+f||l-f<h&&h<m+f&&n-f<j&&j<o+f)){d.snapElements[k].snapping&&d.options.snap.release&&d.options.snap.release.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=!1;continue}if(e.snapMode!="inner"){var p=Math.abs(n-j)<=f,q=Math.abs(o-i)<=f,r=Math.abs(l-h)<=f,s=Math.abs(m-g)<=f;p&&(c.position.top=d._convertPositionTo("relative",{top:n-d.helperProportions.height,left:0}).top-d.margins.top),q&&(c.position.top=d._convertPositionTo("relative",{top:o,left:0}).top-d.margins.top),r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l-d.helperProportions.width}).left-d.margins.left),s&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m}).left-d.margins.left)}var t=p||q||r||s;if(e.snapMode!="outer"){var p=Math.abs(n-i)<=f,q=Math.abs(o-j)<=f,r=Math.abs(l-g)<=f,s=Math.abs(m-h)<=f;p&&(c.position.top=d._convertPositionTo("relative",{top:n,left:0}).top-d.margins.top),q&&(c.position.top=d._convertPositionTo("relative",{top:o-d.helperProportions.height,left:0}).top-d.margins.top),r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l}).left-d.margins.left),s&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m-d.helperProportions.width}).left-d.margins.left)}!d.snapElements[k].snapping&&(p||q||r||s||t)&&d.options.snap.snap&&d.options.snap.snap.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=p||q||r||s||t}}}),a.ui.plugin.add("draggable","stack",{start:function(b,c){var d=a(this).data("draggable").options,e=a.makeArray(a(d.stack)).sort(function(b,c){return(parseInt(a(b).css("zIndex"),10)||0)-(parseInt(a(c).css("zIndex"),10)||0)});if(!!e.length){var f=parseInt(e[0].style.zIndex)||0;a(e).each(function(a){this.style.zIndex=f+a}),this[0].style.zIndex=f+e.length}}}),a.ui.plugin.add("draggable","zIndex",{start:function(b,c){var d=a(c.helper),e=a(this).data("draggable").options;d.css("zIndex")&&(e._zIndex=d.css("zIndex")),d.css("zIndex",e.zIndex)},stop:function(b,c){var d=a(this).data("draggable").options;d._zIndex&&a(c.helper).css("zIndex",d._zIndex)}})})(jQuery);/*
 * jQuery UI Droppable 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Droppables
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.widget.js
 *  jquery.ui.mouse.js
 *  jquery.ui.draggable.js
 */(function(a,b){a.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect"},_create:function(){var b=this.options,c=b.accept;this.isover=0,this.isout=1,this.accept=a.isFunction(c)?c:function(a){return a.is(c)},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},a.ui.ddmanager.droppables[b.scope]=a.ui.ddmanager.droppables[b.scope]||[],a.ui.ddmanager.droppables[b.scope].push(this),b.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){var b=a.ui.ddmanager.droppables[this.options.scope];for(var c=0;c<b.length;c++)b[c]==this&&b.splice(c,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(b,c){b=="accept"&&(this.accept=a.isFunction(c)?c:function(a){return a.is(c)}),a.Widget.prototype._setOption.apply(this,arguments)},_activate:function(b){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),c&&this._trigger("activate",b,this.ui(c))},_deactivate:function(b){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),c&&this._trigger("deactivate",b,this.ui(c))},_over:function(b){var c=a.ui.ddmanager.current;!!c&&(c.currentItem||c.element)[0]!=this.element[0]&&this.accept.call(this.element[0],c.currentItem||c.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",b,this.ui(c)))},_out:function(b){var c=a.ui.ddmanager.current;!!c&&(c.currentItem||c.element)[0]!=this.element[0]&&this.accept.call(this.element[0],c.currentItem||c.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",b,this.ui(c)))},_drop:function(b,c){var d=c||a.ui.ddmanager.current;if(!d||(d.currentItem||d.element)[0]==this.element[0])return!1;var e=!1;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var b=a.data(this,"droppable");if(b.options.greedy&&!b.options.disabled&&b.options.scope==d.options.scope&&b.accept.call(b.element[0],d.currentItem||d.element)&&a.ui.intersect(d,a.extend(b,{offset:b.element.offset()}),b.options.tolerance)){e=!0;return!1}});if(e)return!1;if(this.accept.call(this.element[0],d.currentItem||d.element)){this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",b,this.ui(d));return this.element}return!1},ui:function(a){return{draggable:a.currentItem||a.element,helper:a.helper,position:a.position,offset:a.positionAbs}}}),a.extend(a.ui.droppable,{version:"1.8.17"}),a.ui.intersect=function(b,c,d){if(!c.offset)return!1;var e=(b.positionAbs||b.position.absolute).left,f=e+b.helperProportions.width,g=(b.positionAbs||b.position.absolute).top,h=g+b.helperProportions.height,i=c.offset.left,j=i+c.proportions.width,k=c.offset.top,l=k+c.proportions.height;switch(d){case"fit":return i<=e&&f<=j&&k<=g&&h<=l;case"intersect":return i<e+b.helperProportions.width/2&&f-b.helperProportions.width/2<j&&k<g+b.helperProportions.height/2&&h-b.helperProportions.height/2<l;case"pointer":var m=(b.positionAbs||b.position.absolute).left+(b.clickOffset||b.offset.click).left,n=(b.positionAbs||b.position.absolute).top+(b.clickOffset||b.offset.click).top,o=a.ui.isOver(n,m,k,i,c.proportions.height,c.proportions.width);return o;case"touch":return(g>=k&&g<=l||h>=k&&h<=l||g<k&&h>l)&&(e>=i&&e<=j||f>=i&&f<=j||e<i&&f>j);default:return!1}},a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(b,c){var d=a.ui.ddmanager.droppables[b.options.scope]||[],e=c?c.type:null,f=(b.currentItem||b.element).find(":data(droppable)").andSelf();droppablesLoop:for(var g=0;g<d.length;g++){if(d[g].options.disabled||b&&!d[g].accept.call(d[g].element[0],b.currentItem||b.element))continue;for(var h=0;h<f.length;h++)if(f[h]==d[g].element[0]){d[g].proportions.height=0;continue droppablesLoop}d[g].visible=d[g].element.css("display")!="none";if(!d[g].visible)continue;e=="mousedown"&&d[g]._activate.call(d[g],c),d[g].offset=d[g].element.offset(),d[g].proportions={width:d[g].element[0].offsetWidth,height:d[g].element[0].offsetHeight}}},drop:function(b,c){var d=!1;a.each(a.ui.ddmanager.droppables[b.options.scope]||[],function(){!this.options||(!this.options.disabled&&this.visible&&a.ui.intersect(b,this,this.options.tolerance)&&(d=this._drop.call(this,c)||d),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],b.currentItem||b.element)&&(this.isout=1,this.isover=0,this._deactivate.call(this,c)))});return d},dragStart:function(b,c){b.element.parents(":not(body,html)").bind("scroll.droppable",function(){b.options.refreshPositions||a.ui.ddmanager.prepareOffsets(b,c)})},drag:function(b,c){b.options.refreshPositions&&a.ui.ddmanager.prepareOffsets(b,c),a.each(a.ui.ddmanager.droppables[b.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var d=a.ui.intersect(b,this,this.options.tolerance),e=!d&&this.isover==1?"isout":d&&this.isover==0?"isover":null;if(!e)return;var f;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");g.length&&(f=a.data(g[0],"droppable"),f.greedyChild=e=="isover"?1:0)}f&&e=="isover"&&(f.isover=0,f.isout=1,f._out.call(f,c)),this[e]=1,this[e=="isout"?"isover":"isout"]=0,this[e=="isover"?"_over":"_out"].call(this,c),f&&e=="isout"&&(f.isout=0,f.isover=1,f._over.call(f,c))}})},dragStop:function(b,c){b.element.parents(":not(body,html)").unbind("scroll.droppable"),b.options.refreshPositions||a.ui.ddmanager.prepareOffsets(b,c)}}})(jQuery);/*
 * jQuery UI Resizable 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Resizables
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.mouse.js
 *  jquery.ui.widget.js
 */(function(a,b){a.widget("ui.resizable",a.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1e3},_create:function(){var b=this,c=this.options;this.element.addClass("ui-resizable"),a.extend(this,{_aspectRatio:!!c.aspectRatio,aspectRatio:c.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:c.helper||c.ghost||c.animate?c.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(/relative/.test(this.element.css("position"))&&a.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"}),this.element.wrap(a('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=c.handles||(a(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var d=this.handles.split(",");this.handles={};for(var e=0;e<d.length;e++){var f=a.trim(d[e]),g="ui-resizable-"+f,h=a('<div class="ui-resizable-handle '+g+'"></div>');/sw|se|ne|nw/.test(f)&&h.css({zIndex:++c.zIndex}),"se"==f&&h.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[f]=".ui-resizable-"+f,this.element.append(h)}}this._renderAxis=function(b){b=b||this.element;for(var c in this.handles){this.handles[c].constructor==String&&(this.handles[c]=a(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var d=a(this.handles[c],this.element),e=0;e=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth();var f=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");b.css(f,e),this._proportionallyResize()}if(!a(this.handles[c]).length)continue}},this._renderAxis(this.element),this._handles=a(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!b.resizing){if(this.className)var a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=a&&a[1]?a[1]:"se"}}),c.autoHide&&(this._handles.hide(),a(this.element).addClass("ui-resizable-autohide").hover(function(){c.disabled||(a(this).removeClass("ui-resizable-autohide"),b._handles.show())},function(){c.disabled||b.resizing||(a(this).addClass("ui-resizable-autohide"),b._handles.hide())})),this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(b){a(b).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var c=this.element;c.after(this.originalElement.css({position:c.css("position"),width:c.outerWidth(),height:c.outerHeight(),top:c.css("top"),left:c.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle),b(this.originalElement);return this},_mouseCapture:function(b){var c=!1;for(var d in this.handles)a(this.handles[d])[0]==b.target&&(c=!0);return!this.options.disabled&&c},_mouseStart:function(b){var d=this.options,e=this.element.position(),f=this.element;this.resizing=!0,this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()},(f.is(".ui-draggable")||/absolute/.test(f.css("position")))&&f.css({position:"absolute",top:e.top,left:e.left}),a.browser.opera&&/relative/.test(f.css("position"))&&f.css({position:"relative",top:"auto",left:"auto"}),this._renderProxy();var g=c(this.helper.css("left")),h=c(this.helper.css("top"));d.containment&&(g+=a(d.containment).scrollLeft()||0,h+=a(d.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:g,top:h},this.size=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalSize=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalPosition={left:g,top:h},this.sizeDiff={width:f.outerWidth()-f.width(),height:f.outerHeight()-f.height()},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio=typeof d.aspectRatio=="number"?d.aspectRatio:this.originalSize.width/this.originalSize.height||1;var i=a(".ui-resizable-"+this.axis).css("cursor");a("body").css("cursor",i=="auto"?this.axis+"-resize":i),f.addClass("ui-resizable-resizing"),this._propagate("start",b);return!0},_mouseDrag:function(b){var c=this.helper,d=this.options,e={},f=this,g=this.originalMousePosition,h=this.axis,i=b.pageX-g.left||0,j=b.pageY-g.top||0,k=this._change[h];if(!k)return!1;var l=k.apply(this,[b,i,j]),m=a.browser.msie&&a.browser.version<7,n=this.sizeDiff;this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)l=this._updateRatio(l,b);l=this._respectSize(l,b),this._propagate("resize",b),c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",b,this.ui());return!1},_mouseStop:function(b){this.resizing=!1;var c=this.options,d=this;if(this._helper){var e=this._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&a.ui.hasScroll(e[0],"left")?0:d.sizeDiff.height,h=f?0:d.sizeDiff.width,i={width:d.helper.width()-h,height:d.helper.height()-g},j=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,k=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;c.animate||this.element.css(a.extend(i,{top:k,left:j})),d.helper.height(d.size.height),d.helper.width(d.size.width),this._helper&&!c.animate&&this._proportionallyResize()}a("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove();return!1},_updateVirtualBoundaries:function(a){var b=this.options,c,e,f,g,h;h={minWidth:d(b.minWidth)?b.minWidth:0,maxWidth:d(b.maxWidth)?b.maxWidth:Infinity,minHeight:d(b.minHeight)?b.minHeight:0,maxHeight:d(b.maxHeight)?b.maxHeight:Infinity};if(this._aspectRatio||a)c=h.minHeight*this.aspectRatio,f=h.minWidth/this.aspectRatio,e=h.maxHeight*this.aspectRatio,g=h.maxWidth/this.aspectRatio,c>h.minWidth&&(h.minWidth=c),f>h.minHeight&&(h.minHeight=f),e<h.maxWidth&&(h.maxWidth=e),g<h.maxHeight&&(h.maxHeight=g);this._vBoundaries=h},_updateCache:function(a){var b=this.options;this.offset=this.helper.offset(),d(a.left)&&(this.position.left=a.left),d(a.top)&&(this.position.top=a.top),d(a.height)&&(this.size.height=a.height),d(a.width)&&(this.size.width=a.width)},_updateRatio:function(a,b){var c=this.options,e=this.position,f=this.size,g=this.axis;d(a.height)?a.width=a.height*this.aspectRatio:d(a.width)&&(a.height=a.width/this.aspectRatio),g=="sw"&&(a.left=e.left+(f.width-a.width),a.top=null),g=="nw"&&(a.top=e.top+(f.height-a.height),a.left=e.left+(f.width-a.width));return a},_respectSize:function(a,b){var c=this.helper,e=this._vBoundaries,f=this._aspectRatio||b.shiftKey,g=this.axis,h=d(a.width)&&e.maxWidth&&e.maxWidth<a.width,i=d(a.height)&&e.maxHeight&&e.maxHeight<a.height,j=d(a.width)&&e.minWidth&&e.minWidth>a.width,k=d(a.height)&&e.minHeight&&e.minHeight>a.height;j&&(a.width=e.minWidth),k&&(a.height=e.minHeight),h&&(a.width=e.maxWidth),i&&(a.height=e.maxHeight);var l=this.originalPosition.left+this.originalSize.width,m=this.position.top+this.size.height,n=/sw|nw|w/.test(g),o=/nw|ne|n/.test(g);j&&n&&(a.left=l-e.minWidth),h&&n&&(a.left=l-e.maxWidth),k&&o&&(a.top=m-e.minHeight),i&&o&&(a.top=m-e.maxHeight);var p=!a.width&&!a.height;p&&!a.left&&a.top?a.top=null:p&&!a.top&&a.left&&(a.left=null);return a},_proportionallyResize:function(){var b=this.options;if(!!this._proportionallyResizeElements.length){var c=this.helper||this.element;for(var d=0;d<this._proportionallyResizeElements.length;d++){var e=this._proportionallyResizeElements[d];if(!this.borderDif){var f=[e.css("borderTopWidth"),e.css("borderRightWidth"),e.css("borderBottomWidth"),e.css("borderLeftWidth")],g=[e.css("paddingTop"),e.css("paddingRight"),e.css("paddingBottom"),e.css("paddingLeft")];this.borderDif=a.map(f,function(a,b){var c=parseInt(a,10)||0,d=parseInt(g[b],10)||0;return c+d})}if(a.browser.msie&&(!!a(c).is(":hidden")||!!a(c).parents(":hidden").length))continue;e.css({height:c.height()-this.borderDif[0]-this.borderDif[2]||0,width:c.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var b=this.element,c=this.options;this.elementOffset=b.offset();if(this._helper){this.helper=this.helper||a('<div style="overflow:hidden;"></div>');var d=a.browser.msie&&a.browser.version<7,e=d?1:0,f=d?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+f,height:this.element.outerHeight()+f,position:"absolute",left:this.elementOffset.left-e+"px",top:this.elementOffset.top-e+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(a,b,c){return{width:this.originalSize.width+b}},w:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{left:f.left+b,width:e.width-b}},n:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{top:f.top+c,height:e.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),b!="resize"&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.extend(a.ui.resizable,{version:"1.8.17"}),a.ui.plugin.add("resizable","alsoResize",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.data("resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10),position:b.css("position")})})};typeof e.alsoResize=="object"&&!e.alsoResize.parentNode?e.alsoResize.length?(e.alsoResize=e.alsoResize[0],f(e.alsoResize)):a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0},i=function(b,e){a(b).each(function(){var b=a(this),f=a(this).data("resizable-alsoresize"),g={},i=e&&e.length?e:b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(i,function(a,b){var c=(f[b]||0)+(h[b]||0);c&&c>=0&&(g[b]=c||null)}),a.browser.opera&&/relative/.test(b.css("position"))&&(d._revertToRelativePosition=!0,b.css({position:"absolute",top:"auto",left:"auto"})),b.css(g)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a,b){i(a,b)}):i(e.alsoResize)},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.css({position:b.data("resizable-alsoresize").position})})};d._revertToRelativePosition&&(d._revertToRelativePosition=!1,typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)),a(this).removeData("resizable-alsoresize")}}),a.ui.plugin.add("resizable","animate",{stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d._proportionallyResizeElements,g=f.length&&/textarea/i.test(f[0].nodeName),h=g&&a.ui.hasScroll(f[0],"left")?0:d.sizeDiff.height,i=g?0:d.sizeDiff.width,j={width:d.size.width-i,height:d.size.height-h},k=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,l=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;d.element.animate(a.extend(j,l&&k?{top:l,left:k}:{}),{duration:e.animateDuration,easing:e.animateEasing,step:function(){var c={width:parseInt(d.element.css("width"),10),height:parseInt(d.element.css("height"),10),top:parseInt(d.element.css("top"),10),left:parseInt(d.element.css("left"),10)};f&&f.length&&a(f[0]).css({width:c.width,height:c.height}),d._updateCache(c),d._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(b,d){var e=a(this).data("resizable"),f=e.options,g=e.element,h=f.containment,i=h instanceof a?h.get(0):/parent/.test(h)?g.parent().get(0):h;if(!!i){e.containerElement=a(i);if(/document/.test(h)||h==document)e.containerOffset={left:0,top:0},e.containerPosition={left:0,top:0},e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight};else{var j=a(i),k=[];a(["Top","Right","Left","Bottom"]).each(function(a,b){k[a]=c(j.css("padding"+b))}),e.containerOffset=j.offset(),e.containerPosition=j.position(),e.containerSize={height:j.innerHeight()-k[3],width:j.innerWidth()-k[1]};var l=e.containerOffset,m=e.containerSize.height,n=e.containerSize.width,o=a.ui.hasScroll(i,"left")?i.scrollWidth:n,p=a.ui.hasScroll(i)?i.scrollHeight:m;e.parentData={element:i,left:l.left,top:l.top,width:o,height:p}}}},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.containerSize,g=d.containerOffset,h=d.size,i=d.position,j=d._aspectRatio||b.shiftKey,k={top:0,left:0},l=d.containerElement;l[0]!=document&&/static/.test(l.css("position"))&&(k=g),i.left<(d._helper?g.left:0)&&(d.size.width=d.size.width+(d._helper?d.position.left-g.left:d.position.left-k.left),j&&(d.size.height=d.size.width/e.aspectRatio),d.position.left=e.helper?g.left:0),i.top<(d._helper?g.top:0)&&(d.size.height=d.size.height+(d._helper?d.position.top-g.top:d.position.top),j&&(d.size.width=d.size.height*e.aspectRatio),d.position.top=d._helper?g.top:0),d.offset.left=d.parentData.left+d.position.left,d.offset.top=d.parentData.top+d.position.top;var m=Math.abs((d._helper?d.offset.left-k.left:d.offset.left-k.left)+d.sizeDiff.width),n=Math.abs((d._helper?d.offset.top-k.top:d.offset.top-g.top)+d.sizeDiff.height),o=d.containerElement.get(0)==d.element.parent().get(0),p=/relative|absolute/.test(d.containerElement.css("position"));o&&p&&(m-=d.parentData.left),m+d.size.width>=d.parentData.width&&(d.size.width=d.parentData.width-m,j&&(d.size.height=d.size.width/d.aspectRatio)),n+d.size.height>=d.parentData.height&&(d.size.height=d.parentData.height-n,j&&(d.size.width=d.size.height*d.aspectRatio))},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.position,g=d.containerOffset,h=d.containerPosition,i=d.containerElement,j=a(d.helper),k=j.offset(),l=j.outerWidth()-d.sizeDiff.width,m=j.outerHeight()-d.sizeDiff.height;d._helper&&!e.animate&&/relative/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m}),d._helper&&!e.animate&&/static/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m})}}),a.ui.plugin.add("resizable","ghost",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size;d.ghost=d.originalElement.clone(),d.ghost.css({opacity:.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof e.ghost=="string"?e.ghost:""),d.ghost.appendTo(d.helper)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})},stop:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.helper&&d.helper.get(0).removeChild(d.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size,g=d.originalSize,h=d.originalPosition,i=d.axis,j=e._aspectRatio||b.shiftKey;e.grid=typeof e.grid=="number"?[e.grid,e.grid]:e.grid;var k=Math.round((f.width-g.width)/(e.grid[0]||1))*(e.grid[0]||1),l=Math.round((f.height-g.height)/(e.grid[1]||1))*(e.grid[1]||1);/^(se|s|e)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l):/^(ne)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l):/^(sw)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.left=h.left-k):(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l,d.position.left=h.left-k)}});var c=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}})(jQuery);/*
 * jQuery UI Selectable 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Selectables
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.mouse.js
 *  jquery.ui.widget.js
 */(function(a,b){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var b=this;this.element.addClass("ui-selectable"),this.dragged=!1;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]),c.addClass("ui-selectee"),c.each(function(){var b=a(this),c=b.offset();a.data(this,"selectable-item",{element:this,$element:b,left:c.left,top:c.top,right:c.left+b.outerWidth(),bottom:c.top+b.outerHeight(),startselected:!1,selected:b.hasClass("ui-selected"),selecting:b.hasClass("ui-selecting"),unselecting:b.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=c.addClass("ui-selectee"),this._mouseInit(),this.helper=a("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable"),this._mouseDestroy();return this},_mouseStart:function(b){var c=this;this.opos=[b.pageX,b.pageY];if(!this.options.disabled){var d=this.options;this.selectees=a(d.filter,this.element[0]),this._trigger("start",b),a(d.appendTo).append(this.helper),this.helper.css({left:b.clientX,top:b.clientY,width:0,height:0}),d.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var d=a.data(this,"selectable-item");d.startselected=!0,!b.metaKey&&!b.ctrlKey&&(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",b,{unselecting:d.element}))}),a(b.target).parents().andSelf().each(function(){var d=a.data(this,"selectable-item");if(d){var e=!b.metaKey&&!b.ctrlKey||!d.$element.hasClass("ui-selected");d.$element.removeClass(e?"ui-unselecting":"ui-selected").addClass(e?"ui-selecting":"ui-unselecting"),d.unselecting=!e,d.selecting=e,d.selected=e,e?c._trigger("selecting",b,{selecting:d.element}):c._trigger("unselecting",b,{unselecting:d.element});return!1}})}},_mouseDrag:function(b){var c=this;this.dragged=!0;if(!this.options.disabled){var d=this.options,e=this.opos[0],f=this.opos[1],g=b.pageX,h=b.pageY;if(e>g){var i=g;g=e,e=i}if(f>h){var i=h;h=f,f=i}this.helper.css({left:e,top:f,width:g-e,height:h-f}),this.selectees.each(function(){var i=a.data(this,"selectable-item");if(!!i&&i.element!=c.element[0]){var j=!1;d.tolerance=="touch"?j=!(i.left>g||i.right<e||i.top>h||i.bottom<f):d.tolerance=="fit"&&(j=i.left>e&&i.right<g&&i.top>f&&i.bottom<h),j?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,c._trigger("selecting",b,{selecting:i.element}))):(i.selecting&&((b.metaKey||b.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),c._trigger("unselecting",b,{unselecting:i.element}))),i.selected&&!b.metaKey&&!b.ctrlKey&&!i.startselected&&(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,c._trigger("unselecting",b,{unselecting:i.element})))}});return!1}},_mouseStop:function(b){var c=this;this.dragged=!1;var d=this.options;a(".ui-unselecting",this.element[0]).each(function(){var d=a.data(this,"selectable-item");d.$element.removeClass("ui-unselecting"),d.unselecting=!1,d.startselected=!1,c._trigger("unselected",b,{unselected:d.element})}),a(".ui-selecting",this.element[0]).each(function(){var d=a.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected"),d.selecting=!1,d.selected=!0,d.startselected=!0,c._trigger("selected",b,{selected:d.element})}),this._trigger("stop",b),this.helper.remove();return!1}}),a.extend(a.ui.selectable,{version:"1.8.17"})})(jQuery);/*
 * jQuery UI Sortable 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Sortables
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.mouse.js
 *  jquery.ui.widget.js
 */(function(a,b){a.widget("ui.sortable",a.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){b==="disabled"?(this.options[b]=c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(b);var e=null,f=this,g=a(b.target).parents().each(function(){if(a.data(this,d.widgetName+"-item")==f){e=a(this);return!1}});a.data(b.target,d.widgetName+"-item")==f&&(e=a(b.target));if(!e)return!1;if(this.options.handle&&!c){var h=!1;a(this.options.handle,e).find("*").andSelf().each(function(){this==b.target&&(h=!0)});if(!h)return!1}this.currentItem=e,this._removeCurrentsFromItems();return!0},_mouseStart:function(b,c,d){var e=this.options,f=this;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),e.containment&&this._setContainment(),e.cursor&&(a("body").css("cursor")&&(this._storedCursor=a("body").css("cursor")),a("body").css("cursor",e.cursor)),e.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",e.opacity)),e.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",e.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(var g=this.containers.length-1;g>=0;g--)this.containers[g]._trigger("activate",b,f._uiHash(this));a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b);return!0},_mouseDrag:function(b){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY<c.scrollSensitivity?this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop+c.scrollSpeed:b.pageY-this.overflowOffset.top<c.scrollSensitivity&&(this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop-c.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-b.pageX<c.scrollSensitivity?this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft+c.scrollSpeed:b.pageX-this.overflowOffset.left<c.scrollSensitivity&&(this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft-c.scrollSpeed)):(b.pageY-a(document).scrollTop()<c.scrollSensitivity?d=a(document).scrollTop(a(document).scrollTop()-c.scrollSpeed):a(window).height()-(b.pageY-a(document).scrollTop())<c.scrollSensitivity&&(d=a(document).scrollTop(a(document).scrollTop()+c.scrollSpeed)),b.pageX-a(document).scrollLeft()<c.scrollSensitivity?d=a(document).scrollLeft(a(document).scrollLeft()-c.scrollSpeed):a(window).width()-(b.pageX-a(document).scrollLeft())<c.scrollSensitivity&&(d=a(document).scrollLeft(a(document).scrollLeft()+c.scrollSpeed))),d!==!1&&a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(var e=this.items.length-1;e>=0;e--){var f=this.items[e],g=f.item[0],h=this._intersectsWithPointer(f);if(!h)continue;if(g!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=g&&!a.ui.contains(this.placeholder[0],g)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],g):!0)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f))this._rearrange(b,f);else break;this._trigger("change",b,this._uiHash());break}}this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs;return!1},_mouseStop:function(b,c){if(!!b){a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b);if(this.options.revert){var d=this,e=d.placeholder.offset();d.reverting=!0,a(this.helper).animate({left:e.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1}},cancel:function(){var b=this;if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("deactivate",null,b._uiHash(this)),this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",null,b._uiHash(this)),this.containers[c].containerCache.over=0)}this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem));return this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"=");return d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")});return d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l=d+j>h&&d+j<i&&b+k>f&&b+k<g;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?l:f<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<g&&h<d+this.helperProportions.height/2&&e-this.helperProportions.height/2<i},_intersectsWithPointer:function(b){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,b.top,b.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,b.left,b.width),e=c&&d,f=this._getDragVerticalDirection(),g=this._getDragHorizontalDirection();if(!e)return!1;return this.floating?g&&g=="right"||f=="down"?2:1:f&&(f=="down"?2:1)},_intersectsWithSides:function(b){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,b.top+b.height/2,b.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,b.left+b.width/2,b.width),e=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();return this.floating&&f?f=="right"&&d||f=="left"&&!d:e&&(e=="down"&&c||e=="up"&&!c)},_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a),this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c=this,d=[],e=[],f=this._connectWith();if(f&&b)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&e.push([a.isFunction(j.options.items)?j.options.items.call(j.element):a(j.options.items,j.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),j])}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var g=e.length-1;g>=0;g--)e[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){var a=this.currentItem.find(":data("+this.widgetName+"-item)");for(var b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(b){this.items=[],this.containers=[this];var c=this.items,d=this,e=[[a.isFunction(this.options.items)?this.options.items.call(this.element[0],b,{item:this.currentItem}):a(this.options.items,this.element),this]],f=this._connectWith();if(f)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&(e.push([a.isFunction(j.options.items)?j.options.items.call(j.element[0],b,{item:this.currentItem}):a(j.options.items,j.element),j]),this.containers.push(j))}}for(var g=e.length-1;g>=0;g--){var k=e[g][1],l=e[g][0];for(var i=0,m=l.length;i<m;i++){var n=a(l[i]);n.data(this.widgetName+"-item",k),c.push({item:n,instance:k,width:0,height:0,left:0,top:0})}}},refreshPositions:function(b){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());for(var c=this.items.length-1;c>=0;c--){var d=this.items[c];if(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])continue;var e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item;b||(d.width=e.outerWidth(),d.height=e.outerHeight());var f=e.offset();d.left=f.left,d.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var c=this.containers.length-1;c>=0;c--){var f=this.containers[c].element.offset();this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(b){var c=b||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var e=d.placeholder;d.placeholder={element:function(){var b=a(document.createElement(c.currentItem[0].nodeName)).addClass(e||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];e||(b.style.visibility="hidden");return b},update:function(a,b){if(!e||!!d.forcePlaceholderSize)b.height()||b.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),b.width()||b.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=a(d.placeholder.element.call(c.element,c.currentItem)),c.currentItem.after(c.placeholder),d.placeholder.update(c,c.placeholder)},_contactContainers:function(b){var c=null,d=null;for(var e=this.containers.length-1;e>=0;e--){if(a.ui.contains(this.currentItem[0],this.containers[e].element[0]))continue;if(this._intersectsWith(this.containers[e].containerCache)){if(c&&a.ui.contains(this.containers[e].element[0],c.element[0]))continue;c=this.containers[e],d=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",b,this._uiHash(this)),this.containers[e].containerCache.over=0)}if(!!c)if(this.containers.length===1)this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1;else if(this.currentContainer!=this.containers[d]){var f=1e4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"];for(var i=this.items.length-1;i>=0;i--){if(!a.ui.contains(this.containers[d].element[0],this.items[i].item[0]))continue;var j=this.items[i][this.containers[d].floating?"left":"top"];Math.abs(j-h)<f&&(f=Math.abs(j-h),g=this.items[i])}if(!g&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[d],g?this._rearrange(b,g,null,!0):this._rearrange(b,null,this.containers[d].element,!0),this._trigger("change",b,this._uiHash()),this.containers[d]._trigger("change",b,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1}},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b,this.currentItem])):c.helper=="clone"?this.currentItem.clone():this.currentItem;d.parents("body").length||a(c.appendTo!="parent"?c.appendTo:this.currentItem[0].parentNode)[0].appendChild(d[0]),d[0]==this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(d[0].style.width==""||c.forceHelperSize)&&d.width(this.currentItem.width()),(d[0].style.height==""||c.forceHelperSize)&&d.height(this.currentItem.height());return d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)){var c=a(b.containment)[0],d=a(b.containment).offset(),e=a(c).css("overflow")!="hidden";this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(e?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(e?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var f=b.pageX,g=b.pageY;if(this.originalPosition){this.containment&&(b.pageX-this.offset.click.left<this.containment[0]&&(f=this.containment[0]+this.offset.click.left),b.pageY-this.offset.click.top<this.containment[1]&&(g=this.containment[1]+this.offset.click.top),b.pageX-this.offset.click.left>this.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top));if(c.grid){var h=this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1];g=this.containment?h-this.offset.click.top<this.containment[1]||h-this.offset.click.top>this.containment[3]?h-this.offset.click.top<this.containment[1]?h+c.grid[1]:h-c.grid[1]:h:h;var i=this.originalPageX+Math.round((f-this.originalPageX)/c.grid[0])*c.grid[0];f=this.containment?i-this.offset.click.left<this.containment[0]||i-this.offset.click.left>this.containment[2]?i-this.offset.click.left<this.containment[0]?i+c.grid[0]:i-c.grid[0]:i:i}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:d.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:d.scrollLeft())}},_rearrange:function(a,b,c,d){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?b.item[0]:b.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var e=this,f=this.counter;window.setTimeout(function(){f==e.counter&&e.refreshPositions(!d)},0)},_clear:function(b,c){this.reverting=!1;var d=[],e=this;!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var f in this._storedCSS)if(this._storedCSS[f]=="auto"||this._storedCSS[f]=="static")this._storedCSS[f]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!c&&d.push(function(a){this._trigger("receive",a,this._uiHash(this.fromOutside))}),(this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!c&&d.push(function(a){this._trigger("update",a,this._uiHash())});if(!a.ui.contains(this.element[0],this.currentItem[0])){c||d.push(function(a){this._trigger("remove",a,this._uiHash())});for(var f=this.containers.length-1;f>=0;f--)a.ui.contains(this.containers[f].element[0],this.currentItem[0])&&!c&&(d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.containers[f])),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.containers[f])))}for(var f=this.containers.length-1;f>=0;f--)c||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over=0);this._storedCursor&&a("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",b,this._uiHash());for(var f=0;f<d.length;f++)d[f].call(this,b);this._trigger("stop",b,this._uiHash())}return!1}c||this._trigger("beforeStop",b,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!=this.currentItem[0]&&this.helper.remove(),this.helper=null;if(!c){for(var f=0;f<d.length;f++)d[f].call(this,b);this._trigger("stop",b,this._uiHash())}this.fromOutside=!1;return!0},_trigger:function(){a.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(b){var c=b||this;return{helper:c.helper,placeholder:c.placeholder||a([]),position:c.position,originalPosition:c.originalPosition,offset:c.positionAbs,item:c.currentItem,sender:b?b.element:null}}}),a.extend(a.ui.sortable,{version:"1.8.17"})})(jQuery);/*
 * jQuery UI Accordion 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Accordion
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.widget.js
 */(function(a,b){a.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:!0,clearStyle:!1,collapsible:!1,event:"click",fillSpace:!1,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var b=this,c=b.options;b.running=0,b.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"),b.headers=b.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){c.disabled||a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){c.disabled||a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){c.disabled||a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){c.disabled||a(this).removeClass("ui-state-focus")}),b.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");if(c.navigation){var d=b.element.find("a").filter(c.navigationFilter).eq(0);if(d.length){var e=d.closest(".ui-accordion-header");e.length?b.active=e:b.active=d.closest(".ui-accordion-content").prev()}}b.active=b._findActive(b.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top"),b.active.next().addClass("ui-accordion-content-active"),b._createIcons(),b.resize(),b.element.attr("role","tablist"),b.headers.attr("role","tab").bind("keydown.accordion",function(a){return b._keydown(a)}).next().attr("role","tabpanel"),b.headers.not(b.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide(),b.active.length?b.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):b.headers.eq(0).attr("tabIndex",0),a.browser.safari||b.headers.find("a").attr("tabIndex",-1),c.event&&b.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(a){b._clickHandler.call(b,a,this),a.preventDefault()})},_createIcons:function(){var b=this.options;b.icons&&(a("<span></span>").addClass("ui-icon "+b.icons.header).prependTo(this.headers),this.active.children(".ui-icon").toggleClass(b.icons.header).toggleClass(b.icons.headerSelected),this.element.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.children(".ui-icon").remove(),this.element.removeClass("ui-accordion-icons")},destroy:function(){var b=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"),this.headers.find("a").removeAttr("tabIndex"),this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");(b.autoHeight||b.fillHeight)&&c.css("height","");return a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b=="active"&&this.activate(c),b=="icons"&&(this._destroyIcons(),c&&this._createIcons()),b=="disabled"&&this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(b){if(!(this.options.disabled||b.altKey||b.ctrlKey)){var c=a.ui.keyCode,d=this.headers.length,e=this.headers.index(b.target),f=!1;switch(b.keyCode){case c.RIGHT:case c.DOWN:f=this.headers[(e+1)%d];break;case c.LEFT:case c.UP:f=this.headers[(e-1+d)%d];break;case c.SPACE:case c.ENTER:this._clickHandler({target:b.target},b.target),b.preventDefault()}if(f){a(b.target).attr("tabIndex",-1),a(f).attr("tabIndex",0),f.focus();return!1}return!0}},resize:function(){var b=this.options,c;if(b.fillSpace){if(a.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height(),a.browser.msie&&this.element.parent().css("overflow",d),this.headers.each(function(){c-=a(this).outerHeight(!0)}),this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+a(this).height()))}).css("overflow","auto")}else b.autoHeight&&(c=0,this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c));return this},activate:function(a){this.options.active=a;var b=this._findActive(a)[0];this._clickHandler({target:b},b);return this},_findActive:function(b){return b?typeof b=="number"?this.headers.filter(":eq("+b+")"):this.headers.not(this.headers.not(b)):b===!1?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(b,c){var d=this.options;if(!d.disabled){if(!b.target){if(!d.collapsible)return;this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),this.active.next().addClass("ui-accordion-content-active");var e=this.active.next(),f={options:d,newHeader:a([]),oldHeader:d.active,newContent:a([]),oldContent:e},g=this.active=a([]);this._toggle(g,e,f);return}var h=a(b.currentTarget||c),i=h[0]===this.active[0];d.active=d.collapsible&&i?!1:this.headers.index(h);if(this.running||!d.collapsible&&i)return;var j=this.active,g=h.next(),e=this.active.next(),f={options:d,newHeader:i&&d.collapsible?a([]):h,oldHeader:this.active,newContent:i&&d.collapsible?a([]):g,oldContent:e},k=this.headers.index(this.active[0])>this.headers.index(h[0]);this.active=i?a([]):h,this._toggle(g,e,f,i,k),j.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),i||(h.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected),h.next().addClass("ui-accordion-content-active"));return}},_toggle:function(b,c,d,e,f){var g=this,h=g.options;g.toShow=b,g.toHide=c,g.data=d;var i=function(){if(!!g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data),g.running=c.size()===0?b.size():c.size();if(h.animated){var j={};h.collapsible&&e?j={toShow:a([]),toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace}:j={toShow:b,toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace},h.proxied||(h.proxied=h.animated),h.proxiedDuration||(h.proxiedDuration=h.duration),h.animated=a.isFunction(h.proxied)?h.proxied(j):h.proxied,h.duration=a.isFunction(h.proxiedDuration)?h.proxiedDuration(j):h.proxiedDuration;var k=a.ui.accordion.animations,l=h.duration,m=h.animated;m&&!k[m]&&!a.easing[m]&&(m="slide"),k[m]||(k[m]=function(a){this.slide(a,{easing:m,duration:l||700})}),k[m](j)}else h.collapsible&&e?b.toggle():(c.hide(),b.show()),i(!0);c.prev().attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).blur(),b.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;this.running||(this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""}),this.toHide.removeClass("ui-accordion-content-active"),this.toHide.length&&(this.toHide.parent()[0].className=this.toHide.parent()[0].className),this._trigger("change",null,this.data))}}),a.extend(a.ui.accordion,{version:"1.8.17",animations:{slide:function(b,c){b=a.extend({easing:"swing",duration:300},b,c);if(!b.toHide.size())b.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},b);else{if(!b.toShow.size()){b.toHide.animate({height:"hide",paddingTop:"hide",paddingBottom:"hide"},b);return}var d=b.toShow.css("overflow"),e=0,f={},g={},h=["height","paddingTop","paddingBottom"],i,j=b.toShow;i=j[0].style.width,j.width(j.parent().width()-parseFloat(j.css("paddingLeft"))-parseFloat(j.css("paddingRight"))-(parseFloat(j.css("borderLeftWidth"))||0)-(parseFloat(j.css("borderRightWidth"))||0)),a.each(h,function(c,d){g[d]="hide";var e=(""+a.css(b.toShow[0],d)).match(/^([\d+-.]+)(.*)$/);f[d]={value:e[1],unit:e[2]||"px"}}),b.toShow.css({height:0,overflow:"hidden"}).show(),b.toHide.filter(":hidden").each(b.complete).end().filter(":visible").animate(g,{step:function(a,c){c.prop=="height"&&(e=c.end-c.start===0?0:(c.now-c.start)/(c.end-c.start)),b.toShow[0].style[c.prop]=e*f[c.prop].value+f[c.prop].unit},duration:b.duration,easing:b.easing,complete:function(){b.autoHeight||b.toShow.css("height",""),b.toShow.css({width:i,overflow:d}),b.complete()}})}},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1e3:200})}}})})(jQuery);/*
 * jQuery UI Autocomplete 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Autocomplete
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.widget.js
 *  jquery.ui.position.js
 */(function(a,b){var c=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var b=this,c=this.element[0].ownerDocument,d;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!b.options.disabled&&!b.element.propAttr("readOnly")){d=!1;var e=a.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:b._move("previousPage",c);break;case e.PAGE_DOWN:b._move("nextPage",c);break;case e.UP:b._move("previous",c),c.preventDefault();break;case e.DOWN:b._move("next",c),c.preventDefault();break;case e.ENTER:case e.NUMPAD_ENTER:b.menu.active&&(d=!0,c.preventDefault());case e.TAB:if(!b.menu.active)return;b.menu.select(c);break;case e.ESCAPE:b.element.val(b.term),b.close(c);break;default:clearTimeout(b.searching),b.searching=setTimeout(function(){b.term!=b.element.val()&&(b.selectedItem=null,b.search(null,c))},b.options.delay)}}}).bind("keypress.autocomplete",function(a){d&&(d=!1,a.preventDefault())}).bind("focus.autocomplete",function(){b.options.disabled||(b.selectedItem=null,b.previous=b.element.val())}).bind("blur.autocomplete",function(a){b.options.disabled||(clearTimeout(b.searching),b.closing=setTimeout(function(){b.close(a),b._change(a)},150))}),this._initSource(),this.response=function(){return b._response.apply(b,arguments)},this.menu=a("<ul></ul>").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",c)[0]).mousedown(function(c){var d=b.menu.element[0];a(c.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(c){c.target!==b.element[0]&&c.target!==d&&!a.ui.contains(d,c.target)&&b.close()})},1),setTimeout(function(){clearTimeout(b.closing)},13)}).menu({focus:function(a,c){var d=c.item.data("item.autocomplete");!1!==b._trigger("focus",a,{item:d})&&/^key/.test(a.originalEvent.type)&&b.element.val(d.value)},selected:function(a,d){var e=d.item.data("item.autocomplete"),f=b.previous;b.element[0]!==c.activeElement&&(b.element.focus(),b.previous=f,setTimeout(function(){b.previous=f,b.selectedItem=e},1)),!1!==b._trigger("select",a,{item:e})&&b.element.val(e.value),b.term=b.element.val(),b.close(a),b.selectedItem=e},blur:function(a,c){b.menu.element.is(":visible")&&b.element.val()!==b.term&&b.element.val(b.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"),a.fn.bgiframe&&this.menu.element.bgiframe(),b.beforeunloadHandler=function(){b.element.removeAttr("autocomplete")},a(window).bind("beforeunload",b.beforeunloadHandler)},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"),this.menu.element.remove(),a(window).unbind("beforeunload",this.beforeunloadHandler),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b==="source"&&this._initSource(),b==="appendTo"&&this.menu.element.appendTo(a(c||"body",this.element[0].ownerDocument)[0]),b==="disabled"&&c&&this.xhr&&this.xhr.abort()},_initSource:function(){var b=this,d,e;a.isArray(this.options.source)?(d=this.options.source,this.source=function(b,c){c(a.ui.autocomplete.filter(d,b.term))}):typeof this.options.source=="string"?(e=this.options.source,this.source=function(d,f){b.xhr&&b.xhr.abort(),b.xhr=a.ajax({url:e,data:d,dataType:"json",autocompleteRequest:++c,success:function(a,b){this.autocompleteRequest===c&&f(a)},error:function(){this.autocompleteRequest===c&&f([])}})}):this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val(),this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==!1)return this._search(a)},_search:function(a){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.source({term:a},this.response)},_response:function(a){!this.options.disabled&&a&&a.length?(a=this._normalize(a),this._suggest(a),this._trigger("open")):this.close(),this.pending--,this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.deactivate(),this._trigger("close",a))},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(b){if(b.length&&b[0].label&&b[0].value)return b;return a.map(b,function(b){if(typeof b=="string")return{label:b,value:b};return a.extend({label:b.label||b.value,value:b.value||b.label},b)})},_suggest:function(b){var c=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(c,b),this.menu.deactivate(),this.menu.refresh(),c.show(),this._resizeMenu(),c.position(a.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(new a.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(b,c){var d=this;a.each(c,function(a,c){d._renderItem(b,c)})},_renderItem:function(b,c){return a("<li></li>").data("item.autocomplete",c).append(a("<a></a>").text(c.label)).appendTo(b)},_move:function(a,b){if(!this.menu.element.is(":visible"))this.search(null,b);else{if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term),this.menu.deactivate();return}this.menu[a](b)}},widget:function(){return this.menu.element}}),a.extend(a.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(b,c){var d=new RegExp(a.ui.autocomplete.escapeRegex(c),"i");return a.grep(b,function(a){return d.test(a.label||a.value||a)})}})})(jQuery),function(a){a.widget("ui.menu",{_create:function(){var b=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){!a(c.target).closest(".ui-menu-item a").length||(c.preventDefault(),b.select(c))}),this.refresh()},refresh:function(){var b=this,c=this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem");c.children("a").addClass("ui-corner-all").attr("tabindex",-1).mouseenter(function(c){b.activate(c,a(this).parent())}).mouseleave(function(){b.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var c=b.offset().top-this.element.offset().top,d=this.element.scrollTop(),e=this.element.height();c<0?this.element.scrollTop(d+c):c>=e&&this.element.scrollTop(d+c-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end(),this._trigger("focus",a,{item:b})},deactivate:function(){!this.active||(this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null)},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,c){if(!this.active)this.activate(c,this.element.children(b));else{var d=this.active[a+"All"](".ui-menu-item").eq(0);d.length?this.activate(c,d):this.activate(c,this.element.children(b))}},nextPage:function(b){if(this.hasScroll()){if(!this.active||this.last()){this.activate(b,this.element.children(".ui-menu-item:first"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c-d+a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:last")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(b){if(this.hasScroll()){if(!this.active||this.first()){this.activate(b,this.element.children(".ui-menu-item:last"));return}var c=this.active.offset().top,d=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c+d-a(this).height();return b<10&&b>-10}),result.length||(result=this.element.children(".ui-menu-item:first")),this.activate(b,result)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[a.fn.prop?"prop":"attr"]("scrollHeight")},select:function(a){this._trigger("selected",a,{item:this.active})}})}(jQuery);/*
 * jQuery UI Button 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Button
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.widget.js
 */(function(a,b){var c,d,e,f,g="ui-button ui-widget ui-state-default ui-corner-all",h="ui-state-hover ui-state-active ",i="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",j=function(){var b=a(this).find(":ui-button");setTimeout(function(){b.button("refresh")},1)},k=function(b){var c=b.name,d=b.form,e=a([]);c&&(d?e=a(d).find("[name='"+c+"']"):e=a("[name='"+c+"']",b.ownerDocument).filter(function(){return!this.form}));return e};a.widget("ui.button",{options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",j),typeof this.options.disabled!="boolean"&&(this.options.disabled=this.element.propAttr("disabled")),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var b=this,h=this.options,i=this.type==="checkbox"||this.type==="radio",l="ui-state-hover"+(i?"":" ui-state-active"),m="ui-state-focus";h.label===null&&(h.label=this.buttonElement.html()),this.element.is(":disabled")&&(h.disabled=!0),this.buttonElement.addClass(g).attr("role","button").bind("mouseenter.button",function(){h.disabled||(a(this).addClass("ui-state-hover"),this===c&&a(this).addClass("ui-state-active"))}).bind("mouseleave.button",function(){h.disabled||a(this).removeClass(l)}).bind("click.button",function(a){h.disabled&&(a.preventDefault(),a.stopImmediatePropagation())}),this.element.bind("focus.button",function(){b.buttonElement.addClass(m)}).bind("blur.button",function(){b.buttonElement.removeClass(m)}),i&&(this.element.bind("change.button",function(){f||b.refresh()}),this.buttonElement.bind("mousedown.button",function(a){h.disabled||(f=!1,d=a.pageX,e=a.pageY)}).bind("mouseup.button",function(a){!h.disabled&&(d!==a.pageX||e!==a.pageY)&&(f=!0)})),this.type==="checkbox"?this.buttonElement.bind("click.button",function(){if(h.disabled||f)return!1;a(this).toggleClass("ui-state-active"),b.buttonElement.attr("aria-pressed",b.element[0].checked)}):this.type==="radio"?this.buttonElement.bind("click.button",function(){if(h.disabled||f)return!1;a(this).addClass("ui-state-active"),b.buttonElement.attr("aria-pressed","true");var c=b.element[0];k(c).not(c).map(function(){return a(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown.button",function(){if(h.disabled)return!1;a(this).addClass("ui-state-active"),c=this,a(document).one("mouseup",function(){c=null})}).bind("mouseup.button",function(){if(h.disabled)return!1;a(this).removeClass("ui-state-active")}).bind("keydown.button",function(b){if(h.disabled)return!1;(b.keyCode==a.ui.keyCode.SPACE||b.keyCode==a.ui.keyCode.ENTER)&&a(this).addClass("ui-state-active")}).bind("keyup.button",function(){a(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(b){b.keyCode===a.ui.keyCode.SPACE&&a(this).click()})),this._setOption("disabled",h.disabled),this._resetButton()},_determineButtonType:function(){this.element.is(":checkbox")?this.type="checkbox":this.element.is(":radio")?this.type="radio":this.element.is("input")?this.type="input":this.type="button";if(this.type==="checkbox"||this.type==="radio"){var a=this.element.parents().filter(":last"),b="label[for='"+this.element.attr("id")+"']";this.buttonElement=a.find(b),this.buttonElement.length||(a=a.length?a.siblings():this.element.siblings(),this.buttonElement=a.filter(b),this.buttonElement.length||(this.buttonElement=a.find(b))),this.element.addClass("ui-helper-hidden-accessible");var c=this.element.is(":checked");c&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.attr("aria-pressed",c)}else this.buttonElement=this.element},widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(g+" "+h+" "+i).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title"),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments);b==="disabled"?c?this.element.propAttr("disabled",!0):this.element.propAttr("disabled",!1):this._resetButton()},refresh:function(){var b=this.element.is(":disabled");b!==this.options.disabled&&this._setOption("disabled",b),this.type==="radio"?k(this.element[0]).each(function(){a(this).is(":checked")?a(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):this.type==="checkbox"&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var b=this.buttonElement.removeClass(i),c=a("<span></span>",this.element[0].ownerDocument).addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary,f=[];d.primary||d.secondary?(this.options.text&&f.push("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary")),d.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+d.primary+"'></span>"),d.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+d.secondary+"'></span>"),this.options.text||(f.push(e?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||b.attr("title",c))):f.push("ui-button-text-only"),b.addClass(f.join(" "))}}}),a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c),a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var b=this.element.css("direction")==="rtl";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(b?"ui-corner-left":"ui-corner-right").end().end()},destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"),a.Widget.prototype.destroy.call(this)}})})(jQuery);/*
 * jQuery UI Dialog 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Dialog
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.widget.js
 *  jquery.ui.button.js
 *  jquery.ui.draggable.js
 *  jquery.ui.mouse.js
 *  jquery.ui.position.js
 *  jquery.ui.resizable.js
 */(function(a,b){var c="ui-dialog ui-widget ui-widget-content ui-corner-all ",d={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},e={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},f=a.attrFn||{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0,click:!0};a.widget("ui.dialog",{options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",collision:"fit",using:function(b){var c=a(this).css(b).offset().top;c<0&&a(this).css("top",b.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.options.title=this.options.title||this.originalTitle;var b=this,d=b.options,e=d.title||"&#160;",f=a.ui.dialog.getTitleId(b.element),g=(b.uiDialog=a("<div></div>")).appendTo(document.body).hide().addClass(c+d.dialogClass).css({zIndex:d.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(c){d.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(a){b.moveToTop(!1,a)}),h=b.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g),i=(b.uiDialogTitlebar=a("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),j=a('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){j.addClass("ui-state-hover")},function(){j.removeClass("ui-state-hover")}).focus(function(){j.addClass("ui-state-focus")}).blur(function(){j.removeClass("ui-state-focus")}).click(function(a){b.close(a);return!1}).appendTo(i),k=(b.uiDialogTitlebarCloseText=a("<span></span>")).addClass("ui-icon ui-icon-closethick").text(d.closeText).appendTo(j),l=a("<span></span>").addClass("ui-dialog-title").attr("id",f).html(e).prependTo(i);a.isFunction(d.beforeclose)&&!a.isFunction(d.beforeClose)&&(d.beforeClose=d.beforeclose),i.find("*").add(i).disableSelection(),d.draggable&&a.fn.draggable&&b._makeDraggable(),d.resizable&&a.fn.resizable&&b._makeResizable(),b._createButtons(d.buttons),b._isOpen=!1,a.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy(),a.uiDialog.hide(),a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),a.uiDialog.remove(),a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(b){var c=this,d,e;if(!1!==c._trigger("beforeClose",b)){c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",b)}):(c.uiDialog.hide(),c._trigger("close",b)),a.ui.dialog.overlay.resize(),c.options.modal&&(d=0,a(".ui-dialog").each(function(){this!==c.uiDialog[0]&&(e=a(this).css("z-index"),isNaN(e)||(d=Math.max(d,e)))}),a.ui.dialog.maxZ=d);return c}},isOpen:function(){return this._isOpen},moveToTop:function(b,c){var d=this,e=d.options,f;if(e.modal&&!b||!e.stack&&!e.modal)return d._trigger("focus",c);e.zIndex>a.ui.dialog.maxZ&&(a.ui.dialog.maxZ=e.zIndex),d.overlay&&(a.ui.dialog.maxZ+=1,d.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)),f={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()},a.ui.dialog.maxZ+=1,d.uiDialog.css("z-index",a.ui.dialog.maxZ),d.element.attr(f),d._trigger("focus",c);return d},open:function(){if(!this._isOpen){var b=this,c=b.options,d=b.uiDialog;b.overlay=c.modal?new a.ui.dialog.overlay(b):null,b._size(),b._position(c.position),d.show(c.show),b.moveToTop(!0),c.modal&&d.bind("keydown.ui-dialog",function(b){if(b.keyCode===a.ui.keyCode.TAB){var c=a(":tabbable",this),d=c.filter(":first"),e=c.filter(":last");if(b.target===e[0]&&!b.shiftKey){d.focus(1);return!1}if(b.target===d[0]&&b.shiftKey){e.focus(1);return!1}}}),a(b.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus(),b._isOpen=!0,b._trigger("open");return b}},_createButtons:function(b){var c=this,d=!1,e=a("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=a("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);c.uiDialog.find(".ui-dialog-buttonpane").remove(),typeof b=="object"&&b!==null&&a.each(b,function(){return!(d=!0)}),d&&(a.each(b,function(b,d){d=a.isFunction(d)?{click:d,text:b}:d;var e=a('<button type="button"></button>').click(function(){d.click.apply(c.element[0],arguments)}).appendTo(g);a.each(d,function(a,b){a!=="click"&&(a in f?e[a](b):e.attr(a,b))}),a.fn.button&&e.button()}),e.appendTo(c.uiDialog))},_makeDraggable:function(){function f(a){return{position:a.position,offset:a.offset}}var b=this,c=b.options,d=a(document),e;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(d,g){e=c.height==="auto"?"auto":a(this).height(),a(this).height(a(this).height()).addClass("ui-dialog-dragging"),b._trigger("dragStart",d,f(g))},drag:function(a,c){b._trigger("drag",a,f(c))},stop:function(g,h){c.position=[h.position.left-d.scrollLeft(),h.position.top-d.scrollTop()],a(this).removeClass("ui-dialog-dragging").height(e),b._trigger("dragStop",g,f(h)),a.ui.dialog.overlay.resize()}})},_makeResizable:function(c){function h(a){return{originalPosition:a.originalPosition,originalSize:a.originalSize,position:a.position,size:a.size}}c=c===b?this.options.resizable:c;var d=this,e=d.options,f=d.uiDialog.css("position"),g=typeof c=="string"?c:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:g,start:function(b,c){a(this).addClass("ui-dialog-resizing"),d._trigger("resizeStart",b,h(c))},resize:function(a,b){d._trigger("resize",a,h(b))},stop:function(b,c){a(this).removeClass("ui-dialog-resizing"),e.height=a(this).height(),e.width=a(this).width(),d._trigger("resizeStop",b,h(c)),a.ui.dialog.overlay.resize()}}).css("position",f).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(b){var c=[],d=[0,0],e;if(b){if(typeof b=="string"||typeof b=="object"&&"0"in b)c=b.split?b.split(" "):[b[0],b[1]],c.length===1&&(c[1]=c[0]),a.each(["left","top"],function(a,b){+c[a]===c[a]&&(d[a]=c[a],c[a]=b)}),b={my:c.join(" "),at:c.join(" "),offset:d.join(" ")};b=a.extend({},a.ui.dialog.prototype.options.position,b)}else b=a.ui.dialog.prototype.options.position;e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},b)),e||this.uiDialog.hide()},_setOptions:function(b){var c=this,f={},g=!1;a.each(b,function(a,b){c._setOption(a,b),a in d&&(g=!0),a in e&&(f[a]=b)}),g&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(b,d){var e=this,f=e.uiDialog;switch(b){case"beforeclose":b="beforeClose";break;case"buttons":e._createButtons(d);break;case"closeText":e.uiDialogTitlebarCloseText.text(""+d);break;case"dialogClass":f.removeClass(e.options.dialogClass).addClass(c+d);break;case"disabled":d?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case"draggable":var g=f.is(":data(draggable)");g&&!d&&f.draggable("destroy"),!g&&d&&e._makeDraggable();break;case"position":e._position(d);break;case"resizable":var h=f.is(":data(resizable)");h&&!d&&f.resizable("destroy"),h&&typeof d=="string"&&f.resizable("option","handles",d),!h&&d!==!1&&e._makeResizable(d);break;case"title":a(".ui-dialog-title",e.uiDialogTitlebar).html(""+(d||"&#160;"))}a.Widget.prototype._setOption.apply(e,arguments)},_size:function(){var b=this.options,c,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),b.minWidth>b.width&&(b.width=b.minWidth),c=this.uiDialog.css({height:"auto",width:b.width}).height(),d=Math.max(0,b.minHeight-c);if(b.height==="auto")if(a.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();var f=this.element.css("height","auto").height();e||this.uiDialog.hide(),this.element.height(Math.max(f,d))}else this.element.height(Math.max(b.height-c,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),a.extend(a.ui.dialog,{version:"1.8.17",uuid:0,maxZ:0,getTitleId:function(a){var b=a.attr("id");b||(this.uuid+=1,b=this.uuid);return"ui-dialog-title-"+b},overlay:function(b){this.$el=a.ui.dialog.overlay.create(b)}}),a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(b){this.instances.length===0&&(setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()<a.ui.dialog.overlay.maxZ)return!1})},1),a(document).bind("keydown.dialog-overlay",function(c){b.options.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}),a(window).bind("resize.dialog-overlay",a.ui.dialog.overlay.resize));var c=(this.oldInstances.pop()||a("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});a.fn.bgiframe&&c.bgiframe(),this.instances.push(c);return c},destroy:function(b){var c=a.inArray(b,this.instances);c!=-1&&this.oldInstances.push(this.instances.splice(c,1)[0]),this.instances.length===0&&a([document,window]).unbind(".dialog-overlay"),b.remove();var d=0;a.each(this.instances,function(){d=Math.max(d,this.css("z-index"))}),this.maxZ=d},height:function(){var b,c;if(a.browser.msie&&a.browser.version<7){b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return b<c?a(window).height()+"px":b+"px"}return a(document).height()+"px"},width:function(){var b,c;if(a.browser.msie){b=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth),c=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return b<c?a(window).width()+"px":b+"px"}return a(document).width()+"px"},resize:function(){var b=a([]);a.each(a.ui.dialog.overlay.instances,function(){b=b.add(this)}),b.css({width:0,height:0}).css({width:a.ui.dialog.overlay.width(),height:a.ui.dialog.overlay.height()})}}),a.extend(a.ui.dialog.overlay.prototype,{destroy:function(){a.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);/*
 * jQuery UI Slider 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Slider
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.mouse.js
 *  jquery.ui.widget.js
 */(function(a,b){var c=5;a.widget("ui.slider",a.ui.mouse,{widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var b=this,d=this.options,e=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),f="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",g=d.values&&d.values.length||1,h=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(d.disabled?" ui-slider-disabled ui-disabled":"")),this.range=a([]),d.range&&(d.range===!0&&(d.values||(d.values=[this._valueMin(),this._valueMin()]),d.values.length&&d.values.length!==2&&(d.values=[d.values[0],d.values[0]])),this.range=a("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(d.range==="min"||d.range==="max"?" ui-slider-range-"+d.range:"")));for(var i=e.length;i<g;i+=1)h.push(f);this.handles=e.add(a(h.join("")).appendTo(b.element)),this.handle=this.handles.eq(0),this.handles.add(this.range).filter("a").click(function(a){a.preventDefault()}).hover(function(){d.disabled||a(this).addClass("ui-state-hover")},function(){a(this).removeClass("ui-state-hover")}).focus(function(){d.disabled?a(this).blur():(a(".ui-slider .ui-state-focus").removeClass("ui-state-focus"),a(this).addClass("ui-state-focus"))}).blur(function(){a(this).removeClass("ui-state-focus")}),this.handles.each(function(b){a(this).data("index.ui-slider-handle",b)}),this.handles.keydown(function(d){var e=!0,f=a(this).data("index.ui-slider-handle"),g,h,i,j;if(!b.options.disabled){switch(d.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.PAGE_UP:case a.ui.keyCode.PAGE_DOWN:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:e=!1;if(!b._keySliding){b._keySliding=!0,a(this).addClass("ui-state-active"),g=b._start(d,f);if(g===!1)return}}j=b.options.step,b.options.values&&b.options.values.length?h=i=b.values(f):h=i=b.value();switch(d.keyCode){case a.ui.keyCode.HOME:i=b._valueMin();break;case a.ui.keyCode.END:i=b._valueMax();break;case a.ui.keyCode.PAGE_UP:i=b._trimAlignValue(h+(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.PAGE_DOWN:i=b._trimAlignValue(h-(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(h===b._valueMax())return;i=b._trimAlignValue(h+j);break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(h===b._valueMin())return;i=b._trimAlignValue(h-j)}b._slide(d,f,i);return e}}).keyup(function(c){var d=a(this).data("index.ui-slider-handle");b._keySliding&&(b._keySliding=!1,b._stop(c,d),b._change(c,d),a(this).removeClass("ui-state-active"))}),this._refreshValue(),this._animateOff=!1},destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider"),this._mouseDestroy();return this},_mouseCapture:function(b){var c=this.options,d,e,f,g,h,i,j,k,l;if(c.disabled)return!1;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),d={x:b.pageX,y:b.pageY},e=this._normValueFromMouse(d),f=this._valueMax()-this._valueMin()+1,h=this,this.handles.each(function(b){var c=Math.abs(e-h.values(b));f>c&&(f=c,g=a(this),i=b)}),c.range===!0&&this.values(1)===c.min&&(i+=1,g=a(this.handles[i])),j=this._start(b,i);if(j===!1)return!1;this._mouseSliding=!0,h._handleIndex=i,g.addClass("ui-state-active").focus(),k=g.offset(),l=!a(b.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:b.pageX-k.left-g.width()/2,top:b.pageY-k.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(b,i,e),this._animateOff=!0;return!0},_mouseStart:function(a){return!0},_mouseDrag:function(a){var b={x:a.pageX,y:a.pageY},c=this._normValueFromMouse(b);this._slide(a,this._handleIndex,c);return!1},_mouseStop:function(a){this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(a,this._handleIndex),this._change(a,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1;return!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b,c,d,e,f;this.orientation==="horizontal"?(b=this.elementSize.width,c=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(b=this.elementSize.height,c=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),d=c/b,d>1&&(d=1),d<0&&(d=0),this.orientation==="vertical"&&(d=1-d),e=this._valueMax()-this._valueMin(),f=this._valueMin()+d*e;return this._trimAlignValue(f)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values());return this._trigger("start",a,c)},_slide:function(a,b,c){var d,e,f;this.options.values&&this.options.values.length?(d=this.values(b?0:1),this.options.values.length===2&&this.options.range===!0&&(b===0&&c>d||b===1&&c<d)&&(c=d),c!==this.values(b)&&(e=this.values(),e[b]=c,f=this._trigger("slide",a,{handle:this.handles[b],value:c,values:e}),d=this.values(b?0:1),f!==!1&&this.values(b,c,!0))):c!==this.value()&&(f=this._trigger("slide",a,{handle:this.handles[b],value:c}),f!==!1&&this.value(c))},_stop:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("stop",a,c)},_change:function(a,b){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("change",a,c)}},value:function(a){if(arguments.length)this.options.value=this._trimAlignValue(a),this._refreshValue(),this._change(null,0);else return this._value()},values:function(b,c){var d,e,f;if(arguments.length>1)this.options.values[b]=this._trimAlignValue(c),this._refreshValue(),this._change(null,b);else{if(!arguments.length)return this._values();if(!a.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(b):this.value();d=this.options.values,e=arguments[0];for(f=0;f<d.length;f+=1)d[f]=this._trimAlignValue(e[f]),this._change(null,f);this._refreshValue()}},_setOption:function(b,c){var d,e=0;a.isArray(this.options.values)&&(e=this.options.values.length),a.Widget.prototype._setOption.apply(this,arguments);switch(b){case"disabled":c?(this.handles.filter(".ui-state-focus").blur(),this.handles.removeClass("ui-state-hover"),this.handles.propAttr("disabled",!0),this.element.addClass("ui-disabled")):(this.handles.propAttr("disabled",!1),this.element.removeClass("ui-disabled"));break;case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":this._animateOff=!0,this._refreshValue();for(d=0;d<e;d+=1)this._change(null,d);this._animateOff=!1}},_value:function(){var a=this.options.value;a=this._trimAlignValue(a);return a},_values:function(a){var b,c,d;if(arguments.length){b=this.options.values[a],b=this._trimAlignValue(b);return b}c=this.options.values.slice();for(d=0;d<c.length;d+=1)c[d]=this._trimAlignValue(c[d]);return c},_trimAlignValue:function(a){if(a<=this._valueMin())return this._valueMin();if(a>=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b,d=a-c;Math.abs(c)*2>=b&&(d+=c>0?b:-b);return parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var b=this.options.range,c=this.options,d=this,e=this._animateOff?!1:c.animate,f,g={},h,i,j,k;this.options.values&&this.options.values.length?this.handles.each(function(b,i){f=(d.values(b)-d._valueMin())/(d._valueMax()-d._valueMin())*100,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",a(this).stop(1,1)[e?"animate":"css"](g,c.animate),d.options.range===!0&&(d.orientation==="horizontal"?(b===0&&d.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({width:f-h+"%"},{queue:!1,duration:c.animate})):(b===0&&d.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({height:f-h+"%"},{queue:!1,duration:c.animate}))),h=f}):(i=this.value(),j=this._valueMin(),k=this._valueMax(),f=k!==j?(i-j)/(k-j)*100:0,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",this.handle.stop(1,1)[e?"animate":"css"](g,c.animate),b==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},c.animate),b==="max"&&this.orientation==="horizontal"&&this.range[e?"animate":"css"]({width:100-f+"%"},{queue:!1,duration:c.animate}),b==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},c.animate),b==="max"&&this.orientation==="vertical"&&this.range[e?"animate":"css"]({height:100-f+"%"},{queue:!1,duration:c.animate}))}}),a.extend(a.ui.slider,{version:"1.8.17"})})(jQuery);/*
 * jQuery UI Tabs 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Tabs
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.widget.js
 */(function(a,b){function f(){return++d}function e(){return++c}var c=0,d=0;a.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:!1,cookie:null,collapsible:!1,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(!0)},_setOption:function(a,b){if(a=="selected"){if(this.options.collapsible&&b==this.options.selected)return;this.select(b)}else this.options[a]=b,this._tabify()},_tabId:function(a){return a.title&&a.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+e()},_sanitizeSelector:function(a){return a.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+f());return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(a,b){return{tab:a,panel:b,index:this.anchors.index(a)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function m(b,c){b.css("display",""),!a.support.opacity&&c.opacity&&b[0].style.removeAttribute("filter")}var d=this,e=this.options,f=/^#.+/;this.list=this.element.find("ol,ul").eq(0),this.lis=a(" > li:has(a[href])",this.list),this.anchors=this.lis.map(function(){return a("a",this)[0]}),this.panels=a([]),this.anchors.each(function(b,c){var g=a(c).attr("href"),h=g.split("#")[0],i;h&&(h===location.toString().split("#")[0]||(i=a("base")[0])&&h===i.href)&&(g=c.hash,c.href=g);if(f.test(g))d.panels=d.panels.add(d.element.find(d._sanitizeSelector(g)));else if(g&&g!=="#"){a.data(c,"href.tabs",g),a.data(c,"load.tabs",g.replace(/#.*$/,""));var j=d._tabId(c);c.href="#"+j;var k=d.element.find("#"+j);k.length||(k=a(e.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(d.panels[b-1]||d.list),k.data("destroy.tabs",!0)),d.panels=d.panels.add(k)}else e.disabled.push(b)}),c?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),e.selected===b?(location.hash&&this.anchors.each(function(a,b){if(b.hash==location.hash){e.selected=a;return!1}}),typeof e.selected!="number"&&e.cookie&&(e.selected=parseInt(d._cookie(),10)),typeof e.selected!="number"&&this.lis.filter(".ui-tabs-selected").length&&(e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))),e.selected=e.selected||(this.lis.length?0:-1)):e.selected===null&&(e.selected=-1),e.selected=e.selected>=0&&this.anchors[e.selected]||e.selected<0?e.selected:0,e.disabled=a.unique(e.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(a,b){return d.lis.index(a)}))).sort(),a.inArray(e.selected,e.disabled)!=-1&&e.disabled.splice(a.inArray(e.selected,e.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"),e.selected>=0&&this.anchors.length&&(d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(e.selected).addClass("ui-tabs-selected ui-state-active"),d.element.queue("tabs",function(){d._trigger("show",null,d._ui(d.anchors[e.selected],d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash))[0]))}),this.load(e.selected)),a(window).bind("unload",function(){d.lis.add(d.anchors).unbind(".tabs"),d.lis=d.anchors=d.panels=null})):e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")),this.element[e.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible"),e.cookie&&this._cookie(e.selected,e.cookie);for(var g=0,h;h=this.lis[g];g++)a(h)[a.inArray(g,e.disabled)!=-1&&!a(h).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");e.cache===!1&&this.anchors.removeData("cache.tabs"),this.lis.add(this.anchors).unbind(".tabs");if(e.event!=="mouseover"){var i=function(a,b){b.is(":not(.ui-state-disabled)")&&b.addClass("ui-state-"+a)},j=function(a,b){b.removeClass("ui-state-"+a)};this.lis.bind("mouseover.tabs",function(){i("hover",a(this))}),this.lis.bind("mouseout.tabs",function(){j("hover",a(this))}),this.anchors.bind("focus.tabs",function(){i("focus",a(this).closest("li"))}),this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var k,l;e.fx&&(a.isArray(e.fx)?(k=e.fx[0],l=e.fx[1]):k=l=e.fx);var n=l?function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.hide().removeClass("ui-tabs-hide").animate(l,l.duration||"normal",function(){m(c,l),d._trigger("show",null,d._ui(b,c[0]))})}:function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.removeClass("ui-tabs-hide"),d._trigger("show",null,d._ui(b,c[0]))},o=k?function(a,b){b.animate(k,k.duration||"normal",function(){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),m(b,k),d.element.dequeue("tabs")})}:function(a,b,c){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),d.element.dequeue("tabs")};this.anchors.bind(e.event+".tabs",function(){var b=this,c=a(b).closest("li"),f=d.panels.filter(":not(.ui-tabs-hide)"),g=d.element.find(d._sanitizeSelector(b.hash));if(c.hasClass("ui-tabs-selected")&&!e.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing")||d.panels.filter(":animated").length||d._trigger("select",null,d._ui(this,g[0]))===!1){this.blur();return!1}e.selected=d.anchors.index(this),d.abort();if(e.collapsible){if(c.hasClass("ui-tabs-selected")){e.selected=-1,e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){o(b,f)}).dequeue("tabs"),this.blur();return!1}if(!f.length){e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this)),this.blur();return!1}}e.cookie&&d._cookie(e.selected,e.cookie);if(g.length)f.length&&d.element.queue("tabs",function(){o(b,f)}),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this));else throw"jQuery UI Tabs: Mismatching fragment identifier.";a.browser.msie&&this.blur()}),this.anchors.bind("click.tabs",function(){return!1})},_getIndex:function(a){typeof a=="string"&&(a=this.anchors.index(this.anchors.filter("[href$="+a+"]")));return a},destroy:function(){var b=this.options;this.abort(),this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs"),this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.anchors.each(function(){var b=a.data(this,"href.tabs");b&&(this.href=b);var c=a(this).unbind(".tabs");a.each(["href","load","cache"],function(a,b){c.removeData(b+".tabs")})}),this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}),b.cookie&&this._cookie(null,b.cookie);return this},add:function(c,d,e){e===b&&(e=this.anchors.length);var f=this,g=this.options,h=a(g.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,d)),i=c.indexOf("#")?this._tabId(a("a",h)[0]):c.replace("#","");h.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var j=f.element.find("#"+i);j.length||(j=a(g.panelTemplate).attr("id",i).data("destroy.tabs",!0)),j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"),e>=this.lis.length?(h.appendTo(this.list),j.appendTo(this.list[0].parentNode)):(h.insertBefore(this.lis[e]),j.insertBefore(this.panels[e])),g.disabled=a.map(g.disabled,function(a,b){return a>=e?++a:a}),this._tabify(),this.anchors.length==1&&(g.selected=0,h.addClass("ui-tabs-selected ui-state-active"),j.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0)),this._trigger("add",null,this._ui(this.anchors[e],this.panels[e]));return this},remove:function(b){b=this._getIndex(b);var c=this.options,d=this.lis.eq(b).remove(),e=this.panels.eq(b).remove();d.hasClass("ui-tabs-selected")&&this.anchors.length>1&&this.select(b+(b+1<this.anchors.length?1:-1)),c.disabled=a.map(a.grep(c.disabled,function(a,c){return a!=b}),function(a,c){return a>=b?--a:a}),this._tabify(),this._trigger("remove",null,this._ui(d.find("a")[0],e[0]));return this},enable:function(b){b=this._getIndex(b);var c=this.options;if(a.inArray(b,c.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled"),c.disabled=a.grep(c.disabled,function(a,c){return a!=b}),this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(a){a=this._getIndex(a);var b=this,c=this.options;a!=c.selected&&(this.lis.eq(a).addClass("ui-state-disabled"),c.disabled.push(a),c.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[a],this.panels[a])));return this},select:function(a){a=this._getIndex(a);if(a==-1)if(this.options.collapsible&&this.options.selected!=-1)a=this.options.selected;else return this;this.anchors.eq(a).trigger(this.options.event+".tabs");return this},load:function(b){b=this._getIndex(b);var c=this,d=this.options,e=this.anchors.eq(b)[0],f=a.data(e,"load.tabs");this.abort();if(!f||this.element.queue("tabs").length!==0&&a.data(e,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(d.spinner){var g=a("span",e);g.data("label.tabs",g.html()).html(d.spinner)}this.xhr=a.ajax(a.extend({},d.ajaxOptions,{url:f,success:function(f,g){c.element.find(c._sanitizeSelector(e.hash)).html(f),c._cleanup(),d.cache&&a.data(e,"cache.tabs",!0),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.success(f,g)}catch(h){}},error:function(a,f,g){c._cleanup(),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.error(a,f,b,e)}catch(g){}}})),c.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]),this.panels.stop(!1,!0),this.element.queue("tabs",this.element.queue("tabs").splice(-2,2)),this.xhr&&(this.xhr.abort(),delete this.xhr),this._cleanup();return this},url:function(a,b){this.anchors.eq(a).removeData("cache.tabs").data("load.tabs",b);return this},length:function(){return this.anchors.length}}),a.extend(a.ui.tabs,{version:"1.8.17"}),a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(a,b){var c=this,d=this.options,e=c._rotate||(c._rotate=function(b){clearTimeout(c.rotation),c.rotation=setTimeout(function(){var a=d.selected;c.select(++a<c.anchors.length?a:0)},a),b&&b.stopPropagation()}),f=c._unrotate||(c._unrotate=b?function(a){t=d.selected,e()}:function(a){a.clientX&&c.rotate(null)});a?(this.element.bind("tabsshow",e),this.anchors.bind(d.event+".tabs",f),e()):(clearTimeout(c.rotation),this.element.unbind("tabsshow",e),this.anchors.unbind(d.event+".tabs",f),delete this._rotate,delete this._unrotate);return this}})})(jQuery);/*
 * jQuery UI Datepicker 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Datepicker
 *
 * Depends:
 *  jquery.ui.core.js
 */(function($,undefined){function isArray(a){return a&&($.browser.safari&&typeof a=="object"&&a.length||a.constructor&&a.constructor.toString().match(/\Array\(\)/))}function extendRemove(a,b){$.extend(a,b);for(var c in b)if(b[c]==null||b[c]==undefined)a[c]=b[c];return a}function bindHover(a){var b="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return a.bind("mouseout",function(a){var c=$(a.target).closest(b);!c.length||c.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(c){var d=$(c.target).closest(b);!$.datepicker._isDisabledDatepicker(instActive.inline?a.parent()[0]:instActive.input[0])&&!!d.length&&(d.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),d.addClass("ui-state-hover"),d.hasClass("ui-datepicker-prev")&&d.addClass("ui-datepicker-prev-hover"),d.hasClass("ui-datepicker-next")&&d.addClass("ui-datepicker-next-hover"))})}function Datepicker(){this.debug=!1,this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},$.extend(this._defaults,this.regional[""]),this.dpDiv=bindHover($('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}$.extend($.ui,{datepicker:{version:"1.8.17"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){extendRemove(this._defaults,a||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(a,b){var c=a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:c,input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:b?bindHover($('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')):this.dpDiv}},_connectDatepicker:function(a,b){var c=$(a);b.append=$([]),b.trigger=$([]);c.hasClass(this.markerClassName)||(this._attachments(c,b),c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),this._autoSize(b),$.data(a,PROP_NAME,b),b.settings.disabled&&this._disableDatepicker(a))},_attachments:function(a,b){var c=this._get(b,"appendText"),d=this._get(b,"isRTL");b.append&&b.append.remove(),c&&(b.append=$('<span class="'+this._appendClass+'">'+c+"</span>"),a[d?"before":"after"](b.append)),a.unbind("focus",this._showDatepicker),b.trigger&&b.trigger.remove();var e=this._get(b,"showOn");(e=="focus"||e=="both")&&a.focus(this._showDatepicker);if(e=="button"||e=="both"){var f=this._get(b,"buttonText"),g=this._get(b,"buttonImage");b.trigger=$(this._get(b,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:g,alt:f,title:f}):$('<button type="button"></button>').addClass(this._triggerClass).html(g==""?f:$("<img/>").attr({src:g,alt:f,title:f}))),a[d?"before":"after"](b.trigger),b.trigger.click(function(){$.datepicker._datepickerShowing&&$.datepicker._lastInput==a[0]?$.datepicker._hideDatepicker():$.datepicker._showDatepicker(a[0]);return!1})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var d=function(a){var b=0,c=0;for(var d=0;d<a.length;d++)a[d].length>b&&(b=a[d].length,c=d);return c};b.setMonth(d(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort"))),b.setDate(d(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=$(a);c.hasClass(this.markerClassName)||(c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),$.data(a,PROP_NAME,b),this._setDate(b,this._getDefaultDate(b),!0),this._updateDatepicker(b),this._updateAlternate(b),b.settings.disabled&&this._disableDatepicker(a),b.dpDiv.css("display","block"))},_dialogDatepicker:function(a,b,c,d,e){var f=this._dialogInst;if(!f){this.uuid+=1;var g="dp"+this.uuid;this._dialogInput=$('<input type="text" id="'+g+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>'),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),f=this._dialogInst=this._newInst(this._dialogInput,!1),f.settings={},$.data(this._dialogInput[0],PROP_NAME,f)}extendRemove(f.settings,d||{}),b=b&&b.constructor==Date?this._formatDate(f,b):b,this._dialogInput.val(b),this._pos=e?e.length?e:[e.pageX,e.pageY]:null;if(!this._pos){var h=document.documentElement.clientWidth,i=document.documentElement.clientHeight,j=document.documentElement.scrollLeft||document.body.scrollLeft,k=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[h/2-100+j,i/2-150+k]}this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),f.settings.onSelect=c,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,f);return this},_destroyDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();$.removeData(a,PROP_NAME),d=="input"?(c.append.remove(),c.trigger.remove(),b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(d=="div"||d=="span")&&b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!1,c.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().removeClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b})}},_disableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!0,c.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().addClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b}),this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return!0;return!1},_getInst:function(a){try{return $.data(a,PROP_NAME)}catch(b){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(a,b,c){var d=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?$.extend({},$.datepicker._defaults):d?b=="all"?$.extend({},d.settings):this._get(d,b):null;var e=b||{};typeof b=="string"&&(e={},e[b]=c);if(d){this._curInst==d&&this._hideDatepicker();var f=this._getDateDatepicker(a,!0),g=this._getMinMaxDate(d,"min"),h=this._getMinMaxDate(d,"max");extendRemove(d.settings,e),g!==null&&e.dateFormat!==undefined&&e.minDate===undefined&&(d.settings.minDate=this._formatDate(d,g)),h!==null&&e.dateFormat!==undefined&&e.maxDate===undefined&&(d.settings.maxDate=this._formatDate(d,h)),this._attachments($(a),d),this._autoSize(d),this._setDate(d,f),this._updateAlternate(d),this._updateDatepicker(d)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){var b=this._getInst(a);b&&this._updateDatepicker(b)},_setDateDatepicker:function(a,b){var c=this._getInst(a);c&&(this._setDate(c,b),this._updateDatepicker(c),this._updateAlternate(c))},_getDateDatepicker:function(a,b){var c=this._getInst(a);c&&!c.inline&&this._setDateFromField(c,b);return c?this._getDate(c):null},_doKeyDown:function(a){var b=$.datepicker._getInst(a.target),c=!0,d=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=!0;if($.datepicker._datepickerShowing)switch(a.keyCode){case 9:$.datepicker._hideDatepicker(),c=!1;break;case 13:var e=$("td."+$.datepicker._dayOverClass+":not(."+$.datepicker._currentClass+")",b.dpDiv);e[0]&&$.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,e[0]);var f=$.datepicker._get(b,"onSelect");if(f){var g=$.datepicker._formatDate(b);f.apply(b.input?b.input[0]:null,[g,b])}else $.datepicker._hideDatepicker();return!1;case 27:$.datepicker._hideDatepicker();break;case 33:$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 34:$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 35:(a.ctrlKey||a.metaKey)&&$.datepicker._clearDate(a.target),c=a.ctrlKey||a.metaKey;break;case 36:(a.ctrlKey||a.metaKey)&&$.datepicker._gotoToday(a.target),c=a.ctrlKey||a.metaKey;break;case 37:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?1:-1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 38:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,-7,"D"),c=a.ctrlKey||a.metaKey;break;case 39:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?-1:1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 40:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,7,"D"),c=a.ctrlKey||a.metaKey;break;default:c=!1}else a.keyCode==36&&a.ctrlKey?$.datepicker._showDatepicker(this):c=!1;c&&(a.preventDefault(),a.stopPropagation())},_doKeyPress:function(a){var b=$.datepicker._getInst(a.target);if($.datepicker._get(b,"constrainInput")){var c=$.datepicker._possibleChars($.datepicker._get(b,"dateFormat")),d=String.fromCharCode(a.charCode==undefined?a.keyCode:a.charCode);return a.ctrlKey||a.metaKey||d<" "||!c||c.indexOf(d)>-1}},_doKeyUp:function(a){var b=$.datepicker._getInst(a.target);if(b.input.val()!=b.lastVal)try{var c=$.datepicker.parseDate($.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,$.datepicker._getFormatConfig(b));c&&($.datepicker._setDateFromField(b),$.datepicker._updateAlternate(b),$.datepicker._updateDatepicker(b))}catch(a){$.datepicker.log(a)}return!0},_showDatepicker:function(a){a=a.target||a,a.nodeName.toLowerCase()!="input"&&(a=$("input",a.parentNode)[0]);if(!$.datepicker._isDisabledDatepicker(a)&&$.datepicker._lastInput!=a){var b=$.datepicker._getInst(a);$.datepicker._curInst&&$.datepicker._curInst!=b&&($.datepicker._curInst.dpDiv.stop(!0,!0),b&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var c=$.datepicker._get(b,"beforeShow"),d=c?c.apply(a,[a,b]):{};if(d===!1)return;extendRemove(b.settings,d),b.lastVal=null,$.datepicker._lastInput=a,$.datepicker._setDateFromField(b),$.datepicker._inDialog&&(a.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(a),$.datepicker._pos[1]+=a.offsetHeight);var e=!1;$(a).parents().each(function(){e|=$(this).css("position")=="fixed";return!e}),e&&$.browser.opera&&($.datepicker._pos[0]-=document.documentElement.scrollLeft,$.datepicker._pos[1]-=document.documentElement.scrollTop);var f={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,b.dpDiv.empty(),b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(b),f=$.datepicker._checkOffset(b,f,e),b.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":e?"fixed":"absolute",display:"none",left:f.left+"px",top:f.top+"px"});if(!b.inline){var g=$.datepicker._get(b,"showAnim"),h=$.datepicker._get(b,"duration"),i=function(){var a=b.dpDiv.find("iframe.ui-datepicker-cover");if(!!a.length){var c=$.datepicker._getBorders(b.dpDiv);a.css({left:-c[0],top:-c[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex($(a).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&$.effects[g]?b.dpDiv.show(g,$.datepicker._get(b,"showOptions"),h,i):b.dpDiv[g||"show"](g?h:null,i),(!g||!h)&&i(),b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus(),$.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this;b.maxRows=4;var c=$.datepicker._getBorders(a.dpDiv);instActive=a,a.dpDiv.empty().append(this._generateHTML(a));var d=a.dpDiv.find("iframe.ui-datepicker-cover");!d.length||d.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}),a.dpDiv.find("."+this._dayOverClass+" a").mouseover();var e=this._getNumberOfMonths(a),f=e[1],g=17;a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),f>1&&a.dpDiv.addClass("ui-datepicker-multi-"+f).css("width",g*f+"em"),a.dpDiv[(e[0]!=1||e[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),a==$.datepicker._curInst&&$.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var h=a.yearshtml;setTimeout(function(){h===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml),h=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(a){return{thin:1,medium:2,thick:3}[a]||a};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var d=a.dpDiv.outerWidth(),e=a.dpDiv.outerHeight(),f=a.input?a.input.outerWidth():0,g=a.input?a.input.outerHeight():0,h=document.documentElement.clientWidth+$(document).scrollLeft(),i=document.documentElement.clientHeight+$(document).scrollTop();b.left-=this._get(a,"isRTL")?d-f:0,b.left-=c&&b.left==a.input.offset().left?$(document).scrollLeft():0,b.top-=c&&b.top==a.input.offset().top+g?$(document).scrollTop():0,b.left-=Math.min(b.left,b.left+d>h&&h>d?Math.abs(b.left+d-h):0),b.top-=Math.min(b.top,b.top+e>i&&i>e?Math.abs(e+g):0);return b},_findPos:function(a){var b=this._getInst(a),c=this._get(b,"isRTL");while(a&&(a.type=="hidden"||a.nodeType!=1||$.expr.filters.hidden(a)))a=a[c?"previousSibling":"nextSibling"];var d=$(a).offset();return[d.left,d.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=$.data(a,PROP_NAME))&&this._datepickerShowing){var c=this._get(b,"showAnim"),d=this._get(b,"duration"),e=this,f=function(){$.datepicker._tidyDialog(b),e._curInst=null};$.effects&&$.effects[c]?b.dpDiv.hide(c,$.datepicker._get(b,"showOptions"),d,f):b.dpDiv[c=="slideDown"?"slideUp":c=="fadeIn"?"fadeOut":"hide"](c?d:null,f),c||f(),this._datepickerShowing=!1;var g=this._get(b,"onClose");g&&g.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(!!$.datepicker._curInst){var b=$(a.target),c=$.datepicker._getInst(b[0]);(b[0].id!=$.datepicker._mainDivId&&b.parents("#"+$.datepicker._mainDivId).length==0&&!b.hasClass($.datepicker.markerClassName)&&!b.hasClass($.datepicker._triggerClass)&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||b.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=c)&&$.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){var d=$(a),e=this._getInst(d[0]);this._isDisabledDatepicker(d[0])||(this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c),this._updateDatepicker(e))},_gotoToday:function(a){var b=$(a),c=this._getInst(b[0]);if(this._get(c,"gotoCurrent")&&c.currentDay)c.selectedDay=c.currentDay,c.drawMonth=c.selectedMonth=c.currentMonth,c.drawYear=c.selectedYear=c.currentYear;else{var d=new Date;c.selectedDay=d.getDate(),c.drawMonth=c.selectedMonth=d.getMonth(),c.drawYear=c.selectedYear=d.getFullYear()}this._notifyChange(c),this._adjustDate(b)},_selectMonthYear:function(a,b,c){var d=$(a),e=this._getInst(d[0]);e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10),this._notifyChange(e),this._adjustDate(d)},_selectDay:function(a,b,c,d){var e=$(a);if(!$(d).hasClass(this._unselectableClass)&&!this._isDisabledDatepicker(e[0])){var f=this._getInst(e[0]);f.selectedDay=f.currentDay=$("a",d).html(),f.selectedMonth=f.currentMonth=b,f.selectedYear=f.currentYear=c,this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){var b=$(a),c=this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(a,b){var c=$(a),d=this._getInst(c[0]);b=b!=null?b:this._formatDate(d),d.input&&d.input.val(b),this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[b,d]):d.input&&d.input.trigger("change"),d.inline?this._updateDatepicker(d):(this._hideDatepicker(),this._lastInput=d.input[0],typeof d.input[0]!="object"&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),d=this._getDate(a),e=this.formatDate(c,d,this._getFormatConfig(a));$(b).each(function(){$(this).val(e)})}},noWeekends:function(a){var b=a.getDay();return[b>0&&b<6,""]},iso8601Week:function(a){var b=new Date(a.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();b.setMonth(0),b.setDate(1);return Math.floor(Math.round((c-b)/864e5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var d=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;d=typeof d!="string"?d:(new Date).getFullYear()%100+parseInt(d,10);var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,h=(c?c.monthNames:null)||this._defaults.monthNames,i=-1,j=-1,k=-1,l=-1,m=!1,n=function(b){var c=s+1<a.length&&a.charAt(s+1)==b;c&&s++;return c},o=function(a){var c=n(a),d=a=="@"?14:a=="!"?20:a=="y"&&c?4:a=="o"?3:2,e=new RegExp("^\\d{1,"+d+"}"),f=b.substring(r).match(e);if(!f)throw"Missing number at position "+r;r+=f[0].length;return parseInt(f[0],10)},p=function(a,c,d){var e=$.map(n(a)?d:c,function(a,b){return[[b,a]]}).sort(function(a,b){return-(a[1].length-b[1].length)}),f=-1;$.each(e,function(a,c){var d=c[1];if(b.substr(r,d.length).toLowerCase()==d.toLowerCase()){f=c[0],r+=d.length;return!1}});if(f!=-1)return f+1;throw"Unknown name at position "+r},q=function(){if(b.charAt(r)!=a.charAt(s))throw"Unexpected literal at position "+r;r++},r=0;for(var s=0;s<a.length;s++)if(m)a.charAt(s)=="'"&&!n("'")?m=!1:q();else switch(a.charAt(s)){case"d":k=o("d");break;case"D":p("D",e,f);break;case"o":l=o("o");break;case"m":j=o("m");break;case"M":j=p("M",g,h);break;case"y":i=o("y");break;case"@":var t=new Date(o("@"));i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"!":var t=new Date((o("!")-this._ticksTo1970)/1e4);i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"'":n("'")?q():m=!0;break;default:q()}if(r<b.length)throw"Extra/unparsed characters found in date: "+b.substring(r);i==-1?i=(new Date).getFullYear():i<100&&(i+=(new Date).getFullYear()-(new Date).getFullYear()%100+(i<=d?0:-100));if(l>-1){j=1,k=l;for(;;){var u=this._getDaysInMonth(i,j-1);if(k<=u)break;j++,k-=u}}var t=this._daylightSavingAdjust(new Date(i,j-1,k));if(t.getFullYear()!=i||t.getMonth()+1!=j||t.getDate()!=k)throw"Invalid date";return t},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(a,b,c){if(!b)return"";var d=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,e=(c?c.dayNames:null)||this._defaults.dayNames,f=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,h=function(b){var c=m+1<a.length&&a.charAt(m+1)==b;c&&m++;return c},i=function(a,b,c){var d=""+b;if(h(a))while(d.length<c)d="0"+d;return d},j=function(a,b,c,d){return h(a)?d[b]:c[b]},k="",l=!1;if(b)for(var m=0;m<a.length;m++)if(l)a.charAt(m)=="'"&&!h("'")?l=!1:k+=a.charAt(m);else switch(a.charAt(m)){case"d":k+=i("d",b.getDate(),2);break;case"D":k+=j("D",b.getDay(),d,e);break;case"o":k+=i("o",Math.round(((new Date(b.getFullYear(),b.getMonth(),b.getDate())).getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864e5),3);break;case"m":k+=i("m",b.getMonth()+1,2);break;case"M":k+=j("M",b.getMonth(),f,g);break;case"y":k+=h("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case"@":k+=b.getTime();break;case"!":k+=b.getTime()*1e4+this._ticksTo1970;break;case"'":h("'")?k+="'":l=!0;break;default:k+=a.charAt(m)}return k},_possibleChars:function(a){var b="",c=!1,d=function(b){var c=e+1<a.length&&a.charAt(e+1)==b;c&&e++;return c};for(var e=0;e<a.length;e++)if(c)a.charAt(e)=="'"&&!d("'")?c=!1:b+=a.charAt(e);else switch(a.charAt(e)){case"d":case"m":case"y":case"@":b+="0123456789";break;case"D":case"M":return null;case"'":d("'")?b+="'":c=!0;break;default:b+=a.charAt(e)}return b},_get:function(a,b){return a.settings[b]!==undefined?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),d=a.lastVal=a.input?a.input.val():null,e,f;e=f=this._getDefaultDate(a);var g=this._getFormatConfig(a);try{e=this.parseDate(c,d,g)||f}catch(h){this.log(h),d=b?"":d}a.selectedDay=e.getDate(),a.drawMonth=a.selectedMonth=e.getMonth(),a.drawYear=a.selectedYear=e.getFullYear(),a.currentDay=d?e.getDate():0,a.currentMonth=d?e.getMonth():0,a.currentYear=d?e.getFullYear():0,this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var d=function(a){var b=new Date;b.setDate(b.getDate()+a);return b},e=function(b){try{return $.datepicker.parseDate($.datepicker._get(a,"dateFormat"),b,$.datepicker._getFormatConfig(a))}catch(c){}var d=(b.toLowerCase().match(/^c/)?$.datepicker._getDate(a):null)||new Date,e=d.getFullYear(),f=d.getMonth(),g=d.getDate(),h=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,i=h.exec(b);while(i){switch(i[2]||"d"){case"d":case"D":g+=parseInt(i[1],10);break;case"w":case"W":g+=parseInt(i[1],10)*7;break;case"m":case"M":f+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f));break;case"y":case"Y":e+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f))}i=h.exec(b)}return new Date(e,f,g)},f=b==null||b===""?c:typeof b=="string"?e(b):typeof b=="number"?isNaN(b)?c:d(b):new Date(b.getTime());f=f&&f.toString()=="Invalid Date"?c:f,f&&(f.setHours(0),f.setMinutes(0),f.setSeconds(0),f.setMilliseconds(0));return this._daylightSavingAdjust(f)},_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,f=a.selectedYear,g=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=g.getDate(),a.drawMonth=a.selectedMonth=a.currentMonth=g.getMonth(),a.drawYear=a.selectedYear=a.currentYear=g.getFullYear(),(e!=a.selectedMonth||f!=a.selectedYear)&&!c&&this._notifyChange(a),this._adjustInstDate(a),a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){var b=!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return b},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),d=this._get(a,"showButtonPanel"),e=this._get(a,"hideIfNoPrevNext"),f=this._get(a,"navigationAsDateFormat"),g=this._getNumberOfMonths(a),h=this._get(a,"showCurrentAtPos"),i=this._get(a,"stepMonths"),j=g[0]!=1||g[1]!=1,k=this._daylightSavingAdjust(a.currentDay?new Date(a.currentYear,a.currentMonth,a.currentDay):new Date(9999,9,9)),l=this._getMinMaxDate(a,"min"),m=this._getMinMaxDate(a,"max"),n=a.drawMonth-h,o=a.drawYear;n<0&&(n+=12,o--);if(m){var p=this._daylightSavingAdjust(new Date(m.getFullYear(),m.getMonth()-g[0]*g[1]+1,m.getDate()));p=l&&p<l?l:p;while(this._daylightSavingAdjust(new Date(o,n,1))>p)n--,n<0&&(n=11,o--)}a.drawMonth=n,a.drawYear=o;var q=this._get(a,"prevText");q=f?this.formatDate(q,this._daylightSavingAdjust(new Date(o,n-i,1)),this._getFormatConfig(a)):q;var r=this._canAdjustMonth(a,-1,o,n)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._adjustDate('#"+a.id+"', -"+i+", 'M');\""+' title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>":e?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>",s=this._get(a,"nextText");s=f?this.formatDate(s,this._daylightSavingAdjust(new Date(o,n+i,1)),this._getFormatConfig(a)):s;var t=this._canAdjustMonth(a,1,o,n)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._adjustDate('#"+a.id+"', +"+i+", 'M');\""+' title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>":e?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>",u=this._get(a,"currentText"),v=this._get(a,"gotoCurrent")&&a.currentDay?k:b;u=f?this.formatDate(u,v,this._getFormatConfig(a)):u;var w=a.inline?"":'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+dpuuid+'.datepicker._hideDatepicker();">'+this._get(a,"closeText")+"</button>",x=d?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?w:"")+(this._isInRange(a,v)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._gotoToday('#"+a.id+"');\""+">"+u+"</button>":"")+(c?"":w)+"</div>":"",y=parseInt(this._get(a,"firstDay"),10);y=isNaN(y)?0:y;var z=this._get(a,"showWeek"),A=this._get(a,"dayNames"),B=this._get(a,"dayNamesShort"),C=this._get(a,"dayNamesMin"),D=this._get(a,"monthNames"),E=this._get(a,"monthNamesShort"),F=this._get(a,"beforeShowDay"),G=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths"),I=this._get(a,"calculateWeek")||this.iso8601Week,J=this._getDefaultDate(a),K="";for(var L=0;L<g[0];L++){var M="";this.maxRows=4;for(var N=0;N<g[1];N++){var O=this._daylightSavingAdjust(new Date(o,n,a.selectedDay)),P=" ui-corner-all",Q="";if(j){Q+='<div class="ui-datepicker-group';if(g[1]>1)switch(N){case 0:Q+=" ui-datepicker-group-first",P=" ui-corner-"+(c?"right":"left");break;case g[1]-1:Q+=" ui-datepicker-group-last",P=" ui-corner-"+(c?"left":"right");break;default:Q+=" ui-datepicker-group-middle",P=""}Q+='">'}Q+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+P+'">'+(/all|left/.test(P)&&L==0?c?t:r:"")+(/all|right/.test(P)&&L==0?c?r:t:"")+this._generateMonthYearHeader(a,n,o,l,m,L>0||N>0,D,E)+'</div><table class="ui-datepicker-calendar"><thead>'+"<tr>";var R=z?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(var S=0;S<7;S++){var T=(S+y)%7;R+="<th"+((S+y+6)%7>=5?' class="ui-datepicker-week-end"':"")+">"+'<span title="'+A[T]+'">'+C[T]+"</span></th>"}Q+=R+"</tr></thead><tbody>";var U=this._getDaysInMonth(o,n);o==a.selectedYear&&n==a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,U));var V=(this._getFirstDayOfMonth(o,n)-y+7)%7,W=Math.ceil((V+U)/7),X=j?this.maxRows>W?this.maxRows:W:W;this.maxRows=X;var Y=this._daylightSavingAdjust(new Date(o,n,1-V));for(var Z=0;Z<X;Z++){Q+="<tr>";var _=z?'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(Y)+"</td>":"";for(var S=0;S<7;S++){var ba=F?F.apply(a.input?a.input[0]:null,[Y]):[!0,""],bb=Y.getMonth()!=n,bc=bb&&!H||!ba[0]||l&&Y<l||m&&Y>m;_+='<td class="'+((S+y+6)%7>=5?" ui-datepicker-week-end":"")+(bb?" ui-datepicker-other-month":"")+(Y.getTime()==O.getTime()&&n==a.selectedMonth&&a._keyEvent||J.getTime()==Y.getTime()&&J.getTime()==O.getTime()?" "+this._dayOverClass:"")+(bc?" "+this._unselectableClass+" ui-state-disabled":"")+(bb&&!G?"":" "+ba[1]+(Y.getTime()==k.getTime()?" "+this._currentClass:"")+(Y.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!bb||G)&&ba[2]?' title="'+ba[2]+'"':"")+(bc?"":' onclick="DP_jQuery_'+dpuuid+".datepicker._selectDay('#"+a.id+"',"+Y.getMonth()+","+Y.getFullYear()+', this);return false;"')+">"+(bb&&!G?"&#xa0;":bc?'<span class="ui-state-default">'+Y.getDate()+"</span>":'<a class="ui-state-default'+(Y.getTime()==b.getTime()?" ui-state-highlight":"")+(Y.getTime()==k.getTime()?" ui-state-active":"")+(bb?" ui-priority-secondary":"")+'" href="#">'+Y.getDate()+"</a>")+"</td>",Y.setDate(Y.getDate()+1),Y=this._daylightSavingAdjust(Y)}Q+=_+"</tr>"}n++,n>11&&(n=0,o++),Q+="</tbody></table>"+(j?"</div>"+(g[0]>0&&N==g[1]-1?'<div class="ui-datepicker-row-break"></div>':""):""),M+=Q}K+=M}K+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':""),a._keyEvent=!1;return K},_generateMonthYearHeader:function(a,b,c,d,e,f,g,h){var i=this._get(a,"changeMonth"),j=this._get(a,"changeYear"),k=this
._get(a,"showMonthAfterYear"),l='<div class="ui-datepicker-title">',m="";if(f||!i)m+='<span class="ui-datepicker-month">'+g[b]+"</span>";else{var n=d&&d.getFullYear()==c,o=e&&e.getFullYear()==c;m+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+dpuuid+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" "+">";for(var p=0;p<12;p++)(!n||p>=d.getMonth())&&(!o||p<=e.getMonth())&&(m+='<option value="'+p+'"'+(p==b?' selected="selected"':"")+">"+h[p]+"</option>");m+="</select>"}k||(l+=m+(f||!i||!j?"&#xa0;":""));if(!a.yearshtml){a.yearshtml="";if(f||!j)l+='<span class="ui-datepicker-year">'+c+"</span>";else{var q=this._get(a,"yearRange").split(":"),r=(new Date).getFullYear(),s=function(a){var b=a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?r+parseInt(a,10):parseInt(a,10);return isNaN(b)?r:b},t=s(q[0]),u=Math.max(t,s(q[1]||""));t=d?Math.max(t,d.getFullYear()):t,u=e?Math.min(u,e.getFullYear()):u,a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+dpuuid+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" "+">";for(;t<=u;t++)a.yearshtml+='<option value="'+t+'"'+(t==c?' selected="selected"':"")+">"+t+"</option>";a.yearshtml+="</select>",l+=a.yearshtml,a.yearshtml=null}}l+=this._get(a,"yearSuffix"),k&&(l+=(f||!i||!j?"&#xa0;":"")+m),l+="</div>";return l},_adjustInstDate:function(a,b,c){var d=a.drawYear+(c=="Y"?b:0),e=a.drawMonth+(c=="M"?b:0),f=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+(c=="D"?b:0),g=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,f)));a.selectedDay=g.getDate(),a.drawMonth=a.selectedMonth=g.getMonth(),a.drawYear=a.selectedYear=g.getFullYear(),(c=="M"||c=="Y")&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),e=c&&b<c?c:b;e=d&&e>d?d:e;return e},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){var b=this._get(a,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),f=this._daylightSavingAdjust(new Date(c,d+(b<0?b:e[0]*e[1]),1));b<0&&f.setDate(this._getDaysInMonth(f.getFullYear(),f.getMonth()));return this._isInRange(a,f)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<=d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);var e=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(d,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),e,this._getFormatConfig(a))}}),$.fn.datepicker=function(a){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv),$.datepicker.initialized=!0);var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));return this.each(function(){typeof a=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this].concat(b)):$.datepicker._attachDatepicker(this,a)})},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.8.17",window["DP_jQuery_"+dpuuid]=$})(jQuery);/*
 * jQuery UI Progressbar 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Progressbar
 *
 * Depends:
 *   jquery.ui.core.js
 *   jquery.ui.widget.js
 */(function(a,b){a.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()}),this.valueDiv=a("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove(),a.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===b)return this._value();this._setOption("value",a);return this},_setOption:function(b,c){b==="value"&&(this.options.value=c,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),a.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;typeof a!="number"&&(a=0);return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var a=this.value(),b=this._percentage();this.oldValue!==a&&(this.oldValue=a,this._trigger("change")),this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(b.toFixed(0)+"%"),this.element.attr("aria-valuenow",a)}}),a.extend(a.ui.progressbar,{version:"1.8.17"})})(jQuery);/*
 * jQuery UI Effects 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/
 */jQuery.effects||function(a,b){function l(b){if(!b||typeof b=="number"||a.fx.speeds[b])return!0;if(typeof b=="string"&&!a.effects[b])return!0;return!1}function k(b,c,d,e){typeof b=="object"&&(e=c,d=null,c=b,b=c.effect),a.isFunction(c)&&(e=c,d=null,c={});if(typeof c=="number"||a.fx.speeds[c])e=d,d=c,c={};a.isFunction(d)&&(e=d,d=null),c=c||{},d=d||c.duration,d=a.fx.off?0:typeof d=="number"?d:d in a.fx.speeds?a.fx.speeds[d]:a.fx.speeds._default,e=e||c.complete;return[b,c,d,e]}function j(a,b){var c={_:0},d;for(d in b)a[d]!=b[d]&&(c[d]=b[d]);return c}function i(b){var c,d;for(c in b)d=b[c],(d==null||a.isFunction(d)||c in g||/scrollbar/.test(c)||!/color/i.test(c)&&isNaN(parseFloat(d)))&&delete b[c];return b}function h(){var a=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,b={},c,d;if(a&&a.length&&a[0]&&a[a[0]]){var e=a.length;while(e--)c=a[e],typeof a[c]=="string"&&(d=c.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()}),b[d]=a[c])}else for(c in a)typeof a[c]=="string"&&(b[c]=a[c]);return b}function d(b,d){var e;do{e=a.curCSS(b,d);if(e!=""&&e!="transparent"||a.nodeName(b,"body"))break;d="backgroundColor"}while(b=b.parentNode);return c(e)}function c(b){var c;if(b&&b.constructor==Array&&b.length==3)return b;if(c=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b))return[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)];if(c=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b))return[parseFloat(c[1])*2.55,parseFloat(c[2])*2.55,parseFloat(c[3])*2.55];if(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))return[parseInt(c[1],16),parseInt(c[2],16),parseInt(c[3],16)];if(c=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))return[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)];if(c=/rgba\(0, 0, 0, 0\)/.exec(b))return e.transparent;return e[a.trim(b).toLowerCase()]}a.effects={},a.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","borderColor","color","outlineColor"],function(b,e){a.fx.step[e]=function(a){a.colorInit||(a.start=d(a.elem,e),a.end=c(a.end),a.colorInit=!0),a.elem.style[e]="rgb("+Math.max(Math.min(parseInt(a.pos*(a.end[0]-a.start[0])+a.start[0],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[1]-a.start[1])+a.start[1],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[2]-a.start[2])+a.start[2],10),255),0)+")"}});var e={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]},f=["add","remove","toggle"],g={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.effects.animateClass=function(b,c,d,e){a.isFunction(d)&&(e=d,d=null);return this.queue(function(){var g=a(this),k=g.attr("style")||" ",l=i(h.call(this)),m,n=g.attr("class");a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),m=i(h.call(this)),g.attr("class",n),g.animate(j(l,m),{queue:!1,duration:c,easing:d,complete:function(){a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),typeof g.attr("style")=="object"?(g.attr("style").cssText="",g.attr("style").cssText=k):g.attr("style",k),e&&e.apply(this,arguments),a.dequeue(this)}})})},a.fn.extend({_addClass:a.fn.addClass,addClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{add:b},c,d,e]):this._addClass(b)},_removeClass:a.fn.removeClass,removeClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{remove:b},c,d,e]):this._removeClass(b)},_toggleClass:a.fn.toggleClass,toggleClass:function(c,d,e,f,g){return typeof d=="boolean"||d===b?e?a.effects.animateClass.apply(this,[d?{add:c}:{remove:c},e,f,g]):this._toggleClass(c,d):a.effects.animateClass.apply(this,[{toggle:c},d,e,f])},switchClass:function(b,c,d,e,f){return a.effects.animateClass.apply(this,[{add:c,remove:b},d,e,f])}}),a.extend(a.effects,{version:"1.8.17",save:function(a,b){for(var c=0;c<b.length;c++)b[c]!==null&&a.data("ec.storage."+b[c],a[0].style[b[c]])},restore:function(a,b){for(var c=0;c<b.length;c++)b[c]!==null&&a.css(b[c],a.data("ec.storage."+b[c]))},setMode:function(a,b){b=="toggle"&&(b=a.is(":hidden")?"show":"hide");return b},getBaseline:function(a,b){var c,d;switch(a[0]){case"top":c=0;break;case"middle":c=.5;break;case"bottom":c=1;break;default:c=a[0]/b.height}switch(a[1]){case"left":d=0;break;case"center":d=.5;break;case"right":d=1;break;default:d=a[1]/b.width}return{x:d,y:c}},createWrapper:function(b){if(b.parent().is(".ui-effects-wrapper"))return b.parent();var c={width:b.outerWidth(!0),height:b.outerHeight(!0),"float":b.css("float")},d=a("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e=document.activeElement;b.wrap(d),(b[0]===e||a.contains(b[0],e))&&a(e).focus(),d=b.parent(),b.css("position")=="static"?(d.css({position:"relative"}),b.css({position:"relative"})):(a.extend(c,{position:b.css("position"),zIndex:b.css("z-index")}),a.each(["top","left","bottom","right"],function(a,d){c[d]=b.css(d),isNaN(parseInt(c[d],10))&&(c[d]="auto")}),b.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"}));return d.css(c).show()},removeWrapper:function(b){var c,d=document.activeElement;if(b.parent().is(".ui-effects-wrapper")){c=b.parent().replaceWith(b),(b[0]===d||a.contains(b[0],d))&&a(d).focus();return c}return b},setTransition:function(b,c,d,e){e=e||{},a.each(c,function(a,c){unit=b.cssUnit(c),unit[0]>0&&(e[c]=unit[0]*d+unit[1])});return e}}),a.fn.extend({effect:function(b,c,d,e){var f=k.apply(this,arguments),g={options:f[1],duration:f[2],callback:f[3]},h=g.options.mode,i=a.effects[b];if(a.fx.off||!i)return h?this[h](g.duration,g.callback):this.each(function(){g.callback&&g.callback.call(this)});return i.call(this,g)},_show:a.fn.show,show:function(a){if(l(a))return this._show.apply(this,arguments);var b=k.apply(this,arguments);b[1].mode="show";return this.effect.apply(this,b)},_hide:a.fn.hide,hide:function(a){if(l(a))return this._hide.apply(this,arguments);var b=k.apply(this,arguments);b[1].mode="hide";return this.effect.apply(this,b)},__toggle:a.fn.toggle,toggle:function(b){if(l(b)||typeof b=="boolean"||a.isFunction(b))return this.__toggle.apply(this,arguments);var c=k.apply(this,arguments);c[1].mode="toggle";return this.effect.apply(this,c)},cssUnit:function(b){var c=this.css(b),d=[];a.each(["em","px","%","pt"],function(a,b){c.indexOf(b)>0&&(d=[parseFloat(c),b])});return d}}),a.easing.jswing=a.easing.swing,a.extend(a.easing,{def:"easeOutQuad",swing:function(b,c,d,e,f){return a.easing[a.easing.def](b,c,d,e,f)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b+c;return-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b+c;return d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b*b+c;return-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b*b*b+c;return d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return b==0?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){if(b==0)return c;if(b==e)return c+d;if((b/=e/2)<1)return d/2*Math.pow(2,10*(b-1))+c;return d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c},easeInOutCirc:function(a,b,c,d,e){if((b/=e/2)<1)return-d/2*(Math.sqrt(1-b*b)-1)+c;return d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e)==1)return c+d;g||(g=e*.3);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g))+c},easeOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e)==1)return c+d;g||(g=e*.3);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*b)*Math.sin((b*e-f)*2*Math.PI/g)+d+c},easeInOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e/2)==2)return c+d;g||(g=e*.3*1.5);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);if(b<1)return-0.5*h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g)+c;return h*Math.pow(2,-10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g)*.5+d+c},easeInBack:function(a,c,d,e,f,g){g==b&&(g=1.70158);return e*(c/=f)*c*((g+1)*c-g)+d},easeOutBack:function(a,c,d,e,f,g){g==b&&(g=1.70158);return e*((c=c/f-1)*c*((g+1)*c+g)+1)+d},easeInOutBack:function(a,c,d,e,f,g){g==b&&(g=1.70158);if((c/=f/2)<1)return e/2*c*c*(((g*=1.525)+1)*c-g)+d;return e/2*((c-=2)*c*(((g*=1.525)+1)*c+g)+2)+d},easeInBounce:function(b,c,d,e,f){return e-a.easing.easeOutBounce(b,f-c,0,e,f)+d},easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?d*7.5625*b*b+c:b<2/2.75?d*(7.5625*(b-=1.5/2.75)*b+.75)+c:b<2.5/2.75?d*(7.5625*(b-=2.25/2.75)*b+.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+.984375)+c},easeInOutBounce:function(b,c,d,e,f){if(c<f/2)return a.easing.easeInBounce(b,c*2,0,e,f)*.5+d;return a.easing.easeOutBounce(b,c*2-f,0,e,f)*.5+e*.5+d}})}(jQuery);/*
 * jQuery UI Effects Blind 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Blind
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.blind=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"vertical";a.effects.save(c,d),c.show();var g=a.effects.createWrapper(c).css({overflow:"hidden"}),h=f=="vertical"?"height":"width",i=f=="vertical"?g.height():g.width();e=="show"&&g.css(h,0);var j={};j[h]=e=="show"?i:0,g.animate(j,b.duration,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);/*
 * jQuery UI Effects Bounce 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Bounce
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.bounce=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"effect"),f=b.options.direction||"up",g=b.options.distance||20,h=b.options.times||5,i=b.duration||250;/show|hide/.test(e)&&d.push("opacity"),a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var j=f=="up"||f=="down"?"top":"left",k=f=="up"||f=="left"?"pos":"neg",g=b.options.distance||(j=="top"?c.outerHeight({margin:!0})/3:c.outerWidth({margin:!0})/3);e=="show"&&c.css("opacity",0).css(j,k=="pos"?-g:g),e=="hide"&&(g=g/(h*2)),e!="hide"&&h--;if(e=="show"){var l={opacity:1};l[j]=(k=="pos"?"+=":"-=")+g,c.animate(l,i/2,b.options.easing),g=g/2,h--}for(var m=0;m<h;m++){var n={},p={};n[j]=(k=="pos"?"-=":"+=")+g,p[j]=(k=="pos"?"+=":"-=")+g,c.animate(n,i/2,b.options.easing).animate(p,i/2,b.options.easing),g=e=="hide"?g*2:g/2}if(e=="hide"){var l={opacity:0};l[j]=(k=="pos"?"-=":"+=")+g,c.animate(l,i/2,b.options.easing,function(){c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)})}else{var n={},p={};n[j]=(k=="pos"?"-=":"+=")+g,p[j]=(k=="pos"?"+=":"-=")+g,c.animate(n,i/2,b.options.easing).animate(p,i/2,b.options.easing,function(){a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)})}c.queue("fx",function(){c.dequeue()}),c.dequeue()})}})(jQuery);/*
 * jQuery UI Effects Clip 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Clip
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.clip=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","height","width"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"vertical";a.effects.save(c,d),c.show();var g=a.effects.createWrapper(c).css({overflow:"hidden"}),h=c[0].tagName=="IMG"?g:c,i={size:f=="vertical"?"height":"width",position:f=="vertical"?"top":"left"},j=f=="vertical"?h.height():h.width();e=="show"&&(h.css(i.size,0),h.css(i.position,j/2));var k={};k[i.size]=e=="show"?j:0,k[i.position]=e=="show"?0:j/2,h.animate(k,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()}})})}})(jQuery);/*
 * jQuery UI Effects Drop 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Drop
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.drop=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","opacity"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"left";a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var g=f=="up"||f=="down"?"top":"left",h=f=="up"||f=="left"?"pos":"neg",i=b.options.distance||(g=="top"?c.outerHeight({margin:!0})/2:c.outerWidth({margin:!0})/2);e=="show"&&c.css("opacity",0).css(g,h=="pos"?-i:i);var j={opacity:e=="show"?1:0};j[g]=(e=="show"?h=="pos"?"+=":"-=":h=="pos"?"-=":"+=")+i,c.animate(j,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/*
 * jQuery UI Effects Explode 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Explode
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.explode=function(b){return this.queue(function(){var c=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3,d=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;b.options.mode=b.options.mode=="toggle"?a(this).is(":visible")?"hide":"show":b.options.mode;var e=a(this).show().css("visibility","hidden"),f=e.offset();f.top-=parseInt(e.css("marginTop"),10)||0,f.left-=parseInt(e.css("marginLeft"),10)||0;var g=e.outerWidth(!0),h=e.outerHeight(!0);for(var i=0;i<c;i++)for(var j=0;j<d;j++)e.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-j*(g/d),top:-i*(h/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/d,height:h/c,left:f.left+j*(g/d)+(b.options.mode=="show"?(j-Math.floor(d/2))*(g/d):0),top:f.top+i*(h/c)+(b.options.mode=="show"?(i-Math.floor(c/2))*(h/c):0),opacity:b.options.mode=="show"?0:1}).animate({left:f.left+j*(g/d)+(b.options.mode=="show"?0:(j-Math.floor(d/2))*(g/d)),top:f.top+i*(h/c)+(b.options.mode=="show"?0:(i-Math.floor(c/2))*(h/c)),opacity:b.options.mode=="show"?1:0},b.duration||500);setTimeout(function(){b.options.mode=="show"?e.css({visibility:"visible"}):e.css({visibility:"visible"}).hide(),b.callback&&b.callback.apply(e[0]),e.dequeue(),a("div.ui-effects-explode").remove()},b.duration||500)})}})(jQuery);/*
 * jQuery UI Effects Fade 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Fade
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.fade=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide");c.animate({opacity:d},{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/*
 * jQuery UI Effects Fold 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Fold
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.fold=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.size||15,g=!!b.options.horizFirst,h=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(c,d),c.show();var i=a.effects.createWrapper(c).css({overflow:"hidden"}),j=e=="show"!=g,k=j?["width","height"]:["height","width"],l=j?[i.width(),i.height()]:[i.height(),i.width()],m=/([0-9]+)%/.exec(f);m&&(f=parseInt(m[1],10)/100*l[e=="hide"?0:1]),e=="show"&&i.css(g?{height:0,width:f}:{height:f,width:0});var n={},p={};n[k[0]]=e=="show"?l[0]:f,p[k[1]]=e=="show"?l[1]:0,i.animate(n,h,b.options.easing).animate(p,h,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);/*
 * jQuery UI Effects Highlight 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Highlight
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.highlight=function(b){return this.queue(function(){var c=a(this),d=["backgroundImage","backgroundColor","opacity"],e=a.effects.setMode(c,b.options.mode||"show"),f={backgroundColor:c.css("backgroundColor")};e=="hide"&&(f.opacity=0),a.effects.save(c,d),c.show().css({backgroundImage:"none",backgroundColor:b.options.color||"#ffff99"}).animate(f,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),e=="show"&&!a.support.opacity&&this.style.removeAttribute("filter"),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/*
 * jQuery UI Effects Pulsate 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Pulsate
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.pulsate=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"show");times=(b.options.times||5)*2-1,duration=b.duration?b.duration/2:a.fx.speeds._default/2,isVisible=c.is(":visible"),animateTo=0,isVisible||(c.css("opacity",0).show(),animateTo=1),(d=="hide"&&isVisible||d=="show"&&!isVisible)&&times--;for(var e=0;e<times;e++)c.animate({opacity:animateTo},duration,b.options.easing),animateTo=(animateTo+1)%2;c.animate({opacity:animateTo},duration,b.options.easing,function(){animateTo==0&&c.hide(),b.callback&&b.callback.apply(this,arguments)}),c.queue("fx",function(){c.dequeue()}).dequeue()})}})(jQuery);/*
 * jQuery UI Effects Scale 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Scale
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.puff=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide"),e=parseInt(b.options.percent,10)||150,f=e/100,g={height:c.height(),width:c.width()};a.extend(b.options,{fade:!0,mode:d,percent:d=="hide"?e:100,from:d=="hide"?g:{height:g.height*f,width:g.width*f}}),c.effect("scale",b.options,b.duration,b.callback),c.dequeue()})},a.effects.scale=function(b){return this.queue(function(){var c=a(this),d=a.extend(!0,{},b.options),e=a.effects.setMode(c,b.options.mode||"effect"),f=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:e=="hide"?0:100),g=b.options.direction||"both",h=b.options.origin;e!="effect"&&(d.origin=h||["middle","center"],d.restore=!0);var i={height:c.height(),width:c.width()};c.from=b.options.from||(e=="show"?{height:0,width:0}:i);var j={y:g!="horizontal"?f/100:1,x:g!="vertical"?f/100:1};c.to={height:i.height*j.y,width:i.width*j.x},b.options.fade&&(e=="show"&&(c.from.opacity=0,c.to.opacity=1),e=="hide"&&(c.from.opacity=1,c.to.opacity=0)),d.from=c.from,d.to=c.to,d.mode=e,c.effect("size",d,b.duration,b.callback),c.dequeue()})},a.effects.size=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","width","height","overflow","opacity"],e=["position","top","bottom","left","right","overflow","opacity"],f=["width","height","overflow"],g=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],i=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],j=a.effects.setMode(c,b.options.mode||"effect"),k=b.options.restore||!1,l=b.options.scale||"both",m=b.options.origin,n={height:c.height(),width:c.width()};c.from=b.options.from||n,c.to=b.options.to||n;if(m){var p=a.effects.getBaseline(m,n);c.from.top=(n.height-c.from.height)*p.y,c.from.left=(n.width-c.from.width)*p.x,c.to.top=(n.height-c.to.height)*p.y,c.to.left=(n.width-c.to.width)*p.x}var q={from:{y:c.from.height/n.height,x:c.from.width/n.width},to:{y:c.to.height/n.height,x:c.to.width/n.width}};if(l=="box"||l=="both")q.from.y!=q.to.y&&(d=d.concat(h),c.from=a.effects.setTransition(c,h,q.from.y,c.from),c.to=a.effects.setTransition(c,h,q.to.y,c.to)),q.from.x!=q.to.x&&(d=d.concat(i),c.from=a.effects.setTransition(c,i,q.from.x,c.from),c.to=a.effects.setTransition(c,i,q.to.x,c.to));(l=="content"||l=="both")&&q.from.y!=q.to.y&&(d=d.concat(g),c.from=a.effects.setTransition(c,g,q.from.y,c.from),c.to=a.effects.setTransition(c,g,q.to.y,c.to)),a.effects.save(c,k?d:e),c.show(),a.effects.createWrapper(c),c.css("overflow","hidden").css(c.from);if(l=="content"||l=="both")h=h.concat(["marginTop","marginBottom"]).concat(g),i=i.concat(["marginLeft","marginRight"]),f=d.concat(h).concat(i),c.find("*[width]").each(function(){child=a(this),k&&a.effects.save(child,f);var c={height:child.height(),width:child.width()};child.from={height:c.height*q.from.y,width:c.width*q.from.x},child.to={height:c.height*q.to.y,width:c.width*q.to.x},q.from.y!=q.to.y&&(child.from=a.effects.setTransition(child,h,q.from.y,child.from),child.to=a.effects.setTransition(child,h,q.to.y,child.to)),q.from.x!=q.to.x&&(child.from=a.effects.setTransition(child,i,q.from.x,child.from),child.to=a.effects.setTransition(child,i,q.to.x,child.to)),child.css(child.from),child.animate(child.to,b.duration,b.options.easing,function(){k&&a.effects.restore(child,f)})});c.animate(c.to,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){c.to.opacity===0&&c.css("opacity",c.from.opacity),j=="hide"&&c.hide(),a.effects.restore(c,k?d:e),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/*
 * jQuery UI Effects Shake 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Shake
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.shake=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"effect"),f=b.options.direction||"left",g=b.options.distance||20,h=b.options.times||3,i=b.duration||b.options.duration||140;a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var j=f=="up"||f=="down"?"top":"left",k=f=="up"||f=="left"?"pos":"neg",l={},m={},n={};l[j]=(k=="pos"?"-=":"+=")+g,m[j]=(k=="pos"?"+=":"-=")+g*2,n[j]=(k=="pos"?"-=":"+=")+g*2,c.animate(l,i,b.options.easing);for(var p=1;p<h;p++)c.animate(m,i,b.options.easing).animate(n,i,b.options.easing);c.animate(m,i,b.options.easing).animate(l,i/2,b.options.easing,function(){a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)}),c.queue("fx",function(){c.dequeue()}),c.dequeue()})}})(jQuery);/*
 * jQuery UI Effects Slide 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Slide
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.slide=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"show"),f=b.options.direction||"left";a.effects.save(c,d),c.show(),a.effects.createWrapper(c).css({overflow:"hidden"});var g=f=="up"||f=="down"?"top":"left",h=f=="up"||f=="left"?"pos":"neg",i=b.options.distance||(g=="top"?c.outerHeight({margin:!0}):c.outerWidth({margin:!0}));e=="show"&&c.css(g,h=="pos"?isNaN(i)?"-"+i:-i:i);var j={};j[g]=(e=="show"?h=="pos"?"+=":"-=":h=="pos"?"-=":"+=")+i,c.animate(j,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/*
 * jQuery UI Effects Transfer 1.8.17
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Transfer
 *
 * Depends:
 *  jquery.effects.core.js
 */(function(a,b){a.effects.transfer=function(b){return this.queue(function(){var c=a(this),d=a(b.options.to),e=d.offset(),f={top:e.top,left:e.left,height:d.innerHeight(),width:d.innerWidth()},g=c.offset(),h=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:g.top,left:g.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(f,b.duration,b.options.easing,function(){h.remove(),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);
;// Beginning /res/js/os/jquery-validation/jquery.validate.js:
/**
 * jQuery Validation Plugin 1.8.1
 *
 * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
 * http://docs.jquery.com/Plugins/Validation
 *
 * Copyright (c) 2006 - 2011 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
 */

(function($) {

$.extend($.fn, {
	// http://docs.jquery.com/Plugins/Validation/validate
	validate: function( options ) {

		// if nothing is selected, return nothing; can't chain anyway
		if (!this.length) {
			options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );
			return;
		}

		// check if a validator for this form was already created
		var validator = $.data(this[0], 'validator');
		if ( validator ) {
			return validator;
		}

		validator = new $.validator( options, this[0] );
		$.data(this[0], 'validator', validator);

		if ( validator.settings.onsubmit ) {

			// allow suppresing validation by adding a cancel class to the submit button
			this.find("input, button").filter(".cancel").click(function() {
				validator.cancelSubmit = true;
			});

			// when a submitHandler is used, capture the submitting button
			if (validator.settings.submitHandler) {
				this.find("input, button").filter(":submit").click(function() {
					validator.submitButton = this;
				});
			}

			// validate the form on submit
			this.submit( function( event ) {
				if ( validator.settings.debug )
					// prevent form submit to be able to see console output
					event.preventDefault();

				function handle() {
					if ( validator.settings.submitHandler ) {
						if (validator.submitButton) {
							// insert a hidden input as a replacement for the missing submit button
							var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
						}
						validator.settings.submitHandler.call( validator, validator.currentForm );
						if (validator.submitButton) {
							// and clean up afterwards; thanks to no-block-scope, hidden can be referenced
							hidden.remove();
						}
						return false;
					}
					return true;
				}

				// prevent submit for invalid forms or custom submit handlers
				if ( validator.cancelSubmit ) {
					validator.cancelSubmit = false;
					return handle();
				}
				if ( validator.form() ) {
					if ( validator.pendingRequest ) {
						validator.formSubmitted = true;
						return false;
					}
					return handle();
				} else {
					validator.focusInvalid();
					return false;
				}
			});
		}

		return validator;
	},
	// http://docs.jquery.com/Plugins/Validation/valid
	valid: function() {
        if ( $(this[0]).is('form')) {
            return this.validate().form();
        } else {
            var valid = true;
            var validator = $(this[0].form).validate();
            this.each(function() {
				valid &= validator.element(this);
            });
            return valid;
        }
    },
	// attributes: space seperated list of attributes to retrieve and remove
	removeAttrs: function(attributes) {
		var result = {},
			$element = this;
		$.each(attributes.split(/\s/), function(index, value) {
			result[value] = $element.attr(value);
			$element.removeAttr(value);
		});
		return result;
	},
	// http://docs.jquery.com/Plugins/Validation/rules
	rules: function(command, argument) {
		var element = this[0];

		if (command) {
			var settings = $.data(element.form, 'validator').settings;
			var staticRules = settings.rules;
			var existingRules = $.validator.staticRules(element);
			switch(command) {
			case "add":
				$.extend(existingRules, $.validator.normalizeRule(argument));
				staticRules[element.name] = existingRules;
				if (argument.messages)
					settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
				break;
			case "remove":
				if (!argument) {
					delete staticRules[element.name];
					return existingRules;
				}
				var filtered = {};
				$.each(argument.split(/\s/), function(index, method) {
					filtered[method] = existingRules[method];
					delete existingRules[method];
				});
				return filtered;
			}
		}

		var data = $.validator.normalizeRules(
		$.extend(
			{},
			$.validator.metadataRules(element),
			$.validator.classRules(element),
			$.validator.attributeRules(element),
			$.validator.staticRules(element)
		), element);

		// make sure required is at front
		if (data.required) {
			var param = data.required;
			delete data.required;
			data = $.extend({required: param}, data);
		}

		return data;
	}
});

// Custom selectors
$.extend($.expr[":"], {
	// http://docs.jquery.com/Plugins/Validation/blank
	blank: function(a) {return !$.trim("" + a.value);},
	// http://docs.jquery.com/Plugins/Validation/filled
	filled: function(a) {return !!$.trim("" + a.value);},
	// http://docs.jquery.com/Plugins/Validation/unchecked
	unchecked: function(a) {return !a.checked;}
});

// constructor for validator
$.validator = function( options, form ) {
	this.settings = $.extend( true, {}, $.validator.defaults, options );
	this.currentForm = form;
	this.init();
};

$.validator.format = function(source, params) {
	if ( arguments.length == 1 )
		return function() {
			var args = $.makeArray(arguments);
			args.unshift(source);
			return $.validator.format.apply( this, args );
		};
	if ( arguments.length > 2 && params.constructor != Array  ) {
		params = $.makeArray(arguments).slice(1);
	}
	if ( params.constructor != Array ) {
		params = [ params ];
	}
	$.each(params, function(i, n) {
		source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
	});
	return source;
};

$.extend($.validator, {

	defaults: {
		messages: {},
		groups: {},
		rules: {},
		errorClass: "error",
		validClass: "valid",
		errorElement: "label",
		focusInvalid: true,
		errorContainer: $( [] ),
		errorLabelContainer: $( [] ),
		onsubmit: true,
		ignore: [],
		ignoreTitle: false,
		onfocusin: function(element) {
			this.lastActive = element;

			// hide error label and remove error class on focus if enabled
			if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
				this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
				this.addWrapper(this.errorsFor(element)).hide();
			}
		},
		onfocusout: function(element) {
			if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
				this.element(element);
			}
		},
		onkeyup: function(element) {
			if ( element.name in this.submitted || element == this.lastElement ) {
				this.element(element);
			}
		},
		onclick: function(element) {
			// click on selects, radiobuttons and checkboxes
			if ( element.name in this.submitted )
				this.element(element);
			// or option elements, check parent select in that case
			else if (element.parentNode.name in this.submitted)
				this.element(element.parentNode);
		},
		highlight: function(element, errorClass, validClass) {
			if (element.type === 'radio') {
				this.findByName(element.name).addClass(errorClass).removeClass(validClass);
			} else {
				$(element).addClass(errorClass).removeClass(validClass);
			}
		},
		unhighlight: function(element, errorClass, validClass) {
			if (element.type === 'radio') {
				this.findByName(element.name).removeClass(errorClass).addClass(validClass);
			} else {
				$(element).removeClass(errorClass).addClass(validClass);
			}
		}
	},

	// http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
	setDefaults: function(settings) {
		$.extend( $.validator.defaults, settings );
	},

	messages: {
		required: "This field is required.",
		remote: "Please fix this field.",
		email: "Please enter a valid email address.",
		url: "Please enter a valid URL.",
		date: "Please enter a valid date.",
		dateISO: "Please enter a valid date (ISO).",
		number: "Please enter a valid number.",
		digits: "Please enter only digits.",
		creditcard: "Please enter a valid credit card number.",
		equalTo: "Please enter the same value again.",
		accept: "Please enter a value with a valid extension.",
		maxlength: $.validator.format("Please enter no more than {0} characters."),
		minlength: $.validator.format("Please enter at least {0} characters."),
		rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
		range: $.validator.format("Please enter a value between {0} and {1}."),
		max: $.validator.format("Please enter a value less than or equal to {0}."),
		min: $.validator.format("Please enter a value greater than or equal to {0}.")
	},

	autoCreateRanges: false,

	prototype: {

		init: function() {
			this.labelContainer = $(this.settings.errorLabelContainer);
			this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
			this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
			this.submitted = {};
			this.valueCache = {};
			this.pendingRequest = 0;
			this.pending = {};
			this.invalid = {};
			this.reset();

			var groups = (this.groups = {});
			$.each(this.settings.groups, function(key, value) {
				$.each(value.split(/\s/), function(index, name) {
					groups[name] = key;
				});
			});
			var rules = this.settings.rules;
			$.each(rules, function(key, value) {
				rules[key] = $.validator.normalizeRule(value);
			});

			function delegate(event) {
				var validator = $.data(this[0].form, "validator"),
					eventType = "on" + event.type.replace(/^validate/, "");
				validator.settings[eventType] && validator.settings[eventType].call(validator, this[0] );
			}
			$(this.currentForm)
				.validateDelegate(":text, :password, :file, select, textarea", "focusin focusout keyup", delegate)
				.validateDelegate(":radio, :checkbox, select, option", "click", delegate);

			if (this.settings.invalidHandler)
				$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/form
		form: function() {
			this.checkForm();
			$.extend(this.submitted, this.errorMap);
			this.invalid = $.extend({}, this.errorMap);
			if (!this.valid())
				$(this.currentForm).triggerHandler("invalid-form", [this]);
			this.showErrors();
			return this.valid();
		},

		checkForm: function() {
			this.prepareForm();
			for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
				this.check( elements[i] );
			}
			return this.valid();
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/element
		element: function( element ) {
			element = this.clean( element );
			this.lastElement = element;
			this.prepareElement( element );
			this.currentElements = $(element);
			var result = this.check( element );
			if ( result ) {
				delete this.invalid[element.name];
			} else {
				this.invalid[element.name] = true;
			}
			if ( !this.numberOfInvalids() ) {
				// Hide error containers on last error
				this.toHide = this.toHide.add( this.containers );
			}
			this.showErrors();
			return result;
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/showErrors
		showErrors: function(errors) {
			if(errors) {
				// add items to error list and map
				$.extend( this.errorMap, errors );
				this.errorList = [];
				for ( var name in errors ) {
					this.errorList.push({
						message: errors[name],
						element: this.findByName(name)[0]
					});
				}
				// remove items from success list
				this.successList = $.grep( this.successList, function(element) {
					return !(element.name in errors);
				});
			}
			this.settings.showErrors
				? this.settings.showErrors.call( this, this.errorMap, this.errorList )
				: this.defaultShowErrors();
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/resetForm
		resetForm: function() {
			if ( $.fn.resetForm )
				$( this.currentForm ).resetForm();
			this.submitted = {};
			this.prepareForm();
			this.hideErrors();
			this.elements().removeClass( this.settings.errorClass );
		},

		numberOfInvalids: function() {
			return this.objectLength(this.invalid);
		},

		objectLength: function( obj ) {
			var count = 0;
			for ( var i in obj )
				count++;
			return count;
		},

		hideErrors: function() {
			this.addWrapper( this.toHide ).hide();
		},

		valid: function() {
			return this.size() == 0;
		},

		size: function() {
			return this.errorList.length;
		},

		focusInvalid: function() {
			if( this.settings.focusInvalid ) {
				try {
					$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
					.filter(":visible")
					.focus()
					// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
					.trigger("focusin");
				} catch(e) {
					// ignore IE throwing errors when focusing hidden elements
				}
			}
		},

		findLastActive: function() {
			var lastActive = this.lastActive;
			return lastActive && $.grep(this.errorList, function(n) {
				return n.element.name == lastActive.name;
			}).length == 1 && lastActive;
		},

		elements: function() {
			var validator = this,
				rulesCache = {};

			// select all valid inputs inside the form (no submit or reset buttons)
			return $(this.currentForm)
			.find("input, select, textarea")
			.not(":submit, :reset, :image, [disabled]")
			.not( this.settings.ignore )
			.filter(function() {
				!this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);

				// select only the first element for each name, and only those with rules specified
				if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )
					return false;

				rulesCache[this.name] = true;
				return true;
			});
		},

		clean: function( selector ) {
			return $( selector )[0];
		},

		errors: function() {
			return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
		},

		reset: function() {
			this.successList = [];
			this.errorList = [];
			this.errorMap = {};
			this.toShow = $([]);
			this.toHide = $([]);
			this.currentElements = $([]);
		},

		prepareForm: function() {
			this.reset();
			this.toHide = this.errors().add( this.containers );
		},

		prepareElement: function( element ) {
			this.reset();
			this.toHide = this.errorsFor(element);
		},

		check: function( element ) {
			element = this.clean( element );

			// if radio/checkbox, validate first element in group instead
			/*
			if (this.checkable(element)) {
				//element = this.findByName( element.name ).not(this.settings.ignore)[0];
				//element = this.findByName( element.name ).not(this.settings.ignore)[1];
				var cblLen = this.findByName( element.name ).not(this.settings.ignore).length;
				var cblCntr = 0;
				for(cblCntr = 0;cblCntr < cblLen; cblCntr++){
				element = this.findByName( element.name ).not(this.settings.ignore)[cblCntr];	
				}
			}
			*/
			
			element = this.findByName( element.name ).not(this.settings.ignore)[0];
			
			var rules = $(element).rules();
			var dependencyMismatch = false;
			for (var method in rules ) {
				var rule = { method: method, parameters: rules[method] };
				try {
					var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters );

					// if a method indicates that the field is optional and therefore valid,
					// don't mark it as valid when there are no other rules
					if ( result == "dependency-mismatch" ) {
						dependencyMismatch = true;
						continue;
					}
					dependencyMismatch = false;

					if ( result == "pending" ) {
						this.toHide = this.toHide.not( this.errorsFor(element) );
						return;
					}

					if( !result ) {
						this.formatAndAdd( element, rule );
						return false;
					}
				} catch(e) {
					this.settings.debug && window.console && console.log("exception occured when checking element " + element.id
						 + ", check the '" + rule.method + "' method", e);
					throw e;
				}
			}
			if (dependencyMismatch)
				return;
			if ( this.objectLength(rules) )
				this.successList.push(element);
			return true;
		},

		// return the custom message for the given element and validation method
		// specified in the element's "messages" metadata
		customMetaMessage: function(element, method) {
			if (!$.metadata)
				return;

			var meta = this.settings.meta
				? $(element).metadata()[this.settings.meta]
				: $(element).metadata();

			return meta && meta.messages && meta.messages[method];
		},

		// return the custom message for the given element name and validation method
		customMessage: function( name, method ) {
			var m = this.settings.messages[name];
			return m && (m.constructor == String
				? m
				: m[method]);
		},

		// return the first defined argument, allowing empty strings
		findDefined: function() {
			for(var i = 0; i < arguments.length; i++) {
				if (arguments[i] !== undefined)
					return arguments[i];
			}
			return undefined;
		},

		defaultMessage: function( element, method) {
			return this.findDefined(
				this.customMessage( element.name, method ),
				this.customMetaMessage( element, method ),
				// title is never undefined, so handle empty string as undefined
				!this.settings.ignoreTitle && element.title || undefined,
				$.validator.messages[method],
				"<strong>Warning: No message defined for " + element.name + "</strong>"
			);
		},

		formatAndAdd: function( element, rule ) {
			var message = this.defaultMessage( element, rule.method ),
				theregex = /\$?\{(\d+)\}/g;
			if ( typeof message == "function" ) {
				message = message.call(this, rule.parameters, element);
			} else if (theregex.test(message)) {
				message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters);
			}
			this.errorList.push({
				message: message,
				element: element
			});

			this.errorMap[element.name] = message;
			this.submitted[element.name] = message;
		},

		addWrapper: function(toToggle) {
			if ( this.settings.wrapper )
				toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
			return toToggle;
		},

		defaultShowErrors: function() {
			for ( var i = 0; this.errorList[i]; i++ ) {
				var error = this.errorList[i];
				this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
				this.showLabel( error.element, error.message );
			}
			if( this.errorList.length ) {
				this.toShow = this.toShow.add( this.containers );
			}
			if (this.settings.success) {
				for ( var i = 0; this.successList[i]; i++ ) {
					this.showLabel( this.successList[i] );
				}
			}
			if (this.settings.unhighlight) {
				for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
					this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
				}
			}
			this.toHide = this.toHide.not( this.toShow );
			this.hideErrors();
			this.addWrapper( this.toShow ).show();
		},

		validElements: function() {
			return this.currentElements.not(this.invalidElements());
		},

		invalidElements: function() {
			return $(this.errorList).map(function() {
				return this.element;
			});
		},

		showLabel: function(element, message) {
			var label = this.errorsFor( element );
			if ( label.length ) {
				// refresh error/success class
				label.removeClass().addClass( this.settings.errorClass );

				// check if we have a generated label, replace the message then
				label.attr("generated") && label.html(message);
			} else {
				// create label
				label = $("<" + this.settings.errorElement + "/>")
					.attr({"for":  this.idOrName(element), generated: true})
					.addClass(this.settings.errorClass)
					.html(message || "");
				if ( this.settings.wrapper ) {
					// make sure the element is visible, even in IE
					// actually showing the wrapped element is handled elsewhere
					label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
				}
				if ( !this.labelContainer.append(label).length )
					this.settings.errorPlacement
						? this.settings.errorPlacement(label, $(element) )
						: label.insertAfter(element);
			}
			if ( !message && this.settings.success ) {
				label.text("");
				typeof this.settings.success == "string"
					? label.addClass( this.settings.success )
					: this.settings.success( label );
			}
			this.toShow = this.toShow.add(label);
		},

		errorsFor: function(element) {
			var name = this.idOrName(element);
    		return this.errors().filter(function() {
				return $(this).attr('for') == name;
			});
		},

		idOrName: function(element) {
			return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
		},

		checkable: function( element ) {
			return /radio|checkbox/i.test(element.type);
		},

		findByName: function( name ) {
			// select by name and filter by form for performance over form.find("[name=...]")
			var form = this.currentForm;
			return $(document.getElementsByName(name)).map(function(index, element) {
				return element.form == form && element.name == name && element  || null;
			});
		},

		getLength: function(value, element) {
			switch( element.nodeName.toLowerCase() ) {
			case 'select':
				return $("option:selected", element).length;
			case 'input':
				if( this.checkable( element) )
					return this.findByName(element.name).filter(':checked').length;
			}
			return value.length;
		},

		depend: function(param, element) {
			return this.dependTypes[typeof param]
				? this.dependTypes[typeof param](param, element)
				: true;
		},

		dependTypes: {
			"boolean": function(param, element) {
				return param;
			},
			"string": function(param, element) {
				return !!$(param, element.form).length;
			},
			"function": function(param, element) {
				return param(element);
			}
		},

		optional: function(element) {
			return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";
		},

		startRequest: function(element) {
			if (!this.pending[element.name]) {
				this.pendingRequest++;
				this.pending[element.name] = true;
			}
		},

		stopRequest: function(element, valid) {
			this.pendingRequest--;
			// sometimes synchronization fails, make sure pendingRequest is never < 0
			if (this.pendingRequest < 0)
				this.pendingRequest = 0;
			delete this.pending[element.name];
			if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {
				$(this.currentForm).submit();
				this.formSubmitted = false;
			} else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
				$(this.currentForm).triggerHandler("invalid-form", [this]);
				this.formSubmitted = false;
			}
		},

		previousValue: function(element) {
			return $.data(element, "previousValue") || $.data(element, "previousValue", {
				old: null,
				valid: true,
				message: this.defaultMessage( element, "remote" )
			});
		}

	},

	classRuleSettings: {
		required: {required: true},
		email: {email: true},
		url: {url: true},
		date: {date: true},
		dateISO: {dateISO: true},
		dateDE: {dateDE: true},
		number: {number: true},
		numberDE: {numberDE: true},
		digits: {digits: true},
		creditcard: {creditcard: true}
	},

	addClassRules: function(className, rules) {
		className.constructor == String ?
			this.classRuleSettings[className] = rules :
			$.extend(this.classRuleSettings, className);
	},

	classRules: function(element) {
		var rules = {};
		var classes = $(element).attr('class');
		classes && $.each(classes.split(' '), function() {
			if (this in $.validator.classRuleSettings) {
				$.extend(rules, $.validator.classRuleSettings[this]);
			}
		});
		return rules;
	},

	attributeRules: function(element) {
		var rules = {};
		var $element = $(element);

		for (var method in $.validator.methods) {
			var value = $element.attr(method);
			if (value) {
				rules[method] = value;
			}
		}

		// maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
		if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
			delete rules.maxlength;
		}

		return rules;
	},

	metadataRules: function(element) {
		if (!$.metadata) return {};

		var meta = $.data(element.form, 'validator').settings.meta;
		return meta ?
			$(element).metadata()[meta] :
			$(element).metadata();
	},

	staticRules: function(element) {
		var rules = {};
                // Hack Michael
                if ( ! element ){
                    return rules;
                }
                // End Hack
		var validator = $.data(element.form, 'validator');
		if (validator.settings.rules) {
			rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
		}
		return rules;
	},

	normalizeRules: function(rules, element) {
		// handle dependency check
		$.each(rules, function(prop, val) {
			// ignore rule when param is explicitly false, eg. required:false
			if (val === false) {
				delete rules[prop];
				return;
			}
			if (val.param || val.depends) {
				var keepRule = true;
				switch (typeof val.depends) {
					case "string":
						keepRule = !!$(val.depends, element.form).length;
						break;
					case "function":
						keepRule = val.depends.call(element, element);
						break;
				}
				if (keepRule) {
					rules[prop] = val.param !== undefined ? val.param : true;
				} else {
					delete rules[prop];
				}
			}
		});

		// evaluate parameters
		$.each(rules, function(rule, parameter) {
			rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
		});

		// clean number parameters
		$.each(['minlength', 'maxlength', 'min', 'max'], function() {
			if (rules[this]) {
				rules[this] = Number(rules[this]);
			}
		});
		$.each(['rangelength', 'range'], function() {
			if (rules[this]) {
				rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
			}
		});

		if ($.validator.autoCreateRanges) {
			// auto-create ranges
			if (rules.min && rules.max) {
				rules.range = [rules.min, rules.max];
				delete rules.min;
				delete rules.max;
			}
			if (rules.minlength && rules.maxlength) {
				rules.rangelength = [rules.minlength, rules.maxlength];
				delete rules.minlength;
				delete rules.maxlength;
			}
		}

		// To support custom messages in metadata ignore rule methods titled "messages"
		if (rules.messages) {
			delete rules.messages;
		}

		return rules;
	},

	// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
	normalizeRule: function(data) {
		if( typeof data == "string" ) {
			var transformed = {};
			$.each(data.split(/\s/), function() {
				transformed[this] = true;
			});
			data = transformed;
		}
		return data;
	},

	// http://docs.jquery.com/Plugins/Validation/Validator/addMethod
	addMethod: function(name, method, message) {
		$.validator.methods[name] = method;
		$.validator.messages[name] = message != undefined ? message : $.validator.messages[name];
		if (method.length < 3) {
			$.validator.addClassRules(name, $.validator.normalizeRule(name));
		}
	},

	methods: {

		// http://docs.jquery.com/Plugins/Validation/Methods/required
		required: function(value, element, param) {
			// check if dependency is met
			if ( !this.depend(param, element) )
				return "dependency-mismatch";
			switch( element.nodeName.toLowerCase() ) {
			case 'select':
				// could be an array for select-multiple or a string, both are fine this way
				var val = $(element).val();
				return val && val.length > 0;
			case 'input':
				if ( this.checkable(element) )
					return this.getLength(value, element) > 0;
			default:
				return $.trim(value).length > 0;
			}
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/remote
		remote: function(value, element, param) {
			if ( this.optional(element) )
				return "dependency-mismatch";

			var previous = this.previousValue(element);
			if (!this.settings.messages[element.name] )
				this.settings.messages[element.name] = {};
			previous.originalMessage = this.settings.messages[element.name].remote;
			this.settings.messages[element.name].remote = previous.message;

			param = typeof param == "string" && {url:param} || param;

			if ( this.pending[element.name] ) {
				return "pending";
			}
			if ( previous.old === value ) {
				return previous.valid;
			}

			previous.old = value;
			var validator = this;
			this.startRequest(element);
			var data = {};
			data[element.name] = value;
			$.ajax($.extend(true, {
				url: param,
				mode: "abort",
				port: "validate" + element.name,
				dataType: "json",
				data: data,
				success: function(response) {
					validator.settings.messages[element.name].remote = previous.originalMessage;
					var valid = response === true;
					if ( valid ) {
						var submitted = validator.formSubmitted;
						validator.prepareElement(element);
						validator.formSubmitted = submitted;
						validator.successList.push(element);
						validator.showErrors();
					} else {
						var errors = {};
						var message = response || validator.defaultMessage( element, "remote" );
						errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
						validator.showErrors(errors);
					}
					previous.valid = valid;
					validator.stopRequest(element, valid);
				}
			}, param));
			return "pending";
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/minlength
		minlength: function(value, element, param) {
			return this.optional(element) || this.getLength($.trim(value), element) >= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/maxlength
		maxlength: function(value, element, param) {
			return this.optional(element) || this.getLength($.trim(value), element) <= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/rangelength
		rangelength: function(value, element, param) {
			var length = this.getLength($.trim(value), element);
			return this.optional(element) || ( length >= param[0] && length <= param[1] );
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/min
		min: function( value, element, param ) {
			return this.optional(element) || value >= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/max
		max: function( value, element, param ) {
			return this.optional(element) || value <= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/range
		range: function( value, element, param ) {
			return this.optional(element) || ( value >= param[0] && value <= param[1] );
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/email
		email: function(value, element) {
			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
			return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/url
		url: function(value, element) {
			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
			return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/date
		date: function(value, element) {
			return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/dateISO
		dateISO: function(value, element) {
			return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/number
		number: function(value, element) {
			return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/digits
		digits: function(value, element) {
			return this.optional(element) || /^\d+$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/creditcard
		// based on http://en.wikipedia.org/wiki/Luhn
		creditcard: function(value, element) {
			if ( this.optional(element) )
				return "dependency-mismatch";
			// accept only digits and dashes
			if (/[^0-9-]+/.test(value))
				return false;
			var nCheck = 0,
				nDigit = 0,
				bEven = false;

			value = value.replace(/\D/g, "");

			for (var n = value.length - 1; n >= 0; n--) {
				var cDigit = value.charAt(n);
				var nDigit = parseInt(cDigit, 10);
				if (bEven) {
					if ((nDigit *= 2) > 9)
						nDigit -= 9;
				}
				nCheck += nDigit;
				bEven = !bEven;
			}

			return (nCheck % 10) == 0;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/accept
		accept: function(value, element, param) {
			param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
			return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/equalTo
		equalTo: function(value, element, param) {
			// bind to the blur event of the target in order to revalidate whenever the target field is updated
			// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
			var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
				$(element).valid();
			});
			return value == target.val();
		}

	}

});

// deprecated, use $.validator.format instead
$.format = $.validator.format;

})(jQuery);

// ajax mode: abort
// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
;(function($) {
	var pendingRequests = {};
	// Use a prefilter if available (1.5+)
	if ( $.ajaxPrefilter ) {
		$.ajaxPrefilter(function(settings, _, xhr) {
			var port = settings.port;
			if (settings.mode == "abort") {
				if ( pendingRequests[port] ) {
					pendingRequests[port].abort();
				}
				pendingRequests[port] = xhr;
			}
		});
	} else {
		// Proxy ajax
		var ajax = $.ajax;
		$.ajax = function(settings) {
			var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
				port = ( "port" in settings ? settings : $.ajaxSettings ).port;
			if (mode == "abort") {
				if ( pendingRequests[port] ) {
					pendingRequests[port].abort();
				}
				return (pendingRequests[port] = ajax.apply(this, arguments));
			}
			return ajax.apply(this, arguments);
		};
	}
})(jQuery);

// provides cross-browser focusin and focusout events
// IE has native support, in other browsers, use event caputuring (neither bubbles)

// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
;(function($) {
	// only implement if not provided by jQuery core (since 1.4)
	// TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs
	if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) {
		$.each({
			focus: 'focusin',
			blur: 'focusout'
		}, function( original, fix ){
			$.event.special[fix] = {
				setup:function() {
					this.addEventListener( original, handler, true );
				},
				teardown:function() {
					this.removeEventListener( original, handler, true );
				},
				handler: function(e) {
					arguments[0] = $.event.fix(e);
					arguments[0].type = fix;
					return $.event.handle.apply(this, arguments);
				}
			};
			function handler(e) {
				e = $.event.fix(e);
				e.type = fix;
				return $.event.handle.call(this, e);
			}
		});
	};
	$.extend($.fn, {
		validateDelegate: function(delegate, type, handler) {
			return this.bind(type, function(event) {
				var target = $(event.target);
				if (target.is(delegate)) {
					return handler.apply(target, arguments);
				}
			});
		}
	});
})(jQuery);

;// Beginning /res/js/os/jquery-wysiwyg/jquery.wysiwyg.js:
/**
 * WYSIWYG - jQuery plugin 0.97
 * (0.97.2 - From infinity)
 *
 * Copyright (c) 2008-2009 Juan M Martinez, 2010-2011 Akzhan Abdulin and all contributors
 * https://github.com/akzhan/jwysiwyg
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 */

/*jslint browser: true, forin: true */

(function ($) {
	"use strict";
	/* Wysiwyg namespace: private properties and methods */

	var console = window.console ? window.console : {
		log: $.noop,
		error: function (msg) {
			$.error(msg);
		}
	};
	var supportsProp = (('prop' in $.fn) && ('removeProp' in $.fn));  // !(/^[01]\.[0-5](?:\.|$)/.test($.fn.jquery));

	function Wysiwyg() {
		this.controls = {
			bold: {
				groupIndex: 0,
				visible: true,
				tags: ["b", "strong"],
				css: {
					fontWeight: "bold"
				},
				tooltip: "Bold",
				hotkey: {"ctrl": 1, "key": 66}
			},

			copy: {
				groupIndex: 8,
				visible: false,
				tooltip: "Copy"
			},

			createLink: {
				groupIndex: 6,
				visible: true,
				exec: function () {
					var self = this;
					if ($.wysiwyg.controls && $.wysiwyg.controls.link) {
						$.wysiwyg.controls.link.init(this);
					} else if ($.wysiwyg.autoload) {
						$.wysiwyg.autoload.control("wysiwyg.link.js", function () {
							self.controls.createLink.exec.apply(self);
						});
					} else {
						console.error("$.wysiwyg.controls.link not defined. You need to include wysiwyg.link.js file");
					}
				},
				tags: ["a"],
				tooltip: "Create link"
			},

			cut: {
				groupIndex: 8,
				visible: false,
				tooltip: "Cut"
			},

			decreaseFontSize: {
				groupIndex: 9,
				visible: false,
				tags: ["small"],
				tooltip: "Decrease font size",
				exec: function () {
					this.decreaseFontSize();
				}
			},

			h1: {
				groupIndex: 7,
				visible: true,
				className: "h1",
				command: ($.browser.msie || $.browser.safari) ? "FormatBlock" : "heading",
				"arguments": ($.browser.msie || $.browser.safari) ? "<h1>" : "h1",
				tags: ["h1"],
				tooltip: "Header 1"
			},

			h2: {
				groupIndex: 7,
				visible: true,
				className: "h2",
				command: ($.browser.msie || $.browser.safari)	? "FormatBlock" : "heading",
				"arguments": ($.browser.msie || $.browser.safari) ? "<h2>" : "h2",
				tags: ["h2"],
				tooltip: "Header 2"
			},

			h3: {
				groupIndex: 7,
				visible: true,
				className: "h3",
				command: ($.browser.msie || $.browser.safari) ? "FormatBlock" : "heading",
				"arguments": ($.browser.msie || $.browser.safari) ? "<h3>" : "h3",
				tags: ["h3"],
				tooltip: "Header 3"
			},

			highlight: {
				tooltip:     "Highlight",
				className:   "highlight",
				groupIndex:  1,
				visible:     false,
				css: {
					backgroundColor: "rgb(255, 255, 102)"
				},
				exec: function () {
					var command, node, selection, args;

					if ($.browser.msie || $.browser.safari) {
						command = "backcolor";
					} else {
						command = "hilitecolor";
					}

					if ($.browser.msie) {
						node = this.getInternalRange().parentElement();
					} else {
						selection = this.getInternalSelection();
						node = selection.extentNode || selection.focusNode;

						while (node.style === undefined) {
							node = node.parentNode;
							if (node.tagName && node.tagName.toLowerCase() === "body") {
								return;
							}
						}
					}

					if (node.style.backgroundColor === "rgb(255, 255, 102)" ||
							node.style.backgroundColor === "#ffff66") {
						args = "#ffffff";
					} else {
						args = "#ffff66";
					}

					this.editorDoc.execCommand(command, false, args);
				}
			},

			html: {
				groupIndex: 10,
				visible: false,
				exec: function () {
					var elementHeight;

					if (this.options.resizeOptions && $.fn.resizable) {
						elementHeight = this.element.height();
					}

					if (this.viewHTML) {
						this.setContent(this.original.value);

						$(this.original).hide();
						this.editor.show();

						if (this.options.resizeOptions && $.fn.resizable) {
							// if element.height still the same after frame was shown
							if (elementHeight === this.element.height()) {
								this.element.height(elementHeight + this.editor.height());
							}

							this.element.resizable($.extend(true, {
								alsoResize: this.editor
							}, this.options.resizeOptions));
						}
						
						this.ui.toolbar.find("li").each(function () {
							var li = $(this);

							if (li.hasClass("html")) {
								li.removeClass("active");
							} else {
								li.removeClass('disabled');
							}
						});
					} else {
						this.saveContent();

						$(this.original).css({
							width:	this.element.outerWidth() - 6,
							height: this.element.height() - this.ui.toolbar.height() - 6,
							resize: "none"
						}).show();
						this.editor.hide();
						
						if (this.options.resizeOptions && $.fn.resizable) {
							// if element.height still the same after frame was hidden
							if (elementHeight === this.element.height()) {
								this.element.height(this.ui.toolbar.height());
							}

							this.element.resizable("destroy");
						}

						this.ui.toolbar.find("li").each(function () {
							var li = $(this);

							if (li.hasClass("html")) {
								li.addClass("active");
							} else {
								if (false === li.hasClass("fullscreen")) {
									li.removeClass("active").addClass('disabled');
								}
							}
						});
					}

					this.viewHTML = !(this.viewHTML);
				},
				tooltip: "View source code"
			},

			increaseFontSize: {
				groupIndex: 9,
				visible: false,
				tags: ["big"],
				tooltip: "Increase font size",
				exec: function () {
					this.increaseFontSize();
				}
			},

			indent: {
				groupIndex: 2,
				visible: true,
				tooltip: "Indent"
			},

			insertHorizontalRule: {
				groupIndex: 6,
				visible: true,
				tags: ["hr"],
				tooltip: "Insert Horizontal Rule"
			},

			insertImage: {
				groupIndex: 6,
				visible: true,
				exec: function () {
					var self = this;

					if ($.wysiwyg.controls && $.wysiwyg.controls.image) {
						$.wysiwyg.controls.image.init(this);
					} else if ($.wysiwyg.autoload) {
						$.wysiwyg.autoload.control("wysiwyg.image.js", function () {
							self.controls.insertImage.exec.apply(self);
						});
					} else {
						console.error("$.wysiwyg.controls.image not defined. You need to include wysiwyg.image.js file");
					}
				},
				tags: ["img"],
				tooltip: "Insert image"
			},

			insertOrderedList: {
				groupIndex: 5,
				visible: true,
				tags: ["ol"],
				tooltip: "Insert Ordered List"
			},

			insertTable: {
				groupIndex: 6,
				visible: true,
				exec: function () {
					var self = this;

					if ($.wysiwyg.controls && $.wysiwyg.controls.table) {
						$.wysiwyg.controls.table(this);
					} else if ($.wysiwyg.autoload) {
						$.wysiwyg.autoload.control("wysiwyg.table.js", function () {
							self.controls.insertTable.exec.apply(self);
						});
					} else {
						console.error("$.wysiwyg.controls.table not defined. You need to include wysiwyg.table.js file");
					}
				},
				tags: ["table"],
				tooltip: "Insert table"
			},

			insertUnorderedList: {
				groupIndex: 5,
				visible: true,
				tags: ["ul"],
				tooltip: "Insert Unordered List"
			},

			italic: {
				groupIndex: 0,
				visible: true,
				tags: ["i", "em"],
				css: {
					fontStyle: "italic"
				},
				tooltip: "Italic",
				hotkey: {"ctrl": 1, "key": 73}
			},

			justifyCenter: {
				groupIndex: 1,
				visible: true,
				tags: ["center"],
				css: {
					textAlign: "center"
				},
				tooltip: "Justify Center"
			},

			justifyFull: {
				groupIndex: 1,
				visible: true,
				css: {
					textAlign: "justify"
				},
				tooltip: "Justify Full"
			},

			justifyLeft: {
				visible: true,
				groupIndex: 1,
				css: {
					textAlign: "left"
				},
				tooltip: "Justify Left"
			},

			justifyRight: {
				groupIndex: 1,
				visible: true,
				css: {
					textAlign: "right"
				},
				tooltip: "Justify Right"
			},

			ltr: {
				groupIndex: 10,
				visible: false,
				exec: function () {
					var p = this.dom.getElement("p");

					if (!p) {
						return false;
					}

					$(p).attr("dir", "ltr");
					return true;
				},
				tooltip : "Left to Right"
			},

			outdent: {
				groupIndex: 2,
				visible: true,
				tooltip: "Outdent"
			},

			paragraph: {
				groupIndex: 7,
				visible: false,
				className: "paragraph",
				command: "FormatBlock",
				"arguments": ($.browser.msie || $.browser.safari) ? "<p>" : "p",
				tags: ["p"],
				tooltip: "Paragraph"
			},

			paste: {
				groupIndex: 8,
				visible: false,
				tooltip: "Paste"
			},

			redo: {
				groupIndex: 4,
				visible: true,
				tooltip: "Redo"
			},

			removeFormat: {
				groupIndex: 10,
				visible: true,
				exec: function () {
					this.removeFormat();
				},
				tooltip: "Remove formatting"
			},

			rtl: {
				groupIndex: 10,
				visible: false,
				exec: function () {
					var p = this.dom.getElement("p");

					if (!p) {
						return false;
					}

					$(p).attr("dir", "rtl");
					return true;
				},
				tooltip : "Right to Left"
			},

			strikeThrough: {
				groupIndex: 0,
				visible: true,
				tags: ["s", "strike"],
				css: {
					textDecoration: "line-through"
				},
				tooltip: "Strike-through"
			},

			subscript: {
				groupIndex: 3,
				visible: true,
				tags: ["sub"],
				tooltip: "Subscript"
			},

			superscript: {
				groupIndex: 3,
				visible: true,
				tags: ["sup"],
				tooltip: "Superscript"
			},

			underline: {
				groupIndex: 0,
				visible: true,
				tags: ["u"],
				css: {
					textDecoration: "underline"
				},
				tooltip: "Underline",
				hotkey: {"ctrl": 1, "key": 85}
			},

			undo: {
				groupIndex: 4,
				visible: true,
				tooltip: "Undo"
			},

			code: {
				visible : true,
				groupIndex: 6,
				tooltip: "Code snippet",
				exec: function () {
					var range	= this.getInternalRange(),
						common	= $(range.commonAncestorContainer),
						$nodeName = range.commonAncestorContainer.nodeName.toLowerCase();
					if (common.parent("code").length) {
						common.unwrap();
					} else {
						if ($nodeName !== "body") {
							common.wrap("<code/>");
						}
					}
				}
			}
		};

		this.defaults = {
			html: '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body style="margin: 3px;">INITIAL_CONTENT</body></html>',
			debug: false,
			controls: {},
			css: {},
			events: {},
			autoGrow: false,
			autoSave: true,
			brIE: true,					// http://code.google.com/p/jwysiwyg/issues/detail?id=15
			formHeight: 270,
			formWidth: 440,
			iFrameClass: null,
			initialContent: "<p>Initial content</p>",
			maxHeight: 10000,			// see autoGrow
			maxLength: 0,
			messages: {
				nonSelection: "Select the text you wish to link"
			},
			toolbarHtml: '<ul role="menu" class="toolbar"></ul>',
			removeHeadings: false,
			replaceDivWithP: false,
			resizeOptions: false,
			rmUnusedControls: false,	// https://github.com/akzhan/jwysiwyg/issues/52
			rmUnwantedBr: true,			// http://code.google.com/p/jwysiwyg/issues/detail?id=11
			tableFiller: "Lorem ipsum",
			initialMinHeight: null,

			controlImage: {
				forceRelativeUrls: false
			},

			controlLink: {
				forceRelativeUrls: false
			},

			plugins: { // placeholder for plugins settings
				autoload: false,
				i18n: false,
				rmFormat: {
					rmMsWordMarkup: false
				}
			}
		};

		this.availableControlProperties = [
			"arguments",
			"callback",
			"className",
			"command",
			"css",
			"custom",
			"exec",
			"groupIndex",
			"hotkey",
			"icon",
			"tags",
			"tooltip",
			"visible"
		];

		this.editor			= null;
		this.editorDoc		= null;
		this.element		= null;
		this.options		= {};
		this.original		= null;
		this.savedRange		= null;
		this.timers			= [];
		this.validKeyCodes	= [8, 9, 13, 16, 17, 18, 19, 20, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46];

		this.isDestroyed	= false;

		this.dom		= { // DOM related properties and methods
			ie:		{
				parent: null // link to dom
			},
			w3c:	{
				parent: null // link to dom
			}
		};
		this.dom.parent		= this;
		this.dom.ie.parent	= this.dom;
		this.dom.w3c.parent	= this.dom;

		this.ui			= {};	// UI related properties and methods
		this.ui.self	= this;
		this.ui.toolbar	= null;
		this.ui.initialHeight = null; // ui.grow

		this.dom.getAncestor = function (element, filterTagName) {
			filterTagName = filterTagName.toLowerCase();

			while (element && "body" !== element.tagName.toLowerCase()) {
				if (filterTagName === element.tagName.toLowerCase()) {
					return element;
				}

				element = element.parentNode;
			}

			return null;
		};

		this.dom.getElement = function (filterTagName) {
			var dom = this;

			if (window.getSelection) {
				return dom.w3c.getElement(filterTagName);
			} else {
				return dom.ie.getElement(filterTagName);
			}
		};

		this.dom.ie.getElement = function (filterTagName) {
			var dom			= this.parent,
				selection	= dom.parent.getInternalSelection(),
				range		= selection.createRange(),
				element;

			if ("Control" === selection.type) {
				// control selection
				if (1 === range.length) {
					element = range.item(0);
				} else {
					// multiple control selection
					return null;
				}
			} else {
				element = range.parentElement();
			}

			return dom.getAncestor(element, filterTagName);
		};

		this.dom.w3c.getElement = function (filterTagName) {
			var dom		= this.parent,
				range	= dom.parent.getInternalRange(),
				element;

			if (!range) {
				return null;
			}

			element	= range.commonAncestorContainer;

			if (3 === element.nodeType) {
				element = element.parentNode;
			}

			// if startContainer not Text, Comment, or CDATASection element then
			// startOffset is the number of child nodes between the start of the
			// startContainer and the boundary point of the Range
			if (element === range.startContainer) {
				element = element.childNodes[range.startOffset];
			}

			return dom.getAncestor(element, filterTagName);
		};

		this.ui.addHoverClass = function () {
			$(this).addClass("wysiwyg-button-hover");
		};

		this.ui.appendControls = function () {
			var ui = this,
				self = this.self,
				controls = self.parseControls(),
				hasVisibleControls	= true, // to prevent separator before first item
				groups = [],
				controlsByGroup = {},
				i,
				currentGroupIndex, // jslint wants all vars at top of function
				iterateGroup = function (controlName, control) {
					if (control.groupIndex && currentGroupIndex !== control.groupIndex) {
						currentGroupIndex = control.groupIndex;
						hasVisibleControls = false;
					}

					if (!control.visible) {
						return;
					}

					if (!hasVisibleControls) {
						ui.appendItemSeparator();
						hasVisibleControls = true;
					}

					if (control.custom) {
						ui.appendItemCustom(controlName, control);
					} else {
						ui.appendItem(controlName, control);
					}
				};

			$.each(controls, function (name, c) {
				var index = "empty";

				if (undefined !== c.groupIndex) {
					if ("" === c.groupIndex) {
						index = "empty";
					} else {
						index = c.groupIndex;
					}
				}

				if (undefined === controlsByGroup[index]) {
					groups.push(index);
					controlsByGroup[index] = {};
				}
				controlsByGroup[index][name] = c;
			});

			groups.sort(function (a, b) {
				if ("number" === typeof (a) && typeof (a) === typeof (b)) {
					return (a - b);
				} else {
					a = a.toString();
					b = b.toString();

					if (a > b) {
						return 1;
					}

					if (a === b) {
						return 0;
					}

					return -1;
				}
			});

			if (0 < groups.length) {
				// set to first index in groups to proper placement of separator
				currentGroupIndex = groups[0];
			}

			for (i = 0; i < groups.length; i += 1) {
				$.each(controlsByGroup[groups[i]], iterateGroup);
			}
		};

		this.ui.appendItem = function (name, control) {
			var self = this.self,
				className = control.className || control.command || name || "empty",
				tooltip = control.tooltip || control.command || name || "";

			return $('<li role="menuitem" unselectable="on">' + (className) + "</li>")
				.addClass(className)
				.attr("title", tooltip)
				.hover(this.addHoverClass, this.removeHoverClass)
				.click(function () {
					if ($(this).hasClass("disabled")) {
						return false;
					}

					self.triggerControl.apply(self, [name, control]);

					this.blur();
					self.ui.returnRange();
					self.ui.focus();
					return true;
				})
				.appendTo(self.ui.toolbar);
		};

		this.ui.appendItemCustom = function (name, control) {
			var self = this.self,
				tooltip = control.tooltip || control.command || name || "";

			if (control.callback) {
				$(window).bind("trigger-" + name + ".wysiwyg", control.callback);
			}

			return $('<li role="menuitem" unselectable="on" style="background: url(\'' + control.icon + '\') no-repeat;"></li>')
				.addClass("custom-command-" + name)
				.addClass("wysiwyg-custom-command")
				.addClass(name)
				.attr("title", tooltip)
				.hover(this.addHoverClass, this.removeHoverClass)
				.click(function () {
					if ($(this).hasClass("disabled")) {
						return false;
					}

					self.triggerControl.apply(self, [name, control]);

					this.blur();
					self.ui.returnRange();
					self.ui.focus();

					self.triggerControlCallback(name);
					return true;
				})
				.appendTo(self.ui.toolbar);
		};

		this.ui.appendItemSeparator = function () {
			var self = this.self;
			return $('<li role="separator" class="separator"></li>').appendTo(self.ui.toolbar);
		};

		this.autoSaveFunction = function () {
			this.saveContent();
		};

		this.ui.checkTargets = function (element) {
			var self = this.self;

			$.each(self.options.controls, function (name, control) {
				var className = control.className || control.command || name || "empty",
					tags,
					elm,
					css,
					el,
					checkActiveStatus = function (cssProperty, cssValue) {
						var handler;

						if ("function" === typeof (cssValue)) {
							handler = cssValue;
							if (handler(el.css(cssProperty).toString().toLowerCase(), self)) {
								self.ui.toolbar.find("." + className).addClass("active");
							}
						} else {
							if (el.css(cssProperty).toString().toLowerCase() === cssValue) {
								self.ui.toolbar.find("." + className).addClass("active");
							}
						}
					};

				if ("fullscreen" !== className) {
					self.ui.toolbar.find("." + className).removeClass("active");
				}

				if (control.tags || (control.options && control.options.tags)) {
					tags = control.tags || (control.options && control.options.tags);

					elm = element;
					while (elm) {
						if (elm.nodeType !== 1) {
							break;
						}

						if ($.inArray(elm.tagName.toLowerCase(), tags) !== -1) {
							self.ui.toolbar.find("." + className).addClass("active");
						}

						elm = elm.parentNode;
					}
				}

				if (control.css || (control.options && control.options.css)) {
					css = control.css || (control.options && control.options.css);
					el = $(element);

					while (el) {
						if (el[0].nodeType !== 1) {
							break;
						}
						$.each(css, checkActiveStatus);

						el = el.parent();
					}
				}
			});
		};

		this.ui.designMode = function () {
			var attempts = 3,
				self = this.self,
				runner;
				runner = function (attempts) {
					if ("on" === self.editorDoc.designMode) {
						if (self.timers.designMode) {
							window.clearTimeout(self.timers.designMode);
						}

						// IE needs to reget the document element (this.editorDoc) after designMode was set
						if (self.innerDocument() !== self.editorDoc) {
							self.ui.initFrame();
						}

						return;
					}

					try {
						self.editorDoc.designMode = "on";
					} catch (e) {
					}

					attempts -= 1;
					if (attempts > 0) {
						self.timers.designMode = window.setTimeout(function () { runner(attempts); }, 100);
					}
				};

			runner(attempts);
		};

		this.destroy = function () {
			this.isDestroyed = true;

			var i, $form = this.element.closest("form");

			for (i = 0; i < this.timers.length; i += 1) {
				window.clearTimeout(this.timers[i]);
			}

			// Remove bindings
			$form.unbind(".wysiwyg");
			this.element.remove();
			$.removeData(this.original, "wysiwyg");
			$(this.original).show();
			return this;
		};

		this.getRangeText = function () {
			var r = this.getInternalRange();

			if (r.toString) {
				r = r.toString();
			} else if (r.text) {	// IE
				r = r.text;
			}

			return r;
		};
		//not used?
		this.execute = function (command, arg) {
			if (typeof (arg) === "undefined") {
				arg = null;
			}
			this.editorDoc.execCommand(command, false, arg);
		};

		this.extendOptions = function (options) {
			var controls = {};

			/**
			 * If the user set custom controls, we catch it, and merge with the
			 * defaults controls later.
			 */
			if ("object" === typeof options.controls) {
				controls = options.controls;
				delete options.controls;
			}

			options = $.extend(true, {}, this.defaults, options);
			options.controls = $.extend(true, {}, controls, this.controls, controls);

			if (options.rmUnusedControls) {
				$.each(options.controls, function (controlName) {
					if (!controls[controlName]) {
						delete options.controls[controlName];
					}
				});
			}

			return options;
		};

		this.ui.focus = function () {
			var self = this.self;

			self.editor.get(0).contentWindow.focus();
			return self;
		};

		this.ui.returnRange = function () {
			var self = this.self, sel;

			if (self.savedRange !== null) {
				if (window.getSelection) { //non IE and there is already a selection
					sel = window.getSelection();
					if (sel.rangeCount > 0) {
						sel.removeAllRanges();
					}
					try {
						sel.addRange(self.savedRange);
					} catch (e) {
						console.error(e);
					}
				} else if (window.document.createRange) { // non IE and no selection
					window.getSelection().addRange(self.savedRange);
				} else if (window.document.selection) { //IE
					self.savedRange.select();
				}

				self.savedRange = null;
			}
		};

		this.increaseFontSize = function () {
			if ($.browser.mozilla || $.browser.opera) {
				this.editorDoc.execCommand('increaseFontSize', false, null);
			} else if ($.browser.safari) {
				var newNode = this.editorDoc.createElement('big');
				this.getInternalRange().surroundContents(newNode);
			} else {
				console.error("Internet Explorer?");
			}
		};

		this.decreaseFontSize = function () {
			if ($.browser.mozilla || $.browser.opera) {
				this.editorDoc.execCommand('decreaseFontSize', false, null);
			} else if ($.browser.safari) {
				var newNode = this.editorDoc.createElement('small');
				this.getInternalRange().surroundContents(newNode);
			} else {
				console.error("Internet Explorer?");
			}
		};

		this.getContent = function () {
			return this.events.filter('getContent', this.editorDoc.body.innerHTML);
		};
		
		/**
		 * A jWysiwyg specific event system.
		 *
		 * Example:
		 * 
		 * $("#editor").getWysiwyg().events.bind("getContent", function (orig) {
		 *     return "<div id='content'>"+orgi+"</div>";
		 * });
		 * 
		 * This makes it so that when ever getContent is called, it is wrapped in a div#content.
		 */
		this.events = {
			_events : {},
			
			/**
			 * Similar to jQuery's bind, but for jWysiwyg only.
			 */
			bind : function (eventName, callback) {
				if (typeof (this._events.eventName) !== "object") {
					this._events[eventName] = [];
				}
				this._events[eventName].push(callback);
			},
			
			/**
			 * Similar to jQuery's trigger, but for jWysiwyg only.
			 */
			trigger : function (eventName, args) {
				if (typeof (this._events.eventName) === "object") {
					var editor = this.editor;
					$.each(this._events[eventName], function (k, v) {
						if (typeof (v) === "function") {
							v.apply(editor, args);
						}
					});
				}
			},
			
			/**
			 * This "filters" `originalText` by passing it as the first argument to every callback
			 * with the name `eventName` and taking the return value and passing it to the next function.
			 *
			 * This function returns the result after all the callbacks have been applied to `originalText`.
			 */
			filter : function (eventName, originalText) {
				if (typeof (this._events[eventName]) === "object") {
					var editor = this.editor,
						args = Array.prototype.slice.call(arguments, 1);

					$.each(this._events[eventName], function (k, v) {
						if (typeof (v) === "function") {
							originalText = v.apply(editor, args);
						}
					});
				}
				return originalText;
			}
		};

		this.getElementByAttributeValue = function (tagName, attributeName, attributeValue) {
			var i, value, elements = this.editorDoc.getElementsByTagName(tagName);

			for (i = 0; i < elements.length; i += 1) {
				value = elements[i].getAttribute(attributeName);

				if ($.browser.msie) {
					/** IE add full path, so I check by the last chars. */
					value = value.substr(value.length - attributeValue.length);
				}

				if (value === attributeValue) {
					return elements[i];
				}
			}

			return false;
		};

		this.getInternalRange = function () {
			var selection = this.getInternalSelection();

			if (!selection) {
				return null;
			}

			if (selection.rangeCount && selection.rangeCount > 0) { // w3c
				return selection.getRangeAt(0);
			} else if (selection.createRange) { // ie
				return selection.createRange();
			}

			return null;
		};

		this.getInternalSelection = function () {
			// firefox: document.getSelection is deprecated
			if (this.editor.get(0).contentWindow) {
				if (this.editor.get(0).contentWindow.getSelection) {
					return this.editor.get(0).contentWindow.getSelection();
				}
				if (this.editor.get(0).contentWindow.selection) {
					return this.editor.get(0).contentWindow.selection;
				}
			}
			if (this.editorDoc.getSelection) {
				return this.editorDoc.getSelection();
			}
			if (this.editorDoc.selection) {
				return this.editorDoc.selection;
			}

			return null;
		};

		this.getRange = function () {
			var selection = this.getSelection();

			if (!selection) {
				return null;
			}

			if (selection.rangeCount && selection.rangeCount > 0) { // w3c
				selection.getRangeAt(0);
			} else if (selection.createRange) { // ie
				return selection.createRange();
			}

			return null;
		};

		this.getSelection = function () {
			return (window.getSelection) ? window.getSelection() : window.document.selection;
		};

		// :TODO: you can type long string and letters will be hidden because of overflow
		this.ui.grow = function () {
			var self = this.self,
				innerBody = $(self.editorDoc.body),
				innerHeight = $.browser.msie ? innerBody[0].scrollHeight : innerBody.height() + 2 + 20, // 2 - borders, 20 - to prevent content jumping on grow
				minHeight = self.ui.initialHeight,
				height = Math.max(innerHeight, minHeight);

			height = Math.min(height, self.options.maxHeight);

			self.editor.attr("scrolling", height < self.options.maxHeight ? "no" : "auto"); // hide scrollbar firefox
			innerBody.css("overflow", height < self.options.maxHeight ? "hidden" : ""); // hide scrollbar chrome

			self.editor.get(0).height = height;

			return self;
		};

		this.init = function (element, options) {
			var self = this,
				$form = $(element).closest("form"),
				newX = element.width || element.clientWidth || 0,
				newY = element.height || element.clientHeight || 0
				;

			this.options	= this.extendOptions(options);
			this.original	= element;
			this.ui.toolbar	= $(this.options.toolbarHtml);

			if ($.browser.msie && parseInt($.browser.version, 10) < 8) {
				this.options.autoGrow = false;
			}

			if (newX === 0 && element.cols) {
				newX = (element.cols * 8) + 21;
			}
			if (newY === 0 && element.rows) {
				newY = (element.rows * 16) + 16;
			}

			this.editor = $(window.location.protocol === "https:" ? '<iframe src="javascript:false;"></iframe>' : "<iframe></iframe>").attr("frameborder", "0");

			if (this.options.iFrameClass) {
				this.editor.addClass(this.options.iFrameClass);
			} else {
				this.editor.css({
					minHeight: (newY - 6).toString() + "px",
					// fix for issue 12 ( http://github.com/akzhan/jwysiwyg/issues/issue/12 )
					width: (newX > 50) ? (newX - 8).toString() + "px" : ""
				});
				if ($.browser.msie && parseInt($.browser.version, 10) < 7) {
					this.editor.css("height", newY.toString() + "px");
				}
			}
			/**
			 * http://code.google.com/p/jwysiwyg/issues/detail?id=96
			 */
			this.editor.attr("tabindex", $(element).attr("tabindex"));

			this.element = $("<div/>").addClass("wysiwyg");

			if (!this.options.iFrameClass) {
				this.element.css({
					width: (newX > 0) ? newX.toString() + "px" : "100%"
				});
			}

			$(element).hide().before(this.element);

			this.viewHTML = false;

			/**
			 * @link http://code.google.com/p/jwysiwyg/issues/detail?id=52
			 */
			this.initialContent = $(element).val();
			this.ui.initFrame();

			if (this.options.resizeOptions && $.fn.resizable) {
				this.element.resizable($.extend(true, {
					alsoResize: this.editor
				}, this.options.resizeOptions));
			}

			if (this.options.autoSave) {
				$form.bind("submit.wysiwyg", function () { self.autoSaveFunction(); });
			}

			$form.bind("reset.wysiwyg", function () { self.resetFunction(); });
		};

		this.ui.initFrame = function () {
			var self = this.self,
				stylesheet,
				growHandler,
				saveHandler;

			self.ui.appendControls();
			self.element.append(self.ui.toolbar)
				.append(self.editor);

			self.editorDoc = self.innerDocument();

			if (self.isDestroyed) {
				return null;
			}

			self.ui.designMode();
			self.editorDoc.open();
			self.editorDoc.write(
				self.options.html
					/**
					 * @link http://code.google.com/p/jwysiwyg/issues/detail?id=144
					 */
					.replace(/INITIAL_CONTENT/, function () { return self.wrapInitialContent(); })
			);
			self.editorDoc.close();

			$.wysiwyg.plugin.bind(self);

			$(self.editorDoc).trigger("initFrame.wysiwyg");

			$(self.editorDoc).bind("click.wysiwyg", function (event) {
				self.ui.checkTargets(event.target ? event.target : event.srcElement);
			});

			/**
			 * @link http://code.google.com/p/jwysiwyg/issues/detail?id=20
			 */
			$(self.original).focus(function () {
				if ($(this).filter(":visible")) {
					return;
				}
				self.ui.focus();
			});

			$(self.editorDoc).keydown(function (event) {
				var emptyContentRegex;
				if (event.keyCode === 8) { // backspace
					emptyContentRegex = /^<([\w]+)[^>]*>(<br\/?>)?<\/\1>$/;
					if (emptyContentRegex.test(self.getContent())) { // if content is empty
						event.stopPropagation(); // prevent remove single empty tag
						return false;
					}
				}
				return true;
			});

			if (!$.browser.msie) {
				$(self.editorDoc).keydown(function (event) {
					var controlName;

					/* Meta for Macs. tom@punkave.com */
					if (event.ctrlKey || event.metaKey) {
						for (controlName in self.controls) {
							if (self.controls[controlName].hotkey && self.controls[controlName].hotkey.ctrl) {
								if (event.keyCode === self.controls[controlName].hotkey.key) {
									self.triggerControl.apply(self, [controlName, self.controls[controlName]]);

									return false;
								}
							}
						}
					}

					return true;
				});
			} else if (self.options.brIE) {
				$(self.editorDoc).keydown(function (event) {
					if (event.keyCode === 13) {
						var rng = self.getRange();
						rng.pasteHTML("<br/>");
						rng.collapse(false);
						rng.select();

						return false;
					}

					return true;
				});
			}

			if (self.options.plugins.rmFormat.rmMsWordMarkup) {
				$(self.editorDoc).bind("keyup.wysiwyg", function (event) {
					if (event.ctrlKey || event.metaKey) {
						// CTRL + V (paste)
						if (86 === event.keyCode) {
							if ($.wysiwyg.rmFormat) {
								if ("object" === typeof (self.options.plugins.rmFormat.rmMsWordMarkup)) {
									$.wysiwyg.rmFormat.run(self, {rules: { msWordMarkup: self.options.plugins.rmFormat.rmMsWordMarkup }});
								} else {
									$.wysiwyg.rmFormat.run(self, {rules: { msWordMarkup: { enabled: true }}});
								}
							}
						}
					}
				});
			}

			if (self.options.autoSave) {
				$(self.editorDoc).keydown(function () { self.autoSaveFunction(); })
					.keyup(function () { self.autoSaveFunction(); })
					.mousedown(function () { self.autoSaveFunction(); })
					.bind($.support.noCloneEvent ? "input.wysiwyg" : "paste.wysiwyg", function () { self.autoSaveFunction(); });
			}

			if (self.options.autoGrow) {
				if (self.options.initialMinHeight !== null) {
					self.ui.initialHeight = self.options.initialMinHeight;
				} else {
					self.ui.initialHeight = $(self.editorDoc).height();
				}
				$(self.editorDoc.body).css("border", "1px solid white"); // cancel margin collapsing

				growHandler = function () {
					self.ui.grow();
				};

				$(self.editorDoc).keyup(growHandler);
				$(self.editorDoc).bind("editorRefresh.wysiwyg", growHandler);

				// fix when content height > textarea height
				self.ui.grow();
			}

			if (self.options.css) {
				if (String === self.options.css.constructor) {
					if ($.browser.msie) {
						stylesheet = self.editorDoc.createStyleSheet(self.options.css);
						$(stylesheet).attr({
							"media":	"all"
						});
					} else {
						stylesheet = $("<link/>").attr({
							"href":		self.options.css,
							"media":	"all",
							"rel":		"stylesheet",
							"type":		"text/css"
						});

						$(self.editorDoc).find("head").append(stylesheet);
					}
				} else {
					self.timers.initFrame_Css = window.setTimeout(function () {
						$(self.editorDoc.body).css(self.options.css);
					}, 0);
				}
			}

			if (self.initialContent.length === 0) {
				if ("function" === typeof (self.options.initialContent)) {
					self.setContent(self.options.initialContent());
				} else {
					self.setContent(self.options.initialContent);
				}
			}

			if (self.options.maxLength > 0) {
				$(self.editorDoc).keydown(function (event) {
					if ($(self.editorDoc).text().length >= self.options.maxLength && $.inArray(event.which, self.validKeyCodes) === -1) {
						event.preventDefault();
					}
				});
			}
			
			// Support event callbacks
			$.each(self.options.events, function (key, handler) {
				$(self.editorDoc).bind(key + ".wysiwyg", function (event) {
					// Trigger event handler, providing the event and api to 
					// support additional functionality.
					handler.apply(self.editorDoc, [event, self]);
				});
			});

			// restores selection properly on focus
			if ($.browser.msie) {
				// Event chain: beforedeactivate => focusout => blur.
				// Focusout & blur fired too late to handle internalRange() in dialogs.
				// When clicked on input boxes both got range = null
				$(self.editorDoc).bind("beforedeactivate.wysiwyg", function () {
					self.savedRange = self.getInternalRange();
				});
			} else {
				$(self.editorDoc).bind("blur.wysiwyg", function () {
					self.savedRange = self.getInternalRange();
				});
			}

			$(self.editorDoc.body).addClass("wysiwyg");
			if (self.options.events && self.options.events.save) {
				saveHandler = self.options.events.save;

				$(self.editorDoc).bind("keyup.wysiwyg", saveHandler);
				$(self.editorDoc).bind("change.wysiwyg", saveHandler);

				if ($.support.noCloneEvent) {
					$(self.editorDoc).bind("input.wysiwyg", saveHandler);
				} else {
					$(self.editorDoc).bind("paste.wysiwyg", saveHandler);
					$(self.editorDoc).bind("cut.wysiwyg", saveHandler);
				}
			}
			
			/**
			 * XHTML5 {@link https://github.com/akzhan/jwysiwyg/issues/152}
			 */
			if (self.options.xhtml5 && self.options.unicode) {
				var replacements = {ne:8800,le:8804,para:182,xi:958,darr:8595,nu:957,oacute:243,Uacute:218,omega:969,prime:8242,pound:163,igrave:236,thorn:254,forall:8704,emsp:8195,lowast:8727,brvbar:166,alefsym:8501,nbsp:160,delta:948,clubs:9827,lArr:8656,Omega:937,Auml:196,cedil:184,and:8743,plusmn:177,ge:8805,raquo:187,uml:168,equiv:8801,laquo:171,rdquo:8221,Epsilon:917,divide:247,fnof:402,chi:967,Dagger:8225,iacute:237,rceil:8969,sigma:963,Oslash:216,acute:180,frac34:190,lrm:8206,upsih:978,Scaron:352,part:8706,exist:8707,nabla:8711,image:8465,prop:8733,zwj:8205,omicron:959,aacute:225,Yuml:376,Yacute:221,weierp:8472,rsquo:8217,otimes:8855,kappa:954,thetasym:977,harr:8596,Ouml:214,Iota:921,ograve:242,sdot:8901,copy:169,oplus:8853,acirc:226,sup:8835,zeta:950,Iacute:205,Oacute:211,crarr:8629,Nu:925,bdquo:8222,lsquo:8216,apos:39,Beta:914,eacute:233,egrave:232,lceil:8968,Kappa:922,piv:982,Ccedil:199,ldquo:8220,Xi:926,cent:162,uarr:8593,hellip:8230,Aacute:193,ensp:8194,sect:167,Ugrave:217,aelig:230,ordf:170,curren:164,sbquo:8218,macr:175,Phi:934,Eta:919,rho:961,Omicron:927,sup2:178,euro:8364,aring:229,Theta:920,mdash:8212,uuml:252,otilde:245,eta:951,uacute:250,rArr:8658,nsub:8836,agrave:224,notin:8713,ndash:8211,Psi:936,Ocirc:212,sube:8838,szlig:223,micro:181,not:172,sup1:185,middot:183,iota:953,ecirc:234,lsaquo:8249,thinsp:8201,sum:8721,ntilde:241,scaron:353,cap:8745,atilde:227,lang:10216,__replacement:65533,isin:8712,gamma:947,Euml:203,ang:8736,upsilon:965,Ntilde:209,hearts:9829,Alpha:913,Tau:932,spades:9824,dagger:8224,THORN:222,"int":8747,lambda:955,Eacute:201,Uuml:220,infin:8734,rlm:8207,Aring:197,ugrave:249,Egrave:200,Acirc:194,rsaquo:8250,ETH:208,oslash:248,alpha:945,Ograve:210,Prime:8243,mu:956,ni:8715,real:8476,bull:8226,beta:946,icirc:238,eth:240,prod:8719,larr:8592,ordm:186,perp:8869,Gamma:915,reg:174,ucirc:251,Pi:928,psi:968,tilde:732,asymp:8776,zwnj:8204,Agrave:192,deg:176,AElig:198,times:215,Delta:916,sim:8764,Otilde:213,Mu:924,uArr:8657,circ:710,theta:952,Rho:929,sup3:179,diams:9830,tau:964,Chi:935,frac14:188,oelig:339,shy:173,or:8744,dArr:8659,phi:966,iuml:239,Lambda:923,rfloor:8971,iexcl:161,cong:8773,ccedil:231,Icirc:206,frac12:189,loz:9674,rarr:8594,cup:8746,radic:8730,frasl:8260,euml:235,OElig:338,hArr:8660,Atilde:195,Upsilon:933,there4:8756,ouml:246,oline:8254,Ecirc:202,yacute:253,auml:228,permil:8240,sigmaf:962,iquest:191,empty:8709,pi:960,Ucirc:219,supe:8839,Igrave:204,yen:165,rang:10217,trade:8482,lfloor:8970,minus:8722,Zeta:918,sub:8834,epsilon:949,yuml:255,Sigma:931,Iuml:207,ocirc:244};
				self.events.bind("getContent", function (text) {
					return text.replace(/&(?:amp;)?(?!amp|lt|gt|quot)([a-z][a-z0-9]*);/gi, function (str, p1) {
						if (!replacements[p1]) {
							p1 = p1.toLowerCase();
							if (!replacements[p1]) {
								p1 = "__replacement";
							}
						}
						
						var num = replacements[p1];
						/* Numeric return if ever wanted: return replacements[p1] ? "&#"+num+";" : ""; */
						return String.fromCharCode(num);
					});
				});
			}
		};

		this.innerDocument = function () {
			var element = this.editor.get(0);

			if (element.nodeName.toLowerCase() === "iframe") {
				if (element.contentDocument) {				// Gecko
					return element.contentDocument;
				} else if (element.contentWindow) {			// IE
					return element.contentWindow.document;
				}

				if (this.isDestroyed) {
					return null;
				}

				console.error("Unexpected error in innerDocument");

				/*
				 return ( $.browser.msie )
				 ? document.frames[element.id].document
				 : element.contentWindow.document // contentDocument;
				 */
			}

			return element;
		};

		this.insertHtml = function (szHTML) {
			var img, range;

			if (!szHTML || szHTML.length === 0) {
				return this;
			}

			if ($.browser.msie) {
				this.ui.focus();
				this.editorDoc.execCommand("insertImage", false, "#jwysiwyg#");
				img = this.getElementByAttributeValue("img", "src", "#jwysiwyg#");
				if (img) {
					$(img).replaceWith(szHTML);
				}
			} else {
				if ($.browser.mozilla) { // @link https://github.com/akzhan/jwysiwyg/issues/50
					if (1 === $(szHTML).length) {
						range = this.getInternalRange();
						range.deleteContents();
						range.insertNode($(szHTML).get(0));
					} else {
						this.editorDoc.execCommand("insertHTML", false, szHTML);
					}
				} else {
					if (!this.editorDoc.execCommand("insertHTML", false, szHTML)) {
						this.editor.focus();
						/* :TODO: place caret at the end
						if (window.getSelection) {
						} else {
						}
						this.editor.focus();
						*/
						this.editorDoc.execCommand("insertHTML", false, szHTML);
					}
				}
			}

			this.saveContent();
			
			return this;
		};

		this.parseControls = function () {
			var self = this;

			$.each(this.options.controls, function (controlName, control) {
				$.each(control, function (propertyName) {
					if (-1 === $.inArray(propertyName, self.availableControlProperties)) {
						throw controlName + '["' + propertyName + '"]: property "' + propertyName + '" not exists in Wysiwyg.availableControlProperties';
					}
				});
			});

			if (this.options.parseControls) {
				return this.options.parseControls.call(this);
			}

			return this.options.controls;
		};

		this.removeFormat = function () {
			if ($.browser.msie) {
				this.ui.focus();
			}

			if (this.options.removeHeadings) {
				this.editorDoc.execCommand("formatBlock", false, "<p>"); // remove headings
			}

			this.editorDoc.execCommand("removeFormat", false, null);
			this.editorDoc.execCommand("unlink", false, null);

			if ($.wysiwyg.rmFormat && $.wysiwyg.rmFormat.enabled) {
				if ("object" === typeof (this.options.plugins.rmFormat.rmMsWordMarkup)) {
					$.wysiwyg.rmFormat.run(this, {rules: { msWordMarkup: this.options.plugins.rmFormat.rmMsWordMarkup }});
				} else {
					$.wysiwyg.rmFormat.run(this, {rules: { msWordMarkup: { enabled: true }}});
				}
			}

			return this;
		};

		this.ui.removeHoverClass = function () {
			$(this).removeClass("wysiwyg-button-hover");
		};

		this.resetFunction = function () {
			this.setContent(this.initialContent);
		};

		this.saveContent = function () {
			if (this.original) {
				var content, newContent;

				content = this.getContent();

				if (this.options.rmUnwantedBr) {
					content = content.replace(/<br\/?>$/, "");
				}

				if (this.options.replaceDivWithP) {
					newContent = $("<div/>").addClass("temp").append(content);

					newContent.children("div").each(function () {
						var element = $(this), p = element.find("p"), i;

						if (0 === p.length) {
							p = $("<p></p>");

							if (this.attributes.length > 0) {
								for (i = 0; i < this.attributes.length; i += 1) {
									p.attr(this.attributes[i].name, element.attr(this.attributes[i].name));
								}
							}

							p.append(element.html());

							element.replaceWith(p);
						}
					});
					
					content = newContent.html();
				}

				$(this.original).val(content);

				if (this.options.events && this.options.events.save) {
					this.options.events.save.call(this);
				}
			}

			return this;
		};

		this.setContent = function (newContent) {
			this.editorDoc.body.innerHTML = newContent;
			this.saveContent();

			return this;
		};

		this.triggerControl = function (name, control) {
			var cmd = control.command || name,
				args = control["arguments"] || [];

			if (control.exec) {
				control.exec.apply(this);
			} else {
				this.ui.focus();
				this.ui.withoutCss();
				// when click <Cut>, <Copy> or <Paste> got "Access to XPConnect service denied" code: "1011"
				// in Firefox untrusted JavaScript is not allowed to access the clipboard
				try {
					this.editorDoc.execCommand(cmd, false, args);
				} catch (e) {
					console.error(e);
				}
			}

			if (this.options.autoSave) {
				this.autoSaveFunction();
			}
		};

		this.triggerControlCallback = function (name) {
			$(window).trigger("trigger-" + name + ".wysiwyg", [this]);
		};

		this.ui.withoutCss = function () {
			var self = this.self;

			if ($.browser.mozilla) {
				try {
					self.editorDoc.execCommand("styleWithCSS", false, false);
				} catch (e) {
					try {
						self.editorDoc.execCommand("useCSS", false, true);
					} catch (e2) {
					}
				}
			}

			return self;
		};

		this.wrapInitialContent = function () {
			var content = this.initialContent,
				found = content.match(/<\/?p>/gi);

			if (!found) {
				return "<p>" + content + "</p>";
			} else {
				// :TODO: checking/replacing
			}

			return content;
		};
	}

	/*
	 * Wysiwyg namespace: public properties and methods
	 */
	$.wysiwyg = {
		messages: {
			noObject: "Something goes wrong, check object"
		},

		/**
		 * Custom control support by Alec Gorge ( http://github.com/alecgorge )
		 */
		addControl: function (object, name, settings) {
			return object.each(function () {
				var oWysiwyg = $(this).data("wysiwyg"),
					customControl = {},
					toolbar;

				if (!oWysiwyg) {
					return this;
				}

				customControl[name] = $.extend(true, {visible: true, custom: true}, settings);
				$.extend(true, oWysiwyg.options.controls, customControl);

				// render new toolbar
				toolbar = $(oWysiwyg.options.toolbarHtml);
				oWysiwyg.ui.toolbar.replaceWith(toolbar);
				oWysiwyg.ui.toolbar = toolbar;
				oWysiwyg.ui.appendControls();
			});
		},

		clear: function (object) {
			return object.each(function () {
				var oWysiwyg = $(this).data("wysiwyg");

				if (!oWysiwyg) {
					return this;
				}

				oWysiwyg.setContent("");
			});
		},

		console: console, // let our console be available for extensions

		destroy: function (object) {
			return object.each(function () {
				var oWysiwyg = $(this).data("wysiwyg");

				if (!oWysiwyg) {
					return this;
				}

				oWysiwyg.destroy();
			});
		},

		"document": function (object) {
			// no chains because of return
			var oWysiwyg = object.data("wysiwyg");

			if (!oWysiwyg) {
				return undefined;
			}

			return $(oWysiwyg.editorDoc);
		},

		getContent: function (object) {
			// no chains because of return
			var oWysiwyg = object.data("wysiwyg");

			if (!oWysiwyg) {
				return undefined;
			}

			return oWysiwyg.getContent();
		},

		init: function (object, options) {
			return object.each(function () {
				var opts = $.extend(true, {}, options),
					obj;

				// :4fun:
				// remove this textarea validation and change line in this.saveContent function
				// $(this.original).val(content); to $(this.original).html(content);
				// now you can make WYSIWYG editor on h1, p, and many more tags
				if (("textarea" !== this.nodeName.toLowerCase()) || $(this).data("wysiwyg")) {
					return;
				}

				obj = new Wysiwyg();
				obj.init(this, opts);
				$.data(this, "wysiwyg", obj);

				$(obj.editorDoc).trigger("afterInit.wysiwyg");
			});
		},

		insertHtml: function (object, szHTML) {
			return object.each(function () {
				var oWysiwyg = $(this).data("wysiwyg");

				if (!oWysiwyg) {
					return this;
				}

				oWysiwyg.insertHtml(szHTML);
			});
		},

		plugin: {
			listeners: {},

			bind: function (Wysiwyg) {
				var self = this;

				$.each(this.listeners, function (action, handlers) {
					var i, plugin;

					for (i = 0; i < handlers.length; i += 1) {
						plugin = self.parseName(handlers[i]);

						$(Wysiwyg.editorDoc).bind(action + ".wysiwyg", {plugin: plugin}, function (event) {
							$.wysiwyg[event.data.plugin.name][event.data.plugin.method].apply($.wysiwyg[event.data.plugin.name], [Wysiwyg]);
						});
					}
				});
			},

			exists: function (name) {
				var plugin;

				if ("string" !== typeof (name)) {
					return false;
				}

				plugin = this.parseName(name);

				if (!$.wysiwyg[plugin.name] || !$.wysiwyg[plugin.name][plugin.method]) {
					return false;
				}

				return true;
			},

			listen: function (action, handler) {
				var plugin;

				plugin = this.parseName(handler);

				if (!$.wysiwyg[plugin.name] || !$.wysiwyg[plugin.name][plugin.method]) {
					return false;
				}

				if (!this.listeners[action]) {
					this.listeners[action] = [];
				}

				this.listeners[action].push(handler);

				return true;
			},

			parseName: function (name) {
				var elements;

				if ("string" !== typeof (name)) {
					return false;
				}

				elements = name.split(".");

				if (2 > elements.length) {
					return false;
				}

				return {name: elements[0], method: elements[1]};
			},

			register: function (data) {
				if (!data.name) {
					console.error("Plugin name missing");
				}

				$.each($.wysiwyg, function (pluginName) {
					if (pluginName === data.name) {
						console.error("Plugin with name '" + data.name + "' was already registered");
					}
				});

				$.wysiwyg[data.name] = data;

				return true;
			}
		},

		removeFormat: function (object) {
			return object.each(function () {
				var oWysiwyg = $(this).data("wysiwyg");

				if (!oWysiwyg) {
					return this;
				}

				oWysiwyg.removeFormat();
			});
		},

		save: function (object) {
			return object.each(function () {
				var oWysiwyg = $(this).data("wysiwyg");

				if (!oWysiwyg) {
					return this;
				}

				oWysiwyg.saveContent();
			});
		},

		selectAll: function (object) {
			var oWysiwyg = object.data("wysiwyg"), oBody, oRange, selection;

			if (!oWysiwyg) {
				return this;
			}

			oBody = oWysiwyg.editorDoc.body;
			if (window.getSelection) {
				selection = oWysiwyg.getInternalSelection();
				selection.selectAllChildren(oBody);
			} else {
				oRange = oBody.createTextRange();
				oRange.moveToElementText(oBody);
				oRange.select();
			}
		},

		setContent: function (object, newContent) {
			return object.each(function () {
				var oWysiwyg = $(this).data("wysiwyg");

				if (!oWysiwyg) {
					return this;
				}

				oWysiwyg.setContent(newContent);
			});
		},

		triggerControl: function (object, controlName) {
			return object.each(function () {
				var oWysiwyg = $(this).data("wysiwyg");

				if (!oWysiwyg) {
					return this;
				}

				if (!oWysiwyg.controls[controlName]) {
					console.error("Control '" + controlName + "' not exists");
				}

				oWysiwyg.triggerControl.apply(oWysiwyg, [controlName, oWysiwyg.controls[controlName]]);
			});
		},

		support: {
			prop: supportsProp
		},

		utils: {
			extraSafeEntities: [["<", ">", "'", '"', " "], [32]],

			encodeEntities: function (str) {
				var self = this, aStr, aRet = [];

				if (this.extraSafeEntities[1].length === 0) {
					$.each(this.extraSafeEntities[0], function (i, ch) {
						self.extraSafeEntities[1].push(ch.charCodeAt(0));
					});
				}
				aStr = str.split("");
				$.each(aStr, function (i) {
					var iC = aStr[i].charCodeAt(0);
					if ($.inArray(iC, self.extraSafeEntities[1]) && (iC < 65 || iC > 127 || (iC > 90 && iC < 97))) {
						aRet.push('&#' + iC + ';');
					} else {
						aRet.push(aStr[i]);
					}
				});

				return aRet.join('');
			}
		}
	};

	$.fn.wysiwyg = function (method) {
		var args = arguments, plugin;

		if ("undefined" !== typeof $.wysiwyg[method]) {
			// set argument object to undefined
			args = Array.prototype.concat.call([args[0]], [this], Array.prototype.slice.call(args, 1));
			return $.wysiwyg[method].apply($.wysiwyg, Array.prototype.slice.call(args, 1));
		} else if ("object" === typeof method || !method) {
			Array.prototype.unshift.call(args, this);
			return $.wysiwyg.init.apply($.wysiwyg, args);
		} else if ($.wysiwyg.plugin.exists(method)) {
			plugin = $.wysiwyg.plugin.parseName(method);
			args = Array.prototype.concat.call([args[0]], [this], Array.prototype.slice.call(args, 1));
			return $.wysiwyg[plugin.name][plugin.method].apply($.wysiwyg[plugin.name], Array.prototype.slice.call(args, 1));
		} else {
			console.error("Method '" +  method + "' does not exist on jQuery.wysiwyg.\nTry to include some extra controls or plugins");
		}
	};
	
	$.fn.getWysiwyg = function () {
		return $.data(this, "wysiwyg");
	};
})(jQuery);

;// Beginning /res/js/os/jquery-wysiwyg/controls/wysiwyg.link.js:
/**
 * Controls: Link plugin
 *
 * Depends on jWYSIWYG
 *
 * By: Esteban Beltran (academo) <sergies@gmail.com>
 */
(function ($) {
	if (undefined === $.wysiwyg) {
		throw "wysiwyg.image.js depends on $.wysiwyg";
	}

	if (!$.wysiwyg.controls) {
		$.wysiwyg.controls = {};
	}

	/*
	* Wysiwyg namespace: public properties and methods
	*/
	$.wysiwyg.controls.link = {
		init: function (Wysiwyg) {
			var self = this, elements, dialog, url, a, selection,
				formLinkHtml, formTextLegend, formTextUrl, formTextTitle, formTextTarget,
				formTextSubmit, formTextReset,
				baseUrl;

			formTextLegend  = "Insert Link";
			formTextUrl     = "Link URL";
			formTextTitle   = "Link Title";
			formTextTarget  = "Link Target";
			formTextSubmit  = "Insert Link";
			formTextReset   = "Cancel";

			if ($.wysiwyg.i18n) {
				formTextLegend = $.wysiwyg.i18n.t(formTextLegend, "dialogs.link");
				formTextUrl    = $.wysiwyg.i18n.t(formTextUrl, "dialogs.link");
				formTextTitle  = $.wysiwyg.i18n.t(formTextTitle, "dialogs.link");
				formTextTarget = $.wysiwyg.i18n.t(formTextTarget, "dialogs.link");
				formTextSubmit = $.wysiwyg.i18n.t(formTextSubmit, "dialogs.link");
				formTextReset  = $.wysiwyg.i18n.t(formTextReset, "dialogs");
			}

			formLinkHtml = '<form class="wysiwyg"><fieldset><legend>' + formTextLegend + '</legend>' +
				'<label>' + formTextUrl + ': <input type="text" name="linkhref" value=""/></label>' +
				'<label>' + formTextTitle + ': <input type="text" name="linktitle" value=""/></label>' +
				'<label>' + formTextTarget + ': <input type="text" name="linktarget" value=""/></label>' +
				'<input type="submit" class="button" value="' + formTextSubmit + '"/> ' +
				'<input type="reset" value="' + formTextReset + '"/></fieldset></form>';

			a = {
				self: Wysiwyg.dom.getElement("a"), // link to element node
				href: "http://",
				title: "",
				target: ""
			};

			if (a.self) {
				a.href = a.self.href ? a.self.href : a.href;
				a.title = a.self.title ? a.self.title : "";
				a.target = a.self.target ? a.self.target : "";
			}

			if ($.fn.dialog) {
				elements = $(formLinkHtml);
				elements.find("input[name=linkhref]").val(a.href);
				elements.find("input[name=linktitle]").val(a.title);
				elements.find("input[name=linktarget]").val(a.target);

				if ($.browser.msie) {
					dialog = elements.appendTo(Wysiwyg.editorDoc.body);
				} else {
					dialog = elements.appendTo("body");
				}

				dialog.dialog({
					modal: true,
					open: function (ev, ui) {
						$("input:submit", dialog).click(function (e) {
							e.preventDefault();

							var url = $('input[name="linkhref"]', dialog).val(),
								title = $('input[name="linktitle"]', dialog).val(),
								target = $('input[name="linktarget"]', dialog).val(),
								baseUrl;

							if (Wysiwyg.options.controlLink.forceRelativeUrls) {
								baseUrl = window.location.protocol + "//" + window.location.hostname;
								if (0 === url.indexOf(baseUrl)) {
									url = url.substr(baseUrl.length);
								}
							}

							if (a.self) {
								if ("string" === typeof (url)) {
									if (url.length > 0) {
										// to preserve all link attributes
										$(a.self).attr("href", url).attr("title", title).attr("target", target);
									} else {
										$(a.self).replaceWith(a.self.innerHTML);
									}
								}
							} else {
								if ($.browser.msie) {
									Wysiwyg.ui.returnRange();
								}

								//Do new link element
								selection = Wysiwyg.getRangeText();
								img = Wysiwyg.dom.getElement("img");

								if ((selection && selection.length > 0) || img) {
									if ($.browser.msie) {
										Wysiwyg.ui.focus();
									}

									if ("string" === typeof (url)) {
										if (url.length > 0) {
											Wysiwyg.editorDoc.execCommand("createLink", false, url);
										} else {
											Wysiwyg.editorDoc.execCommand("unlink", false, null);
										}
									}

									a.self = Wysiwyg.dom.getElement("a");

									$(a.self).attr("href", url).attr("title", title);

									/**
									 * @url https://github.com/akzhan/jwysiwyg/issues/16
									 */
									$(a.self).attr("target", target);
								} else if (Wysiwyg.options.messages.nonSelection) {
									window.alert(Wysiwyg.options.messages.nonSelection);
								}
							}

							Wysiwyg.saveContent();

							$(dialog).dialog("close");
						});
						$("input:reset", dialog).click(function (e) {
							e.preventDefault();
							$(dialog).dialog("close");
						});
					},
					close: function (ev, ui) {
						dialog.dialog("destroy");
					}
				});
			} else {
				if (a.self) {
					url = window.prompt("URL", a.href);

					if (Wysiwyg.options.controlLink.forceRelativeUrls) {
						baseUrl = window.location.protocol + "//" + window.location.hostname;
						if (0 === url.indexOf(baseUrl)) {
							url = url.substr(baseUrl.length);
						}
					}

					if ("string" === typeof (url)) {
						if (url.length > 0) {
							$(a.self).attr("href", url);
						} else {
							$(a.self).replaceWith(a.self.innerHTML);
						}
					}
				} else {
					//Do new link element
					selection = Wysiwyg.getRangeText();
					img = Wysiwyg.dom.getElement("img");

					if ((selection && selection.length > 0) || img) {
						if ($.browser.msie) {
							Wysiwyg.ui.focus();
							Wysiwyg.editorDoc.execCommand("createLink", true, null);
						} else {
							url = window.prompt(formTextUrl, a.href);

							if (Wysiwyg.options.controlLink.forceRelativeUrls) {
								baseUrl = window.location.protocol + "//" + window.location.hostname;
								if (0 === url.indexOf(baseUrl)) {
									url = url.substr(baseUrl.length);
								}
							}

							if ("string" === typeof (url)) {
								if (url.length > 0) {
									Wysiwyg.editorDoc.execCommand("createLink", false, url);
								} else {
									Wysiwyg.editorDoc.execCommand("unlink", false, null);
								}
							}
						}
					} else if (Wysiwyg.options.messages.nonSelection) {
						window.alert(Wysiwyg.options.messages.nonSelection);
					}
				}

				Wysiwyg.saveContent();
			}

			$(Wysiwyg.editorDoc).trigger("editorRefresh.wysiwyg");
		}
	};

	$.wysiwyg.createLink = function (object, url) {
		return object.each(function () {
			var oWysiwyg = $(this).data("wysiwyg"),
				selection;

			if (!oWysiwyg) {
				return this;
			}

			if (!url || url.length === 0) {
				return this;
			}

			selection = oWysiwyg.getRangeText();

			if (selection && selection.length > 0) {
				if ($.browser.msie) {
					oWysiwyg.ui.focus();
				}
				oWysiwyg.editorDoc.execCommand("unlink", false, null);
				oWysiwyg.editorDoc.execCommand("createLink", false, url);
			} else if (oWysiwyg.options.messages.nonSelection) {
				window.alert(oWysiwyg.options.messages.nonSelection);
			}
		});
	};
})(jQuery);

;// Beginning /res/js/os/dataTables/jquery.dataTables.min.js:
/*
 * File:        jquery.dataTables.min.js
 * Version:     1.7.4
 * Author:      Allan Jardine (www.sprymedia.co.uk)
 * Info:        www.datatables.net
 * 
 * Copyright 2008-2010 Allan Jardine, all rights reserved.
 *
 * This source file is free software, under either the GPL v2 license or a
 * BSD style license, as supplied with this software.
 * 
 * This source file is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
 */
(function(j,X,p){j.fn.dataTableSettings=[];var E=j.fn.dataTableSettings;j.fn.dataTableExt={};var n=j.fn.dataTableExt;n.sVersion="1.7.4";n.sErrMode="alert";n.iApiIndex=0;n.oApi={};n.afnFiltering=[];n.aoFeatures=[];n.ofnSearch={};n.afnSortData=[];n.oStdClasses={sPagePrevEnabled:"paginate_enabled_previous",sPagePrevDisabled:"paginate_disabled_previous",sPageNextEnabled:"paginate_enabled_next",sPageNextDisabled:"paginate_disabled_next",sPageJUINext:"",sPageJUIPrev:"",sPageButton:"paginate_button",sPageButtonActive:"paginate_active",
sPageButtonStaticDisabled:"paginate_button",sPageFirst:"first",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last",sStripOdd:"odd",sStripEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",
sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:""};n.oJUIClasses={sPagePrevEnabled:"fg-button ui-button ui-state-default ui-corner-left",sPagePrevDisabled:"fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",
sPageNextEnabled:"fg-button ui-button ui-state-default ui-corner-right",sPageNextDisabled:"fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",sPageJUINext:"ui-icon ui-icon-circle-arrow-e",sPageJUIPrev:"ui-icon ui-icon-circle-arrow-w",sPageButton:"fg-button ui-button ui-state-default",sPageButtonActive:"fg-button ui-button ui-state-default ui-state-disabled",sPageButtonStaticDisabled:"fg-button ui-button ui-state-default ui-state-disabled",sPageFirst:"first ui-corner-tl ui-corner-bl",
sPagePrevious:"previous",sPageNext:"next",sPageLast:"last ui-corner-tr ui-corner-br",sStripOdd:"odd",sStripEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"ui-state-default",sSortDesc:"ui-state-default",sSortable:"ui-state-default",sSortableAsc:"ui-state-default",
sSortableDesc:"ui-state-default",sSortableNone:"ui-state-default",sSortColumn:"sorting_",sSortJUIAsc:"css_right ui-icon ui-icon-triangle-1-n",sSortJUIDesc:"css_right ui-icon ui-icon-triangle-1-s",sSortJUI:"css_right ui-icon ui-icon-carat-2-n-s",sSortJUIAscAllowed:"css_right ui-icon ui-icon-carat-1-n",sSortJUIDescAllowed:"css_right ui-icon ui-icon-carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead ui-state-default",sScrollHeadInner:"dataTables_scrollHeadInner",
sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot ui-state-default",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:"ui-state-default"};n.oPagination={two_button:{fnInit:function(g,l,r){var s,v,y;if(g.bJUI){s=p.createElement("a");v=p.createElement("a");y=p.createElement("span");y.className=g.oClasses.sPageJUINext;v.appendChild(y);y=p.createElement("span");y.className=g.oClasses.sPageJUIPrev;s.appendChild(y)}else{s=p.createElement("div");v=p.createElement("div")}s.className=
g.oClasses.sPagePrevDisabled;v.className=g.oClasses.sPageNextDisabled;s.title=g.oLanguage.oPaginate.sPrevious;v.title=g.oLanguage.oPaginate.sNext;l.appendChild(s);l.appendChild(v);j(s).click(function(){g.oApi._fnPageChange(g,"previous")&&r(g)});j(v).click(function(){g.oApi._fnPageChange(g,"next")&&r(g)});j(s).bind("selectstart",function(){return false});j(v).bind("selectstart",function(){return false});if(g.sTableId!==""&&typeof g.aanFeatures.p=="undefined"){l.setAttribute("id",g.sTableId+"_paginate");
s.setAttribute("id",g.sTableId+"_previous");v.setAttribute("id",g.sTableId+"_next")}},fnUpdate:function(g){if(g.aanFeatures.p)for(var l=g.aanFeatures.p,r=0,s=l.length;r<s;r++)if(l[r].childNodes.length!==0){l[r].childNodes[0].className=g._iDisplayStart===0?g.oClasses.sPagePrevDisabled:g.oClasses.sPagePrevEnabled;l[r].childNodes[1].className=g.fnDisplayEnd()==g.fnRecordsDisplay()?g.oClasses.sPageNextDisabled:g.oClasses.sPageNextEnabled}}},iFullNumbersShowPages:5,full_numbers:{fnInit:function(g,l,r){var s=
p.createElement("span"),v=p.createElement("span"),y=p.createElement("span"),D=p.createElement("span"),w=p.createElement("span");s.innerHTML=g.oLanguage.oPaginate.sFirst;v.innerHTML=g.oLanguage.oPaginate.sPrevious;D.innerHTML=g.oLanguage.oPaginate.sNext;w.innerHTML=g.oLanguage.oPaginate.sLast;var x=g.oClasses;s.className=x.sPageButton+" "+x.sPageFirst;v.className=x.sPageButton+" "+x.sPagePrevious;D.className=x.sPageButton+" "+x.sPageNext;w.className=x.sPageButton+" "+x.sPageLast;l.appendChild(s);l.appendChild(v);
l.appendChild(y);l.appendChild(D);l.appendChild(w);j(s).click(function(){g.oApi._fnPageChange(g,"first")&&r(g)});j(v).click(function(){g.oApi._fnPageChange(g,"previous")&&r(g)});j(D).click(function(){g.oApi._fnPageChange(g,"next")&&r(g)});j(w).click(function(){g.oApi._fnPageChange(g,"last")&&r(g)});j("span",l).bind("mousedown",function(){return false}).bind("selectstart",function(){return false});if(g.sTableId!==""&&typeof g.aanFeatures.p=="undefined"){l.setAttribute("id",g.sTableId+"_paginate");
s.setAttribute("id",g.sTableId+"_first");v.setAttribute("id",g.sTableId+"_previous");D.setAttribute("id",g.sTableId+"_next");w.setAttribute("id",g.sTableId+"_last")}},fnUpdate:function(g,l){if(g.aanFeatures.p){var r=n.oPagination.iFullNumbersShowPages,s=Math.floor(r/2),v=Math.ceil(g.fnRecordsDisplay()/g._iDisplayLength),y=Math.ceil(g._iDisplayStart/g._iDisplayLength)+1,D="",w,x=g.oClasses;if(v<r){s=1;w=v}else if(y<=s){s=1;w=r}else if(y>=v-s){s=v-r+1;w=v}else{s=y-Math.ceil(r/2)+1;w=s+r-1}for(r=s;r<=
w;r++)D+=y!=r?'<span class="'+x.sPageButton+'">'+r+"</span>":'<span class="'+x.sPageButtonActive+'">'+r+"</span>";w=g.aanFeatures.p;var z,C=function(){g._iDisplayStart=(this.innerHTML*1-1)*g._iDisplayLength;l(g);return false},L=function(){return false};r=0;for(s=w.length;r<s;r++)if(w[r].childNodes.length!==0){z=j("span:eq(2)",w[r]);z.html(D);j("span",z).click(C).bind("mousedown",L).bind("selectstart",L);z=w[r].getElementsByTagName("span");z=[z[0],z[1],z[z.length-2],z[z.length-1]];j(z).removeClass(x.sPageButton+
" "+x.sPageButtonActive+" "+x.sPageButtonStaticDisabled);if(y==1){z[0].className+=" "+x.sPageButtonStaticDisabled;z[1].className+=" "+x.sPageButtonStaticDisabled}else{z[0].className+=" "+x.sPageButton;z[1].className+=" "+x.sPageButton}if(v===0||y==v||g._iDisplayLength==-1){z[2].className+=" "+x.sPageButtonStaticDisabled;z[3].className+=" "+x.sPageButtonStaticDisabled}else{z[2].className+=" "+x.sPageButton;z[3].className+=" "+x.sPageButton}}}}}};n.oSort={"string-asc":function(g,l){g=g.toLowerCase();
l=l.toLowerCase();return g<l?-1:g>l?1:0},"string-desc":function(g,l){g=g.toLowerCase();l=l.toLowerCase();return g<l?1:g>l?-1:0},"html-asc":function(g,l){g=g.replace(/<.*?>/g,"").toLowerCase();l=l.replace(/<.*?>/g,"").toLowerCase();return g<l?-1:g>l?1:0},"html-desc":function(g,l){g=g.replace(/<.*?>/g,"").toLowerCase();l=l.replace(/<.*?>/g,"").toLowerCase();return g<l?1:g>l?-1:0},"date-asc":function(g,l){g=Date.parse(g);l=Date.parse(l);if(isNaN(g)||g==="")g=Date.parse("01/01/1970 00:00:00");if(isNaN(l)||
l==="")l=Date.parse("01/01/1970 00:00:00");return g-l},"date-desc":function(g,l){g=Date.parse(g);l=Date.parse(l);if(isNaN(g)||g==="")g=Date.parse("01/01/1970 00:00:00");if(isNaN(l)||l==="")l=Date.parse("01/01/1970 00:00:00");return l-g},"numeric-asc":function(g,l){return(g=="-"||g===""?0:g*1)-(l=="-"||l===""?0:l*1)},"numeric-desc":function(g,l){return(l=="-"||l===""?0:l*1)-(g=="-"||g===""?0:g*1)}};n.aTypes=[function(g){if(g.length===0)return"numeric";var l,r=false;l=g.charAt(0);if("0123456789-".indexOf(l)==
-1)return null;for(var s=1;s<g.length;s++){l=g.charAt(s);if("0123456789.".indexOf(l)==-1)return null;if(l=="."){if(r)return null;r=true}}return"numeric"},function(g){var l=Date.parse(g);if(l!==null&&!isNaN(l)||g.length===0)return"date";return null},function(g){if(g.indexOf("<")!=-1&&g.indexOf(">")!=-1)return"html";return null}];n.fnVersionCheck=function(g){var l=function(w,x){for(;w.length<x;)w+="0";return w},r=n.sVersion.split(".");g=g.split(".");for(var s="",v="",y=0,D=g.length;y<D;y++){s+=l(r[y],
3);v+=l(g[y],3)}return parseInt(s,10)>=parseInt(v,10)};n._oExternConfig={iNextUnique:0};j.fn.dataTable=function(g){function l(){this.fnRecordsTotal=function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsTotal,10):this.aiDisplayMaster.length};this.fnRecordsDisplay=function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsDisplay,10):this.aiDisplay.length};this.fnDisplayEnd=function(){return this.oFeatures.bServerSide?this.oFeatures.bPaginate===false||this._iDisplayLength==-1?
this._iDisplayStart+this.aiDisplay.length:Math.min(this._iDisplayStart+this._iDisplayLength,this._iRecordsDisplay):this._iDisplayEnd};this.sInstance=this.oInstance=null;this.oFeatures={bPaginate:true,bLengthChange:true,bFilter:true,bSort:true,bInfo:true,bAutoWidth:true,bProcessing:false,bSortClasses:true,bStateSave:false,bServerSide:false};this.oScroll={sX:"",sXInner:"",sY:"",bCollapse:false,bInfinite:false,iLoadGap:100,iBarWidth:0};this.aanFeatures=[];this.oLanguage={sProcessing:"Processing...",
sLengthMenu:"Show _MENU_ entries",sZeroRecords:"No matching records found",sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sSearch:"Search:",sUrl:"",oPaginate:{sFirst:"First",sPrevious:"Previous",sNext:"Next",sLast:"Last"},fnInfoCallback:null};this.aoData=[];this.aiDisplay=[];this.aiDisplayMaster=[];this.aoColumns=[];this.iNextId=0;this.asDataSearch=
[];this.oPreviousSearch={sSearch:"",bRegex:false,bSmart:true};this.aoPreSearchCols=[];this.aaSorting=[[0,"asc",0]];this.aaSortingFixed=null;this.asStripClasses=[];this.asDestoryStrips=[];this.sDestroyWidth=0;this.fnFooterCallback=this.fnHeaderCallback=this.fnRowCallback=null;this.aoDrawCallback=[];this.fnInitComplete=null;this.sTableId="";this.nTableWrapper=this.nTBody=this.nTFoot=this.nTHead=this.nTable=null;this.bInitialised=false;this.aoOpenRows=[];this.sDom="lfrtip";this.sPaginationType="two_button";
this.iCookieDuration=7200;this.sCookiePrefix="SpryMedia_DataTables_";this.fnCookieCallback=null;this.aoStateSave=[];this.aoStateLoad=[];this.sAjaxSource=this.oLoadedState=null;this.bAjaxDataGet=true;this.fnServerData=function(a,b,c){j.ajax({url:a,data:b,success:c,dataType:"json",cache:false,error:function(d,f){f=="parsererror"&&alert("DataTables warning: JSON data from server could not be parsed. This is caused by a JSON formatting error.")}})};this.fnFormatNumber=function(a){if(a<1E3)return a;else{var b=
a+"";a=b.split("");var c="";b=b.length;for(var d=0;d<b;d++){if(d%3===0&&d!==0)c=","+c;c=a[b-d-1]+c}}return c};this.aLengthMenu=[10,25,50,100];this.bDrawing=this.iDraw=0;this.iDrawError=-1;this._iDisplayLength=10;this._iDisplayStart=0;this._iDisplayEnd=10;this._iRecordsDisplay=this._iRecordsTotal=0;this.bJUI=false;this.oClasses=n.oStdClasses;this.bSorted=this.bFiltered=false;this.oInit=null}function r(a){return function(){var b=[B(this[n.iApiIndex])].concat(Array.prototype.slice.call(arguments));return n.oApi[a].apply(this,
b)}}function s(a){var b,c;if(a.bInitialised===false)setTimeout(function(){s(a)},200);else{pa(a);z(a);K(a,true);a.oFeatures.bAutoWidth&&Y(a);b=0;for(c=a.aoColumns.length;b<c;b++)if(a.aoColumns[b].sWidth!==null)a.aoColumns[b].nTh.style.width=u(a.aoColumns[b].sWidth);if(a.oFeatures.bSort)O(a);else{a.aiDisplay=a.aiDisplayMaster.slice();F(a);C(a)}if(a.sAjaxSource!==null&&!a.oFeatures.bServerSide)a.fnServerData.call(a.oInstance,a.sAjaxSource,[],function(d){for(b=0;b<d.aaData.length;b++)w(a,d.aaData[b]);
a.iInitDisplayStart=a._iDisplayStart;if(a.oFeatures.bSort)O(a);else{a.aiDisplay=a.aiDisplayMaster.slice();F(a);C(a)}K(a,false);typeof a.fnInitComplete=="function"&&a.fnInitComplete.call(a.oInstance,a,d)});else a.oFeatures.bServerSide||K(a,false)}}function v(a,b,c){o(a.oLanguage,b,"sProcessing");o(a.oLanguage,b,"sLengthMenu");o(a.oLanguage,b,"sEmptyTable");o(a.oLanguage,b,"sZeroRecords");o(a.oLanguage,b,"sInfo");o(a.oLanguage,b,"sInfoEmpty");o(a.oLanguage,b,"sInfoFiltered");o(a.oLanguage,b,"sInfoPostFix");
o(a.oLanguage,b,"sSearch");if(typeof b.oPaginate!="undefined"){o(a.oLanguage.oPaginate,b.oPaginate,"sFirst");o(a.oLanguage.oPaginate,b.oPaginate,"sPrevious");o(a.oLanguage.oPaginate,b.oPaginate,"sNext");o(a.oLanguage.oPaginate,b.oPaginate,"sLast")}typeof b.sEmptyTable=="undefined"&&typeof b.sZeroRecords!="undefined"&&o(a.oLanguage,b,"sZeroRecords","sEmptyTable");c&&s(a)}function y(a,b){a.aoColumns[a.aoColumns.length++]={sType:null,_bAutoType:true,bVisible:true,bSearchable:true,bSortable:true,asSorting:["asc",
"desc"],sSortingClass:a.oClasses.sSortable,sSortingClassJUI:a.oClasses.sSortJUI,sTitle:b?b.innerHTML:"",sName:"",sWidth:null,sWidthOrig:null,sClass:null,fnRender:null,bUseRendered:true,iDataSort:a.aoColumns.length-1,sSortDataType:"std",nTh:b?b:p.createElement("th"),nTf:null};b=a.aoColumns.length-1;if(typeof a.aoPreSearchCols[b]=="undefined"||a.aoPreSearchCols[b]===null)a.aoPreSearchCols[b]={sSearch:"",bRegex:false,bSmart:true};else{if(typeof a.aoPreSearchCols[b].bRegex=="undefined")a.aoPreSearchCols[b].bRegex=
true;if(typeof a.aoPreSearchCols[b].bSmart=="undefined")a.aoPreSearchCols[b].bSmart=true}D(a,b,null)}function D(a,b,c){b=a.aoColumns[b];if(typeof c!="undefined"&&c!==null){if(typeof c.sType!="undefined"){b.sType=c.sType;b._bAutoType=false}o(b,c,"bVisible");o(b,c,"bSearchable");o(b,c,"bSortable");o(b,c,"sTitle");o(b,c,"sName");o(b,c,"sWidth");o(b,c,"sWidth","sWidthOrig");o(b,c,"sClass");o(b,c,"fnRender");o(b,c,"bUseRendered");o(b,c,"iDataSort");o(b,c,"asSorting");o(b,c,"sSortDataType")}if(!a.oFeatures.bSort)b.bSortable=
false;if(!b.bSortable||j.inArray("asc",b.asSorting)==-1&&j.inArray("desc",b.asSorting)==-1){b.sSortingClass=a.oClasses.sSortableNone;b.sSortingClassJUI=""}else if(j.inArray("asc",b.asSorting)!=-1&&j.inArray("desc",b.asSorting)==-1){b.sSortingClass=a.oClasses.sSortableAsc;b.sSortingClassJUI=a.oClasses.sSortJUIAscAllowed}else if(j.inArray("asc",b.asSorting)==-1&&j.inArray("desc",b.asSorting)!=-1){b.sSortingClass=a.oClasses.sSortableDesc;b.sSortingClassJUI=a.oClasses.sSortJUIDescAllowed}}function w(a,
b){if(b.length!=a.aoColumns.length&&a.iDrawError!=a.iDraw){I(a,0,"Added data (size "+b.length+") does not match known number of columns ("+a.aoColumns.length+")");a.iDrawError=a.iDraw;return-1}b=b.slice();var c=a.aoData.length;a.aoData.push({nTr:p.createElement("tr"),_iId:a.iNextId++,_aData:b,_anHidden:[],_sRowStripe:""});for(var d,f,e=0;e<b.length;e++){d=p.createElement("td");if(b[e]===null)b[e]="";if(typeof a.aoColumns[e].fnRender=="function"){f=a.aoColumns[e].fnRender({iDataRow:c,iDataColumn:e,
aData:b,oSettings:a});d.innerHTML=f;if(a.aoColumns[e].bUseRendered)a.aoData[c]._aData[e]=f}else d.innerHTML=b[e];if(typeof b[e]!="string")b[e]+="";b[e]=j.trim(b[e]);if(a.aoColumns[e].sClass!==null)d.className=a.aoColumns[e].sClass;if(a.aoColumns[e]._bAutoType&&a.aoColumns[e].sType!="string"){f=Z(a.aoData[c]._aData[e]);if(a.aoColumns[e].sType===null)a.aoColumns[e].sType=f;else if(a.aoColumns[e].sType!=f)a.aoColumns[e].sType="string"}if(a.aoColumns[e].bVisible){a.aoData[c].nTr.appendChild(d);a.aoData[c]._anHidden[e]=
null}else a.aoData[c]._anHidden[e]=d}a.aiDisplayMaster.push(c);return c}function x(a){var b,c,d,f,e,i,h,k;if(a.sAjaxSource===null){h=a.nTBody.childNodes;b=0;for(c=h.length;b<c;b++)if(h[b].nodeName.toUpperCase()=="TR"){i=a.aoData.length;a.aoData.push({nTr:h[b],_iId:a.iNextId++,_aData:[],_anHidden:[],_sRowStripe:""});a.aiDisplayMaster.push(i);k=a.aoData[i]._aData;i=h[b].childNodes;d=e=0;for(f=i.length;d<f;d++)if(i[d].nodeName.toUpperCase()=="TD"){k[e]=j.trim(i[d].innerHTML);e++}}}h=R(a);i=[];b=0;for(c=
h.length;b<c;b++){d=0;for(f=h[b].childNodes.length;d<f;d++){e=h[b].childNodes[d];e.nodeName.toUpperCase()=="TD"&&i.push(e)}}i.length!=h.length*a.aoColumns.length&&I(a,1,"Unexpected number of TD elements. Expected "+h.length*a.aoColumns.length+" and got "+i.length+". DataTables does not support rowspan / colspan in the table body, and there must be one cell for each row/column combination.");h=0;for(d=a.aoColumns.length;h<d;h++){if(a.aoColumns[h].sTitle===null)a.aoColumns[h].sTitle=a.aoColumns[h].nTh.innerHTML;
f=a.aoColumns[h]._bAutoType;e=typeof a.aoColumns[h].fnRender=="function";k=a.aoColumns[h].sClass!==null;var m=a.aoColumns[h].bVisible,q,t;if(f||e||k||!m){b=0;for(c=a.aoData.length;b<c;b++){q=i[b*d+h];if(f)if(a.aoColumns[h].sType!="string"){t=Z(a.aoData[b]._aData[h]);if(a.aoColumns[h].sType===null)a.aoColumns[h].sType=t;else if(a.aoColumns[h].sType!=t)a.aoColumns[h].sType="string"}if(e){t=a.aoColumns[h].fnRender({iDataRow:b,iDataColumn:h,aData:a.aoData[b]._aData,oSettings:a});q.innerHTML=t;if(a.aoColumns[h].bUseRendered)a.aoData[b]._aData[h]=
t}if(k)q.className+=" "+a.aoColumns[h].sClass;if(m)a.aoData[b]._anHidden[h]=null;else{a.aoData[b]._anHidden[h]=q;q.parentNode.removeChild(q)}}}}}function z(a){var b,c,d,f=0;if(a.nTHead.getElementsByTagName("th").length!==0){b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;if(a.aoColumns[b].bVisible){if(a.aoColumns[b].sTitle!=c.innerHTML)c.innerHTML=a.aoColumns[b].sTitle}else{c.parentNode.removeChild(c);f++}}}else{f=p.createElement("tr");b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;
c.innerHTML=a.aoColumns[b].sTitle;if(a.aoColumns[b].bVisible){if(a.aoColumns[b].sClass!==null)c.className=a.aoColumns[b].sClass;f.appendChild(c)}}j(a.nTHead).html("")[0].appendChild(f)}if(a.bJUI){b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;f=p.createElement("div");f.className=a.oClasses.sSortJUIWrapper;j(c).contents().appendTo(f);f.appendChild(p.createElement("span"));c.appendChild(f)}}d=function(){this.onselectstart=function(){return false};return false};if(a.oFeatures.bSort)for(b=
0;b<a.aoColumns.length;b++)if(a.aoColumns[b].bSortable!==false){$(a,a.aoColumns[b].nTh,b);j(a.aoColumns[b].nTh).mousedown(d)}else j(a.aoColumns[b].nTh).addClass(a.oClasses.sSortableNone);if(a.nTFoot!==null){f=0;c=a.nTFoot.getElementsByTagName("th");b=0;for(d=c.length;b<d;b++)if(typeof a.aoColumns[b]!="undefined"){a.aoColumns[b].nTf=c[b-f];if(a.oClasses.sFooterTH!=="")a.aoColumns[b].nTf.className+=" "+a.oClasses.sFooterTH;if(!a.aoColumns[b].bVisible){c[b-f].parentNode.removeChild(c[b-f]);f++}}}}function C(a){var b,
c,d=[],f=0,e=false;b=a.asStripClasses.length;c=a.aoOpenRows.length;a.bDrawing=true;if(typeof a.iInitDisplayStart!="undefined"&&a.iInitDisplayStart!=-1){a._iDisplayStart=a.oFeatures.bServerSide?a.iInitDisplayStart:a.iInitDisplayStart>=a.fnRecordsDisplay()?0:a.iInitDisplayStart;a.iInitDisplayStart=-1;F(a)}if(!(a.oFeatures.bServerSide&&!qa(a))){a.oFeatures.bServerSide||a.iDraw++;if(a.aiDisplay.length!==0){var i=a._iDisplayStart,h=a._iDisplayEnd;if(a.oFeatures.bServerSide){i=0;h=a.aoData.length}for(i=
i;i<h;i++){var k=a.aoData[a.aiDisplay[i]],m=k.nTr;if(b!==0){var q=a.asStripClasses[f%b];if(k._sRowStripe!=q){j(m).removeClass(k._sRowStripe).addClass(q);k._sRowStripe=q}}if(typeof a.fnRowCallback=="function"){m=a.fnRowCallback.call(a.oInstance,m,a.aoData[a.aiDisplay[i]]._aData,f,i);if(!m&&!e){I(a,0,"A node was not returned by fnRowCallback");e=true}}d.push(m);f++;if(c!==0)for(k=0;k<c;k++)m==a.aoOpenRows[k].nParent&&d.push(a.aoOpenRows[k].nTr)}}else{d[0]=p.createElement("tr");if(typeof a.asStripClasses[0]!=
"undefined")d[0].className=a.asStripClasses[0];e=p.createElement("td");e.setAttribute("valign","top");e.colSpan=S(a);e.className=a.oClasses.sRowEmpty;e.innerHTML=typeof a.oLanguage.sEmptyTable!="undefined"&&a.fnRecordsTotal()===0?a.oLanguage.sEmptyTable:a.oLanguage.sZeroRecords.replace("_MAX_",a.fnFormatNumber(a.fnRecordsTotal()));d[f].appendChild(e)}typeof a.fnHeaderCallback=="function"&&a.fnHeaderCallback.call(a.oInstance,j(">tr",a.nTHead)[0],U(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay);
typeof a.fnFooterCallback=="function"&&a.fnFooterCallback.call(a.oInstance,j(">tr",a.nTFoot)[0],U(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay);f=p.createDocumentFragment();b=p.createDocumentFragment();if(a.nTBody){e=a.nTBody.parentNode;b.appendChild(a.nTBody);if(!a.oScroll.bInfinite||!a._bInitComplete||a.bSorted||a.bFiltered){c=a.nTBody.childNodes;for(b=c.length-1;b>=0;b--)c[b].parentNode.removeChild(c[b])}b=0;for(c=d.length;b<c;b++)f.appendChild(d[b]);a.nTBody.appendChild(f);e!==null&&e.appendChild(a.nTBody)}b=
0;for(c=a.aoDrawCallback.length;b<c;b++)a.aoDrawCallback[b].fn.call(a.oInstance,a);a.bSorted=false;a.bFiltered=false;a.bDrawing=false;if(typeof a._bInitComplete=="undefined"){a._bInitComplete=true;if(typeof a.fnInitComplete=="function"&&(a.oFeatures.bServerSide||a.sAjaxSource===null))a.fnInitComplete.call(a.oInstance,a)}}}function L(a){if(a.oFeatures.bSort)O(a,a.oPreviousSearch);else if(a.oFeatures.bFilter)P(a,a.oPreviousSearch);else{F(a);C(a)}}function qa(a){if(a.bAjaxDataGet){K(a,true);var b=a.aoColumns.length,
c=[],d;a.iDraw++;c.push({name:"sEcho",value:a.iDraw});c.push({name:"iColumns",value:b});c.push({name:"sColumns",value:aa(a)});c.push({name:"iDisplayStart",value:a._iDisplayStart});c.push({name:"iDisplayLength",value:a.oFeatures.bPaginate!==false?a._iDisplayLength:-1});var f=[];for(d=0;d<b;d++)f.push(a.aoColumns[d].sName);c.push({name:"sNames",value:f.join(",")});if(a.oFeatures.bFilter!==false){c.push({name:"sSearch",value:a.oPreviousSearch.sSearch});c.push({name:"bRegex",value:a.oPreviousSearch.bRegex});
for(d=0;d<b;d++){c.push({name:"sSearch_"+d,value:a.aoPreSearchCols[d].sSearch});c.push({name:"bRegex_"+d,value:a.aoPreSearchCols[d].bRegex});c.push({name:"bSearchable_"+d,value:a.aoColumns[d].bSearchable})}}if(a.oFeatures.bSort!==false){f=a.aaSortingFixed!==null?a.aaSortingFixed.length:0;var e=a.aaSorting.length;c.push({name:"iSortingCols",value:f+e});for(d=0;d<f;d++){c.push({name:"iSortCol_"+d,value:a.aaSortingFixed[d][0]});c.push({name:"sSortDir_"+d,value:a.aaSortingFixed[d][1]})}for(d=0;d<e;d++){c.push({name:"iSortCol_"+
(d+f),value:a.aaSorting[d][0]});c.push({name:"sSortDir_"+(d+f),value:a.aaSorting[d][1]})}for(d=0;d<b;d++)c.push({name:"bSortable_"+d,value:a.aoColumns[d].bSortable})}a.fnServerData.call(a.oInstance,a.sAjaxSource,c,function(i){ra(a,i)});return false}else return true}function ra(a,b){if(typeof b.sEcho!="undefined")if(b.sEcho*1<a.iDraw)return;else a.iDraw=b.sEcho*1;if(!a.oScroll.bInfinite||a.oScroll.bInfinite&&(a.bSorted||a.bFiltered))ba(a);a._iRecordsTotal=b.iTotalRecords;a._iRecordsDisplay=b.iTotalDisplayRecords;
var c=aa(a);if(c=typeof b.sColumns!="undefined"&&c!==""&&b.sColumns!=c)var d=sa(a,b.sColumns);for(var f=0,e=b.aaData.length;f<e;f++)if(c){for(var i=[],h=0,k=a.aoColumns.length;h<k;h++)i.push(b.aaData[f][d[h]]);w(a,i)}else w(a,b.aaData[f]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=false;C(a);a.bAjaxDataGet=true;K(a,false)}function pa(a){var b=p.createElement("div");a.nTable.parentNode.insertBefore(b,a.nTable);a.nTableWrapper=p.createElement("div");a.nTableWrapper.className=a.oClasses.sWrapper;
a.sTableId!==""&&a.nTableWrapper.setAttribute("id",a.sTableId+"_wrapper");for(var c=a.nTableWrapper,d=a.sDom.split(""),f,e,i,h,k,m,q,t=0;t<d.length;t++){e=0;i=d[t];if(i=="<"){h=p.createElement("div");k=d[t+1];if(k=="'"||k=='"'){m="";for(q=2;d[t+q]!=k;){m+=d[t+q];q++}if(m=="H")m="fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix";else if(m=="F")m="fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix";if(m.indexOf(".")!=-1){k=m.split(".");
h.setAttribute("id",k[0].substr(1,k[0].length-1));h.className=k[1]}else if(m.charAt(0)=="#")h.setAttribute("id",m.substr(1,m.length-1));else h.className=m;t+=q}c.appendChild(h);c=h}else if(i==">")c=c.parentNode;else if(i=="l"&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange){f=ta(a);e=1}else if(i=="f"&&a.oFeatures.bFilter){f=ua(a);e=1}else if(i=="r"&&a.oFeatures.bProcessing){f=va(a);e=1}else if(i=="t"){f=wa(a);e=1}else if(i=="i"&&a.oFeatures.bInfo){f=xa(a);e=1}else if(i=="p"&&a.oFeatures.bPaginate){f=
ya(a);e=1}else if(n.aoFeatures.length!==0){h=n.aoFeatures;q=0;for(k=h.length;q<k;q++)if(i==h[q].cFeature){if(f=h[q].fnInit(a))e=1;break}}if(e==1&&f!==null){if(typeof a.aanFeatures[i]!="object")a.aanFeatures[i]=[];a.aanFeatures[i].push(f);c.appendChild(f)}}b.parentNode.replaceChild(a.nTableWrapper,b)}function wa(a){if(a.oScroll.sX===""&&a.oScroll.sY==="")return a.nTable;var b=p.createElement("div"),c=p.createElement("div"),d=p.createElement("div"),f=p.createElement("div"),e=p.createElement("div"),
i=p.createElement("div"),h=a.nTable.cloneNode(false),k=a.nTable.cloneNode(false),m=a.nTable.getElementsByTagName("thead")[0],q=a.nTable.getElementsByTagName("tfoot").length===0?null:a.nTable.getElementsByTagName("tfoot")[0],t=typeof g.bJQueryUI!="undefined"&&g.bJQueryUI?n.oJUIClasses:n.oStdClasses;c.appendChild(d);e.appendChild(i);f.appendChild(a.nTable);b.appendChild(c);b.appendChild(f);d.appendChild(h);h.appendChild(m);if(q!==null){b.appendChild(e);i.appendChild(k);k.appendChild(q)}b.className=
t.sScrollWrapper;c.className=t.sScrollHead;d.className=t.sScrollHeadInner;f.className=t.sScrollBody;e.className=t.sScrollFoot;i.className=t.sScrollFootInner;c.style.overflow="hidden";c.style.position="relative";e.style.overflow="hidden";f.style.overflow="auto";c.style.border="0";e.style.border="0";d.style.width="150%";h.removeAttribute("id");h.style.marginLeft="0";a.nTable.style.marginLeft="0";if(q!==null){k.removeAttribute("id");k.style.marginLeft="0"}d=j(">caption",a.nTable);i=0;for(k=d.length;i<
k;i++)h.appendChild(d[i]);if(a.oScroll.sX!==""){c.style.width=u(a.oScroll.sX);f.style.width=u(a.oScroll.sX);if(q!==null)e.style.width=u(a.oScroll.sX);j(f).scroll(function(){c.scrollLeft=this.scrollLeft;if(q!==null)e.scrollLeft=this.scrollLeft})}if(a.oScroll.sY!=="")f.style.height=u(a.oScroll.sY);a.aoDrawCallback.push({fn:za,sName:"scrolling"});a.oScroll.bInfinite&&j(f).scroll(function(){if(!a.bDrawing)if(j(this).scrollTop()+j(this).height()>j(a.nTable).height()-a.oScroll.iLoadGap)if(a.fnDisplayEnd()<
a.fnRecordsDisplay()){ca(a,"next");F(a);C(a)}});a.nScrollHead=c;a.nScrollFoot=e;return b}function za(a){var b=a.nScrollHead.getElementsByTagName("div")[0],c=b.getElementsByTagName("table")[0],d=a.nTable.parentNode,f,e,i,h,k,m,q,t,H=[];i=a.nTable.getElementsByTagName("thead");i.length>0&&a.nTable.removeChild(i[0]);if(a.nTFoot!==null){k=a.nTable.getElementsByTagName("tfoot");k.length>0&&a.nTable.removeChild(k[0])}i=a.nTHead.cloneNode(true);a.nTable.insertBefore(i,a.nTable.childNodes[0]);if(a.nTFoot!==
null){k=a.nTFoot.cloneNode(true);a.nTable.insertBefore(k,a.nTable.childNodes[1])}var J=da(i);f=0;for(e=J.length;f<e;f++){q=ea(a,f);J[f].style.width=a.aoColumns[q].sWidth}a.nTFoot!==null&&M(function(A){A.style.width=""},k.getElementsByTagName("tr"));f=j(a.nTable).outerWidth();if(a.oScroll.sX===""){a.nTable.style.width="100%";if(j.browser.msie&&j.browser.version<=7)a.nTable.style.width=u(j(a.nTable).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sXInner!=="")a.nTable.style.width=u(a.oScroll.sXInner);
else if(f==j(d).width()&&j(d).height()<j(a.nTable).height()){a.nTable.style.width=u(f-a.oScroll.iBarWidth);if(j(a.nTable).outerWidth()>f-a.oScroll.iBarWidth)a.nTable.style.width=u(f)}else a.nTable.style.width=u(f);f=j(a.nTable).outerWidth();e=a.nTHead.getElementsByTagName("tr");i=i.getElementsByTagName("tr");M(function(A,G){m=A.style;m.paddingTop="0";m.paddingBottom="0";m.borderTopWidth="0";m.borderBottomWidth="0";m.height=0;t=j(A).width();G.style.width=u(t);H.push(t)},i,e);j(i).height(0);if(a.nTFoot!==
null){h=k.getElementsByTagName("tr");k=a.nTFoot.getElementsByTagName("tr");M(function(A,G){m=A.style;m.paddingTop="0";m.paddingBottom="0";m.borderTopWidth="0";m.borderBottomWidth="0";t=j(A).width();G.style.width=u(t);H.push(t)},h,k);j(h).height(0)}M(function(A){A.innerHTML="";A.style.width=u(H.shift())},i);a.nTFoot!==null&&M(function(A){A.innerHTML="";A.style.width=u(H.shift())},h);if(j(a.nTable).outerWidth()<f)if(a.oScroll.sX==="")I(a,1,"The table cannot fit into the current element which will cause column misalignment. It is suggested that you enable x-scrolling or increase the width the table has in which to be drawn");
else a.oScroll.sXInner!==""&&I(a,1,"The table cannot fit into the current element which will cause column misalignment. It is suggested that you increase the sScrollXInner property to allow it to draw in a larger area, or simply remove that parameter to allow automatic calculation");if(a.oScroll.sY==="")if(j.browser.msie&&j.browser.version<=7)d.style.height=u(a.nTable.offsetHeight+a.oScroll.iBarWidth);if(a.oScroll.sY!==""&&a.oScroll.bCollapse){d.style.height=u(a.oScroll.sY);h=a.oScroll.sX!==""&&a.nTable.offsetWidth>
d.offsetWidth?a.oScroll.iBarWidth:0;if(a.nTable.offsetHeight<d.offsetHeight)d.style.height=u(j(a.nTable).height()+h)}h=j(a.nTable).outerWidth();c.style.width=u(h);b.style.width=u(h+a.oScroll.iBarWidth);b.parentNode.style.width=u(j(d).width());if(a.nTFoot!==null){b=a.nScrollFoot.getElementsByTagName("div")[0];c=b.getElementsByTagName("table")[0];b.style.width=u(a.nTable.offsetWidth+a.oScroll.iBarWidth);c.style.width=u(a.nTable.offsetWidth)}if(a.bSorted||a.bFiltered)d.scrollTop=0}function V(a){if(a.oFeatures.bAutoWidth===
false)return false;Y(a);for(var b=0,c=a.aoColumns.length;b<c;b++)a.aoColumns[b].nTh.style.width=a.aoColumns[b].sWidth}function ua(a){var b=p.createElement("div");a.sTableId!==""&&typeof a.aanFeatures.f=="undefined"&&b.setAttribute("id",a.sTableId+"_filter");b.className=a.oClasses.sFilter;b.innerHTML=a.oLanguage.sSearch+(a.oLanguage.sSearch===""?"":" ")+'<input type="text" />';var c=j("input",b);c.val(a.oPreviousSearch.sSearch.replace('"',"&quot;"));c.keyup(function(){for(var d=a.aanFeatures.f,f=0,
e=d.length;f<e;f++)d[f]!=this.parentNode&&j("input",d[f]).val(this.value);this.value!=a.oPreviousSearch.sSearch&&P(a,{sSearch:this.value,bRegex:a.oPreviousSearch.bRegex,bSmart:a.oPreviousSearch.bSmart})});c.keypress(function(d){if(d.keyCode==13)return false});return b}function P(a,b,c){Aa(a,b.sSearch,c,b.bRegex,b.bSmart);for(b=0;b<a.aoPreSearchCols.length;b++)Ba(a,a.aoPreSearchCols[b].sSearch,b,a.aoPreSearchCols[b].bRegex,a.aoPreSearchCols[b].bSmart);n.afnFiltering.length!==0&&Ca(a);a.bFiltered=true;
a._iDisplayStart=0;F(a);C(a);fa(a,0)}function Ca(a){for(var b=n.afnFiltering,c=0,d=b.length;c<d;c++)for(var f=0,e=0,i=a.aiDisplay.length;e<i;e++){var h=a.aiDisplay[e-f];if(!b[c](a,a.aoData[h]._aData,h)){a.aiDisplay.splice(e-f,1);f++}}}function Ba(a,b,c,d,f){if(b!==""){var e=0;b=ga(b,d,f);for(d=a.aiDisplay.length-1;d>=0;d--){f=ha(a.aoData[a.aiDisplay[d]]._aData[c],a.aoColumns[c].sType);if(!b.test(f)){a.aiDisplay.splice(d,1);e++}}}}function Aa(a,b,c,d,f){var e=ga(b,d,f);if(typeof c=="undefined"||c===
null)c=0;if(n.afnFiltering.length!==0)c=1;if(b.length<=0){a.aiDisplay.splice(0,a.aiDisplay.length);a.aiDisplay=a.aiDisplayMaster.slice()}else if(a.aiDisplay.length==a.aiDisplayMaster.length||a.oPreviousSearch.sSearch.length>b.length||c==1||b.indexOf(a.oPreviousSearch.sSearch)!==0){a.aiDisplay.splice(0,a.aiDisplay.length);fa(a,1);for(c=0;c<a.aiDisplayMaster.length;c++)e.test(a.asDataSearch[c])&&a.aiDisplay.push(a.aiDisplayMaster[c])}else{var i=0;for(c=0;c<a.asDataSearch.length;c++)if(!e.test(a.asDataSearch[c])){a.aiDisplay.splice(c-
i,1);i++}}a.oPreviousSearch.sSearch=b;a.oPreviousSearch.bRegex=d;a.oPreviousSearch.bSmart=f}function fa(a,b){a.asDataSearch.splice(0,a.asDataSearch.length);b=typeof b!="undefined"&&b==1?a.aiDisplayMaster:a.aiDisplay;for(var c=0,d=b.length;c<d;c++)a.asDataSearch[c]=ia(a,a.aoData[b[c]]._aData)}function ia(a,b){for(var c="",d=p.createElement("div"),f=0,e=a.aoColumns.length;f<e;f++)if(a.aoColumns[f].bSearchable)c+=ha(b[f],a.aoColumns[f].sType)+"  ";if(c.indexOf("&")!==-1){d.innerHTML=c;c=d.textContent?
d.textContent:d.innerText;c=c.replace(/\n/g," ").replace(/\r/g,"")}return c}function ga(a,b,c){if(c){a=b?a.split(" "):ja(a).split(" ");a="^(?=.*?"+a.join(")(?=.*?")+").*$";return new RegExp(a,"i")}else{a=b?a:ja(a);return new RegExp(a,"i")}}function ha(a,b){if(typeof n.ofnSearch[b]=="function")return n.ofnSearch[b](a);else if(b=="html")return a.replace(/\n/g," ").replace(/<.*?>/g,"");else if(typeof a=="string")return a.replace(/\n/g," ");return a}function O(a,b){var c=[],d=n.oSort,f=a.aoData,e,i,h,
k;if(!a.oFeatures.bServerSide&&(a.aaSorting.length!==0||a.aaSortingFixed!==null)){c=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(h=0;h<c.length;h++){e=c[h][0];i=N(a,e);k=a.aoColumns[e].sSortDataType;if(typeof n.afnSortData[k]!="undefined"){var m=n.afnSortData[k](a,e,i);i=0;for(k=f.length;i<k;i++)f[i]._aData[e]=m[i]}}if(X.runtime){var q=[],t=c.length;for(h=0;h<t;h++){e=a.aoColumns[c[h][0]].iDataSort;q.push([e,a.aoColumns[e].sType+"-"+c[h][1]])}a.aiDisplayMaster.sort(function(H,
J){for(var A,G=0;G<t;G++){A=d[q[G][1]](f[H]._aData[q[G][0]],f[J]._aData[q[G][0]]);if(A!==0)return A}return 0})}else{this.ClosureDataTables={fn:function(){},data:f,sort:n.oSort,master:a.aiDisplayMaster.slice()};k="this.ClosureDataTables.fn = function(a,b){var iTest, oSort=this.ClosureDataTables.sort, aoData=this.ClosureDataTables.data, aiOrig=this.ClosureDataTables.master;";for(h=0;h<c.length-1;h++){e=a.aoColumns[c[h][0]].iDataSort;i=a.aoColumns[e].sType;k+="iTest = oSort['"+i+"-"+c[h][1]+"']( aoData[a]._aData["+
e+"], aoData[b]._aData["+e+"] ); if ( iTest === 0 )"}if(c.length>0){e=a.aoColumns[c[c.length-1][0]].iDataSort;i=a.aoColumns[e].sType;k+="iTest = oSort['"+i+"-"+c[c.length-1][1]+"']( aoData[a]._aData["+e+"], aoData[b]._aData["+e+"] );if (iTest===0) return oSort['numeric-asc'](jQuery.inArray(a,aiOrig), jQuery.inArray(b,aiOrig)); return iTest;}";eval(k);a.aiDisplayMaster.sort(this.ClosureDataTables.fn)}this.ClosureDataTables=undefined}}if(typeof b=="undefined"||b)T(a);a.bSorted=true;if(a.oFeatures.bFilter)P(a,
a.oPreviousSearch,1);else{a.aiDisplay=a.aiDisplayMaster.slice();a._iDisplayStart=0;F(a);C(a)}}function $(a,b,c,d){j(b).click(function(f){if(a.aoColumns[c].bSortable!==false){var e=function(){var i,h;if(f.shiftKey){for(var k=false,m=0;m<a.aaSorting.length;m++)if(a.aaSorting[m][0]==c){k=true;i=a.aaSorting[m][0];h=a.aaSorting[m][2]+1;if(typeof a.aoColumns[i].asSorting[h]=="undefined")a.aaSorting.splice(m,1);else{a.aaSorting[m][1]=a.aoColumns[i].asSorting[h];a.aaSorting[m][2]=h}break}k===false&&a.aaSorting.push([c,
a.aoColumns[c].asSorting[0],0])}else if(a.aaSorting.length==1&&a.aaSorting[0][0]==c){i=a.aaSorting[0][0];h=a.aaSorting[0][2]+1;if(typeof a.aoColumns[i].asSorting[h]=="undefined")h=0;a.aaSorting[0][1]=a.aoColumns[i].asSorting[h];a.aaSorting[0][2]=h}else{a.aaSorting.splice(0,a.aaSorting.length);a.aaSorting.push([c,a.aoColumns[c].asSorting[0],0])}O(a)};if(a.oFeatures.bProcessing){K(a,true);setTimeout(function(){e();a.oFeatures.bServerSide||K(a,false)},0)}else e();typeof d=="function"&&d(a)}})}function T(a){var b,
c,d,f,e,i=a.aoColumns.length,h=a.oClasses;for(b=0;b<i;b++)a.aoColumns[b].bSortable&&j(a.aoColumns[b].nTh).removeClass(h.sSortAsc+" "+h.sSortDesc+" "+a.aoColumns[b].sSortingClass);f=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(b=0;b<a.aoColumns.length;b++)if(a.aoColumns[b].bSortable){e=a.aoColumns[b].sSortingClass;d=-1;for(c=0;c<f.length;c++)if(f[c][0]==b){e=f[c][1]=="asc"?h.sSortAsc:h.sSortDesc;d=c;break}j(a.aoColumns[b].nTh).addClass(e);if(a.bJUI){c=j("span",
a.aoColumns[b].nTh);c.removeClass(h.sSortJUIAsc+" "+h.sSortJUIDesc+" "+h.sSortJUI+" "+h.sSortJUIAscAllowed+" "+h.sSortJUIDescAllowed);c.addClass(d==-1?a.aoColumns[b].sSortingClassJUI:f[d][1]=="asc"?h.sSortJUIAsc:h.sSortJUIDesc)}}else j(a.aoColumns[b].nTh).addClass(a.aoColumns[b].sSortingClass);e=h.sSortColumn;if(a.oFeatures.bSort&&a.oFeatures.bSortClasses){d=W(a);if(d.length>=i)for(b=0;b<i;b++)if(d[b].className.indexOf(e+"1")!=-1){c=0;for(a=d.length/i;c<a;c++)d[i*c+b].className=j.trim(d[i*c+b].className.replace(e+
"1",""))}else if(d[b].className.indexOf(e+"2")!=-1){c=0;for(a=d.length/i;c<a;c++)d[i*c+b].className=j.trim(d[i*c+b].className.replace(e+"2",""))}else if(d[b].className.indexOf(e+"3")!=-1){c=0;for(a=d.length/i;c<a;c++)d[i*c+b].className=j.trim(d[i*c+b].className.replace(" "+e+"3",""))}h=1;var k;for(b=0;b<f.length;b++){k=parseInt(f[b][0],10);c=0;for(a=d.length/i;c<a;c++)d[i*c+k].className+=" "+e+h;h<3&&h++}}}function ya(a){if(a.oScroll.bInfinite)return null;var b=p.createElement("div");b.className=
a.oClasses.sPaging+a.sPaginationType;n.oPagination[a.sPaginationType].fnInit(a,b,function(c){F(c);C(c)});typeof a.aanFeatures.p=="undefined"&&a.aoDrawCallback.push({fn:function(c){n.oPagination[c.sPaginationType].fnUpdate(c,function(d){F(d);C(d)})},sName:"pagination"});return b}function ca(a,b){var c=a._iDisplayStart;if(b=="first")a._iDisplayStart=0;else if(b=="previous"){a._iDisplayStart=a._iDisplayLength>=0?a._iDisplayStart-a._iDisplayLength:0;if(a._iDisplayStart<0)a._iDisplayStart=0}else if(b==
"next")if(a._iDisplayLength>=0){if(a._iDisplayStart+a._iDisplayLength<a.fnRecordsDisplay())a._iDisplayStart+=a._iDisplayLength}else a._iDisplayStart=0;else if(b=="last")if(a._iDisplayLength>=0){b=parseInt((a.fnRecordsDisplay()-1)/a._iDisplayLength,10)+1;a._iDisplayStart=(b-1)*a._iDisplayLength}else a._iDisplayStart=0;else I(a,0,"Unknown paging action: "+b);return c!=a._iDisplayStart}function xa(a){var b=p.createElement("div");b.className=a.oClasses.sInfo;if(typeof a.aanFeatures.i=="undefined"){a.aoDrawCallback.push({fn:Da,
sName:"information"});a.sTableId!==""&&b.setAttribute("id",a.sTableId+"_info")}return b}function Da(a){if(!(!a.oFeatures.bInfo||a.aanFeatures.i.length===0)){var b=a._iDisplayStart+1,c=a.fnDisplayEnd(),d=a.fnRecordsTotal(),f=a.fnRecordsDisplay(),e=a.fnFormatNumber(b),i=a.fnFormatNumber(c),h=a.fnFormatNumber(d),k=a.fnFormatNumber(f);if(a.oScroll.bInfinite)e=a.fnFormatNumber(1);e=a.fnRecordsDisplay()===0&&a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfoEmpty+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()===
0?a.oLanguage.sInfoEmpty+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",h)+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfo.replace("_START_",e).replace("_END_",i).replace("_TOTAL_",k)+a.oLanguage.sInfoPostFix:a.oLanguage.sInfo.replace("_START_",e).replace("_END_",i).replace("_TOTAL_",k)+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",a.fnFormatNumber(a.fnRecordsTotal()))+a.oLanguage.sInfoPostFix;if(a.oLanguage.fnInfoCallback!==null)e=a.oLanguage.fnInfoCallback(a,b,
c,d,f,e);a=a.aanFeatures.i;b=0;for(c=a.length;b<c;b++)j(a[b]).html(e)}}function ta(a){if(a.oScroll.bInfinite)return null;var b='<select size="1" '+(a.sTableId===""?"":'name="'+a.sTableId+'_length"')+">",c,d;if(a.aLengthMenu.length==2&&typeof a.aLengthMenu[0]=="object"&&typeof a.aLengthMenu[1]=="object"){c=0;for(d=a.aLengthMenu[0].length;c<d;c++)b+='<option value="'+a.aLengthMenu[0][c]+'">'+a.aLengthMenu[1][c]+"</option>"}else{c=0;for(d=a.aLengthMenu.length;c<d;c++)b+='<option value="'+a.aLengthMenu[c]+
'">'+a.aLengthMenu[c]+"</option>"}b+="</select>";var f=p.createElement("div");a.sTableId!==""&&typeof a.aanFeatures.l=="undefined"&&f.setAttribute("id",a.sTableId+"_length");f.className=a.oClasses.sLength;f.innerHTML=a.oLanguage.sLengthMenu.replace("_MENU_",b);j('select option[value="'+a._iDisplayLength+'"]',f).attr("selected",true);j("select",f).change(function(){var e=j(this).val(),i=a.aanFeatures.l;c=0;for(d=i.length;c<d;c++)i[c]!=this.parentNode&&j("select",i[c]).val(e);a._iDisplayLength=parseInt(e,
10);F(a);if(a.fnDisplayEnd()==a.fnRecordsDisplay()){a._iDisplayStart=a.fnDisplayEnd()-a._iDisplayLength;if(a._iDisplayStart<0)a._iDisplayStart=0}if(a._iDisplayLength==-1)a._iDisplayStart=0;C(a)});return f}function va(a){var b=p.createElement("div");a.sTableId!==""&&typeof a.aanFeatures.r=="undefined"&&b.setAttribute("id",a.sTableId+"_processing");b.innerHTML=a.oLanguage.sProcessing;b.className=a.oClasses.sProcessing;a.nTable.parentNode.insertBefore(b,a.nTable);return b}function K(a,b){if(a.oFeatures.bProcessing){a=
a.aanFeatures.r;for(var c=0,d=a.length;c<d;c++)a[c].style.visibility=b?"visible":"hidden"}}function ea(a,b){for(var c=-1,d=0;d<a.aoColumns.length;d++){a.aoColumns[d].bVisible===true&&c++;if(c==b)return d}return null}function N(a,b){for(var c=-1,d=0;d<a.aoColumns.length;d++){a.aoColumns[d].bVisible===true&&c++;if(d==b)return a.aoColumns[d].bVisible===true?c:null}return null}function Q(a,b){var c,d;c=a._iDisplayStart;for(d=a._iDisplayEnd;c<d;c++)if(a.aoData[a.aiDisplay[c]].nTr==b)return a.aiDisplay[c];
c=0;for(d=a.aoData.length;c<d;c++)if(a.aoData[c].nTr==b)return c;return null}function S(a){for(var b=0,c=0;c<a.aoColumns.length;c++)a.aoColumns[c].bVisible===true&&b++;return b}function F(a){a._iDisplayEnd=a.oFeatures.bPaginate===false?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength>a.aiDisplay.length||a._iDisplayLength==-1?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function Ea(a,b){if(!a||a===null||a==="")return 0;if(typeof b=="undefined")b=p.getElementsByTagName("body")[0];var c=
p.createElement("div");c.style.width=a;b.appendChild(c);a=c.offsetWidth;b.removeChild(c);return a}function Y(a){var b=0,c,d=0,f=a.aoColumns.length,e,i=j("th",a.nTHead);for(e=0;e<f;e++)if(a.aoColumns[e].bVisible){d++;if(a.aoColumns[e].sWidth!==null){c=Ea(a.aoColumns[e].sWidthOrig,a.nTable.parentNode);if(c!==null)a.aoColumns[e].sWidth=u(c);b++}}if(f==i.length&&b===0&&d==f&&a.oScroll.sX===""&&a.oScroll.sY==="")for(e=0;e<a.aoColumns.length;e++){c=j(i[e]).width();if(c!==null)a.aoColumns[e].sWidth=u(c)}else{b=
a.nTable.cloneNode(false);e=p.createElement("tbody");c=p.createElement("tr");b.removeAttribute("id");b.appendChild(a.nTHead.cloneNode(true));if(a.nTFoot!==null){b.appendChild(a.nTFoot.cloneNode(true));M(function(h){h.style.width=""},b.getElementsByTagName("tr"))}b.appendChild(e);e.appendChild(c);e=j("thead th",b);if(e.length===0)e=j("tbody tr:eq(0)>td",b);e.each(function(h){this.style.width="";h=ea(a,h);if(h!==null&&a.aoColumns[h].sWidthOrig!=="")this.style.width=a.aoColumns[h].sWidthOrig});for(e=
0;e<f;e++)if(a.aoColumns[e].bVisible){d=Fa(a,e);if(d!==null){d=d.cloneNode(true);c.appendChild(d)}}e=a.nTable.parentNode;e.appendChild(b);if(a.oScroll.sX!==""&&a.oScroll.sXInner!=="")b.style.width=u(a.oScroll.sXInner);else if(a.oScroll.sX!==""){b.style.width="";if(j(b).width()<e.offsetWidth)b.style.width=u(e.offsetWidth)}else if(a.oScroll.sY!=="")b.style.width=u(e.offsetWidth);b.style.visibility="hidden";Ga(a,b);f=j("tbody tr:eq(0)>td",b);if(f.length===0)f=j("thead tr:eq(0)>th",b);for(e=c=0;e<a.aoColumns.length;e++)if(a.aoColumns[e].bVisible){d=
j(f[c]).width();if(d!==null&&d>0)a.aoColumns[e].sWidth=u(d);c++}a.nTable.style.width=u(j(b).outerWidth());b.parentNode.removeChild(b)}}function Ga(a,b){if(a.oScroll.sX===""&&a.oScroll.sY!==""){j(b).width();b.style.width=u(j(b).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sX!=="")b.style.width=u(j(b).outerWidth())}function Fa(a,b,c){if(typeof c=="undefined"||c){c=Ha(a,b);b=N(a,b);if(c<0)return null;return a.aoData[c].nTr.getElementsByTagName("td")[b]}var d=-1,f,e;c=-1;var i=p.createElement("div");
i.style.visibility="hidden";i.style.position="absolute";p.body.appendChild(i);f=0;for(e=a.aoData.length;f<e;f++){i.innerHTML=a.aoData[f]._aData[b];if(i.offsetWidth>d){d=i.offsetWidth;c=f}}p.body.removeChild(i);if(c>=0){b=N(a,b);if(a=a.aoData[c].nTr.getElementsByTagName("td")[b])return a}return null}function Ha(a,b){for(var c=-1,d=-1,f=0;f<a.aoData.length;f++){var e=a.aoData[f]._aData[b];if(e.length>c){c=e.length;d=f}}return d}function u(a){if(a===null)return"0px";if(typeof a=="number"){if(a<0)return"0px";
return a+"px"}var b=a.charCodeAt(a.length-1);if(b<48||b>57)return a;return a+"px"}function Ma(a,b){if(a.length!=b.length)return 1;for(var c=0;c<a.length;c++)if(a[c]!=b[c])return 2;return 0}function Z(a){for(var b=n.aTypes,c=b.length,d=0;d<c;d++){var f=b[d](a);if(f!==null)return f}return"string"}function B(a){for(var b=0;b<E.length;b++)if(E[b].nTable==a)return E[b];return null}function U(a){for(var b=[],c=a.aoData.length,d=0;d<c;d++)b.push(a.aoData[d]._aData);return b}function R(a){for(var b=[],c=
a.aoData.length,d=0;d<c;d++)b.push(a.aoData[d].nTr);return b}function W(a){var b=R(a),c=[],d,f=[],e,i,h,k;e=0;for(i=b.length;e<i;e++){c=[];h=0;for(k=b[e].childNodes.length;h<k;h++){d=b[e].childNodes[h];d.nodeName.toUpperCase()=="TD"&&c.push(d)}h=d=0;for(k=a.aoColumns.length;h<k;h++)if(a.aoColumns[h].bVisible)f.push(c[h-d]);else{f.push(a.aoData[e]._anHidden[h]);d++}}return f}function ja(a){return a.replace(new RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^)","g"),"\\$1")}function ka(a,
b){for(var c=-1,d=0,f=a.length;d<f;d++)if(a[d]==b)c=d;else a[d]>b&&a[d]--;c!=-1&&a.splice(c,1)}function sa(a,b){b=b.split(",");for(var c=[],d=0,f=a.aoColumns.length;d<f;d++)for(var e=0;e<f;e++)if(a.aoColumns[d].sName==b[e]){c.push(e);break}return c}function aa(a){for(var b="",c=0,d=a.aoColumns.length;c<d;c++)b+=a.aoColumns[c].sName+",";if(b.length==d)return"";return b.slice(0,-1)}function I(a,b,c){a=a.sTableId===""?"DataTables warning: "+c:"DataTables warning (table id = '"+a.sTableId+"'): "+c;if(b===
0)if(n.sErrMode=="alert")alert(a);else throw a;else typeof console!="undefined"&&typeof console.log!="undefined"&&console.log(a)}function ba(a){a.aoData.splice(0,a.aoData.length);a.aiDisplayMaster.splice(0,a.aiDisplayMaster.length);a.aiDisplay.splice(0,a.aiDisplay.length);F(a)}function la(a){if(!(!a.oFeatures.bStateSave||typeof a.bDestroying!="undefined")){var b,c,d,f="{";f+='"iCreate":'+(new Date).getTime()+",";f+='"iStart":'+a._iDisplayStart+",";f+='"iEnd":'+a._iDisplayEnd+",";f+='"iLength":'+a._iDisplayLength+
",";f+='"sFilter":"'+encodeURIComponent(a.oPreviousSearch.sSearch)+'",';f+='"sFilterEsc":'+!a.oPreviousSearch.bRegex+",";f+='"aaSorting":[ ';for(b=0;b<a.aaSorting.length;b++)f+="["+a.aaSorting[b][0]+',"'+a.aaSorting[b][1]+'"],';f=f.substring(0,f.length-1);f+="],";f+='"aaSearchCols":[ ';for(b=0;b<a.aoPreSearchCols.length;b++)f+='["'+encodeURIComponent(a.aoPreSearchCols[b].sSearch)+'",'+!a.aoPreSearchCols[b].bRegex+"],";f=f.substring(0,f.length-1);f+="],";f+='"abVisCols":[ ';for(b=0;b<a.aoColumns.length;b++)f+=
a.aoColumns[b].bVisible+",";f=f.substring(0,f.length-1);f+="]";b=0;for(c=a.aoStateSave.length;b<c;b++){d=a.aoStateSave[b].fn(a,f);if(d!=="")f=d}f+="}";Ia(a.sCookiePrefix+a.sInstance,f,a.iCookieDuration,a.sCookiePrefix,a.fnCookieCallback)}}function Ja(a,b){if(a.oFeatures.bStateSave){var c,d,f;d=ma(a.sCookiePrefix+a.sInstance);if(d!==null&&d!==""){try{c=typeof j.parseJSON=="function"?j.parseJSON(d.replace(/'/g,'"')):eval("("+d+")")}catch(e){return}d=0;for(f=a.aoStateLoad.length;d<f;d++)if(!a.aoStateLoad[d].fn(a,
c))return;a.oLoadedState=j.extend(true,{},c);a._iDisplayStart=c.iStart;a.iInitDisplayStart=c.iStart;a._iDisplayEnd=c.iEnd;a._iDisplayLength=c.iLength;a.oPreviousSearch.sSearch=decodeURIComponent(c.sFilter);a.aaSorting=c.aaSorting.slice();a.saved_aaSorting=c.aaSorting.slice();if(typeof c.sFilterEsc!="undefined")a.oPreviousSearch.bRegex=!c.sFilterEsc;if(typeof c.aaSearchCols!="undefined")for(d=0;d<c.aaSearchCols.length;d++)a.aoPreSearchCols[d]={sSearch:decodeURIComponent(c.aaSearchCols[d][0]),bRegex:!c.aaSearchCols[d][1]};
if(typeof c.abVisCols!="undefined"){b.saved_aoColumns=[];for(d=0;d<c.abVisCols.length;d++){b.saved_aoColumns[d]={};b.saved_aoColumns[d].bVisible=c.abVisCols[d]}}}}}function Ia(a,b,c,d,f){var e=new Date;e.setTime(e.getTime()+c*1E3);c=X.location.pathname.split("/");a=a+"_"+c.pop().replace(/[\/:]/g,"").toLowerCase();var i;if(f!==null){i=typeof j.parseJSON=="function"?j.parseJSON(b):eval("("+b+")");b=f(a,i,e.toGMTString(),c.join("/")+"/")}else b=a+"="+encodeURIComponent(b)+"; expires="+e.toGMTString()+
"; path="+c.join("/")+"/";f="";e=9999999999999;if((ma(a)!==null?p.cookie.length:b.length+p.cookie.length)+10>4096){a=p.cookie.split(";");for(var h=0,k=a.length;h<k;h++)if(a[h].indexOf(d)!=-1){var m=a[h].split("=");try{i=eval("("+decodeURIComponent(m[1])+")")}catch(q){continue}if(typeof i.iCreate!="undefined"&&i.iCreate<e){f=m[0];e=i.iCreate}}if(f!=="")p.cookie=f+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+c.join("/")+"/"}p.cookie=b}function ma(a){var b=X.location.pathname.split("/");a=a+"_"+
b[b.length-1].replace(/[\/:]/g,"").toLowerCase()+"=";b=p.cookie.split(";");for(var c=0;c<b.length;c++){for(var d=b[c];d.charAt(0)==" ";)d=d.substring(1,d.length);if(d.indexOf(a)===0)return decodeURIComponent(d.substring(a.length,d.length))}return null}function da(a){a=a.getElementsByTagName("tr");if(a.length==1)return a[0].getElementsByTagName("th");var b=[],c=[],d,f,e,i,h,k,m=function(G,Na,na){for(;typeof G[Na][na]!="undefined";)na++;return na},q=function(G){if(typeof b[G]=="undefined")b[G]=[]};
d=0;for(i=a.length;d<i;d++){q(d);var t=0,H=[];f=0;for(h=a[d].childNodes.length;f<h;f++)if(a[d].childNodes[f].nodeName.toUpperCase()=="TD"||a[d].childNodes[f].nodeName.toUpperCase()=="TH")H.push(a[d].childNodes[f]);f=0;for(h=H.length;f<h;f++){var J=H[f].getAttribute("colspan")*1,A=H[f].getAttribute("rowspan")*1;if(!J||J===0||J===1){k=m(b,d,t);b[d][k]=H[f].nodeName.toUpperCase()=="TD"?4:H[f];if(A||A===0||A===1)for(e=1;e<A;e++){q(d+e);b[d+e][k]=2}t++}else{k=m(b,d,t);for(e=0;e<J;e++)b[d][k+e]=3;t+=J}}}d=
0;for(i=b.length;d<i;d++){f=0;for(h=b[d].length;f<h;f++)if(typeof b[d][f]=="object")c[f]=b[d][f]}return c}function Ka(){var a=p.createElement("p"),b=a.style;b.width="100%";b.height="200px";var c=p.createElement("div");b=c.style;b.position="absolute";b.top="0px";b.left="0px";b.visibility="hidden";b.width="200px";b.height="150px";b.overflow="hidden";c.appendChild(a);p.body.appendChild(c);b=a.offsetWidth;c.style.overflow="scroll";a=a.offsetWidth;if(b==a)a=c.clientWidth;p.body.removeChild(c);return b-
a}function M(a,b,c){for(var d=0,f=b.length;d<f;d++)for(var e=0,i=b[d].childNodes.length;e<i;e++)if(b[d].childNodes[e].nodeType==1)typeof c!="undefined"?a(b[d].childNodes[e],c[d].childNodes[e]):a(b[d].childNodes[e])}function o(a,b,c,d){if(typeof d=="undefined")d=c;if(typeof b[c]!="undefined")a[d]=b[c]}this.oApi={};this.fnDraw=function(a){var b=B(this[n.iApiIndex]);if(typeof a!="undefined"&&a===false){F(b);C(b)}else L(b)};this.fnFilter=function(a,b,c,d,f){var e=B(this[n.iApiIndex]);if(e.oFeatures.bFilter){if(typeof c==
"undefined")c=false;if(typeof d=="undefined")d=true;if(typeof f=="undefined")f=true;if(typeof b=="undefined"||b===null){P(e,{sSearch:a,bRegex:c,bSmart:d},1);if(f&&typeof e.aanFeatures.f!="undefined"){b=e.aanFeatures.f;c=0;for(d=b.length;c<d;c++)j("input",b[c]).val(a)}}else{e.aoPreSearchCols[b].sSearch=a;e.aoPreSearchCols[b].bRegex=c;e.aoPreSearchCols[b].bSmart=d;P(e,e.oPreviousSearch,1)}}};this.fnSettings=function(){return B(this[n.iApiIndex])};this.fnVersionCheck=n.fnVersionCheck;this.fnSort=function(a){var b=
B(this[n.iApiIndex]);b.aaSorting=a;O(b)};this.fnSortListener=function(a,b,c){$(B(this[n.iApiIndex]),a,b,c)};this.fnAddData=function(a,b){if(a.length===0)return[];var c=[],d,f=B(this[n.iApiIndex]);if(typeof a[0]=="object")for(var e=0;e<a.length;e++){d=w(f,a[e]);if(d==-1)return c;c.push(d)}else{d=w(f,a);if(d==-1)return c;c.push(d)}f.aiDisplay=f.aiDisplayMaster.slice();if(typeof b=="undefined"||b)L(f);return c};this.fnDeleteRow=function(a,b,c){var d=B(this[n.iApiIndex]);a=typeof a=="object"?Q(d,a):a;
var f=d.aoData.splice(a,1),e=j.inArray(a,d.aiDisplay);d.asDataSearch.splice(e,1);ka(d.aiDisplayMaster,a);ka(d.aiDisplay,a);typeof b=="function"&&b.call(this,d,f);if(d._iDisplayStart>=d.aiDisplay.length){d._iDisplayStart-=d._iDisplayLength;if(d._iDisplayStart<0)d._iDisplayStart=0}if(typeof c=="undefined"||c){F(d);C(d)}return f};this.fnClearTable=function(a){var b=B(this[n.iApiIndex]);ba(b);if(typeof a=="undefined"||a)C(b)};this.fnOpen=function(a,b,c){var d=B(this[n.iApiIndex]);this.fnClose(a);var f=
p.createElement("tr"),e=p.createElement("td");f.appendChild(e);e.className=c;e.colSpan=S(d);e.innerHTML=b;b=j("tr",d.nTBody);j.inArray(a,b)!=-1&&j(f).insertAfter(a);d.aoOpenRows.push({nTr:f,nParent:a});return f};this.fnClose=function(a){for(var b=B(this[n.iApiIndex]),c=0;c<b.aoOpenRows.length;c++)if(b.aoOpenRows[c].nParent==a){(a=b.aoOpenRows[c].nTr.parentNode)&&a.removeChild(b.aoOpenRows[c].nTr);b.aoOpenRows.splice(c,1);return 0}return 1};this.fnGetData=function(a){var b=B(this[n.iApiIndex]);if(typeof a!=
"undefined"){a=typeof a=="object"?Q(b,a):a;return b.aoData[a]._aData}return U(b)};this.fnGetNodes=function(a){var b=B(this[n.iApiIndex]);if(typeof a!="undefined")return b.aoData[a].nTr;return R(b)};this.fnGetPosition=function(a){var b=B(this[n.iApiIndex]);if(a.nodeName.toUpperCase()=="TR")return Q(b,a);else if(a.nodeName.toUpperCase()=="TD")for(var c=Q(b,a.parentNode),d=0,f=0;f<b.aoColumns.length;f++)if(b.aoColumns[f].bVisible){if(b.aoData[c].nTr.getElementsByTagName("td")[f-d]==a)return[c,f-d,f]}else d++;
return null};this.fnUpdate=function(a,b,c,d,f){var e=B(this[n.iApiIndex]),i;b=typeof b=="object"?Q(e,b):b;if(typeof a!="object"){i=a;e.aoData[b]._aData[c]=i;if(e.aoColumns[c].fnRender!==null){i=e.aoColumns[c].fnRender({iDataRow:b,iDataColumn:c,aData:e.aoData[b]._aData,oSettings:e});if(e.aoColumns[c].bUseRendered)e.aoData[b]._aData[c]=i}c=N(e,c);if(c!==null)e.aoData[b].nTr.getElementsByTagName("td")[c].innerHTML=i}else{if(a.length!=e.aoColumns.length){I(e,0,"An array passed to fnUpdate must have the same number of columns as the table in question - in this case "+
e.aoColumns.length);return 1}for(var h=0;h<a.length;h++){i=a[h];e.aoData[b]._aData[h]=i;if(e.aoColumns[h].fnRender!==null){i=e.aoColumns[h].fnRender({iDataRow:b,iDataColumn:h,aData:e.aoData[b]._aData,oSettings:e});if(e.aoColumns[h].bUseRendered)e.aoData[b]._aData[h]=i}c=N(e,h);if(c!==null)e.aoData[b].nTr.getElementsByTagName("td")[c].innerHTML=i}}a=j.inArray(b,e.aiDisplay);e.asDataSearch[a]=ia(e,e.aoData[b]._aData);if(typeof f=="undefined"||f)V(e);if(typeof d=="undefined"||d)L(e);return 0};this.fnSetColumnVis=
function(a,b,c){var d=B(this[n.iApiIndex]),f,e;e=d.aoColumns.length;var i,h;if(d.aoColumns[a].bVisible!=b){i=j(">tr",d.nTHead)[0];var k=j(">tr",d.nTFoot)[0],m=[],q=[];for(f=0;f<e;f++){m.push(d.aoColumns[f].nTh);q.push(d.aoColumns[f].nTf)}if(b){for(f=b=0;f<a;f++)d.aoColumns[f].bVisible&&b++;if(b>=S(d)){i.appendChild(m[a]);k&&k.appendChild(q[a]);f=0;for(e=d.aoData.length;f<e;f++){i=d.aoData[f]._anHidden[a];d.aoData[f].nTr.appendChild(i)}}else{for(f=a;f<e;f++){h=N(d,f);if(h!==null)break}i.insertBefore(m[a],
i.getElementsByTagName("th")[h]);k&&k.insertBefore(q[a],k.getElementsByTagName("th")[h]);W(d);f=0;for(e=d.aoData.length;f<e;f++){i=d.aoData[f]._anHidden[a];d.aoData[f].nTr.insertBefore(i,j(">td:eq("+h+")",d.aoData[f].nTr)[0])}}d.aoColumns[a].bVisible=true}else{i.removeChild(m[a]);k&&k.removeChild(q[a]);h=W(d);f=0;for(e=d.aoData.length;f<e;f++){i=h[f*d.aoColumns.length+a*1];d.aoData[f]._anHidden[a]=i;i.parentNode.removeChild(i)}d.aoColumns[a].bVisible=false}f=0;for(e=d.aoOpenRows.length;f<e;f++)d.aoOpenRows[f].nTr.colSpan=
S(d);if(typeof c=="undefined"||c){V(d);C(d)}la(d)}};this.fnPageChange=function(a,b){var c=B(this[n.iApiIndex]);ca(c,a);F(c);if(typeof b=="undefined"||b)C(c)};this.fnDestroy=function(){var a=B(this[n.iApiIndex]),b=a.nTableWrapper.parentNode,c=a.nTBody,d,f;a.bDestroying=true;d=0;for(f=a.aoColumns.length;d<f;d++)a.aoColumns[d].bVisible===false&&this.fnSetColumnVis(d,true);j("tbody>tr>td."+a.oClasses.sRowEmpty,a.nTable).parent().remove();if(a.nTable!=a.nTHead.parentNode){j(">thead",a.nTable).remove();
a.nTable.appendChild(a.nTHead)}if(a.nTFoot&&a.nTable!=a.nTFoot.parentNode){j(">tfoot",a.nTable).remove();a.nTable.appendChild(a.nTFoot)}a.nTable.parentNode.removeChild(a.nTable);j(a.nTableWrapper).remove();a.aaSorting=[];a.aaSortingFixed=[];T(a);j(R(a)).removeClass(a.asStripClasses.join(" "));if(a.bJUI){j("th",a.nTHead).removeClass([n.oStdClasses.sSortable,n.oJUIClasses.sSortableAsc,n.oJUIClasses.sSortableDesc,n.oJUIClasses.sSortableNone].join(" "));j("th span",a.nTHead).remove()}else j("th",a.nTHead).removeClass([n.oStdClasses.sSortable,
n.oStdClasses.sSortableAsc,n.oStdClasses.sSortableDesc,n.oStdClasses.sSortableNone].join(" "));b.appendChild(a.nTable);d=0;for(f=a.aoData.length;d<f;d++)c.appendChild(a.aoData[d].nTr);a.nTable.style.width=u(a.sDestroyWidth);j(">tr:even",c).addClass(a.asDestoryStrips[0]);j(">tr:odd",c).addClass(a.asDestoryStrips[1]);d=0;for(f=E.length;d<f;d++)E[d]==a&&E.splice(d,1)};this.fnAdjustColumnSizing=function(a){V(B(this[n.iApiIndex]));if(typeof a=="undefined"||a)this.fnDraw(false)};for(var oa in n.oApi)if(oa)this[oa]=
r(oa);this.oApi._fnExternApiFunc=r;this.oApi._fnInitalise=s;this.oApi._fnLanguageProcess=v;this.oApi._fnAddColumn=y;this.oApi._fnColumnOptions=D;this.oApi._fnAddData=w;this.oApi._fnGatherData=x;this.oApi._fnDrawHead=z;this.oApi._fnDraw=C;this.oApi._fnReDraw=L;this.oApi._fnAjaxUpdate=qa;this.oApi._fnAjaxUpdateDraw=ra;this.oApi._fnAddOptionsHtml=pa;this.oApi._fnFeatureHtmlTable=wa;this.oApi._fnScrollDraw=za;this.oApi._fnAjustColumnSizing=V;this.oApi._fnFeatureHtmlFilter=ua;this.oApi._fnFilterComplete=
P;this.oApi._fnFilterCustom=Ca;this.oApi._fnFilterColumn=Ba;this.oApi._fnFilter=Aa;this.oApi._fnBuildSearchArray=fa;this.oApi._fnBuildSearchRow=ia;this.oApi._fnFilterCreateSearch=ga;this.oApi._fnDataToSearch=ha;this.oApi._fnSort=O;this.oApi._fnSortAttachListener=$;this.oApi._fnSortingClasses=T;this.oApi._fnFeatureHtmlPaginate=ya;this.oApi._fnPageChange=ca;this.oApi._fnFeatureHtmlInfo=xa;this.oApi._fnUpdateInfo=Da;this.oApi._fnFeatureHtmlLength=ta;this.oApi._fnFeatureHtmlProcessing=va;this.oApi._fnProcessingDisplay=
K;this.oApi._fnVisibleToColumnIndex=ea;this.oApi._fnColumnIndexToVisible=N;this.oApi._fnNodeToDataIndex=Q;this.oApi._fnVisbleColumns=S;this.oApi._fnCalculateEnd=F;this.oApi._fnConvertToWidth=Ea;this.oApi._fnCalculateColumnWidths=Y;this.oApi._fnScrollingWidthAdjust=Ga;this.oApi._fnGetWidestNode=Fa;this.oApi._fnGetMaxLenString=Ha;this.oApi._fnStringToCss=u;this.oApi._fnArrayCmp=Ma;this.oApi._fnDetectType=Z;this.oApi._fnSettingsFromNode=B;this.oApi._fnGetDataMaster=U;this.oApi._fnGetTrNodes=R;this.oApi._fnGetTdNodes=
W;this.oApi._fnEscapeRegex=ja;this.oApi._fnDeleteIndex=ka;this.oApi._fnReOrderIndex=sa;this.oApi._fnColumnOrdering=aa;this.oApi._fnLog=I;this.oApi._fnClearTable=ba;this.oApi._fnSaveState=la;this.oApi._fnLoadState=Ja;this.oApi._fnCreateCookie=Ia;this.oApi._fnReadCookie=ma;this.oApi._fnGetUniqueThs=da;this.oApi._fnScrollBarWidth=Ka;this.oApi._fnApplyToChildren=M;this.oApi._fnMap=o;var La=this;return this.each(function(){var a=0,b,c,d,f;a=0;for(b=E.length;a<b;a++){if(E[a].nTable==this)if(typeof g=="undefined"||
typeof g.bRetrieve!="undefined"&&g.bRetrieve===true)return E[a].oInstance;else if(typeof g.bDestroy!="undefined"&&g.bDestroy===true){E[a].oInstance.fnDestroy();break}else{I(E[a],0,"Cannot reinitialise DataTable.\n\nTo retrieve the DataTables object for this table, please pass either no arguments to the dataTable() function, or set bRetrieve to true. Alternatively, to destory the old table and create a new one, set bDestroy to true (note that a lot of changes to the configuration can be made through the API which is usually much faster).");
return}if(E[a].sTableId!==""&&E[a].sTableId==this.getAttribute("id")){E.splice(a,1);break}}var e=new l;E.push(e);var i=false,h=false;a=this.getAttribute("id");if(a!==null){e.sTableId=a;e.sInstance=a}else e.sInstance=n._oExternConfig.iNextUnique++;if(this.nodeName.toLowerCase()!="table")I(e,0,"Attempted to initialise DataTables on a node which is not a table: "+this.nodeName);else{e.oInstance=La;e.nTable=this;e.oApi=La.oApi;e.sDestroyWidth=j(this).width();if(typeof g!="undefined"&&g!==null){e.oInit=
g;o(e.oFeatures,g,"bPaginate");o(e.oFeatures,g,"bLengthChange");o(e.oFeatures,g,"bFilter");o(e.oFeatures,g,"bSort");o(e.oFeatures,g,"bInfo");o(e.oFeatures,g,"bProcessing");o(e.oFeatures,g,"bAutoWidth");o(e.oFeatures,g,"bSortClasses");o(e.oFeatures,g,"bServerSide");o(e.oScroll,g,"sScrollX","sX");o(e.oScroll,g,"sScrollXInner","sXInner");o(e.oScroll,g,"sScrollY","sY");o(e.oScroll,g,"bScrollCollapse","bCollapse");o(e.oScroll,g,"bScrollInfinite","bInfinite");o(e.oScroll,g,"iScrollLoadGap","iLoadGap");
o(e,g,"asStripClasses");o(e,g,"fnRowCallback");o(e,g,"fnHeaderCallback");o(e,g,"fnFooterCallback");o(e,g,"fnCookieCallback");o(e,g,"fnInitComplete");o(e,g,"fnServerData");o(e,g,"fnFormatNumber");o(e,g,"aaSorting");o(e,g,"aaSortingFixed");o(e,g,"aLengthMenu");o(e,g,"sPaginationType");o(e,g,"sAjaxSource");o(e,g,"iCookieDuration");o(e,g,"sCookiePrefix");o(e,g,"sDom");o(e,g,"oSearch","oPreviousSearch");o(e,g,"aoSearchCols","aoPreSearchCols");o(e,g,"iDisplayLength","_iDisplayLength");o(e,g,"bJQueryUI",
"bJUI");o(e.oLanguage,g,"fnInfoCallback");typeof g.fnDrawCallback=="function"&&e.aoDrawCallback.push({fn:g.fnDrawCallback,sName:"user"});typeof g.fnStateSaveCallback=="function"&&e.aoStateSave.push({fn:g.fnStateSaveCallback,sName:"user"});typeof g.fnStateLoadCallback=="function"&&e.aoStateLoad.push({fn:g.fnStateLoadCallback,sName:"user"});e.oFeatures.bServerSide&&e.oFeatures.bSort&&e.oFeatures.bSortClasses&&e.aoDrawCallback.push({fn:T,sName:"server_side_sort_classes"});if(typeof g.bJQueryUI!="undefined"&&
g.bJQueryUI){e.oClasses=n.oJUIClasses;if(typeof g.sDom=="undefined")e.sDom='<"H"lfr>t<"F"ip>'}if(e.oScroll.sX!==""||e.oScroll.sY!=="")e.oScroll.iBarWidth=Ka();if(typeof g.iDisplayStart!="undefined"&&typeof e.iInitDisplayStart=="undefined"){e.iInitDisplayStart=g.iDisplayStart;e._iDisplayStart=g.iDisplayStart}if(typeof g.bStateSave!="undefined"){e.oFeatures.bStateSave=g.bStateSave;Ja(e,g);e.aoDrawCallback.push({fn:la,sName:"state_save"})}if(typeof g.aaData!="undefined")h=true;if(typeof g!="undefined"&&
typeof g.aoData!="undefined")g.aoColumns=g.aoData;if(typeof g.oLanguage!="undefined")if(typeof g.oLanguage.sUrl!="undefined"&&g.oLanguage.sUrl!==""){e.oLanguage.sUrl=g.oLanguage.sUrl;j.getJSON(e.oLanguage.sUrl,null,function(q){v(e,q,true)});i=true}else v(e,g.oLanguage,false)}else g={};if(typeof g.asStripClasses=="undefined"){e.asStripClasses.push(e.oClasses.sStripOdd);e.asStripClasses.push(e.oClasses.sStripEven)}c=false;d=j("tbody>tr",this);a=0;for(b=e.asStripClasses.length;a<b;a++)if(d.filter(":lt(2)").hasClass(e.asStripClasses[a])){c=
true;break}if(c){e.asDestoryStrips=["",""];if(j(d[0]).hasClass(e.oClasses.sStripOdd))e.asDestoryStrips[0]+=e.oClasses.sStripOdd+" ";if(j(d[0]).hasClass(e.oClasses.sStripEven))e.asDestoryStrips[0]+=e.oClasses.sStripEven;if(j(d[1]).hasClass(e.oClasses.sStripOdd))e.asDestoryStrips[1]+=e.oClasses.sStripOdd+" ";if(j(d[1]).hasClass(e.oClasses.sStripEven))e.asDestoryStrips[1]+=e.oClasses.sStripEven;d.removeClass(e.asStripClasses.join(" "))}a=this.getElementsByTagName("thead");c=a.length===0?[]:da(a[0]);
var k;if(typeof g.aoColumns=="undefined"){k=[];a=0;for(b=c.length;a<b;a++)k.push(null)}else k=g.aoColumns;a=0;for(b=k.length;a<b;a++){if(typeof g.saved_aoColumns!="undefined"&&g.saved_aoColumns.length==b){if(k[a]===null)k[a]={};k[a].bVisible=g.saved_aoColumns[a].bVisible}y(e,c?c[a]:null)}if(typeof g.aoColumnDefs!="undefined")for(a=g.aoColumnDefs.length-1;a>=0;a--){var m=g.aoColumnDefs[a].aTargets;j.isArray(m)||I(e,1,"aTargets must be an array of targets, not a "+typeof m);c=0;for(d=m.length;c<d;c++)if(typeof m[c]==
"number"&&m[c]>=0){for(;e.aoColumns.length<=m[c];)y(e);D(e,m[c],g.aoColumnDefs[a])}else if(typeof m[c]=="number"&&m[c]<0)D(e,e.aoColumns.length+m[c],g.aoColumnDefs[a]);else if(typeof m[c]=="string"){b=0;for(f=e.aoColumns.length;b<f;b++)if(m[c]=="_all"||e.aoColumns[b].nTh.className.indexOf(m[c])!=-1)D(e,b,g.aoColumnDefs[a])}}if(typeof k!="undefined"){a=0;for(b=k.length;a<b;a++)D(e,a,k[a])}a=0;for(b=e.aaSorting.length;a<b;a++){if(e.aaSorting[a][0]>=e.aoColumns.length)e.aaSorting[a][0]=0;k=e.aoColumns[e.aaSorting[a][0]];
if(typeof e.aaSorting[a][2]=="undefined")e.aaSorting[a][2]=0;if(typeof g.aaSorting=="undefined"&&typeof e.saved_aaSorting=="undefined")e.aaSorting[a][1]=k.asSorting[0];c=0;for(d=k.asSorting.length;c<d;c++)if(e.aaSorting[a][1]==k.asSorting[c]){e.aaSorting[a][2]=c;break}}T(e);this.getElementsByTagName("thead").length===0&&this.appendChild(p.createElement("thead"));this.getElementsByTagName("tbody").length===0&&this.appendChild(p.createElement("tbody"));e.nTHead=this.getElementsByTagName("thead")[0];
e.nTBody=this.getElementsByTagName("tbody")[0];if(this.getElementsByTagName("tfoot").length>0)e.nTFoot=this.getElementsByTagName("tfoot")[0];if(h)for(a=0;a<g.aaData.length;a++)w(e,g.aaData[a]);else x(e);e.aiDisplay=e.aiDisplayMaster.slice();e.bInitialised=true;i===false&&s(e)}})}})(jQuery,window,document);

;// Beginning /res/js/os/dataTables/jquery.dataTables.rowGrouping.js:
/*
* File:        jquery.dataTables.grouping.js
* Version:     1.0.
* Author:      Jovan Popovic 
* 
* Copyright 2011 Jovan Popovic, all rights reserved.
*
* This source file is free software, under either the GPL v2 license or a
* BSD style license, as supplied with this software.
* 
* This source file is distributed in the hope that it will be useful, but 
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
* or FITNESS FOR A PARTICULAR PURPOSE. 
* Parameters:
* @iGroupingColumnIndex                                 Integer             Index of the column that will be used for grouping - default 0
* @sGroupingColumnSortDirection                         Enumeration         Sort direction of the group
* @iGroupingOrderByColumnIndex                          Integer             Index of the column that will be used for ordering groups
* @sGrupingClass                                        String              Class that will be associated to the group row. Default - "group"
* @bSetGroupingClassOnTR                                Boolean             If set class will be set to the TR instead of the TD withing the grouping TR
* @bHideGroupingColumn                                  Boolean             Hide column used for grouping once results are grouped. Default - true
* @bHideGroupingOrderByColumn                           Boolean             Hide column used for ordering groups once results are grouped. Default - true
* @sGroupBy                                             Enumeration         Type of grouping that should be applied. Values "name"(default), "letter", "year"
* @sGroupLabelPrefix                                    String              Prefix that will be added to each group cell
* @bExpandableGrouping                                  Boolean             Attach expand/collapse handlers to the grouping rows
* @bExpandSingleGroup                                   Boolean             Use accordon grouping
* @iExpandGroupOffset                                   Integer             Number of pixels to set scroll position above the currently selected group. If -1 scroll will be alligned to the table
* General settings
* @sDateFormat: "dd/MM/yyyy"                            String              Date format used for grouping
* @sEmptyGroupLabel                                     String              Lable that will be placed as group if grouping cells are empty. Default "-"

* Parameters used in the second level grouping
* @iGroupingColumnIndex2                                Integer             Index of the secondary column that will be used for grouping - default 0
* @sGroupingColumnSortDirection2                        Enumeration         Sort direction of the secondary group
* @iGroupingOrderByColumnIndex2                         Integer             Index of the column that will be used for ordering secondary groups
* @sGrupingClass2                                       String              Class that will be associated to the secondary group row. Default "subgroup"
* @bHideGroupingColumn2                                 Boolean             Hide column used for secondary grouping once results are grouped. Default - true,
* @bHideGroupingOrderByColumn2                          Boolean             Hide column used for ordering secondary groups once results are grouped. Default - true,
* @sGroupBy2                                            Enumeration         Type of grouping that should be applied to secondary column. Values "name"(default), "letter", "year",
* @sGroupLabelPrefix2                                   String              Prefix that will be added to each secondary group cell
* @fnOnGrouped                                          Function            Function that is called when grouping is finished. Function has no parameters.
*/
(function ($) {

    $.fn.rowGrouping = function (options) {

        function _fnOnGrouped() {

        }

        function _getMonthName(iMonth) {
            var asMonths = ["January", "February", "March", "April", "May", "June", "Jully", "August", "September", "October", "November", "December"];
            return asMonths[iMonth - 1];
        }

        var defaults = {

            iGroupingColumnIndex: 0,
            sGroupingColumnSortDirection: "",
            iGroupingOrderByColumnIndex: -1,
            sGrupingClass: "group",
            bHideGroupingColumn: true,
            bHideGroupingOrderByColumn: true,
            sGroupBy: "name",
            sGroupLabelPrefix: "",
            bExpandableGrouping: false,
            bExpandSingleGroup: false,
            iExpandGroupOffset: 100,
            asExpandedGroups: null,

            sDateFormat: "dd/MM/yyyy",
            sEmptyGroupLabel: "-",
            bSetGroupingClassOnTR: false,

            iGroupingColumnIndex2: -1,
            sGroupingColumnSortDirection2: "",
            iGroupingOrderByColumnIndex2: -1,
            sGrupingClass2: "subgroup",
            bHideGroupingColumn2: true,
            bHideGroupingOrderByColumn2: true,
            sGroupBy2: "name",
            sGroupLabelPrefix2: "",
            bExpandableGrouping2: false,

            fnOnGrouped: _fnOnGrouped


        };


        return this.each(function (index, elem) {

            var oTable = $(elem).dataTable();
            function _fnIsGroupExpanded(sGroup) {
                return ($.inArray(sGroup, asExpandedGroups) != -1);
            }
            function _fnGetYear(x) {
                return x.substr(iYearIndex, iYearLength);
            }
            function _fnGetGroupByName(x) {
                return x;
            }

            function _fnGetGroupByLetter(x) {
                return x.substr(0, 1);
            }

            function _fnGetGroupByYear(x) {
                return _fnGetYear(x);
                //return Date.parseExact(x, properties.sDateFormat).getFullYear();//slooooow
            }

            function _fnGetGroupByYearMonth(x) {
                //var date = Date.parseExact(x, "dd/MM/yyyy");
                //return date.getFullYear() + " / " + date.getMonthName();
                //return x.substr(iYearIndex, iYearLength) + '/' + x.substr(iMonthIndex, iMonthLength);
                return x.substr(iYearIndex, iYearLength) + ' ' + _getMonthName(x.substr(iMonthIndex, iMonthLength));
            }

            function _fnGetCleanedGroup(sGroup) {
                return sGroup.toLowerCase().replace(" ", "-");
            }

            //var oTable = this;
            var iYearIndex = 6;
            var iYearLength = 4;
            var asExpandedGroups = new Array();
            var bInitialGrouping = true;

            var properties = $.extend(defaults, options);

            if (properties.iGroupingOrderByColumnIndex == -1) {
                properties.bCustomColumnOrdering = false;
                properties.iGroupingOrderByColumnIndex = properties.iGroupingColumnIndex;
            } else {
                properties.bCustomColumnOrdering = true;
            }

            if (properties.sGroupingColumnSortDirection == "") {
                if (properties.sGroupBy == "year")
                    properties.sGroupingColumnSortDirection = "desc";
                else
                    properties.sGroupingColumnSortDirection = "asc";
            }


            if (properties.iGroupingOrderByColumnIndex2 == -1) {
                properties.bCustomColumnOrdering2 = false;
                properties.iGroupingOrderByColumnIndex2 = properties.iGroupingColumnIndex2;
            } else {
                properties.bCustomColumnOrdering2 = true;
            }

            if (properties.sGroupingColumnSortDirection2 == "") {
                if (properties.sGroupBy2 == "year")
                    properties.sGroupingColumnSortDirection2 = "desc";
                else
                    properties.sGroupingColumnSortDirection2 = "asc";
            }

            if (properties.asExpandedGroups != null) {
                if (properties.asExpandedGroups == "NONE") {
                    properties.asExpandedGroups = [];
                    asExpandedGroups = properties.asExpandedGroups;
                    bInitialGrouping = false;
                } else if (properties.asExpandedGroups == "ALL") {

                } else if (properties.asExpandedGroups.constructor == String) {
                    var currentGroup = properties.asExpandedGroups;
                    properties.asExpandedGroups = new Array();
                    properties.asExpandedGroups.push(_fnGetCleanedGroup(currentGroup));
                    asExpandedGroups = properties.asExpandedGroups;
                    bInitialGrouping = false;
                } else if (properties.asExpandedGroups.constructor == Array) {
                    for (var i = 0; i < properties.asExpandedGroups.length; i++) {
                        asExpandedGroups.push(_fnGetCleanedGroup(properties.asExpandedGroups[i]));
                        if (properties.bExpandSingleGroup)
                            break;
                    }
                    bInitialGrouping = false;
                }
            }

            iYearIndex = properties.sDateFormat.toLowerCase().indexOf('yy');
            iYearLength = properties.sDateFormat.toLowerCase().lastIndexOf('y') - properties.sDateFormat.toLowerCase().indexOf('y') + 1;

            iMonthIndex = properties.sDateFormat.toLowerCase().indexOf('mm');
            iMonthLength = properties.sDateFormat.toLowerCase().lastIndexOf('m') - properties.sDateFormat.toLowerCase().indexOf('m') + 1;

            var fnGetGroup = _fnGetGroupByName;
            switch (properties.sGroupBy) {
                case "letter": fnGetGroup = _fnGetGroupByLetter;
                    break;
                case "year": fnGetGroup = _fnGetGroupByYear;
                    break;
                case "month": fnGetGroup = _fnGetGroupByYearMonth;
                    break;
                default: fnGetGroup = _fnGetGroupByName;
                    break;
            }




            var _fnDrawCallBackWithGrouping = function (oSettings) {

                var bUseSecondaryGrouping = false;

                if (properties.iGroupingColumnIndex2 != -1)
                    bUseSecondaryGrouping = true;

                //-----Start grouping

                if (oSettings.aiDisplay.length == 0) {
                    return;
                }

                var nTrs = $('tbody tr', oTable);
                var iColspan = nTrs[0].getElementsByTagName('td').length;
                var sLastGroup = null;
                var sLastGroup2 = null;
                for (var i = 0; i < nTrs.length; i++) {
                    var iDisplayIndex = oSettings._iDisplayStart + i;
                    var sGroupData = "";
                    var sGroup = null;
                    var sGroupData2 = "";
                    var sGroup2 = null;

                    sGroupData = oSettings.aoData[oSettings.aiDisplay[iDisplayIndex]]._aData[properties.iGroupingColumnIndex];
                    var sGroup = sGroupData;
                    if (properties.sGroupBy != "year")
                        sGroup = fnGetGroup(sGroupData);

                    if (bUseSecondaryGrouping) {
                        sGroupData2 = oSettings.aoData[oSettings.aiDisplay[iDisplayIndex]]._aData[properties.iGroupingColumnIndex2];
                        if (properties.sGroupBy2 != "year")
                            sGroup2 = fnGetGroup(sGroupData2);
                    }

                    if (sLastGroup == null || sGroup != sLastGroup) {
                        var sGroupCleaned = _fnGetCleanedGroup(sGroup);

                        if (properties.bExpandableGrouping && bInitialGrouping) {
                            if (properties.bExpandSingleGroup) {
                                if (asExpandedGroups.length == 0)
                                    asExpandedGroups.push(sGroupCleaned);
                            } else {
                                asExpandedGroups.push(sGroupCleaned);
                            }
                        }


                        var nGroup = document.createElement('tr');
                        var nCell = document.createElement('td');

                        nGroup.id = "group-id-" + oTable.attr("id") + "-" + sGroupCleaned;

                        if (properties.bSetGroupingClassOnTR) {
                            nGroup.className = properties.sGrupingClass + " " + sGroupCleaned;
                        } else {
                            nCell.className = properties.sGrupingClass + " " + sGroupCleaned;
                        }

                        nCell.colSpan = iColspan;
                        nCell.innerHTML = properties.sGroupLabelPrefix + (sGroup == "" ? properties.sEmptyGroupLabel : sGroup);
                        if (properties.bExpandableGrouping) {


                            if (_fnIsGroupExpanded(sGroupCleaned)) {
                                nCell.className += " expanded-group";
                            } else {
                                nCell.className += " collapsed-group";
                            }
                            nCell.className += " group-item-expander";
                            nCell.rel = sGroupCleaned;


                            ///*************


                            $(nCell).click(function (e) {


                                var sGroup = $(this).attr("rel");

                                var bIsExpanded = _fnIsGroupExpanded(sGroup);
                                if (properties.bExpandSingleGroup) {
                                    if (!bIsExpanded) {
                                        var sCurrentGroup = asExpandedGroups[0];
                                        asExpandedGroups = new Array();
                                        asExpandedGroups.push(sGroup);

                                        $(".group-item-" + sCurrentGroup, oTable).hide();
                                        $(".group-item-" + sGroup, oTable).show();

                                        var oTrExpandedGroup = $(".expanded-group");
                                        oTrExpandedGroup.removeClass("expanded-group");
                                        oTrExpandedGroup.addClass("collapsed-group");
                                        $(this).addClass("expanded-group");
                                        $(this).removeClass("collapsed-group");
                                        if (properties.iExpandGroupOffset != -1) {
                                            var position = $("#group-id-" + oTable.attr("id") + "-" + sGroup).offset().top - properties.iExpandGroupOffset;
                                            window.scroll(0, position);
                                        } else {
                                            var position = oTable.offset().top;
                                            window.scroll(0, position);
                                        }
                                    }
                                } else {
                                    if (bIsExpanded) {
                                        var index = $.inArray(sGroup, asExpandedGroups);
                                        asExpandedGroups.splice(index, 1);
                                        $(this).removeClass("expanded-group");
                                        $(this).addClass("collapsed-group");
                                        $(".group-item-" + sGroup, oTable).hide();
                                    } else {
                                        asExpandedGroups.push(sGroup);
                                        $(this).addClass("expanded-group");
                                        $(this).removeClass("collapsed-group");
                                        $(".group-item-" + sGroup, oTable).show();
                                    }
                                }
                                e.preventDefault();

                            }
                    );






                            ///***********






                        }
                        nGroup.appendChild(nCell);
                        nTrs[i].parentNode.insertBefore(nGroup, nTrs[i]);
                        sLastGroup = sGroup;
                        sLastGroup2 = null; //to reset second level grouping





                    } // end if (sLastGroup == null || sGroup != sLastGroup)

                    if (properties.bExpandableGrouping) {
                        $(nTrs[i]).addClass("group-item-" + sGroupCleaned);
                        if (/*properties.bExpandSingleGroup &&*/!_fnIsGroupExpanded(sGroupCleaned)) {
                            $(nTrs[i]).hide();
                        }
                    }


                    if (bUseSecondaryGrouping) {

                        if (sLastGroup2 == null || sGroup2 != sLastGroup2) {
                            var nGroup2 = document.createElement('tr');
                            var nCell2 = document.createElement('td');

                            if (properties.bSetGroupingClassOnTR) {
                                nGroup2.className = properties.sGrupingClass2 + " " + sGroup2.toLowerCase().replace(" ", "-");
                            } else {
                                nCell2.className = properties.sGrupingClass2 + " " + sGroup2.toLowerCase().replace(" ", "-");
                            }

                            nCell2.colSpan = iColspan;
                            nCell2.innerHTML = properties.sGroupLabelPrefix2 + (sGroup2 == "" ? properties.sEmptyGroupLabel : sGroup2);

                            nGroup2.appendChild(nCell2);
                            nTrs[i].parentNode.insertBefore(nGroup2, nTrs[i]);
                            sLastGroup2 = sGroup2;
                        }


                    } //end if (bUseSecondaryGrouping)



                } // end for (var i = 0; i < nTrs.length; i++)


                //-----End grouping
                properties.fnOnGrouped();

                bInitialGrouping = false;
            };




            oTable.fnSetColumnVis(properties.iGroupingColumnIndex, !properties.bHideGroupingColumn);
            if (properties.bCustomColumnOrdering) {
                oTable.fnSetColumnVis(properties.iGroupingOrderByColumnIndex, !properties.bHideGroupingOrderByColumn);
            }
            if (properties.iGroupingColumnIndex2 != -1) {
                oTable.fnSetColumnVis(properties.iGroupingColumnIndex2, !properties.bHideGroupingColumn2);
            }
            if (properties.bCustomColumnOrdering2) {
                oTable.fnSetColumnVis(properties.iGroupingOrderByColumnIndex2, !properties.bHideGroupingOrderByColumn2);
            }
            oTable.fnSettings().aoDrawCallback.push({
                "fn": _fnDrawCallBackWithGrouping,
                "sName": "fnRowGroupung"
            });

            var aaSortingFixed = new Array();
            aaSortingFixed.push([properties.iGroupingOrderByColumnIndex, properties.sGroupingColumnSortDirection]);
            if (properties.iGroupingColumnIndex2 != -1) {
                aaSortingFixed.push([properties.iGroupingOrderByColumnIndex2, properties.sGroupingColumnSortDirection2]);
            }

            oTable.fnSettings().aaSortingFixed = aaSortingFixed;
            //Old way
            //oTable.fnSettings().aaSortingFixed = [[properties.iGroupingOrderByColumnIndex, properties.sGroupingColumnSortDirection]];

            switch (properties.sGroupBy) {
                case "name":
                    break;


                case "letter":

                    /* Create an array with the values of all the input boxes in a column */
                    oTable.fnSettings().aoColumns[properties.iGroupingOrderByColumnIndex].sSortDataType = "rg-letter";
                    $.fn.dataTableExt.afnSortData['rg-letter'] = function (oSettings, iColumn) {
                        var aData = [];
                        $('td:eq(' + iColumn + ')', oSettings.oApi._fnGetTrNodes(oSettings)).each(function () {
                            aData.push(_fnGetGroupByLetter(this.innerHTML));
                        });
                        return aData;
                    }


                    break;


                case "year":


                    /* Create an array with the values of all the input boxes in a column */
                    oTable.fnSettings().aoColumns[properties.iGroupingOrderByColumnIndex].sSortDataType = "rg-date";
                    $.fn.dataTableExt.afnSortData['rg-date'] = function (oSettings, iColumn) {
                        var aData = [];
                        $('td:eq(' + iColumn + ')', oSettings.oApi._fnGetTrNodes(oSettings)).each(function () {
                            aData.push(_fnGetYear(this.innerHTML));
                        });
                        return aData;
                    }




                    break;
                default:
                    break;

            }
            if (properties.sGroupBy == "name" || properties.sGroupBy == "letter") {

            } else {
                //oTable.fnSettings().aaSortingFixed = [[properties.iGroupingOrderByColumnIndex, properties.sGroupingColumnSortDirection]];

            }

            oTable.fnDraw();





        });
    };
})(jQuery);
;// Beginning /res/js/os/underscore.js:
//     Underscore.js 1.2.1
//     (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
//     Underscore is freely distributable under the MIT license.
//     Portions of Underscore are inspired or borrowed from Prototype,
//     Oliver Steele's Functional, and John Resig's Micro-Templating.
//     For all details and documentation:
//     http://documentcloud.github.com/underscore

(function() {

  // Baseline setup
  // --------------

  // Establish the root object, `window` in the browser, or `global` on the server.
  var root = this;

  // Save the previous value of the `_` variable.
  var previousUnderscore = root._;

  // Establish the object that gets returned to break out of a loop iteration.
  var breaker = {};

  // Save bytes in the minified (but not gzipped) version:
  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;

  // Create quick reference variables for speed access to core prototypes.
  var slice            = ArrayProto.slice,
      unshift          = ArrayProto.unshift,
      toString         = ObjProto.toString,
      hasOwnProperty   = ObjProto.hasOwnProperty;

  // All **ECMAScript 5** native function implementations that we hope to use
  // are declared here.
  var
    nativeForEach      = ArrayProto.forEach,
    nativeMap          = ArrayProto.map,
    nativeReduce       = ArrayProto.reduce,
    nativeReduceRight  = ArrayProto.reduceRight,
    nativeFilter       = ArrayProto.filter,
    nativeEvery        = ArrayProto.every,
    nativeSome         = ArrayProto.some,
    nativeIndexOf      = ArrayProto.indexOf,
    nativeLastIndexOf  = ArrayProto.lastIndexOf,
    nativeIsArray      = Array.isArray,
    nativeKeys         = Object.keys,
    nativeBind         = FuncProto.bind;

  // Create a safe reference to the Underscore object for use below.
  var _ = function(obj) { return new wrapper(obj); };

  // Export the Underscore object for **Node.js** and **"CommonJS"**, with
  // backwards-compatibility for the old `require()` API. If we're not in
  // CommonJS, add `_` to the global object.
  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = _;
    }
    exports._ = _;
  } else if (typeof define === 'function' && define.amd) {
    // Register as a named module with AMD.
    define('underscore', function() {
      return _;
    });
  } else {
    // Exported as a string, for Closure Compiler "advanced" mode.
    root['_'] = _;
  }

  // Current version.
  _.VERSION = '1.2.1';

  // Collection Functions
  // --------------------

  // The cornerstone, an `each` implementation, aka `forEach`.
  // Handles objects with the built-in `forEach`, arrays, and raw objects.
  // Delegates to **ECMAScript 5**'s native `forEach` if available.
  var each = _.each = _.forEach = function(obj, iterator, context) {
    if (obj == null) return;
    if (nativeForEach && obj.forEach === nativeForEach) {
      obj.forEach(iterator, context);
    } else if (obj.length === +obj.length) {
      for (var i = 0, l = obj.length; i < l; i++) {
        if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
      }
    } else {
      for (var key in obj) {
        if (hasOwnProperty.call(obj, key)) {
          if (iterator.call(context, obj[key], key, obj) === breaker) return;
        }
      }
    }
  };

  // Return the results of applying the iterator to each element.
  // Delegates to **ECMAScript 5**'s native `map` if available.
  _.map = function(obj, iterator, context) {
    var results = [];
    if (obj == null) return results;
    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
    each(obj, function(value, index, list) {
      results[results.length] = iterator.call(context, value, index, list);
    });
    return results;
  };

  // **Reduce** builds up a single result from a list of values, aka `inject`,
  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
    var initial = memo !== void 0;
    if (obj == null) obj = [];
    if (nativeReduce && obj.reduce === nativeReduce) {
      if (context) iterator = _.bind(iterator, context);
      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
    }
    each(obj, function(value, index, list) {
      if (!initial) {
        memo = value;
        initial = true;
      } else {
        memo = iterator.call(context, memo, value, index, list);
      }
    });
    if (!initial) throw new TypeError("Reduce of empty array with no initial value");
    return memo;
  };

  // The right-associative version of reduce, also known as `foldr`.
  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
    if (obj == null) obj = [];
    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
      if (context) iterator = _.bind(iterator, context);
      return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
    }
    var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
    return _.reduce(reversed, iterator, memo, context);
  };

  // Return the first value which passes a truth test. Aliased as `detect`.
  _.find = _.detect = function(obj, iterator, context) {
    var result;
    any(obj, function(value, index, list) {
      if (iterator.call(context, value, index, list)) {
        result = value;
        return true;
      }
    });
    return result;
  };

  // Return all the elements that pass a truth test.
  // Delegates to **ECMAScript 5**'s native `filter` if available.
  // Aliased as `select`.
  _.filter = _.select = function(obj, iterator, context) {
    var results = [];
    if (obj == null) return results;
    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
    each(obj, function(value, index, list) {
      if (iterator.call(context, value, index, list)) results[results.length] = value;
    });
    return results;
  };

  // Return all the elements for which a truth test fails.
  _.reject = function(obj, iterator, context) {
    var results = [];
    if (obj == null) return results;
    each(obj, function(value, index, list) {
      if (!iterator.call(context, value, index, list)) results[results.length] = value;
    });
    return results;
  };

  // Determine whether all of the elements match a truth test.
  // Delegates to **ECMAScript 5**'s native `every` if available.
  // Aliased as `all`.
  _.every = _.all = function(obj, iterator, context) {
    var result = true;
    if (obj == null) return result;
    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
    each(obj, function(value, index, list) {
      if (!(result = result && iterator.call(context, value, index, list))) return breaker;
    });
    return result;
  };

  // Determine if at least one element in the object matches a truth test.
  // Delegates to **ECMAScript 5**'s native `some` if available.
  // Aliased as `any`.
  var any = _.some = _.any = function(obj, iterator, context) {
    iterator = iterator || _.identity;
    var result = false;
    if (obj == null) return result;
    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
    each(obj, function(value, index, list) {
      if (result |= iterator.call(context, value, index, list)) return breaker;
    });
    return !!result;
  };

  // Determine if a given value is included in the array or object using `===`.
  // Aliased as `contains`.
  _.include = _.contains = function(obj, target) {
    var found = false;
    if (obj == null) return found;
    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
    found = any(obj, function(value) {
      if (value === target) return true;
    });
    return found;
  };

  // Invoke a method (with arguments) on every item in a collection.
  _.invoke = function(obj, method) {
    var args = slice.call(arguments, 2);
    return _.map(obj, function(value) {
      return (method.call ? method || value : value[method]).apply(value, args);
    });
  };

  // Convenience version of a common use case of `map`: fetching a property.
  _.pluck = function(obj, key) {
    return _.map(obj, function(value){ return value[key]; });
  };

  // Return the maximum element or (element-based computation).
  _.max = function(obj, iterator, context) {
    if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
    if (!iterator && _.isEmpty(obj)) return -Infinity;
    var result = {computed : -Infinity};
    each(obj, function(value, index, list) {
      var computed = iterator ? iterator.call(context, value, index, list) : value;
      computed >= result.computed && (result = {value : value, computed : computed});
    });
    return result.value;
  };

  // Return the minimum element (or element-based computation).
  _.min = function(obj, iterator, context) {
    if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
    if (!iterator && _.isEmpty(obj)) return Infinity;
    var result = {computed : Infinity};
    each(obj, function(value, index, list) {
      var computed = iterator ? iterator.call(context, value, index, list) : value;
      computed < result.computed && (result = {value : value, computed : computed});
    });
    return result.value;
  };

  // Shuffle an array.
  _.shuffle = function(obj) {
    var shuffled = [], rand;
    each(obj, function(value, index, list) {
      if (index == 0) {
        shuffled[0] = value;
      } else {
        rand = Math.floor(Math.random() * (index + 1));
        shuffled[index] = shuffled[rand];
        shuffled[rand] = value;
      }
    });
    return shuffled;
  };

  // Sort the object's values by a criterion produced by an iterator.
  _.sortBy = function(obj, iterator, context) {
    return _.pluck(_.map(obj, function(value, index, list) {
      return {
        value : value,
        criteria : iterator.call(context, value, index, list)
      };
    }).sort(function(left, right) {
      var a = left.criteria, b = right.criteria;
      return a < b ? -1 : a > b ? 1 : 0;
    }), 'value');
  };

  // Groups the object's values by a criterion. Pass either a string attribute
  // to group by, or a function that returns the criterion.
  _.groupBy = function(obj, val) {
    var result = {};
    var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
    each(obj, function(value, index) {
      var key = iterator(value, index);
      (result[key] || (result[key] = [])).push(value);
    });
    return result;
  };

  // Use a comparator function to figure out at what index an object should
  // be inserted so as to maintain order. Uses binary search.
  _.sortedIndex = function(array, obj, iterator) {
    iterator || (iterator = _.identity);
    var low = 0, high = array.length;
    while (low < high) {
      var mid = (low + high) >> 1;
      iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
    }
    return low;
  };

  // Safely convert anything iterable into a real, live array.
  _.toArray = function(iterable) {
    if (!iterable)                return [];
    if (iterable.toArray)         return iterable.toArray();
    if (_.isArray(iterable))      return slice.call(iterable);
    if (_.isArguments(iterable))  return slice.call(iterable);
    return _.values(iterable);
  };

  // Return the number of elements in an object.
  _.size = function(obj) {
    return _.toArray(obj).length;
  };

  // Array Functions
  // ---------------

  // Get the first element of an array. Passing **n** will return the first N
  // values in the array. Aliased as `head`. The **guard** check allows it to work
  // with `_.map`.
  _.first = _.head = function(array, n, guard) {
    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
  };

  // Returns everything but the last entry of the array. Especcialy useful on
  // the arguments object. Passing **n** will return all the values in
  // the array, excluding the last N. The **guard** check allows it to work with
  // `_.map`.
  _.initial = function(array, n, guard) {
    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
  };

  // Get the last element of an array. Passing **n** will return the last N
  // values in the array. The **guard** check allows it to work with `_.map`.
  _.last = function(array, n, guard) {
    return (n != null) && !guard ? slice.call(array, array.length - n) : array[array.length - 1];
  };

  // Returns everything but the first entry of the array. Aliased as `tail`.
  // Especially useful on the arguments object. Passing an **index** will return
  // the rest of the values in the array from that index onward. The **guard**
  // check allows it to work with `_.map`.
  _.rest = _.tail = function(array, index, guard) {
    return slice.call(array, (index == null) || guard ? 1 : index);
  };

  // Trim out all falsy values from an array.
  _.compact = function(array) {
    return _.filter(array, function(value){ return !!value; });
  };

  // Return a completely flattened version of an array.
  _.flatten = function(array, shallow) {
    return _.reduce(array, function(memo, value) {
      if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
      memo[memo.length] = value;
      return memo;
    }, []);
  };

  // Return a version of the array that does not contain the specified value(s).
  _.without = function(array) {
    return _.difference(array, slice.call(arguments, 1));
  };

  // Produce a duplicate-free version of the array. If the array has already
  // been sorted, you have the option of using a faster algorithm.
  // Aliased as `unique`.
  _.uniq = _.unique = function(array, isSorted, iterator) {
    var initial = iterator ? _.map(array, iterator) : array;
    var result = [];
    _.reduce(initial, function(memo, el, i) {
      if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
        memo[memo.length] = el;
        result[result.length] = array[i];
      }
      return memo;
    }, []);
    return result;
  };

  // Produce an array that contains the union: each distinct element from all of
  // the passed-in arrays.
  _.union = function() {
    return _.uniq(_.flatten(arguments, true));
  };

  // Produce an array that contains every item shared between all the
  // passed-in arrays. (Aliased as "intersect" for back-compat.)
  _.intersection = _.intersect = function(array) {
    var rest = slice.call(arguments, 1);
    return _.filter(_.uniq(array), function(item) {
      return _.every(rest, function(other) {
        return _.indexOf(other, item) >= 0;
      });
    });
  };

  // Take the difference between one array and another.
  // Only the elements present in just the first array will remain.
  _.difference = function(array, other) {
    return _.filter(array, function(value){ return !_.include(other, value); });
  };

  // Zip together multiple lists into a single array -- elements that share
  // an index go together.
  _.zip = function() {
    var args = slice.call(arguments);
    var length = _.max(_.pluck(args, 'length'));
    var results = new Array(length);
    for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
    return results;
  };

  // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
  // we need this function. Return the position of the first occurrence of an
  // item in an array, or -1 if the item is not included in the array.
  // Delegates to **ECMAScript 5**'s native `indexOf` if available.
  // If the array is large and already in sort order, pass `true`
  // for **isSorted** to use binary search.
  _.indexOf = function(array, item, isSorted) {
    if (array == null) return -1;
    var i, l;
    if (isSorted) {
      i = _.sortedIndex(array, item);
      return array[i] === item ? i : -1;
    }
    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
    for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
    return -1;
  };

  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
  _.lastIndexOf = function(array, item) {
    if (array == null) return -1;
    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
    var i = array.length;
    while (i--) if (array[i] === item) return i;
    return -1;
  };

  // Generate an integer Array containing an arithmetic progression. A port of
  // the native Python `range()` function. See
  // [the Python documentation](http://docs.python.org/library/functions.html#range).
  _.range = function(start, stop, step) {
    if (arguments.length <= 1) {
      stop = start || 0;
      start = 0;
    }
    step = arguments[2] || 1;

    var len = Math.max(Math.ceil((stop - start) / step), 0);
    var idx = 0;
    var range = new Array(len);

    while(idx < len) {
      range[idx++] = start;
      start += step;
    }

    return range;
  };

  // Function (ahem) Functions
  // ------------------

  // Reusable constructor function for prototype setting.
  var ctor = function(){};

  // Create a function bound to a given object (assigning `this`, and arguments,
  // optionally). Binding with arguments is also known as `curry`.
  // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
  // We check for `func.bind` first, to fail fast when `func` is undefined.
  _.bind = function bind(func, context) {
    var bound, args;
    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
    if (!_.isFunction(func)) throw new TypeError;
    args = slice.call(arguments, 2);
    return bound = function() {
      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
      ctor.prototype = func.prototype;
      var self = new ctor;
      var result = func.apply(self, args.concat(slice.call(arguments)));
      if (Object(result) === result) return result;
      return self;
    };
  };

  // Bind all of an object's methods to that object. Useful for ensuring that
  // all callbacks defined on an object belong to it.
  _.bindAll = function(obj) {
    var funcs = slice.call(arguments, 1);
    if (funcs.length == 0) funcs = _.functions(obj);
    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
    return obj;
  };

  // Memoize an expensive function by storing its results.
  _.memoize = function(func, hasher) {
    var memo = {};
    hasher || (hasher = _.identity);
    return function() {
      var key = hasher.apply(this, arguments);
      return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
    };
  };

  // Delays a function for the given number of milliseconds, and then calls
  // it with the arguments supplied.
  _.delay = function(func, wait) {
    var args = slice.call(arguments, 2);
    return setTimeout(function(){ return func.apply(func, args); }, wait);
  };

  // Defers a function, scheduling it to run after the current call stack has
  // cleared.
  _.defer = function(func) {
    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
  };

  // Returns a function, that, when invoked, will only be triggered at most once
  // during a given window of time.
  _.throttle = function(func, wait) {
    var timeout, context, args, throttling, finishThrottle;
    finishThrottle = _.debounce(function(){ throttling = false; }, wait);
    return function() {
      context = this; args = arguments;
      var throttler = function() {
        timeout = null;
        func.apply(context, args);
        finishThrottle();
      };
      if (!timeout) timeout = setTimeout(throttler, wait);
      if (!throttling) func.apply(context, args);
      if (finishThrottle) finishThrottle();
      throttling = true;
    };
  };

  // Returns a function, that, as long as it continues to be invoked, will not
  // be triggered. The function will be called after it stops being called for
  // N milliseconds.
  _.debounce = function(func, wait) {
    var timeout;
    return function() {
      var context = this, args = arguments;
      var throttler = function() {
        timeout = null;
        func.apply(context, args);
      };
      clearTimeout(timeout);
      timeout = setTimeout(throttler, wait);
    };
  };

  // Returns a function that will be executed at most one time, no matter how
  // often you call it. Useful for lazy initialization.
  _.once = function(func) {
    var ran = false, memo;
    return function() {
      if (ran) return memo;
      ran = true;
      return memo = func.apply(this, arguments);
    };
  };

  // Returns the first function passed as an argument to the second,
  // allowing you to adjust arguments, run code before and after, and
  // conditionally execute the original function.
  _.wrap = function(func, wrapper) {
    return function() {
      var args = [func].concat(slice.call(arguments));
      return wrapper.apply(this, args);
    };
  };

  // Returns a function that is the composition of a list of functions, each
  // consuming the return value of the function that follows.
  _.compose = function() {
    var funcs = slice.call(arguments);
    return function() {
      var args = slice.call(arguments);
      for (var i = funcs.length - 1; i >= 0; i--) {
        args = [funcs[i].apply(this, args)];
      }
      return args[0];
    };
  };

  // Returns a function that will only be executed after being called N times.
  _.after = function(times, func) {
    return function() {
      if (--times < 1) { return func.apply(this, arguments); }
    };
  };

  // Object Functions
  // ----------------

  // Retrieve the names of an object's properties.
  // Delegates to **ECMAScript 5**'s native `Object.keys`
  _.keys = nativeKeys || function(obj) {
    if (obj !== Object(obj)) throw new TypeError('Invalid object');
    var keys = [];
    for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
    return keys;
  };

  // Retrieve the values of an object's properties.
  _.values = function(obj) {
    return _.map(obj, _.identity);
  };

  // Return a sorted list of the function names available on the object.
  // Aliased as `methods`
  _.functions = _.methods = function(obj) {
    var names = [];
    for (var key in obj) {
      if (_.isFunction(obj[key])) names.push(key);
    }
    return names.sort();
  };

  // Extend a given object with all the properties in passed-in object(s).
  _.extend = function(obj) {
    each(slice.call(arguments, 1), function(source) {
      for (var prop in source) {
        if (source[prop] !== void 0) obj[prop] = source[prop];
      }
    });
    return obj;
  };

  // Fill in a given object with default properties.
  _.defaults = function(obj) {
    each(slice.call(arguments, 1), function(source) {
      for (var prop in source) {
        if (obj[prop] == null) obj[prop] = source[prop];
      }
    });
    return obj;
  };

  // Create a (shallow-cloned) duplicate of an object.
  _.clone = function(obj) {
    if (!_.isObject(obj)) return obj;
    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
  };

  // Invokes interceptor with the obj, and then returns obj.
  // The primary purpose of this method is to "tap into" a method chain, in
  // order to perform operations on intermediate results within the chain.
  _.tap = function(obj, interceptor) {
    interceptor(obj);
    return obj;
  };

  // Internal recursive comparison function.
  function eq(a, b, stack) {
    // Identical objects are equal. `0 === -0`, but they aren't identical.
    // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
    if (a === b) return a !== 0 || 1 / a == 1 / b;
    // A strict comparison is necessary because `null == undefined`.
    if ((a == null) || (b == null)) return a === b;
    // Unwrap any wrapped objects.
    if (a._chain) a = a._wrapped;
    if (b._chain) b = b._wrapped;
    // Invoke a custom `isEqual` method if one is provided.
    if (_.isFunction(a.isEqual)) return a.isEqual(b);
    if (_.isFunction(b.isEqual)) return b.isEqual(a);
    // Compare object types.
    var typeA = typeof a;
    if (typeA != typeof b) return false;
    // Optimization; ensure that both values are truthy or falsy.
    if (!a != !b) return false;
    // `NaN` values are equal.
    if (_.isNaN(a)) return _.isNaN(b);
    // Compare string objects by value.
    var isStringA = _.isString(a), isStringB = _.isString(b);
    if (isStringA || isStringB) return isStringA && isStringB && String(a) == String(b);
    // Compare number objects by value.
    var isNumberA = _.isNumber(a), isNumberB = _.isNumber(b);
    if (isNumberA || isNumberB) return isNumberA && isNumberB && +a == +b;
    // Compare boolean objects by value. The value of `true` is 1; the value of `false` is 0.
    var isBooleanA = _.isBoolean(a), isBooleanB = _.isBoolean(b);
    if (isBooleanA || isBooleanB) return isBooleanA && isBooleanB && +a == +b;
    // Compare dates by their millisecond values.
    var isDateA = _.isDate(a), isDateB = _.isDate(b);
    if (isDateA || isDateB) return isDateA && isDateB && a.getTime() == b.getTime();
    // Compare RegExps by their source patterns and flags.
    var isRegExpA = _.isRegExp(a), isRegExpB = _.isRegExp(b);
    if (isRegExpA || isRegExpB) {
      // Ensure commutative equality for RegExps.
      return isRegExpA && isRegExpB &&
             a.source == b.source &&
             a.global == b.global &&
             a.multiline == b.multiline &&
             a.ignoreCase == b.ignoreCase;
    }
    // Ensure that both values are objects.
    if (typeA != 'object') return false;
    // Arrays or Arraylikes with different lengths are not equal.
    if (a.length !== b.length) return false;
    // Objects with different constructors are not equal.
    if (a.constructor !== b.constructor) return false;
    // Assume equality for cyclic structures. The algorithm for detecting cyclic
    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
    var length = stack.length;
    while (length--) {
      // Linear search. Performance is inversely proportional to the number of
      // unique nested structures.
      if (stack[length] == a) return true;
    }
    // Add the first object to the stack of traversed objects.
    stack.push(a);
    var size = 0, result = true;
    // Deep compare objects.
    for (var key in a) {
      if (hasOwnProperty.call(a, key)) {
        // Count the expected number of properties.
        size++;
        // Deep compare each member.
        if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
      }
    }
    // Ensure that both objects contain the same number of properties.
    if (result) {
      for (key in b) {
        if (hasOwnProperty.call(b, key) && !size--) break;
      }
      result = !size;
    }
    // Remove the first object from the stack of traversed objects.
    stack.pop();
    return result;
  }

  // Perform a deep comparison to check if two objects are equal.
  _.isEqual = function(a, b) {
    return eq(a, b, []);
  };

  // Is a given array, string, or object empty?
  // An "empty" object has no enumerable own-properties.
  _.isEmpty = function(obj) {
    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
    for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
    return true;
  };

  // Is a given value a DOM element?
  _.isElement = function(obj) {
    return !!(obj && obj.nodeType == 1);
  };

  // Is a given value an array?
  // Delegates to ECMA5's native Array.isArray
  _.isArray = nativeIsArray || function(obj) {
    return toString.call(obj) == '[object Array]';
  };

  // Is a given variable an object?
  _.isObject = function(obj) {
    return obj === Object(obj);
  };

  // Is a given variable an arguments object?
  if (toString.call(arguments) == '[object Arguments]') {
    _.isArguments = function(obj) {
      return toString.call(obj) == '[object Arguments]';
    };
  } else {
    _.isArguments = function(obj) {
      return !!(obj && hasOwnProperty.call(obj, 'callee'));
    };
  }

  // Is a given value a function?
  _.isFunction = function(obj) {
    return toString.call(obj) == '[object Function]';
  };

  // Is a given value a string?
  _.isString = function(obj) {
    return toString.call(obj) == '[object String]';
  };

  // Is a given value a number?
  _.isNumber = function(obj) {
    return toString.call(obj) == '[object Number]';
  };

  // Is the given value `NaN`?
  _.isNaN = function(obj) {
    // `NaN` is the only value for which `===` is not reflexive.
    return obj !== obj;
  };

  // Is a given value a boolean?
  _.isBoolean = function(obj) {
    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
  };

  // Is a given value a date?
  _.isDate = function(obj) {
    return toString.call(obj) == '[object Date]';
  };

  // Is the given value a regular expression?
  _.isRegExp = function(obj) {
    return toString.call(obj) == '[object RegExp]';
  };

  // Is a given value equal to null?
  _.isNull = function(obj) {
    return obj === null;
  };

  // Is a given variable undefined?
  _.isUndefined = function(obj) {
    return obj === void 0;
  };

  // Utility Functions
  // -----------------

  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
  // previous owner. Returns a reference to the Underscore object.
  _.noConflict = function() {
    root._ = previousUnderscore;
    return this;
  };

  // Keep the identity function around for default iterators.
  _.identity = function(value) {
    return value;
  };

  // Run a function **n** times.
  _.times = function (n, iterator, context) {
    for (var i = 0; i < n; i++) iterator.call(context, i);
  };

  // Escape a string for HTML interpolation.
  _.escape = function(string) {
    return (''+string).replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
  };

  // Add your own custom functions to the Underscore object, ensuring that
  // they're correctly added to the OOP wrapper as well.
  _.mixin = function(obj) {
    each(_.functions(obj), function(name){
      addToWrapper(name, _[name] = obj[name]);
    });
  };

  // Generate a unique integer id (unique within the entire client session).
  // Useful for temporary DOM ids.
  var idCounter = 0;
  _.uniqueId = function(prefix) {
    var id = idCounter++;
    return prefix ? prefix + id : id;
  };

  // By default, Underscore uses ERB-style template delimiters, change the
  // following template settings to use alternative delimiters.
  _.templateSettings = {
    evaluate    : /<%([\s\S]+?)%>/g,
    interpolate : /<%=([\s\S]+?)%>/g,
    escape      : /<%-([\s\S]+?)%>/g
  };

  // JavaScript micro-templating, similar to John Resig's implementation.
  // Underscore templating handles arbitrary delimiters, preserves whitespace,
  // and correctly escapes quotes within interpolated code.
  _.template = function(str, data) {
    var c  = _.templateSettings;
    var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
      'with(obj||{}){__p.push(\'' +
      str.replace(/\\/g, '\\\\')
         .replace(/'/g, "\\'")
         .replace(c.escape, function(match, code) {
           return "',_.escape(" + code.replace(/\\'/g, "'") + "),'";
         })
         .replace(c.interpolate, function(match, code) {
           return "'," + code.replace(/\\'/g, "'") + ",'";
         })
         .replace(c.evaluate || null, function(match, code) {
           return "');" + code.replace(/\\'/g, "'")
                              .replace(/[\r\n\t]/g, ' ') + "__p.push('";
         })
         .replace(/\r/g, '\\r')
         .replace(/\n/g, '\\n')
         .replace(/\t/g, '\\t')
         + "');}return __p.join('');";
    var func = new Function('obj', tmpl);
    return data ? func(data) : func;
  };

  // The OOP Wrapper
  // ---------------

  // If Underscore is called as a function, it returns a wrapped object that
  // can be used OO-style. This wrapper holds altered versions of all the
  // underscore functions. Wrapped objects may be chained.
  var wrapper = function(obj) { this._wrapped = obj; };

  // Expose `wrapper.prototype` as `_.prototype`
  _.prototype = wrapper.prototype;

  // Helper function to continue chaining intermediate results.
  var result = function(obj, chain) {
    return chain ? _(obj).chain() : obj;
  };

  // A method to easily add functions to the OOP wrapper.
  var addToWrapper = function(name, func) {
    wrapper.prototype[name] = function() {
      var args = slice.call(arguments);
      unshift.call(args, this._wrapped);
      return result(func.apply(_, args), this._chain);
    };
  };

  // Add all of the Underscore functions to the wrapper object.
  _.mixin(_);

  // Add all mutator Array functions to the wrapper.
  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
    var method = ArrayProto[name];
    wrapper.prototype[name] = function() {
      method.apply(this._wrapped, arguments);
      return result(this._wrapped, this._chain);
    };
  });

  // Add all accessor Array functions to the wrapper.
  each(['concat', 'join', 'slice'], function(name) {
    var method = ArrayProto[name];
    wrapper.prototype[name] = function() {
      return result(method.apply(this._wrapped, arguments), this._chain);
    };
  });

  // Start chaining a wrapped Underscore object.
  wrapper.prototype.chain = function() {
    this._chain = true;
    return this;
  };

  // Extracts the result from a wrapped and chained object.
  wrapper.prototype.value = function() {
    return this._wrapped;
  };

})();

;// Beginning /res/js/os/underscore.string.js:
// Underscore.string
// (c) 2010 Esa-Matti Suuronen <esa-matti aet suuronen dot org>
// Underscore.strings is freely distributable under the terms of the MIT license.
// Documentation: https://github.com/edtsech/underscore.string
// Some code is borrowed from MooTools and Alexandru Marasteanu.

// Version 1.1.4

(function(){
    // ------------------------- Baseline setup ---------------------------------

    // Establish the root object, "window" in the browser, or "global" on the server.
    var root = this;

    var nativeTrim = String.prototype.trim;

    function str_repeat(i, m) {
        for (var o = []; m > 0; o[--m] = i);
        return o.join('');
    }

    function defaultToWhiteSpace(characters){
        if (characters) {
            return _s.escapeRegExp(characters);
        }
        return '\\s';
    }

    var _s = {

        isBlank: function(str){
            return !!str.match(/^\s*$/);
        },

        capitalize : function(str) {
            return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase();
        },

        chop: function(str, step){
            step = step || str.length;
            var arr = [];
            for (var i = 0; i < str.length;) {
                arr.push(str.slice(i,i + step));
                i = i + step;
            }
            return arr;
        },

        clean: function(str){
            return _s.strip(str.replace(/\s+/g, ' '));
        },

        count: function(str, substr){
            var count = 0, index;
            for (var i=0; i < str.length;) {
                index = str.indexOf(substr, i);
                index >= 0 && count++;
                i = i + (index >= 0 ? index : 0) + substr.length;
            }
            return count;
        },

        chars: function(str) {
            return str.split('');
        },

        escapeHTML: function(str) {
            return String(str||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
        },

        unescapeHTML: function(str) {
            return String(str||'').replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
        },

        escapeRegExp: function(str){
            // From MooTools core 1.2.4
            return String(str||'').replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
        },

        insert: function(str, i, substr){
            var arr = str.split('');
            arr.splice(i, 0, substr);
            return arr.join('');
        },

        includes: function(str, needle){
            return str.indexOf(needle) !== -1;
        },

        join: function(sep) {
            // TODO: Could this be faster by converting
            // arguments to Array and using array.join(sep)?
            sep = String(sep);
            var str = "";
            for (var i=1; i < arguments.length; i += 1) {
                str += String(arguments[i]);
                if ( i !== arguments.length-1 ) {
                    str += sep;
                }
            }
            return str;
        },

        lines: function(str) {
            return str.split("\n");
        },

//        reverse: function(str){
//            return Array.prototype.reverse.apply(str.split('')).join('');
//        },

        splice: function(str, i, howmany, substr){
            var arr = str.split('');
            arr.splice(i, howmany, substr);
            return arr.join('');
        },

        startsWith: function(str, starts){
            return str.length >= starts.length && str.substring(0, starts.length) === starts;
        },

        endsWith: function(str, ends){
            return str.length >= ends.length && str.substring(str.length - ends.length) === ends;
        },

        succ: function(str){
            var arr = str.split('');
            arr.splice(str.length-1, 1, String.fromCharCode(str.charCodeAt(str.length-1) + 1));
            return arr.join('');
        },

        titleize: function(str){
            var arr = str.split(' '),
                word;
            for (var i=0; i < arr.length; i++) {
                word = arr[i].split('');
                if(typeof word[0] !== 'undefined') word[0] = word[0].toUpperCase();
                i+1 === arr.length ? arr[i] = word.join('') : arr[i] = word.join('') + ' ';
            }
            return arr.join('');
        },

        camelize: function(str){
          return _s.trim(str).replace(/(\-|_|\s)+(.)?/g, function(match, separator, chr) {
            return chr ? chr.toUpperCase() : '';
          });
        },

        underscored: function(str){
          return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/\-|\s+/g, '_').toLowerCase();
        },

        dasherize: function(str){
          return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1-$2').replace(/^([A-Z]+)/, '-$1').replace(/\_|\s+/g, '-').toLowerCase();
        },

        trim: function(str, characters){
            if (!characters && nativeTrim) {
                return nativeTrim.call(str);
            }
            characters = defaultToWhiteSpace(characters);
            return str.replace(new RegExp('\^[' + characters + ']+|[' + characters + ']+$', 'g'), '');
        },

        ltrim: function(str, characters){
            characters = defaultToWhiteSpace(characters);
            return str.replace(new RegExp('\^[' + characters + ']+', 'g'), '');
        },

        rtrim: function(str, characters){
            characters = defaultToWhiteSpace(characters);
            return str.replace(new RegExp('[' + characters + ']+$', 'g'), '');
        },

        truncate: function(str, length, truncateStr){
            truncateStr = truncateStr || '...';
            return str.slice(0,length) + truncateStr;
        },

        words: function(str, delimiter) {
            delimiter = delimiter || " ";
            return str.split(delimiter);
        },


        pad: function(str, length, padStr, type) {

            var padding = '';
            var padlen  = 0;

            if (!padStr) { padStr = ' '; }
            else if (padStr.length > 1) { padStr = padStr[0]; }
            switch(type) {
                case "right":
                    padlen = (length - str.length);
                    padding = str_repeat(padStr, padlen);
                    str = str+padding;
                    break;
                case "both":
                    padlen = (length - str.length);
                    padding = {
                        'left' : str_repeat(padStr, Math.ceil(padlen/2)),
                        'right': str_repeat(padStr, Math.floor(padlen/2))
                    };
                    str = padding.left+str+padding.right;
                    break;
                default: // "left"
                    padlen = (length - str.length);
                    padding = str_repeat(padStr, padlen);;
                    str = padding+str;
            }
            return str;
        },

        lpad: function(str, length, padStr) {
            return _s.pad(str, length, padStr);
        },

        rpad: function(str, length, padStr) {
            return _s.pad(str, length, padStr, 'right');
        },

        lrpad: function(str, length, padStr) {
            return _s.pad(str, length, padStr, 'both');
        },


        /**
         * Credits for this function goes to
         * http://www.diveintojavascript.com/projects/sprintf-for-javascript
         *
         * Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
         * All rights reserved.
         * */
        sprintf: function(){

            var i = 0, a, f = arguments[i++], o = [], m, p, c, x, s = '';
            while (f) {
                if (m = /^[^\x25]+/.exec(f)) {
                    o.push(m[0]);
                }
                else if (m = /^\x25{2}/.exec(f)) {
                    o.push('%');
                }
                else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) {
                    if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) {
                        throw('Too few arguments.');
                    }
                    if (/[^s]/.test(m[7]) && (typeof(a) != 'number')) {
                        throw('Expecting number but found ' + typeof(a));
                    }
                    switch (m[7]) {
                        case 'b': a = a.toString(2); break;
                        case 'c': a = String.fromCharCode(a); break;
                        case 'd': a = parseInt(a); break;
                        case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break;
                        case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break;
                        case 'o': a = a.toString(8); break;
                        case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break;
                        case 'u': a = Math.abs(a); break;
                        case 'x': a = a.toString(16); break;
                        case 'X': a = a.toString(16).toUpperCase(); break;
                    }
                    a = (/[def]/.test(m[7]) && m[2] && a >= 0 ? '+'+ a : a);
                    c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' ';
                    x = m[5] - String(a).length - s.length;
                    p = m[5] ? str_repeat(c, x) : '';
                    o.push(s + (m[4] ? a + p : p + a));
                }
                else {
                    throw('Huh ?!');
                }
                f = f.substring(m[0].length);
            }
            return o.join('');
        }
    }

    // Aliases

    _s.strip  = _s.trim;
    _s.lstrip = _s.ltrim;
    _s.rstrip = _s.rtrim;
    _s.center = _s.lrpad
    _s.ljust  = _s.lpad
    _s.rjust  = _s.rpad

    // CommonJS module is defined
    if (typeof window === 'undefined' && typeof module !== 'undefined') {
        // Export module
        module.exports = _s;

    // Integrate with Underscore.js
    } else if (typeof root._ !== 'undefined') {
        root._.mixin(_s);

    // Or define it
    } else {
        root._ = _s;
    }

}());

;// Beginning /res/js/os/json2.js:
/*
    http://www.JSON.org/json2.js
    2011-02-23

    Public Domain.

    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.

    See http://www.JSON.org/js.html


    This code should be minified before deployment.
    See http://javascript.crockford.com/jsmin.html

    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
    NOT CONTROL.


    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. It can be a
                        function or an array of strings.

            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 value

            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 of strings, 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 representations, 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
            the 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.
*/

/*jslint evil: true, strict: false, regexp: false */

/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
    lastIndex, length, parse, prototype, push, replace, slice, stringify,
    test, toJSON, toString, valueOf
*/


// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.

var JSON;
if (!JSON) {
    JSON = {};
}

(function () {
    "use strict";

    function f(n) {
        // Format integers to have at least two digits.
        return n < 10 ? '0' + n : n;
    }

    if (typeof Date.prototype.toJSON !== 'function') {

        Date.prototype.toJSON = function (key) {

            return isFinite(this.valueOf()) ?
                this.getUTCFullYear()     + '-' +
                f(this.getUTCMonth() + 1) + '-' +
                f(this.getUTCDate())      + 'T' +
                f(this.getUTCHours())     + ':' +
                f(this.getUTCMinutes())   + ':' +
                f(this.getUTCSeconds())   + 'Z' : null;
        };

        String.prototype.toJSON      =
            Number.prototype.toJSON  =
            Boolean.prototype.toJSON = function (key) {
                return this.valueOf();
            };
    }

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\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.

        escapable.lastIndex = 0;
        return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
            var c = meta[a];
            return typeof c === 'string' ? c :
                '\\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 = [];

// Is the value an array?

            if (Object.prototype.toString.apply(value) === '[object Array]') {

// The value 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) {
                    if (typeof rep[i] === 'string') {
                        k = rep[i];
                        v = str(k, value);
                        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.prototype.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        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;
        }
    }

// If the JSON object does not yet have a stringify method, give it one.

    if (typeof JSON.stringify !== 'function') {
        JSON.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 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});
        };
    }


// If the JSON object does not yet have a parse method, give it one.

    if (typeof JSON.parse !== 'function') {
        JSON.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.prototype.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.

            text = String(text);
            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 the JSON 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(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/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');
        };
    }
}());

;// Beginning /res/js/os/jquery.formatCurrency-1.4.0.min.js:
(function($){$.formatCurrency={};$.formatCurrency.regions=[];$.formatCurrency.regions[""]={symbol:"$",positiveFormat:"%s%n",negativeFormat:"(%s%n)",decimalSymbol:".",digitGroupSymbol:",",groupDigits:true};
$.fn.formatCurrency=function(destination,settings){if(arguments.length==1&&typeof destination!=="string"){settings=destination;destination=false
}var defaults={name:"formatCurrency",colorize:false,region:"",global:true,roundToDecimalPlace:2,eventOnDecimalsEntered:false};defaults=$.extend(defaults,$.formatCurrency.regions[""]);
settings=$.extend(defaults,settings);if(settings.region.length>0){settings=$.extend(settings,getRegionOrCulture(settings.region))}settings.regex=generateRegex(settings);
return this.each(function(){$this=$(this);var num="0";num=$this[$this.is("input, select, textarea")?"val":"html"]();if(num.search("\\(")>=0){num="-"+num
}if(num===""||(num==="-"&&settings.roundToDecimalPlace===-1)){return}if(isNaN(num)){num=num.replace(settings.regex,"");if(num===""||(num==="-"&&settings.roundToDecimalPlace===-1)){return
}if(settings.decimalSymbol!="."){num=num.replace(settings.decimalSymbol,".")}if(isNaN(num)){num="0"}}var numParts=String(num).split(".");var isPositive=(num==Math.abs(num));
var hasDecimals=(numParts.length>1);var decimals=(hasDecimals?numParts[1].toString():"0");var originalDecimals=decimals;num=Math.abs(numParts[0]);
num=isNaN(num)?0:num;if(settings.roundToDecimalPlace>=0){decimals=parseFloat("1."+decimals);decimals=decimals.toFixed(settings.roundToDecimalPlace);
if(decimals.substring(0,1)=="2"){num=Number(num)+1}decimals=decimals.substring(2)}num=String(num);if(settings.groupDigits){for(var i=0;i<Math.floor((num.length-(1+i))/3);
i++){num=num.substring(0,num.length-(4*i+3))+settings.digitGroupSymbol+num.substring(num.length-(4*i+3))}}if((hasDecimals&&settings.roundToDecimalPlace==-1)||settings.roundToDecimalPlace>0){num+=settings.decimalSymbol+decimals
}var format=isPositive?settings.positiveFormat:settings.negativeFormat;var money=format.replace(/%s/g,settings.symbol);money=money.replace(/%n/g,num);
var $destination=$([]);if(!destination){$destination=$this}else{$destination=$(destination)}$destination[$destination.is("input, select, textarea")?"val":"html"](money);
if(hasDecimals&&settings.eventOnDecimalsEntered&&originalDecimals.length>settings.roundToDecimalPlace){$destination.trigger("decimalsEntered",originalDecimals)
}if(settings.colorize){$destination.css("color",isPositive?"black":"red")}})};$.fn.toNumber=function(settings){var defaults=$.extend({name:"toNumber",region:"",global:true},$.formatCurrency.regions[""]);
settings=jQuery.extend(defaults,settings);if(settings.region.length>0){settings=$.extend(settings,getRegionOrCulture(settings.region))}settings.regex=generateRegex(settings);
return this.each(function(){var method=$(this).is("input, select, textarea")?"val":"html";$(this)[method]($(this)[method]().replace("(","(-").replace(settings.regex,""))
})};$.fn.asNumber=function(settings){var defaults=$.extend({name:"asNumber",region:"",parse:true,parseType:"Float",global:true},$.formatCurrency.regions[""]);
settings=jQuery.extend(defaults,settings);if(settings.region.length>0){settings=$.extend(settings,getRegionOrCulture(settings.region))}settings.regex=generateRegex(settings);
settings.parseType=validateParseType(settings.parseType);var method=$(this).is("input, select, textarea")?"val":"html";var num=$(this)[method]();
num=num?num:"";num=num.replace("(","(-");num=num.replace(settings.regex,"");if(!settings.parse){return num}if(num.length==0){num="0"}if(settings.decimalSymbol!="."){num=num.replace(settings.decimalSymbol,".")
}return window["parse"+settings.parseType](num)};function getRegionOrCulture(region){var regionInfo=$.formatCurrency.regions[region];if(regionInfo){return regionInfo
}else{if(/(\w+)-(\w+)/g.test(region)){var culture=region.replace(/(\w+)-(\w+)/g,"$1");return $.formatCurrency.regions[culture]}}return null}function validateParseType(parseType){switch(parseType.toLowerCase()){case"int":return"Int";
case"float":return"Float";default:throw"invalid parseType"}}function generateRegex(settings){if(settings.symbol===""){return new RegExp("[^\\d"+settings.decimalSymbol+"-]","g")
}else{var symbol=settings.symbol.replace("$","\\$").replace(".","\\.");return new RegExp(symbol+"|[^\\d"+settings.decimalSymbol+"-]","g")}}})(jQuery);
;// Beginning /res/js/os/plugins/jquery.placeholder.min.js:
/*!
 * jQuery Placeholder plugin
 *
 * This plugin is used to support the HTML5 placeholder attribute on most non-HTML5-compliant browsers.
 * 
 * Usage: $.Placeholder.init({ color : "rgb(0,0,0)" });
 * 
 * Date: Sept 2011
 * Author: Otacon (byf1987_at_gmail.com)
 * Project page: https://code.google.com/p/jquery-placeholder-js/
 * Version: 1.2
 * Changelog: 
    1.2 Added semicolons to the end of function, thanks to Tony (ty*****_at_gmail.com)
	1.1	Updated the code to meet jQuery plugin format. Added parameterized init. 
 	1.0 Initial release.
 * Tested on: Chrome 10.0; IE6 (IETester); IE8 (IETester)
 * Known Issues: 
 * 	Placeholder for Password is currently not supported
 */
(function($){ 
	$.Placeholder = {
		settings : {
			color : "rgb(169,169,169)", // darkGrey does not work in ie
			dataName : "original-font-color" // the name of the data tag used by this module
		},
		
		// -- Bind event to components --
		init : function(settings){
			// Merge default settings with the ones provided
			if(settings)
			{
				$.extend($.Placeholder.settings, settings);
			}
			
			// -- Util Methods --	
			var getContent = function(element){
				return $(element).val();		
			};
		
			var setContent = function(element, content){
				$(element).val(content);		
			};
			
			var getPlaceholder = function(element){
				return $(element).attr("placeholder");
			};
			
			var isContentEmpty = function(element){
				var content = getContent(element);
				return (content.length === 0) || content == getPlaceholder(element);
			};
				
			var setPlaceholderStyle = function(element){
				$(element).data($.Placeholder.settings.dataName, $(element).css("color"));
				$(element).css("color", $.Placeholder.settings.color);		
			};
			
			var clearPlaceholderStyle = function(element){
				$(element).css("color", $(element).data($.Placeholder.settings.dataName));		
				$(element).removeData($.Placeholder.settings.dataName);
			};
			
			var showPlaceholder = function(element){
				setContent(element, getPlaceholder(element));
				setPlaceholderStyle(element);	
			};
			
			var hidePlaceholder = function(element){
				if($(element).data($.Placeholder.settings.dataName)){
					setContent(element, "");
					clearPlaceholderStyle(element);
				}
			};
			
			// -- Event Handlers --
			var inputFocused = function(){
				if(isContentEmpty(this)){
					hidePlaceholder(this);		
				}
			};
			
			var inputBlurred = function(){
				if(isContentEmpty(this)){
					showPlaceholder(this);
				}
			};
			
			var parentFormSubmitted = function(){
				if(isContentEmpty(this)){
					hidePlaceholder(this);		
				}	
			};
			
			// -- Execution --
			$("textarea, input[type='text']").each(function(index, element){
				if($(element).attr("placeholder")){
					$(element).focus(inputFocused);
					$(element).blur(inputBlurred);
					$(element).bind("parentformsubmitted", parentFormSubmitted);
					
					// triggers show place holder on module init
					$(element).trigger("blur");
					// triggers form submitted event on parent form submit
					$(element).parents("form").submit(function(){
						$(element).trigger("parentformsubmitted");
					});
				}
			});
			
			return this;
		}
	}
})(jQuery);

;// Beginning /res/js/os/placeholdersupport.js:
$(document).ready(function(){
	// TODO: This should be done with livequery when the plugin is added. That way
	// this plugin will be run on dynamically added content with the placeholder
	// attribute.
	var isInputSupported = 'placeholder' in document.createElement('input'),
    isTextareaSupported = 'placeholder' in document.createElement('textarea');
	if (!isInputSupported || !isTextareaSupported) {
		$.Placeholder.init();
		$('[placeholder]').addClass('legacyPlaceholder');
	}
})
;// Beginning /res/js/os/bootstrap-modal.js:
/* =========================================================
 * bootstrap-modal.js v1.4.0
 * http://twitter.github.com/bootstrap/javascript.html#modal
 * =========================================================
 * Copyright 2011 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================= */


!function( $ ){

  "use strict"

 /* CSS TRANSITION SUPPORT (https://gist.github.com/373874)
  * ======================================================= */

  var transitionEnd

  $(document).ready(function () {

    $.support.transition = (function () {
      var thisBody = document.body || document.documentElement
        , thisStyle = thisBody.style
        , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined
      return support
    })()

    // set CSS transition event type
    if ( $.support.transition ) {
      transitionEnd = "TransitionEnd"
      if ( $.browser.webkit ) {
      	transitionEnd = "webkitTransitionEnd"
      } else if ( $.browser.mozilla ) {
      	transitionEnd = "transitionend"
      } else if ( $.browser.opera ) {
      	transitionEnd = "oTransitionEnd"
      }
    }

  })


 /* MODAL PUBLIC CLASS DEFINITION
  * ============================= */

  var Modal = function ( content, options ) {
    this.settings = $.extend({}, $.fn.modal.defaults, options)
    this.$element = $(content)
      .delegate('.close', 'click.modal', $.proxy(this.hide, this))

    if ( this.settings.show ) {
      this.show()
    }

    return this
  }

  Modal.prototype = {

      toggle: function () {
        return this[!this.isShown ? 'show' : 'hide']()
      }

    , show: function () {
        var that = this
        this.isShown = true
        this.$element.trigger('show')

        escape.call(this)
        backdrop.call(this, function () {
          var transition = $.support.transition && that.$element.hasClass('fade')

          that.$element
            .appendTo(document.body)
            .show()

          if (transition) {
            that.$element[0].offsetWidth // force reflow
          }

          that.$element.addClass('in')

          transition ?
            that.$element.one(transitionEnd, function () { that.$element.trigger('shown') }) :
            that.$element.trigger('shown')

        })

        return this
      }

    , hide: function (e) {
        e && e.preventDefault()

        if ( !this.isShown ) {
          return this
        }

        var that = this
        this.isShown = false

        escape.call(this)

        this.$element
          .trigger('hide')
          .removeClass('in')

        $.support.transition && this.$element.hasClass('fade') ?
          hideWithTransition.call(this) :
          hideModal.call(this)

        return this
      }

  }


 /* MODAL PRIVATE METHODS
  * ===================== */

  function hideWithTransition() {
    // firefox drops transitionEnd events :{o
    var that = this
      , timeout = setTimeout(function () {
          that.$element.unbind(transitionEnd)
          hideModal.call(that)
        }, 500)

    this.$element.one(transitionEnd, function () {
      clearTimeout(timeout)
      hideModal.call(that)
    })
  }

  function hideModal (that) {
    this.$element
      .hide()
      .trigger('hidden')

    backdrop.call(this)
  }

  function backdrop ( callback ) {
    var that = this
      , animate = this.$element.hasClass('fade') ? 'fade' : ''
    if ( this.isShown && this.settings.backdrop ) {
      var doAnimate = $.support.transition && animate

      this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
        .appendTo(document.body)

      if ( this.settings.backdrop != 'static' ) {
        this.$backdrop.click($.proxy(this.hide, this))
      }

      if ( doAnimate ) {
        this.$backdrop[0].offsetWidth // force reflow
      }

      this.$backdrop.addClass('in')

      doAnimate ?
        this.$backdrop.one(transitionEnd, callback) :
        callback()

    } else if ( !this.isShown && this.$backdrop ) {
      this.$backdrop.removeClass('in')

      $.support.transition && this.$element.hasClass('fade')?
        this.$backdrop.one(transitionEnd, $.proxy(removeBackdrop, this)) :
        removeBackdrop.call(this)

    } else if ( callback ) {
       callback()
    }
  }

  function removeBackdrop() {
    this.$backdrop.remove()
    this.$backdrop = null
  }

  function escape() {
    var that = this
    if ( this.isShown && this.settings.keyboard ) {
      $(document).bind('keyup.modal', function ( e ) {
        if ( e.which == 27 ) {
          that.hide()
        }
      })
    } else if ( !this.isShown ) {
      $(document).unbind('keyup.modal')
    }
  }


 /* MODAL PLUGIN DEFINITION
  * ======================= */

  $.fn.modal = function ( options ) {
    var modal = this.data('modal')

    if (!modal) {

      if (typeof options == 'string') {
        options = {
          show: /show|toggle/.test(options)
        }
      }

      return this.each(function () {
        $(this).data('modal', new Modal(this, options))
      })
    }

    if ( options === true ) {
      return modal
    }

    if ( typeof options == 'string' ) {
      modal[options]()
    } else if ( modal ) {
      modal.toggle()
    }

    return this
  }

  $.fn.modal.Modal = Modal

  $.fn.modal.defaults = {
    backdrop: false
  , keyboard: false
  , show: false
  }


 /* MODAL DATA- IMPLEMENTATION
  * ========================== */

  $(document).ready(function () {
    $('body').delegate('[data-controls-modal]', 'click', function (e) {
      e.preventDefault()
      var $this = $(this).data('show', true)
      $('#' + $this.attr('data-controls-modal')).modal( $this.data() )
    })
  })

}( window.jQuery || window.ender );

;// Beginning /res/js/os/jquery.livequery.js:
/*! Copyright (c) 2008 Brandon Aaron (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.
 *
 * Version: 1.0.3
 * Requires jQuery 1.1.3+
 * Docs: http://docs.jquery.com/Plugins/livequery
 */

(function($) {
	
$.extend($.fn, {
	livequery: function(type, fn, fn2) {
		var self = this, q;
		
		// Handle different call patterns
		if ($.isFunction(type))
			fn2 = fn, fn = type, type = undefined;
			
		// See if Live Query already exists
		$.each( $.livequery.queries, function(i, query) {
			if ( self.selector == query.selector && self.context == query.context &&
				type == query.type && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) )
					// Found the query, exit the each loop
					return (q = query) && false;
		});
		
		// Create new Live Query if it wasn't found
		q = q || new $.livequery(this.selector, this.context, type, fn, fn2);
		
		// Make sure it is running
		q.stopped = false;
		
		// Run it immediately for the first time
		q.run();
		
		// Contnue the chain
		return this;
	},
	
	expire: function(type, fn, fn2) {
		var self = this;
		
		// Handle different call patterns
		if ($.isFunction(type))
			fn2 = fn, fn = type, type = undefined;
			
		// Find the Live Query based on arguments and stop it
		$.each( $.livequery.queries, function(i, query) {
			if ( self.selector == query.selector && self.context == query.context && 
				(!type || type == query.type) && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.stopped )
					$.livequery.stop(query.id);
		});
		
		// Continue the chain
		return this;
	}
});

$.livequery = function(selector, context, type, fn, fn2) {
	this.selector = selector;
	this.context  = context || document;
	this.type     = type;
	this.fn       = fn;
	this.fn2      = fn2;
	this.elements = [];
	this.stopped  = false;
	
	// The id is the index of the Live Query in $.livequery.queries
	this.id = $.livequery.queries.push(this)-1;
	
	// Mark the functions for matching later on
	fn.$lqguid = fn.$lqguid || $.livequery.guid++;
	if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++;
	
	// Return the Live Query
	return this;
};

$.livequery.prototype = {
	stop: function() {
		var query = this;
		
		if ( this.type )
			// Unbind all bound events
			this.elements.unbind(this.type, this.fn);
		else if (this.fn2)
			// Call the second function for all matched elements
			this.elements.each(function(i, el) {
				query.fn2.apply(el);
			});
			
		// Clear out matched elements
		this.elements = [];
		
		// Stop the Live Query from running until restarted
		this.stopped = true;
	},
	
	run: function() {
		// Short-circuit if stopped
		if ( this.stopped ) return;
		var query = this;
		
		var oEls = this.elements,
			els  = $(this.selector, this.context),
			nEls = els.not(oEls);
		
		// Set elements to the latest set of matched elements
		this.elements = els;
		
		if (this.type) {
			// Bind events to newly matched elements
			nEls.bind(this.type, this.fn);
			
			// Unbind events to elements no longer matched
			if (oEls.length > 0)
				$.each(oEls, function(i, el) {
					if ( $.inArray(el, els) < 0 )
						$.event.remove(el, query.type, query.fn);
				});
		}
		else {
			// Call the first function for newly matched elements
			nEls.each(function() {
				query.fn.apply(this);
			});
			
			// Call the second function for elements no longer matched
			if ( this.fn2 && oEls.length > 0 )
				$.each(oEls, function(i, el) {
					if ( $.inArray(el, els) < 0 )
						query.fn2.apply(el);
				});
		}
	}
};

$.extend($.livequery, {
	guid: 0,
	queries: [],
	queue: [],
	running: false,
	timeout: null,
	
	checkQueue: function() {
		if ( $.livequery.running && $.livequery.queue.length ) {
			var length = $.livequery.queue.length;
			// Run each Live Query currently in the queue
			while ( length-- )
				$.livequery.queries[ $.livequery.queue.shift() ].run();
		}
	},
	
	pause: function() {
		// Don't run anymore Live Queries until restarted
		$.livequery.running = false;
	},
	
	play: function() {
		// Restart Live Queries
		$.livequery.running = true;
		// Request a run of the Live Queries
		$.livequery.run();
	},
	
	registerPlugin: function() {
		$.each( arguments, function(i,n) {
			// Short-circuit if the method doesn't exist
			if (!$.fn[n]) return;
			
			// Save a reference to the original method
			var old = $.fn[n];
			
			// Create a new method
			$.fn[n] = function() {
				// Call the original method
				var r = old.apply(this, arguments);
				
				// Request a run of the Live Queries
				$.livequery.run();
				
				// Return the original methods result
				return r;
			}
		});
	},
	
	run: function(id) {
		if (id != undefined) {
			// Put the particular Live Query in the queue if it doesn't already exist
			if ( $.inArray(id, $.livequery.queue) < 0 )
				$.livequery.queue.push( id );
		}
		else
			// Put each Live Query in the queue if it doesn't already exist
			$.each( $.livequery.queries, function(id) {
				if ( $.inArray(id, $.livequery.queue) < 0 )
					$.livequery.queue.push( id );
			});
		
		// Clear timeout if it already exists
		if ($.livequery.timeout) clearTimeout($.livequery.timeout);
		// Create a timeout to check the queue and actually run the Live Queries
		$.livequery.timeout = setTimeout($.livequery.checkQueue, 20);
	},
	
	stop: function(id) {
		if (id != undefined)
			// Stop are particular Live Query
			$.livequery.queries[ id ].stop();
		else
			// Stop all Live Queries
			$.each( $.livequery.queries, function(id) {
				$.livequery.queries[ id ].stop();
			});
	}
});

// Register core DOM manipulation methods
$.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');

// Run Live Queries when the Document is ready
$(function() { $.livequery.play(); });


// Save a reference to the original init method
var init = $.prototype.init;

// Create a new init method that exposes two new properties: selector and context
$.prototype.init = function(a,c) {
	// Call the original init and save the result
	var r = init.apply(this, arguments);
	
	// Copy over properties if they exist already
	if (a && a.selector)
		r.context = a.context, r.selector = a.selector;
		
	// Set properties
	if ( typeof a == 'string' )
		r.context = c || document, r.selector = a;
	
	// Return the result
	return r;
};

// Give the init function the jQuery prototype for later instantiation (needed after Rev 4091)
$.prototype.init.prototype = $.prototype;
	
})(jQuery);
;// Beginning /res/js/os/backbone.js:
//     Backbone.js 0.5.3
//     (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
//     Backbone may be freely distributed under the MIT license.
//     For all details and documentation:
//     http://documentcloud.github.com/backbone

(function(){

  // Initial Setup
  // -------------

  // Save a reference to the global object.
  var root = this;

  // Save the previous value of the `Backbone` variable.
  var previousBackbone = root.Backbone;

  // The top-level namespace. All public Backbone classes and modules will
  // be attached to this. Exported for both CommonJS and the browser.
  var Backbone;
  if (typeof exports !== 'undefined') {
    Backbone = exports;
  } else {
    Backbone = root.Backbone = {};
  }

  // Current version of the library. Keep in sync with `package.json`.
  Backbone.VERSION = '0.5.3';

  // Require Underscore, if we're on the server, and it's not already present.
  var _ = root._;
  if (!_ && (typeof require !== 'undefined')) _ = require('underscore')._;

  // For Backbone's purposes, jQuery or Zepto owns the `$` variable.
  var $ = root.jQuery || root.Zepto;

  // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
  // to its previous owner. Returns a reference to this Backbone object.
  Backbone.noConflict = function() {
    root.Backbone = previousBackbone;
    return this;
  };

  // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option will
  // fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and set a
  // `X-Http-Method-Override` header.
  Backbone.emulateHTTP = false;

  // Turn on `emulateJSON` to support legacy servers that can't deal with direct
  // `application/json` requests ... will encode the body as
  // `application/x-www-form-urlencoded` instead and will send the model in a
  // form param named `model`.
  Backbone.emulateJSON = false;

  // Backbone.Events
  // -----------------

  // A module that can be mixed in to *any object* in order to provide it with
  // custom events. You may `bind` or `unbind` a callback function to an event;
  // `trigger`-ing an event fires all callbacks in succession.
  //
  //     var object = {};
  //     _.extend(object, Backbone.Events);
  //     object.bind('expand', function(){ alert('expanded'); });
  //     object.trigger('expand');
  //
  Backbone.Events = {

    // Bind an event, specified by a string name, `ev`, to a `callback` function.
    // Passing `"all"` will bind the callback to all events fired.
    bind : function(ev, callback, context) {
      var calls = this._callbacks || (this._callbacks = {});
      var list  = calls[ev] || (calls[ev] = []);
      list.push([callback, context]);
      return this;
    },

    // Remove one or many callbacks. If `callback` is null, removes all
    // callbacks for the event. If `ev` is null, removes all bound callbacks
    // for all events.
    unbind : function(ev, callback) {
      var calls;
      if (!ev) {
        this._callbacks = {};
      } else if (calls = this._callbacks) {
        if (!callback) {
          calls[ev] = [];
        } else {
          var list = calls[ev];
          if (!list) return this;
          for (var i = 0, l = list.length; i < l; i++) {
            if (list[i] && callback === list[i][0]) {
              list[i] = null;
              break;
            }
          }
        }
      }
      return this;
    },

    // Trigger an event, firing all bound callbacks. Callbacks are passed the
    // same arguments as `trigger` is, apart from the event name.
    // Listening for `"all"` passes the true event name as the first argument.
    trigger : function(eventName) {
      var list, calls, ev, callback, args;
      var both = 2;
      if (!(calls = this._callbacks)) return this;
      while (both--) {
        ev = both ? eventName : 'all';
        if (list = calls[ev]) {
          for (var i = 0, l = list.length; i < l; i++) {
            if (!(callback = list[i])) {
              list.splice(i, 1); i--; l--;
            } else {
              args = both ? Array.prototype.slice.call(arguments, 1) : arguments;
              callback[0].apply(callback[1] || this, args);
            }
          }
        }
      }
      return this;
    }

  };

  // Backbone.Model
  // --------------

  // Create a new model, with defined attributes. A client id (`cid`)
  // is automatically generated and assigned for you.
  Backbone.Model = function(attributes, options) {
    var defaults;
    attributes || (attributes = {});
    if (defaults = this.defaults) {
      if (_.isFunction(defaults)) defaults = defaults.call(this);
      attributes = _.extend({}, defaults, attributes);
    }
    this.attributes = {};
    this._escapedAttributes = {};
    this.cid = _.uniqueId('c');
    this.set(attributes, {silent : true});
    this._changed = false;
    this._previousAttributes = _.clone(this.attributes);
    if (options && options.collection) this.collection = options.collection;
    this.initialize(attributes, options);
  };

  // Attach all inheritable methods to the Model prototype.
  _.extend(Backbone.Model.prototype, Backbone.Events, {

    // A snapshot of the model's previous attributes, taken immediately
    // after the last `"change"` event was fired.
    _previousAttributes : null,

    // Has the item been changed since the last `"change"` event?
    _changed : false,

    // The default name for the JSON `id` attribute is `"id"`. MongoDB and
    // CouchDB users may want to set this to `"_id"`.
    idAttribute : 'id',

    // Initialize is an empty function by default. Override it with your own
    // initialization logic.
    initialize : function(){},

    // Return a copy of the model's `attributes` object.
    toJSON : function() {
      return _.clone(this.attributes);
    },

    // Get the value of an attribute.
    get : function(attr) {
      return this.attributes[attr];
    },

    // Get the HTML-escaped value of an attribute.
    escape : function(attr) {
      var html;
      if (html = this._escapedAttributes[attr]) return html;
      var val = this.attributes[attr];
      return this._escapedAttributes[attr] = escapeHTML(val == null ? '' : '' + val);
    },

    // Returns `true` if the attribute contains a value that is not null
    // or undefined.
    has : function(attr) {
      return this.attributes[attr] != null;
    },

    // Set a hash of model attributes on the object, firing `"change"` unless you
    // choose to silence it.
    set : function(attrs, options) {

      // Extract attributes and options.
      options || (options = {});
      if (!attrs) return this;
      if (attrs.attributes) attrs = attrs.attributes;
      var now = this.attributes, escaped = this._escapedAttributes;

      // Run validation.
      if (!options.silent && this.validate && !this._performValidation(attrs, options)) return false;

      // Check for changes of `id`.
      if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];

      // We're about to start triggering change events.
      var alreadyChanging = this._changing;
      this._changing = true;

      // Update attributes.
      for (var attr in attrs) {
        var val = attrs[attr];
        if (!_.isEqual(now[attr], val)) {
          now[attr] = val;
          delete escaped[attr];
          this._changed = true;
          if (!options.silent) this.trigger('change:' + attr, this, val, options);
        }
      }

      // Fire the `"change"` event, if the model has been changed.
      if (!alreadyChanging && !options.silent && this._changed) this.change(options);
      this._changing = false;
      return this;
    },

    // Remove an attribute from the model, firing `"change"` unless you choose
    // to silence it. `unset` is a noop if the attribute doesn't exist.
    unset : function(attr, options) {
      if (!(attr in this.attributes)) return this;
      options || (options = {});
      var value = this.attributes[attr];

      // Run validation.
      var validObj = {};
      validObj[attr] = void 0;
      if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;

      // Remove the attribute.
      delete this.attributes[attr];
      delete this._escapedAttributes[attr];
      if (attr == this.idAttribute) delete this.id;
      this._changed = true;
      if (!options.silent) {
        this.trigger('change:' + attr, this, void 0, options);
        this.change(options);
      }
      return this;
    },

    // Clear all attributes on the model, firing `"change"` unless you choose
    // to silence it.
    clear : function(options) {
      options || (options = {});
      var attr;
      var old = this.attributes;

      // Run validation.
      var validObj = {};
      for (attr in old) validObj[attr] = void 0;
      if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;

      this.attributes = {};
      this._escapedAttributes = {};
      this._changed = true;
      if (!options.silent) {
        for (attr in old) {
          this.trigger('change:' + attr, this, void 0, options);
        }
        this.change(options);
      }
      return this;
    },

    // Fetch the model from the server. If the server's representation of the
    // model differs from its current attributes, they will be overriden,
    // triggering a `"change"` event.
    fetch : function(options) {
      options || (options = {});
      var model = this;
      var success = options.success;
      options.success = function(resp, status, xhr) {
        if (!model.set(model.parse(resp, xhr), options)) return false;
        if (success) success(model, resp);
      };
      options.error = wrapError(options.error, model, options);
      return (this.sync || Backbone.sync).call(this, 'read', this, options);
    },

    // Set a hash of model attributes, and sync the model to the server.
    // If the server returns an attributes hash that differs, the model's
    // state will be `set` again.
    save : function(attrs, options) {
      options || (options = {});
      if (attrs && !this.set(attrs, options)) return false;
      var model = this;
      var success = options.success;
      options.success = function(resp, status, xhr) {
        if (!model.set(model.parse(resp, xhr), options)) return false;
        if (success) success(model, resp, xhr);
      };
      options.error = wrapError(options.error, model, options);
      var method = this.isNew() ? 'create' : 'update';
      return (this.sync || Backbone.sync).call(this, method, this, options);
    },

    // Destroy this model on the server if it was already persisted. Upon success, the model is removed
    // from its collection, if it has one.
    destroy : function(options) {
      options || (options = {});
      if (this.isNew()) return this.trigger('destroy', this, this.collection, options);
      var model = this;
      var success = options.success;
      options.success = function(resp) {
        model.trigger('destroy', model, model.collection, options);
        if (success) success(model, resp);
      };
      options.error = wrapError(options.error, model, options);
      return (this.sync || Backbone.sync).call(this, 'delete', this, options);
    },

    // Default URL for the model's representation on the server -- if you're
    // using Backbone's restful methods, override this to change the endpoint
    // that will be called.
    url : function() {
      var base = getUrl(this.collection) || this.urlRoot || urlError();
      if (this.isNew()) return base;
      return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
    },

    // **parse** converts a response into the hash of attributes to be `set` on
    // the model. The default implementation is just to pass the response along.
    parse : function(resp, xhr) {
      return resp;
    },

    // Create a new model with identical attributes to this one.
    clone : function() {
      return new this.constructor(this);
    },

    // A model is new if it has never been saved to the server, and lacks an id.
    isNew : function() {
      return this.id == null;
    },

    // Call this method to manually fire a `change` event for this model.
    // Calling this will cause all objects observing the model to update.
    change : function(options) {
      this.trigger('change', this, options);
      this._previousAttributes = _.clone(this.attributes);
      this._changed = false;
    },

    // Determine if the model has changed since the last `"change"` event.
    // If you specify an attribute name, determine if that attribute has changed.
    hasChanged : function(attr) {
      if (attr) return this._previousAttributes[attr] != this.attributes[attr];
      return this._changed;
    },

    // Return an object containing all the attributes that have changed, or false
    // if there are no changed attributes. Useful for determining what parts of a
    // view need to be updated and/or what attributes need to be persisted to
    // the server.
    changedAttributes : function(now) {
      now || (now = this.attributes);
      var old = this._previousAttributes;
      var changed = false;
      for (var attr in now) {
        if (!_.isEqual(old[attr], now[attr])) {
          changed = changed || {};
          changed[attr] = now[attr];
        }
      }
      return changed;
    },

    // Get the previous value of an attribute, recorded at the time the last
    // `"change"` event was fired.
    previous : function(attr) {
      if (!attr || !this._previousAttributes) return null;
      return this._previousAttributes[attr];
    },

    // Get all of the attributes of the model at the time of the previous
    // `"change"` event.
    previousAttributes : function() {
      return _.clone(this._previousAttributes);
    },

    // Run validation against a set of incoming attributes, returning `true`
    // if all is well. If a specific `error` callback has been passed,
    // call that instead of firing the general `"error"` event.
    _performValidation : function(attrs, options) {
      var error = this.validate(attrs);
      if (error) {
        if (options.error) {
          options.error(this, error, options);
        } else {
          this.trigger('error', this, error, options);
        }
        return false;
      }
      return true;
    }

  });

  // Backbone.Collection
  // -------------------

  // Provides a standard collection class for our sets of models, ordered
  // or unordered. If a `comparator` is specified, the Collection will maintain
  // its models in sort order, as they're added and removed.
  Backbone.Collection = function(models, options) {
    options || (options = {});
    if (options.comparator) this.comparator = options.comparator;
    _.bindAll(this, '_onModelEvent', '_removeReference');
    this._reset();
    if (models) this.reset(models, {silent: true});
    this.initialize.apply(this, arguments);
  };

  // Define the Collection's inheritable methods.
  _.extend(Backbone.Collection.prototype, Backbone.Events, {

    // The default model for a collection is just a **Backbone.Model**.
    // This should be overridden in most cases.
    model : Backbone.Model,

    // Initialize is an empty function by default. Override it with your own
    // initialization logic.
    initialize : function(){},

    // The JSON representation of a Collection is an array of the
    // models' attributes.
    toJSON : function() {
      return this.map(function(model){ return model.toJSON(); });
    },

    // Add a model, or list of models to the set. Pass **silent** to avoid
    // firing the `added` event for every new model.
    add : function(models, options) {
      if (_.isArray(models)) {
        for (var i = 0, l = models.length; i < l; i++) {
          this._add(models[i], options);
        }
      } else {
        this._add(models, options);
      }
      return this;
    },

    // Remove a model, or a list of models from the set. Pass silent to avoid
    // firing the `removed` event for every model removed.
    remove : function(models, options) {
      if (_.isArray(models)) {
        for (var i = 0, l = models.length; i < l; i++) {
          this._remove(models[i], options);
        }
      } else {
        this._remove(models, options);
      }
      return this;
    },

    // Get a model from the set by id.
    get : function(id) {
      if (id == null) return null;
      return this._byId[id.id != null ? id.id : id];
    },

    // Get a model from the set by client id.
    getByCid : function(cid) {
      return cid && this._byCid[cid.cid || cid];
    },

    // Get the model at the given index.
    at: function(index) {
      return this.models[index];
    },

    // Force the collection to re-sort itself. You don't need to call this under normal
    // circumstances, as the set will maintain sort order as each item is added.
    sort : function(options) {
      options || (options = {});
      if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
      this.models = this.sortBy(this.comparator);
      if (!options.silent) this.trigger('reset', this, options);
      return this;
    },

    // Pluck an attribute from each model in the collection.
    pluck : function(attr) {
      return _.map(this.models, function(model){ return model.get(attr); });
    },

    // When you have more items than you want to add or remove individually,
    // you can reset the entire set with a new list of models, without firing
    // any `added` or `removed` events. Fires `reset` when finished.
    reset : function(models, options) {
      models  || (models = []);
      options || (options = {});
      this.each(this._removeReference);
      this._reset();
      this.add(models, {silent: true});
      if (!options.silent) this.trigger('reset', this, options);
      return this;
    },

    // Fetch the default set of models for this collection, resetting the
    // collection when they arrive. If `add: true` is passed, appends the
    // models to the collection instead of resetting.
    fetch : function(options) {
      options || (options = {});
      var collection = this;
      var success = options.success;
      options.success = function(resp, status, xhr) {
        collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
        if (success) success(collection, resp);
      };
      options.error = wrapError(options.error, collection, options);
      return (this.sync || Backbone.sync).call(this, 'read', this, options);
    },

    // Create a new instance of a model in this collection. After the model
    // has been created on the server, it will be added to the collection.
    // Returns the model, or 'false' if validation on a new model fails.
    create : function(model, options) {
      var coll = this;
      options || (options = {});
      model = this._prepareModel(model, options);
      if (!model) return false;
      var success = options.success;
      options.success = function(nextModel, resp, xhr) {
        coll.add(nextModel, options);
        if (success) success(nextModel, resp, xhr);
      };
      model.save(null, options);
      return model;
    },

    // **parse** converts a response into a list of models to be added to the
    // collection. The default implementation is just to pass it through.
    parse : function(resp, xhr) {
      return resp;
    },

    // Proxy to _'s chain. Can't be proxied the same way the rest of the
    // underscore methods are proxied because it relies on the underscore
    // constructor.
    chain: function () {
      return _(this.models).chain();
    },

    // Reset all internal state. Called when the collection is reset.
    _reset : function(options) {
      this.length = 0;
      this.models = [];
      this._byId  = {};
      this._byCid = {};
    },

    // Prepare a model to be added to this collection
    _prepareModel: function(model, options) {
      if (!(model instanceof Backbone.Model)) {
        var attrs = model;
        model = new this.model(attrs, {collection: this});
        if (model.validate && !model._performValidation(attrs, options)) model = false;
      } else if (!model.collection) {
        model.collection = this;
      }
      return model;
    },

    // Internal implementation of adding a single model to the set, updating
    // hash indexes for `id` and `cid` lookups.
    // Returns the model, or 'false' if validation on a new model fails.
    _add : function(model, options) {
      options || (options = {});
      model = this._prepareModel(model, options);
      if (!model) return false;
      var already = this.getByCid(model);
      if (already) throw new Error(["Can't add the same model to a set twice", already.id]);
      this._byId[model.id] = model;
      this._byCid[model.cid] = model;
      var index = options.at != null ? options.at :
                  this.comparator ? this.sortedIndex(model, this.comparator) :
                  this.length;
      this.models.splice(index, 0, model);
      model.bind('all', this._onModelEvent);
      this.length++;
      if (!options.silent) model.trigger('add', model, this, options);
      return model;
    },

    // Internal implementation of removing a single model from the set, updating
    // hash indexes for `id` and `cid` lookups.
    _remove : function(model, options) {
      options || (options = {});
      model = this.getByCid(model) || this.get(model);
      if (!model) return null;
      delete this._byId[model.id];
      delete this._byCid[model.cid];
      this.models.splice(this.indexOf(model), 1);
      this.length--;
      if (!options.silent) model.trigger('remove', model, this, options);
      this._removeReference(model);
      return model;
    },

    // Internal method to remove a model's ties to a collection.
    _removeReference : function(model) {
      if (this == model.collection) {
        delete model.collection;
      }
      model.unbind('all', this._onModelEvent);
    },

    // Internal method called every time a model in the set fires an event.
    // Sets need to update their indexes when models change ids. All other
    // events simply proxy through. "add" and "remove" events that originate
    // in other collections are ignored.
    _onModelEvent : function(ev, model, collection, options) {
      if ((ev == 'add' || ev == 'remove') && collection != this) return;
      if (ev == 'destroy') {
        this._remove(model, options);
      }
      if (model && ev === 'change:' + model.idAttribute) {
        delete this._byId[model.previous(model.idAttribute)];
        this._byId[model.id] = model;
      }
      this.trigger.apply(this, arguments);
    }

  });

  // Underscore methods that we want to implement on the Collection.
  var methods = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find', 'detect',
    'filter', 'select', 'reject', 'every', 'all', 'some', 'any', 'include',
    'contains', 'invoke', 'max', 'min', 'sortBy', 'sortedIndex', 'toArray', 'size',
    'first', 'rest', 'last', 'without', 'indexOf', 'lastIndexOf', 'isEmpty', 'groupBy'];

  // Mix in each Underscore method as a proxy to `Collection#models`.
  _.each(methods, function(method) {
    Backbone.Collection.prototype[method] = function() {
      return _[method].apply(_, [this.models].concat(_.toArray(arguments)));
    };
  });

  // Backbone.Router
  // -------------------

  // Routers map faux-URLs to actions, and fire events when routes are
  // matched. Creating a new one sets its `routes` hash, if not set statically.
  Backbone.Router = function(options) {
    options || (options = {});
    if (options.routes) this.routes = options.routes;
    this._bindRoutes();
    this.initialize.apply(this, arguments);
  };

  // Cached regular expressions for matching named param parts and splatted
  // parts of route strings.
  var namedParam    = /:([\w\d]+)/g;
  var splatParam    = /\*([\w\d]+)/g;
  var escapeRegExp  = /[-[\]{}()+?.,\\^$|#\s]/g;

  // Set up all inheritable **Backbone.Router** properties and methods.
  _.extend(Backbone.Router.prototype, Backbone.Events, {

    // Initialize is an empty function by default. Override it with your own
    // initialization logic.
    initialize : function(){},

    // Manually bind a single named route to a callback. For example:
    //
    //     this.route('search/:query/p:num', 'search', function(query, num) {
    //       ...
    //     });
    //
    route : function(route, name, callback) {
      Backbone.history || (Backbone.history = new Backbone.History);
      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
      Backbone.history.route(route, _.bind(function(fragment) {
        var args = this._extractParameters(route, fragment);
        callback.apply(this, args);
        this.trigger.apply(this, ['route:' + name].concat(args));
      }, this));
    },

    // Simple proxy to `Backbone.history` to save a fragment into the history.
    navigate : function(fragment, triggerRoute) {
      Backbone.history.navigate(fragment, triggerRoute);
    },

    // Bind all defined routes to `Backbone.history`. We have to reverse the
    // order of the routes here to support behavior where the most general
    // routes can be defined at the bottom of the route map.
    _bindRoutes : function() {
      if (!this.routes) return;
      var routes = [];
      for (var route in this.routes) {
        routes.unshift([route, this.routes[route]]);
      }
      for (var i = 0, l = routes.length; i < l; i++) {
        this.route(routes[i][0], routes[i][1], this[routes[i][1]]);
      }
    },

    // Convert a route string into a regular expression, suitable for matching
    // against the current location hash.
    _routeToRegExp : function(route) {
      route = route.replace(escapeRegExp, "\\$&")
                   .replace(namedParam, "([^\/]*)")
                   .replace(splatParam, "(.*?)");
      return new RegExp('^' + route + '$');
    },

    // Given a route, and a URL fragment that it matches, return the array of
    // extracted parameters.
    _extractParameters : function(route, fragment) {
      return route.exec(fragment).slice(1);
    }

  });

  // Backbone.History
  // ----------------

  // Handles cross-browser history management, based on URL fragments. If the
  // browser does not support `onhashchange`, falls back to polling.
  Backbone.History = function() {
    this.handlers = [];
    _.bindAll(this, 'checkUrl');
  };

  // Cached regex for cleaning hashes.
  var hashStrip = /^#*/;

  // Cached regex for detecting MSIE.
  var isExplorer = /msie [\w.]+/;

  // Has the history handling already been started?
  var historyStarted = false;

  // Set up all inheritable **Backbone.History** properties and methods.
  _.extend(Backbone.History.prototype, {

    // The default interval to poll for hash changes, if necessary, is
    // twenty times a second.
    interval: 50,

    // Get the cross-browser normalized URL fragment, either from the URL,
    // the hash, or the override.
    getFragment : function(fragment, forcePushState) {
      if (fragment == null) {
        if (this._hasPushState || forcePushState) {
          fragment = window.location.pathname;
          var search = window.location.search;
          if (search) fragment += search;
          if (fragment.indexOf(this.options.root) == 0) fragment = fragment.substr(this.options.root.length);
        } else {
          fragment = window.location.hash;
        }
      }
      return decodeURIComponent(fragment.replace(hashStrip, ''));
    },

    // Start the hash change handling, returning `true` if the current URL matches
    // an existing route, and `false` otherwise.
    start : function(options) {

      // Figure out the initial configuration. Do we need an iframe?
      // Is pushState desired ... is it available?
      if (historyStarted) throw new Error("Backbone.history has already been started");
      this.options          = _.extend({}, {root: '/'}, this.options, options);
      this._wantsPushState  = !!this.options.pushState;
      this._hasPushState    = !!(this.options.pushState && window.history && window.history.pushState);
      var fragment          = this.getFragment();
      var docMode           = document.documentMode;
      var oldIE             = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
      if (oldIE) {
        this.iframe = $('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
        this.navigate(fragment);
      }

      // Depending on whether we're using pushState or hashes, and whether
      // 'onhashchange' is supported, determine how we check the URL state.
      if (this._hasPushState) {
        $(window).bind('popstate', this.checkUrl);
      } else if ('onhashchange' in window && !oldIE) {
        $(window).bind('hashchange', this.checkUrl);
      } else {
        setInterval(this.checkUrl, this.interval);
      }

      // Determine if we need to change the base url, for a pushState link
      // opened by a non-pushState browser.
      this.fragment = fragment;
      historyStarted = true;
      var loc = window.location;
      var atRoot  = loc.pathname == this.options.root;
      if (this._wantsPushState && !this._hasPushState && !atRoot) {
        this.fragment = this.getFragment(null, true);
        window.location.replace(this.options.root + '#' + this.fragment);
        // Return immediately as browser will do redirect to new url
        return true;
      } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
        this.fragment = loc.hash.replace(hashStrip, '');
        window.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment);
      }

      if (!this.options.silent) {
        return this.loadUrl();
      }
    },

    // Add a route to be tested when the fragment changes. Routes added later may
    // override previous routes.
    route : function(route, callback) {
      this.handlers.unshift({route : route, callback : callback});
    },

    // Checks the current URL to see if it has changed, and if it has,
    // calls `loadUrl`, normalizing across the hidden iframe.
    checkUrl : function(e) {
      var current = this.getFragment();
      if (current == this.fragment && this.iframe) current = this.getFragment(this.iframe.location.hash);
      if (current == this.fragment || current == decodeURIComponent(this.fragment)) return false;
      if (this.iframe) this.navigate(current);
      this.loadUrl() || this.loadUrl(window.location.hash);
    },

    // Attempt to load the current URL fragment. If a route succeeds with a
    // match, returns `true`. If no defined routes matches the fragment,
    // returns `false`.
    loadUrl : function(fragmentOverride) {
      var fragment = this.fragment = this.getFragment(fragmentOverride);
      var matched = _.any(this.handlers, function(handler) {
        if (handler.route.test(fragment)) {
          handler.callback(fragment);
          return true;
        }
      });
      return matched;
    },

    // Save a fragment into the hash history. You are responsible for properly
    // URL-encoding the fragment in advance. This does not trigger
    // a `hashchange` event.
    navigate : function(fragment, triggerRoute) {
      var frag = (fragment || '').replace(hashStrip, '');
      if (this.fragment == frag || this.fragment == decodeURIComponent(frag)) return;
      if (this._hasPushState) {
        var loc = window.location;
        if (frag.indexOf(this.options.root) != 0) frag = this.options.root + frag;
        this.fragment = frag;
        window.history.pushState({}, document.title, loc.protocol + '//' + loc.host + frag);
      } else {
        window.location.hash = this.fragment = frag;
        if (this.iframe && (frag != this.getFragment(this.iframe.location.hash))) {
          this.iframe.document.open().close();
          this.iframe.location.hash = frag;
        }
      }
      if (triggerRoute) this.loadUrl(fragment);
    }

  });

  // Backbone.View
  // -------------

  // Creating a Backbone.View creates its initial element outside of the DOM,
  // if an existing element is not provided...
  Backbone.View = function(options) {
    this.cid = _.uniqueId('view');
    this._configure(options || {});
    this._ensureElement();
    this.delegateEvents();
    this.initialize.apply(this, arguments);
  };

  // Element lookup, scoped to DOM elements within the current view.
  // This should be prefered to global lookups, if you're dealing with
  // a specific view.
  var selectorDelegate = function(selector) {
    return $(selector, this.el);
  };

  // Cached regex to split keys for `delegate`.
  var eventSplitter = /^(\S+)\s*(.*)$/;

  // List of view options to be merged as properties.
  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName'];

  // Set up all inheritable **Backbone.View** properties and methods.
  _.extend(Backbone.View.prototype, Backbone.Events, {

    // The default `tagName` of a View's element is `"div"`.
    tagName : 'div',

    // Attach the `selectorDelegate` function as the `$` property.
    $       : selectorDelegate,

    // Initialize is an empty function by default. Override it with your own
    // initialization logic.
    initialize : function(){},

    // **render** is the core function that your view should override, in order
    // to populate its element (`this.el`), with the appropriate HTML. The
    // convention is for **render** to always return `this`.
    render : function() {
      return this;
    },

    // Remove this view from the DOM. Note that the view isn't present in the
    // DOM by default, so calling this method may be a no-op.
    remove : function() {
      $(this.el).remove();
      return this;
    },

    // For small amounts of DOM Elements, where a full-blown template isn't
    // needed, use **make** to manufacture elements, one at a time.
    //
    //     var el = this.make('li', {'class': 'row'}, this.model.escape('title'));
    //
    make : function(tagName, attributes, content) {
      var el = document.createElement(tagName);
      if (attributes) $(el).attr(attributes);
      if (content) $(el).html(content);
      return el;
    },

    // Set callbacks, where `this.callbacks` is a hash of
    //
    // *{"event selector": "callback"}*
    //
    //     {
    //       'mousedown .title':  'edit',
    //       'click .button':     'save'
    //     }
    //
    // pairs. Callbacks will be bound to the view, with `this` set properly.
    // Uses event delegation for efficiency.
    // Omitting the selector binds the event to `this.el`.
    // This only works for delegate-able events: not `focus`, `blur`, and
    // not `change`, `submit`, and `reset` in Internet Explorer.
    delegateEvents : function(events) {
      if (!(events || (events = this.events))) return;
      if (_.isFunction(events)) events = events.call(this);
      $(this.el).unbind('.delegateEvents' + this.cid);
      for (var key in events) {
        var method = this[events[key]];
        if (!method) throw new Error('Event "' + events[key] + '" does not exist');
        var match = key.match(eventSplitter);
        var eventName = match[1], selector = match[2];
        method = _.bind(method, this);
        eventName += '.delegateEvents' + this.cid;
        if (selector === '') {
          $(this.el).bind(eventName, method);
        } else {
          $(this.el).delegate(selector, eventName, method);
        }
      }
    },

    // Performs the initial configuration of a View with a set of options.
    // Keys with special meaning *(model, collection, id, className)*, are
    // attached directly to the view.
    _configure : function(options) {
      if (this.options) options = _.extend({}, this.options, options);
      for (var i = 0, l = viewOptions.length; i < l; i++) {
        var attr = viewOptions[i];
        if (options[attr]) this[attr] = options[attr];
      }
      this.options = options;
    },

    // Ensure that the View has a DOM element to render into.
    // If `this.el` is a string, pass it through `$()`, take the first
    // matching element, and re-assign it to `el`. Otherwise, create
    // an element from the `id`, `className` and `tagName` proeprties.
    _ensureElement : function() {
      if (!this.el) {
        var attrs = this.attributes || {};
        if (this.id) attrs.id = this.id;
        if (this.className) attrs['class'] = this.className;
        this.el = this.make(this.tagName, attrs);
      } else if (_.isString(this.el)) {
        this.el = $(this.el).get(0);
      }
    }

  });

  // The self-propagating extend function that Backbone classes use.
  var extend = function (protoProps, classProps) {
    var child = inherits(this, protoProps, classProps);
    child.extend = this.extend;
    return child;
  };

  // Set up inheritance for the model, collection, and view.
  Backbone.Model.extend = Backbone.Collection.extend =
    Backbone.Router.extend = Backbone.View.extend = extend;

  // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
  var methodMap = {
    'create': 'POST',
    'update': 'PUT',
    'delete': 'DELETE',
    'read'  : 'GET'
  };

  // Backbone.sync
  // -------------

  // Override this function to change the manner in which Backbone persists
  // models to the server. You will be passed the type of request, and the
  // model in question. By default, uses makes a RESTful Ajax request
  // to the model's `url()`. Some possible customizations could be:
  //
  // * Use `setTimeout` to batch rapid-fire updates into a single request.
  // * Send up the models as XML instead of JSON.
  // * Persist models via WebSockets instead of Ajax.
  //
  // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
  // as `POST`, with a `_method` parameter containing the true HTTP method,
  // as well as all requests with the body as `application/x-www-form-urlencoded` instead of
  // `application/json` with the model in a param named `model`.
  // Useful when interfacing with server-side languages like **PHP** that make
  // it difficult to read the body of `PUT` requests.
  Backbone.sync = function(method, model, options) {
    var type = methodMap[method];

    // Default JSON-request options.
    var params = _.extend({
      type:         type,
      dataType:     'json'
    }, options);

    // Ensure that we have a URL.
    if (!params.url) {
      params.url = getUrl(model) || urlError();
    }

    // Ensure that we have the appropriate request data.
    if (!params.data && model && (method == 'create' || method == 'update')) {
      params.contentType = 'application/json';
      params.data = JSON.stringify(model.toJSON());
    }

    // For older servers, emulate JSON by encoding the request into an HTML-form.
    if (Backbone.emulateJSON) {
      params.contentType = 'application/x-www-form-urlencoded';
      params.data        = params.data ? {model : params.data} : {};
    }

    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
    // And an `X-HTTP-Method-Override` header.
    if (Backbone.emulateHTTP) {
      if (type === 'PUT' || type === 'DELETE') {
        if (Backbone.emulateJSON) params.data._method = type;
        params.type = 'POST';
        params.beforeSend = function(xhr) {
          xhr.setRequestHeader('X-HTTP-Method-Override', type);
        };
      }
    }

    // Don't process data on a non-GET request.
    if (params.type !== 'GET' && !Backbone.emulateJSON) {
      params.processData = false;
    }

    // Make the request.
    return $.ajax(params);
  };

  // Helpers
  // -------

  // Shared empty constructor function to aid in prototype-chain creation.
  var ctor = function(){};

  // Helper function to correctly set up the prototype chain, for subclasses.
  // Similar to `goog.inherits`, but uses a hash of prototype properties and
  // class properties to be extended.
  var inherits = function(parent, protoProps, staticProps) {
    var child;

    // The constructor function for the new subclass is either defined by you
    // (the "constructor" property in your `extend` definition), or defaulted
    // by us to simply call `super()`.
    if (protoProps && protoProps.hasOwnProperty('constructor')) {
      child = protoProps.constructor;
    } else {
      child = function(){ return parent.apply(this, arguments); };
    }

    // Inherit class (static) properties from parent.
    _.extend(child, parent);

    // Set the prototype chain to inherit from `parent`, without calling
    // `parent`'s constructor function.
    ctor.prototype = parent.prototype;
    child.prototype = new ctor();

    // Add prototype properties (instance properties) to the subclass,
    // if supplied.
    if (protoProps) _.extend(child.prototype, protoProps);

    // Add static properties to the constructor function, if supplied.
    if (staticProps) _.extend(child, staticProps);

    // Correctly set child's `prototype.constructor`.
    child.prototype.constructor = child;

    // Set a convenience property in case the parent's prototype is needed later.
    child.__super__ = parent.prototype;

    return child;
  };

  // Helper function to get a URL from a Model or Collection as a property
  // or as a function.
  var getUrl = function(object) {
    if (!(object && object.url)) return null;
    return _.isFunction(object.url) ? object.url() : object.url;
  };

  // Throw an error when a URL is needed, and none is supplied.
  var urlError = function() {
    throw new Error('A "url" property or function must be specified');
  };

  // Wrap an optional error callback with a fallback error event.
  var wrapError = function(onError, model, options) {
    return function(resp) {
      if (onError) {
        onError(model, resp, options);
      } else {
        model.trigger('error', model, resp, options);
      }
    };
  };

  // Helper function to escape a string for HTML rendering.
  var escapeHTML = function(string) {
    return string.replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
  };

}).call(this);

;// Beginning /res/js/v2/ss/plugins/jquery.ss.js:
/*
 * This extends $ with "ss" to allow us to make utility calls such as $.ss.dialog.input(...)
 */
(function($){
    $.ss = {
        "enable_datepickers": function(container){
            $('.date_input', container).datepicker({
                dateFormat: 'dd M yy',
                onClose: function () {$(this).valid(); }
            });
        },
        "dialog": {
            /*
             * Shows a simple dialog for getting a string input from the user. The 
             * callback function has this set to the dictionary:
             * {
             *     "value": the user's entered value
             * }
             */
            "input": function(title, callback, initial_value ){
                $('<div>').ssdialog({
                    'content': {
                        'html': '<input type="text" value="'+(initial_value ||'')+'">',
                        'refresh_on_show': true
                    },
                    'title': title,
                    'height': 142,
                    'focus_input': true,
                    'buttons': {
                        'Save': null,
                        'OK': function(namespace){
                            var value = this.data(namespace)['container'].find('input').val().trim();
                            if(!value){
                                alert("Please enter a value.");
                            } else {
                                callback = _.bind(callback, {"value": value});
                                callback();
                                this[namespace]('hide');
                            }
                        }
                    }
                });
            },
            /*
             * Shows a simple message to the user.
             */
            "message": function(title, message, callback){
                $('<div>').ssdialog({
                    'content': {
                        'html': "<span>" + message + "</span>",
                        'refresh_on_show': true
                    },
                    'title': title,
                    'buttons': {
                        'Save': null,
                        'Cancel': null,
                        'OK': function(namespace){
                            if(callback) {
                                callback();
                            }
                            this[namespace]('hide');
                        }
                    }
                });
            },
            /*
             * Similar to the native JavaScript confirm in purpose. For the callback, the
             * 'this' object will have an attribute 'confirmed' that will be true if the user
             * hit OK and false otherwise.
             */
            "confirm": function(title, message, callback, button_text){
                button_text || (button_text = "OK");
                var buttons = {
                    'Save': null
                };
                buttons[button_text] = function(namespace){
                    if(callback) {
                        callback = _.bind(callback, {"confirmed": true});
                        callback();
                    }
                    this[namespace]('hide');
                };
                buttons['Cancel'] = function(namespace){
                    if(callback) {
                        callback = _.bind(callback, {"confirmed": false});
                        callback();
                    }
                    this[namespace]('hide');
                };
                
                $('<div>').ssdialog({
                    'content': {
                        'html': "<span>" + message + "</span>",
                        'refresh_on_show': true
                    },
                    'title': title,
                    'buttons': buttons
                });
            }
        },
        "wysiwyg":{
            /*
             * Creates a wysiwyg editor the given jQuery object (which should be a textarea).
             */
            "create": function($input, options){
                
                options = options || {};
                var settings = {
                    "callback_fun": null,
                    "use_wysiwyg_blur_callback": true,
                    "hide_html_and_formatting": false
                };
                $.extend(true, settings, options);
                
                var wysiwyg_blur_fun = function(event, wysiwyg_data){
                    // Webkit browsers (Safari, Chrome) don't fire the relevant blur event
                    // for this to work. See: 
                    // http://stackoverflow.com/questions/3891387/iframe-issue-in-google-chrome
                    //
                    // The hack to get around this is below in wysiwyg_focus_fun.
                    var $element = wysiwyg_data['element'];
                    
                    // Only assume we want to blur if the element has the focus class. This is 
                    // to handle the case where our Webkit hack and the regular blur callback
                    // both fire. We don't use the hack exclusively because it doesn't handle
                    // the case where we tab out of the wysiwyg area which can be done in FireFox.
                    if($element.hasClass('focus_shadow')){
                        wysiwyg_data['element'].removeClass('focus_shadow');
                        if(settings['callback_fun']){
                            settings['callback_fun'](event, wysiwyg_data);
                        }
                    }
                };
                
                var frames;
                
                var $document = $(document);
                var unique_id = $.ss.util.unique_id();
                var wysiwyg_focus_fun = function(event, wysiwyg_data){
                    
                    // Webkit browsers don't fire the needed blur event to remove
                    // the focus_shadow class, so instead we remove it by looking
                    // for the user clicking elsewhere on the page.
                    
                    var $element = wysiwyg_data['element'];
                    if(!$element.data("unique_wysiwyg_id")){
                        $element.data("unique_wysiwyg_id", unique_id);
                    }
                    var remove_fun_key = "ss_wysiwyg_blur_hack_fun_" + unique_id;
                    if(!$document.data(remove_fun_key)){
                        $document.data(remove_fun_key, true);
                        $element.addClass('focus_shadow');
                        
                        $document.bind('ss_wysiwyg_blur', function(event, data){
                            // If a wysiwyg ID is provided, don't blur that one.
                            if(!data || !data['unique_id'] || ($element.data("unique_wysiwyg_id") != data['unique_id'])){
                                // Only blur if it has focus in the first place.
                                if($element.hasClass('focus_shadow')){
                                    wysiwyg_blur_fun(event, wysiwyg_data);
                                }
                            }
                        });
                    }
                    
                    // If it hasn't been added already, add a callback to the $document to handle
                    // clicking on it causing the wysiwygs to blur.
                    if(!$document.data("has_wysiwyg_blur")){
                        $document.data("has_wysiwyg_blur", true);
                        $document.click(function(event){
                            var $container = $(event.target).closest(".wysiwyg");
                            
                            // Ian hack - This first 'if' condition is a very hackish way of making sure we're not clicking
                            // on the format edit area of a richtext editor.
                            if( !($(event.target).siblings(".wysiwyg").height() == 23) ){
                                if($container.length){
                                    // Ian hack - don't try to trigger this if the .wysiwyg is a form. This prevents blurring
                                    // when popping up a dialog to build a link which is necessary to be able to add links in
                                    // wysiwyg areas on the custom page builder.
                                    if( !($container.is('form') || $container.hasClass("ui-dialog-content") 
                                            || $container.hasClass("ui-widget-content")) ){
                                        $document.trigger('ss_wysiwyg_blur', {"unique_id":$container.data("unique_wysiwyg_id")});
                                    }
                                } else if($(event.target).is(":visible")){
                                    $document.trigger('ss_wysiwyg_blur');
                                }
                            }
                        });
                    }
                    
                    // Make sure to blur all wysiwygs in case one has focus and the user clicks on
                    // another.
                    $document.trigger('ss_wysiwyg_blur', {"unique_id":$element.data("unique_wysiwyg_id")});
                    $element.addClass('focus_shadow');
                };
                
                var events = {
                    'click' : wysiwyg_focus_fun,
                    //'blur' : wysiwyg_blur_fun,
                    'keyup' : wysiwyg_focus_fun
                };
                
                // The blur event provided doesn't work well in all cases so sometimes we might
                // not want to use it. For instance, it will trigger when clicking on the toolbar.
                if(settings['use_wysiwyg_blur_callback']){
                    events['blur'] = wysiwyg_blur_fun;
                }
                
                var controls = {
                    insertImage: false,
                    insertTable: false,
                    h1: false,
                    h2: false,
                    h3: false,
                    html: {visible: true},
                    code: false
                };
                if(settings.hide_html_and_formatting){
                    controls['html'] = {visible: false};
                    controls['removeFormat'] = false;
                }
                $input.wysiwyg({
                    controls: controls,
                    autoGrow: true,
                    css: $('head link[rel="stylesheet"]').first().attr('href'),
                    initialContent: "",
                    iFrameClass: "wysiwyg_iframe",
                    events: events
                });
                
                _.each(window.frames, function (frame) {
                    if (frame) {
                        try {
                            frame.document.documentElement.style.backgroundImage = 'none';
                            frame.document.documentElement.style.backgroundColor = '#FFF';
                        } 
                        catch (e) {
                            // Revisit: (DannyD) Swallow this error for now. There is something 
                            // wrong with the preceeding 2 lines. The error prevents the saving
                            // of profile edits/saves.
                        } 
                    }
                });
            }
        },
        "util": {
            /*
             * Given a position x, y (e.g. cursor position) finds of the coordinates are inside
             * or outside a given element. If you need it, you can modify this method to be
             * able to specify using inner/outer width or height to optionally include margins
             * and borders.
             */
            "within_box": function(x, y, $elem){
                var options = options || {};
                var settings = {
                    "use_outer": true,
                    "include_margin": false
                };
                
                var offset = $elem.offset();
                var left = offset.left;
                var right = left + $elem.width();
                var top = offset.top;
                var bottom = top + $elem.height();
                
                var inside = (x > left && x < right) && (y > top && y < bottom);
                return inside;
            },
            /*
             * Returns a string guaranteed to be unique each time this function is called.
             */
            "unique_id": function(){
                var $document = $(document);
                var old_unique_id = $document.data('ss_unique_id');
                if(old_unique_id === undefined){
                    old_unique_id = -1;
                }
                var new_unique_id = old_unique_id + 1;
                $document.data('ss_unique_id', new_unique_id);
                return "ss_unique_id_" + new_unique_id;
            },
            /*
             * 
             */
            "clone": function(to_clone, deep){
                if(deep===undefined){
                    deep = false;
                }
                return $.extend(deep, {}, to_clone);
            }
        }
    };
})(jQuery);

;// Beginning /res/js/v2/ss/plugins/jquery.ssdialog.js:
(function($){
    var namespace = 'ssdialog';
    var loadingHtml = "<div class='loading'></div>";
    var methods = {
        'init' : function(options){
            
            return this.each(function(){
                var $this = $(this);
                var data = $this.data(namespace);

                // Override the settings with any user supplied options
                var settings = {
                    'show_on_initialize' : true,
                    'destroy_on_close' : true,
                    'title' : '',
                    'width' : 400,
                    'dynamic_width' : false,
                    'height' : 'auto',
                    'modal' : true,
                    'resizable' : false,
                    'refresh_after_save' : false,
                    'save_url' : window.location.pathname,
                    'success_callback' : null,
                    'failure_callback' : null,
                    'close_callback' : null,
                    'open_callback' : null,
                    'load_callback' : null,
                    'focus_input' : false,
                    'save_on_enter' : false,
                    'buttons' : {
                        // defaults filled in below
                    },
                    'content' : {
                        'html' : loadingHtml,
                        'url' : null,
                        'preload' : false,
                        'refresh_on_show' : true,
                        'disabled' : false
                    }
                };
                var cancel_button_label = options.cancel_button_label || 'Cancel';
                var save_button_label = options.save_button_label || 'Save';

                settings.buttons[ cancel_button_label ] = function(a, b, c){
                                                              $this[namespace]('hide');
                                                          }

                settings.buttons[ save_button_label ] = function(){
                                                            $this[namespace]('save');
                                                        };
                $.extend(true, settings, options);
                
                // Remove any buttons that aren't set and give the buttons
                // the proper context for this, as well as the namespace.
                var buttons = {};
                for(var key in settings["buttons"]){
                    var fun = settings["buttons"][key];
                    if(fun){
                        fun = _.bind(fun, $this, namespace);
                        buttons[key] = fun;
                    }
                }
                settings["buttons"] = buttons;

                
                
                // Run the initialization steps if not yet initialized
                if(!data){
                    
                    // Create the containing div for the dialog
                    var $container = $('<div/>', {
                        'class' : namespace,
                        'html' : settings['content']['html']
                    });
                    
                    // Initialize the jQuery dialog
                    $container.dialog({
                        'autoOpen' : false,
                        'close' : function(event, ui){
                            if(settings['destroy_on_close']){
                                $this[namespace]('destroy');
                            }
                            if(settings['close_callback']){
                                settings['close_callback'](arguments);
                            }
                        },
                        'title' : settings['title'],
                        'width' : settings['width'],
                        'height' : settings['height'],
                        'modal' : settings['modal'],
                        'resizable' : settings['resizable'],
                        'buttons' : settings['buttons'],
                        'open' : function(){
                            // Temporary fix to make the last button of the dialog blue and the rest silver
                            $(this).parent().find(".ui-dialog-buttonset button:not(:last-child)").addClass('default');
                            $(this).parent().find(".ui-dialog-buttonset button").removeClass("ui-button").removeClass("ui-state-default");
                            if(settings['open_callback']){
                                settings['open_callback'](arguments);
                            }
                        }
                    });
                    
                    // Bind the click event to open
                    $this.bind('click.' + namespace, function(event){
                        event.preventDefault();
                        $this[namespace]('show');
                    });
                    
                    // Set the data
                    $this.data(namespace, {
                        'showing' : false,
                        'container' : $container,
                        'settings' : settings
                    });
                    
                    // Load the content if a URL is supplied and we're preloading
                    if(settings['content']['preload'] && settings['content']['url']){
                        $this[namespace]('load');
                    }
                }
                
                // Show if should be shown on initialize
                if(settings['show_on_initialize']){
                    $this[namespace]('show');
                }
            });
        },
        'show' : function(refresh_on_show){
            return this.each(function(){
                var $this = $(this);
                var data = $this.data(namespace);
                if(!data['showing']){
                    data['showing'] = true;
                    $this.data(namespace, data);
                    
                    // Decide whether to refresh or not
                    var should_refresh;
                    if(refresh_on_show !== undefined){
                        should_refresh = refresh_on_show;
                    } else {
                        should_refresh = data['settings']['content']['refresh_on_show'] && data['settings']['content']['url'];
                    }
                    if(should_refresh){
                        $this[namespace]('load');
                    }
                    
                    // Open the dialog
                    data['container'].dialog('open');
                }
            });
        },
        'hide' : function(){
            return this.each(function(){
                var $this = $(this);
                var data = $this.data(namespace);
                if(data['showing']){
                    data['showing'] = false;
                    $this.data(namespace, data);
                    data['container'].dialog('close');
                }
            });
        },
        'get_container' : function(){
            return this.each(function(){
                var $this = $(this);
                var data = $this.data(namespace);
                return data['container'];
            });
        },
        'load' : function(){
            return this.each(function(){
                var $this = $(this);
                var data = $this.data(namespace);
                var url = data['settings']['content']['url'];
                var disabled = data['settings']['content']['disabled'];
                var focus_input = data['settings']['focus_input'];
                var save_on_enter = data['settings']['save_on_enter'];
                var dynamic_width = data['settings']['dynamic_width'];
                if(url){
                    var $container = data['container'];
                    
                    // Put in the loading indication then load the content from the URL
                    $container.html(loadingHtml);
                    $container.load(url, function(response, status, xhr){
                        // After loading the content make sure to centre the dialog
                        data['container'].dialog('option', 'position', 'center');
                        
                        // Set the width of the dialog dynamically if required
                        if(dynamic_width){
                            var $dialog = $container.parent();
                            var fudge_factor = 23; // Hack to make things looks good; could likely calculate this if you have the time - Ian
                            var new_width = $container.children().width() + fudge_factor;
                            var old_width = $dialog.width();
                            var old_left = parseInt($dialog.css('left'), 10);
                            var new_left = old_left - ((new_width - old_width) / 2);
                            
                            $dialog.width(new_width);
                            $dialog.css('left', new_left + 'px');
                        }
                        
                        // If required, disable the contents by covering them with an absolutely
                        // positioned div
                        if(disabled){
                            $container.append("<div class='disabling_div'></div>");
                        }
                        
                        // Focus on the topmost input/textarea if needed
                        if(focus_input){
                            $container.find('input[type="text"], textarea').first().focus();
                        }
                        
                        // Override the enter key of inputs to make it save the dialog
                        if(save_on_enter){
                            $container.find('input[type="text"], textarea').keydown(function(event){
                                var code = (event.keyCode ? event.keyCode : event.which);
                                if(code == $.ui.keyCode.ENTER){
                                    event.preventDefault();
                                    $this[namespace]('save');
                                }
                            });
                        }
                        
                        // Trigger the callback, if there is one.
                        if(data['settings']['load_callback']){
                            data['settings']['load_callback'](data);
                        }
                    });
                } else {
                    $.error("No URL supplied for dialog.");
                }
            });
        },
        'save' : function(){
            return this.each(function(){
                var $this = $(this);
                var data = $this.data(namespace);
                
                var $container = data['container'];
                var $form = $container.find('form.item_edit_form');
                var form_data = $form.serialize();
                
                $container.html(loadingHtml);
                $container.dialog('option', 'position', 'center');
                
                var $buttons = $container.parent().find('button');
                $buttons.attr('disabled', true);
                
                $.ajax({
                    'url' : data['settings']['save_url'],
                    'type' : 'PUT',
                    'data' : form_data,
                    'success' : function(server_data, textStatus, jqXHR){
                        if(data['settings']['refresh_after_save']){
                            location.reload();
                        } else {
                            $buttons.attr('disabled', false);
                            $this[namespace]('hide');
                        }
                        
                        if(data['settings']['success_callback']){
                            var callback = _.bind(data['settings']['success_callback'], this);
                            callback(server_data, textStatus, jqXHR);
                        }
                    },
                    'error' : function(server_data, textStatus, jqXHR){
                        if(data['settings']['failure_callback']){
                            var callback = _.bind(data['settings']['failure_callback'], this);
                            callback(server_data, textStatus, jqXHR);
                        } else {
                            $buttons.attr('disabled', false);
                            $this[namespace]('hide');
                            alert("We're sorry, but there was an error saving your changes. Please try again later.");
                        }
                    }
                });
                
            });
        },
        'destroy' : function(){
            return this.each(function(){
                var $this = $(this);
                $this.data(namespace)['container'].empty();
                $this.removeData(namespace);
                $this.unbind("." + namespace);
            });
        },
        'show_loading' : function(){
            var data = $(this).data(namespace);
            var $container = data['container'];
            $container.html(loadingHtml);
            $container.dialog('option', 'position', 'center');
        }
    };
    
    $.fn[namespace] = function(method){
        if(methods[method]) {
            // We're calling one of the methods directly
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if ( typeof method === 'object' || !method) {
            // We're calling the init method
            return methods.init.apply(this, arguments);
        } else {
            // We're not calling a method or initializing; this is an error
            $.error('Method ' + method + ' does not exist on jQuery.' + namespace);
        }
    };
    
})(jQuery);

;// Beginning /res/js/v2/ss/plugins/selectalleventadmin.js:
(function($){
    
    // TODO: This can be re-written later to be a proper 'select all' plugin. For now, this is
    // just used on the event admin dialog.
    
    $('[type="checkbox"].select_all_event_admin').live('click', function(){
        // Find the checkboxes I need to check/uncheck.
        var $this = $(this);
        $checkboxes = $this.parent().parent().find('.permissions_table').find('[type="checkbox"]');
        
        // Find whether I need to check or uncheck all the checkboxes
        var should_select = $this.prop('checked');
        
        // Check or uncheck the boxes as appropriate
        $checkboxes.prop('checked', should_select);
    });
    $('[type="checkbox"].event_admin').live('click', function(){
        // Find whether I need to check the select all checkbox
        var should_select = !$('input.event_admin[type=checkbox]:not(:checked)').length
        // Check or uncheck the select all as appropriate
        $('[type="checkbox"].select_all_event_admin').prop('checked', should_select);
    });
    
    
    //self.init = function () {
    // Find whether I need to check the select all checkbox
    //if ($('input.event_admin[type=checkbox]')) {
    //var should_select = !$('input.event_admin[type=checkbox]:not(:checked)').length
    //console.log(should_select);
    //debugger;
    // Check or uncheck the select all as appropriate
    //$('[type="checkbox"].select_all_event_admin').prop('checked', should_select);
    //};
})(jQuery);
;// Beginning /res/js/v2/ss/plugins/jquery.ssiconmenu.js:
(function($){
    
    $.fn.ss_icon_menu = function(options){
        var settings = $.extend({
            
        });
        
        return this.each(function(){
            var $this = $(this);
            var data = $this.data('ss_icon_menu');
            if(!data) {
                
                var open_class = "icon_menu_open";
                var row_class = "row_selected";
                var $row = $this.closest("tr");
                
                // Create the icon
                var $icon = $('<a href="#"><img class="action_button" src="/res/img/v2/icons/gear_16.png"></a>');
                
                // Handle the click event
                $icon.click(function(event){
                    event.preventDefault();
                    $this.toggleClass(open_class);
                    $row.toggleClass(row_class);

                    // Position the child menu
                    var $image = $icon.find('img');
                    var $box = $this.find('ul');

                    $box.position( { of : $icon,
                                     my : 'left top',
                                     at : 'right top',
                                     offset: '3 -5' } );
 
                });
                
                // Make sure we can close if we click outside of the menu or on a menu item
                $(document).click(function(event){
                    var $target = $(event.target);
                    var target_in_menu = $this.find($target).length || $this[0]==$target[0];
                    var target_in_menu_link = $target.closest('a').closest('ul').closest('.ss_icon_menu').length;
                    if(!target_in_menu || target_in_menu_link){
                        $this.removeClass(open_class);
                        $row.removeClass(row_class);
                        $this.trigger("ss_icon_menu_closed");
                    }
                });
                
                // Add the icon to the DOM
                $this.prepend($icon);
                
                                
                
                $this.data('ss_icon_menu', {
                    'initialized' : true
                });
            }
        });
    };
    
    // Initializes this for where it's to be used
    $(".ss_icon_menu").livequery(function(){
        $(this).ss_icon_menu();
    });
})(jQuery);

;// Beginning /res/js/v2/ss.js:
// using jQuery, underscore.js, underscore.string

// namespace for SilkStart, and the only global variable we should use
var SS = SS ? (function () {console.error('Namespace already exists.'); return SS; }()) : {};

SS.models = {};

SS.controllers = {};

SS.widgets = {};

SS.bb = {};
SS.bb.models = {};
SS.bb.views = {};

// the only time document.ready should be called - and the entry point for our app
$(document).ready(function () {
    
    // this is some config stuff that should eventually be factored out
    SS.page.models = {};
    _.each(SS.page.config, function (model, key) {
        _.each(model, function (spec, name) {
            SS.page.models[name] = SS.models[key](spec);
        });
    });
    
    // here is the actual important part, where we initialize all the controllers
    _.each(SS.controllers, function (controller, key) {
        controller.init();
    });
});

;// Beginning /res/js/v2/models/ss.model.js:
// this is the base model which all the models originally inherit from
SS.model = function (spec, my) {
    var self = {};
    
    my.ajax_error = function (action_failed, data) {
        return function (jqXHR, text_status) {$(document).trigger('ss_ajax_error', [action_failed, text_status, data, jqXHR]); };
    };
    
    return self;
};

;// Beginning /res/js/v2/models/ss.models.user.js:
SS.models.user = function (spec, my) {
    var self;
    
    my = my || {};
    
    self = SS.models.item(spec, my);
    
    self.save_settings = function (data) {
        $.ajax({
            url: spec.url + '/settings',
            type: 'PUT',
            data: data,
            error:  my.ajax_error('user settings edit', data),
            success: function (response) { $(document).trigger('ss_profile_settings_saved', [response]); }
        });        
    };
    
    self.follow = function () {
        $.ajax({
            url: spec.url + '/follow',
            type: 'PUT',
            error:  my.ajax_error('user follow')
        });
    };
    
    self.unfollow = function () {     
        $.ajax({
            url: spec.url + '/follow',
            type: 'DELETE',
            error:  my.ajax_error('user unfollow')
        });        
    };
    
    self.message = function (message_subject, message_body) {
        var params = {
                target_user_id: spec.id,
                'message:subject': message_subject,
                'message:body': message_body,
                message_id: '',
                target_type: 'user'
            };
        
        $.ajax({
            url: '/messages',
            type: 'POST',
            data: params,
            error:  my.ajax_error('user message', params)
        });        
    };
    
    self.enable = function () {
        var params = {state: 'active'};
        
        $.ajax({
            url: spec.url + '/update_state',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('user enable', params)
        });        
    };
    
    self.disable = function () {        
        $.ajax({
            url: spec.url,
            type: 'DELETE',
            error:  my.ajax_error('user delete')
        });        
    };
    
    self.reset_password = function () {
        var params = {user_id: spec.id};
        
        $.ajax({
            url: '/auth/admin_password_reset',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('user reset password')
        });        
    };
    
    self.unlink = function (network) {
        $.ajax({
            url: '/social/ajax_unlink_' + network,
            type: 'PUT',
            error:  my.ajax_error('user unlink', {network: network}),
            success: function () { $(document).trigger('ss_profile_unlinked'); }
        });          
    };
    
    self.link = function (network) {
        var params = {network: network},
            share = function () {
                $.ajax({
                    url: '/social/ajax_share_joined',
                    type: 'PUT',
                    data: params,
                    error:  my.ajax_error('user link', params),
                    success: function () { $(document).trigger('ss_profile_linked'); }
                });          
            };

        if (network === 'facebook') {
            $.ajax({
                url: '/social/ajax_linked',
                type: 'PUT',
                data: params,
                error:  my.ajax_error('user link', params),
                success: function () { $(document).trigger('ss_profile_linked'); }
            });          
        } else {
            $(document).trigger('ss_profile_linked');
        }
    };
    self.cancel_membership = function (membership_info_id) {
        $.ajax({
            url: spec.url + '/cancel_membership',
            type: 'POST',
            data: {'membership_info_id': membership_info_id},
            error:  my.ajax_error('user settings edit', membership_info_id),
            success: function (response) { $(document).trigger('ss_profile_membership_cancelled', [response]); }
        });        
    };

    self.clear_professional_history = function () {     
        $.ajax({
            url: spec.url + '/clear_professional_history',
            type: 'POST',
            error:  my.ajax_error('user clear professional history')
        });        
    };
     
    self.delete_profile_img = function(){
    	var params = {user_id: spec.owner_id};
    	$.ajax({
            url: spec.url + '/delete_profile_img',
            type: 'POST',
            data: params,
            success:function(){debugger;window.location.reload();},
            error:  my.ajax_error('user delete profile img')
        });
    };
    
    return self;
};

;// Beginning /res/js/v2/models/ss.models.item_clump.js:
SS.models.item_clump = function (spec, my) {
    var self,
        latest_request_id = 0,
        namespace_params = function () {
            var namespaced_params = {};
            _.each(spec, function (value, key) {
                if (key === 'sub_filters') {
                    _.each(value, function (sub_value, sub_key) {
                        if (sub_key === spec.asset_type || sub_key === 'all') {
                            _.each(sub_value, function (sub_filter_value, sub_filter_key) {
                                namespaced_params['item_clump:' + sub_filter_key] = sub_filter_value;
                            });
                        }
                    });
                } else {
                    namespaced_params['item_clump:' + key] = value;
                }
            });
            return namespaced_params;
        };
    
    my = my || {};
    
    spec.url = '/activityfeed/item_clump';
    spec.skip = 0;
    
    self = SS.model(spec, my); 
    
    self.filter = function (filters) {
        var this_request_id;

        latest_request_id += 1;
        this_request_id = latest_request_id;

        spec.skip = 0;
        
        _.each(filters, function (value, key) {
            spec[key] = value;
        });
        
        _.each(spec.sub_filters, function (asset_sub_filter, asset_type) {
            if (!(asset_type === spec.asset_type || asset_type === 'all')) {
                delete spec.sub_filters[asset_type];
            }
        });
        
        $.ajax({
            url: spec.url,
            type: 'GET',
            data: namespace_params(),
            success: function (content) {
                if (this_request_id === latest_request_id) {
                    $(document).trigger('ss_item_clump_updated', [spec.id, content]); 
                }
            },
            error: my.ajax_error('item clump filter', namespace_params())
        });       
    };
    
    self.add_older = function (skip) {
        var amount_to_add = skip || spec.limit || 15,
            this_request_id;

        latest_request_id += 1;
        this_request_id = latest_request_id;

        spec.skip = spec.skip + amount_to_add;
        
        $.ajax({ 
            url: spec.url,
            type: 'GET',
            data: namespace_params(),
            success: function (content) {
                if (this_request_id === latest_request_id) {
                    $(document).trigger('ss_item_clump_added_older', [spec.id, content]); 
                }
            },
            error: my.ajax_error('item clump add older items', namespace_params())
        });          
    };
    
    self.get_params = function () {
        return namespace_params();
    };
    
    return self;
};

;// Beginning /res/js/v2/models/ss.models.item.js:
// some items use this directly (eg discussions) becuase they don't need
// more than this, but some items have their own models and inherit from this
// like groups for instance - that list is defined in ss.controller.js
SS.models.item = function (spec, my) {
    var self;
    
    my = my || {}; 
    
    self = SS.model(spec, my);
    
    self.get = function (key) {
        return spec[key];
    };
    
    self.create = function (id, data, type, parent_url) {
        $.ajax({
            url: spec.url,
            type: 'POST',
            data: data,
            success: function (data) {
                if (!id) {
                    $(document).trigger('ss_item_created', [data, type, parent_url]);
                } else {
                    $(document).trigger('ss_item_clump_items_added', [id, data]);
                }
            },
            error:  my.ajax_error('item create', {data: data})
        });
    };
    
    self.remove = function (full_delete) {
        var url;
        if (full_delete){
            url = spec.url + '/destroy';
        }else{
            url = spec.url + '/remove';
        }

        full_delete = full_delete || false;
        $.ajax({
            url: url,
            type: 'DELETE',
            error: my.ajax_error('item delete')
        });
    };
    
    self.edit = function (data, inline) {
        $.ajax({
            url: spec.url,
            type: 'PUT',
            data: data,
            success: function () {
                $(document).trigger('ss_item_saved', inline);
            },
            error:  my.ajax_error('item edit', data)
        });        
    };

    self.like = function () {
        $.ajax({
            url: spec.url + '/like',
            type: 'PUT',
            error:  my.ajax_error('item like')
        });
    };

    self.unlike = function () {
        $.ajax({
            url: spec.url + '/unlike',
            type: 'PUT',
            error:  my.ajax_error('item unlike')
        });
    };
    
    self.share = function (targets, message) {
        var params = {targets: targets, message: message};
        
        $.ajax({
            url: spec.url + '/share',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('item share', params)
        });
    };

    self.post_comment = function (comment) {
        var params = {comment: comment};
        
        $.ajax({
            url: spec.url + '/post_comment',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('item comment', params)
        });
    };

    self.remove_comment = function (comment_id) {
        var params = {};
        
        $.ajax({
            url: spec.url + '/comments/' + comment_id,
            type: 'DELETE',
            data: params,
            error:  my.ajax_error('item remove comment', params)
        });
    };

    self.add_tag = function (tag) {
        var params = {tag: tag};
        
        $.ajax({
            url: spec.url + '/add_tag',
            type: 'GET',
            data: params,
            error:  my.ajax_error('item add tags', params)
        });
    };

    self.remove_tag = function (tag) {
        var params = {tag: tag};
        
        $.ajax({
            url: spec.url + '/remove_tag',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('item remove tag', params)
        });
    };

    self.add_relation = function (item_id, relation_id, direction) {
        var params = {};
        
        $.ajax({
            url: spec.url + '/relations/' + relation_id + '/' + direction + '/' + item_id,
            type: 'PUT',
            data: params,
            error:  my.ajax_error('item add relation', params)
        });
    };

    self.remove_relation = function (item_id, relation_id, direction) {
        var params = {};
        
        $.ajax({
            url: spec.url + '/relations/' + relation_id + '/' + direction + '/' + item_id,
            type: 'DELETE',
            data: params,
            error:  my.ajax_error('item remove relation', params)
        });
    };

    self.update_state = function (state) {
        var params = {state: state};
        
        $.ajax({
            url: spec.url + '/update_state',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('item update state', params)
        });
    };

    self.is_new = function () {
        return spec.id ? false : true;
    };

    return self;
};

;// Beginning /res/js/v2/models/ss.models.group.js:
SS.models.group = function (spec, my) {
    var self;
    
    my = my || {};
    
    self = SS.models.item(spec, my);
    
    self.create = function () {
        $.ajax({
            url: '/chapters',
            type: 'POST',
            error: my.ajax_error('group create')
        });
    };
    
    self.join = function () {
        $.ajax({
            url: spec.url + '/join',
            type: 'PUT',
            success: function () {$(document).trigger('ss_group_joined_left'); },
            error: my.ajax_error('group join')
        });
    };
    
    self.join_request = function () {
        $.ajax({
            url: spec.url + '/join',
            type: 'PUT',
            error: my.ajax_error('group join request')
        });
    };
    
    self.leave = function () {
        $.ajax({
            url: spec.url + '/leave',
            type: 'DELETE',
            success: function () {$(document).trigger('ss_group_joined_left'); },
            error: my.ajax_error('group leave')
        });
    };
    
    self.message_all = function (message_subject, message_body) {
        var params = {
                chapter_id: spec.id,
                'message:subject': message_subject,
                'message:body': message_body
            };
            
        $.ajax({
            url: spec.url + '/send_group_message',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('group message members', params)
        });        
    };

    self.invite_users = function (targets, email_targets, dialog) {
        var params = {
            targets: targets,
            email_targets: email_targets,
            //group_invite_existing_user_subject: $('.group_invite_existing_user_subject', dialog).val(),
            //group_invite_existing_user_body: $('.group_invite_existing_user_body', dialog).val(),
            //group_invite_new_user_subject: $('.group_invite_new_user_subject', dialog).val(),
            //group_invite_new_user_body: $('.group_invite_new_user_body', dialog).val()
            group_invite_personalization: $('.group_invite_personalization', dialog).val()
        };
        
        $.ajax({
            url: spec.url + '/invite',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('group invite users', params)
        });        
    };
    
    self.add_leader = function (user_id) {
        var params = {user_id: user_id};
         
        $.ajax({
            url: spec.url + '/add_leader',
            type: 'POST',
            data: params,
            error:  my.ajax_error('group add leader', params)
        });        
    };
    
    self.remove_leader = function (user_id) {
        var params = {user_id: user_id};
         
        $.ajax({
            url: spec.url + '/remove_leader',
            type: 'POST',
            data: params,
            error:  my.ajax_error('group remove leader', params)
        });        
    };
    
    self.accept_member = function (user_id) {
        var params = {user_id: user_id};
         
        $.ajax({
            url: spec.url + '/approve_pending_member',
            type: 'POST',
            data: params,
            error:  my.ajax_error('group accept pending member', params)
        });        
    };
    
    self.reject_member = function (user_id) {
        var params = {user_id: user_id};
         
        $.ajax({
            url: spec.url + '/reject_pending_member',
            type: 'POST',
            data: params,
            error:  my.ajax_error('group reject pending member', params)
        });        
    };
    
    self.add_member = function (user_id) {
        var params = {user_id: user_id};
         
        $.ajax({
            url: spec.url + '/add_member',
            type: 'POST',
            data: params,
            error:  my.ajax_error('group add member', params)
        });        
    };
    
    self.remove_member = function (user_id) {
        var params = {user_id: user_id};
         
        $.ajax({
            url: spec.url + '/remove_member',
            type: 'POST',
            data: params,
            error:  my.ajax_error('group remove member', params)
        });        
    };
    
    return self;
};

;// Beginning /res/js/v2/models/ss.models.company.js:
SS.models.company = function (spec, my) {
    var self;
    
    my = my || {};
    
    self = SS.models.item(spec, my);
    
    self.create = function (data) {
        $.ajax({
            url: '/companies',
            type: 'POST',
            data: data,
            error: my.ajax_error('company create'),
            success: function () { $(document).trigger('ss_company_saved'); }
        });
    };
 
    self.add_member = function (user_id) {
        var params = {user_id: user_id};
         
        $.ajax({
            url: spec.url + '/add_member',
            type: 'POST',
            data: params,
            success: function () {$(document).trigger('ss_company_member_added'); },
            error:  my.ajax_error('company add member', params)
        });        
    };
    
    self.remove_member = function (user_id) {
        var params = {user_id: user_id};
         
        $.ajax({
            url: spec.url + '/remove_member',
            type: 'POST',
            data: params,
            error:  my.ajax_error('company remove member', params)
        });        
    };

    self.join_company = function (user_id) {
        var params = {user_id: user_id};
        
        $.ajax({
            url: spec.url + '/add_member',
            type: 'POST',
            data: params,
            error:  my.ajax_error('user join company', params),
            success: function () { $(document).trigger('ss_company_joined'); }
        });          
    };
 
    self.message = function (message_subject, message_body) {
        var params = {
                target_user_id: spec.id,
                'message:subject': message_subject,
                'message:body': message_body,
                message_id: '',
                target_type: 'company'
            };
        
        $.ajax({
            url: '/messages',
            type: 'POST',
            data: params,
            error:  my.ajax_error('company message', params)
        });        
    };
    
    return self;
};

;// Beginning /res/js/v2/models/ss.models.event.js:
SS.models.event = function (spec, my) {
    var self;
    
    my = my || {};
    
    self = SS.models.item(spec, my);
    
    self.create = function () {
        $.ajax({
            url: '/events',
            type: 'POST',
            error: my.ajax_error('event create')
        });
    };

    self.rsvp = function () {
        $.ajax({
            url: spec.url + '/rsvp',
            type: 'POST',
            success: function () {$(document).trigger('ss_event_rsvped_unrsvped'); },
            error:  my.ajax_error('event rsvp')
        });        
    };
    
    self.rsvp_user = function (url,user_id) {
    	var params={'curr_user:id':user_id}
        $.ajax({
            url: url + '/rsvp_user',
            data:params,
            type: 'POST',
            success: function () {
            	$('.create_new_user').removeAttr('disabled');
            	$('admin_payment_manually_register_cancel').removeAttr('disabled');
            	$('admin_payment_rsvp_user').removeAttr('disabled');
            	$('admin_payment_rsvp_user_make_another').removeAttr('disabled');
            	window.location=url },
            error:  my.ajax_error('event rsvp')
        });        
    };
    
    self.rsvp_new_user = function (url,first_name,last_name,email) {
    	var params={'new_user:first_name':first_name,
    				'new_user:last_name':last_name,
    				'new_user:email':email}
        $.ajax({
            url: url + '/rsvp_user',
            data:params,
            type: 'POST',
            success: function () {
            	$('.create_new_user').removeAttr('disabled');
            	$('admin_payment_manually_register_cancel').removeAttr('disabled');
            	$('admin_payment_rsvp_user').removeAttr('disabled');
            	$('admin_payment_rsvp_user_make_another').removeAttr('disabled');
            	window.location=url },
            error:  my.ajax_error('event rsvp')
        });        
    };
    
    self.rsvp_user_make_another = function (url,user_id) {
    	var params={'curr_user:id':user_id}
        $.ajax({
            url: url + '/rsvp_user',
            data:params,
            type: 'POST',
            success: function () {
            	$('.create_new_user').removeAttr('disabled');
            	$('admin_payment_manually_register_cancel').removeAttr('disabled');
            	$('admin_payment_rsvp_user').removeAttr('disabled');
            	$('admin_payment_rsvp_user_make_another').removeAttr('disabled');
            	window.location=url+'/manually_register_to_event' },
            error:  my.ajax_error('event rsvp')
        });        
    };
    
    self.rsvp_new_user_make_another = function (url,first_name,last_name,email) {
    	var params={'new_user:first_name':first_name,
					'new_user:last_name':last_name,
					'new_user:email':email}
        $.ajax({
            url: url + '/rsvp_user',
            data:params,
            type: 'POST',
            success: function () {
            	$('.create_new_user').removeAttr('disabled');
            	$('admin_payment_manually_register_cancel').removeAttr('disabled');
            	$('admin_payment_rsvp_user').removeAttr('disabled');
            	$('admin_payment_rsvp_user_make_another').removeAttr('disabled');
            	window.location=url+'/manually_register_to_event' },
            error:  my.ajax_error('event rsvp')
        });        
    };
    
    self.unrsvp = function () {
        $.ajax({
            url: spec.url + '/unrsvp',
            type: 'DELETE',
            success: function () {$(document).trigger('ss_event_rsvped_unrsvped'); },
            error:  my.ajax_error('event unrsvp')
        });        
    };
    
    self.cancel_ticket = function (attendee_id) {
        var params = {attendee_id: attendee_id};
        
        $.ajax({
            url: '/event/ajax_cancel_ticket',
            type: 'POST',
            data: params,
            error:  my.ajax_error('event cancel ticket')
        });
    };
    
    self.message_attendees = function (message_subject, message_body) {
        var params = {
                event_id: spec.id,
                'message:subject': message_subject,
                'message:body': message_body
            };
            
        $.ajax({
            url: spec.url + '/message_attendees',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('event message attendees', params)
        });        
    };
    
    self.invite_users = function (targets, email_targets, dialog) {
        var params = {
            targets: targets,
            email_targets: email_targets,
            //group_invite_existing_user_subject: $('.group_invite_existing_user_subject', dialog).val(),
            //group_invite_existing_user_body: $('.group_invite_existing_user_body', dialog).val(),
            //group_invite_new_user_subject: $('.group_invite_new_user_subject', dialog).val(),
            //group_invite_new_user_body: $('.group_invite_new_user_body', dialog).val()
            event_invite_personalization: $('.event_invite_personalization', dialog).val()
        };
        
        $.ajax({
            url: spec.url + '/invite',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('group invite users', params)
        });        
    };
    
    self.invite_users_by_prev_events = function (targets,dialog) {
        var params = {
            targets: targets,
            event_invite_personalization: $('.event_invite_personalization', dialog).val()
        };
        
        $.ajax({
            url: spec.url + '/invite_by_event',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('group invite users by event', params)
        });        
    };
    
    self.invite_users_by_groups = function (targets,dialog) {
        var params = {
            targets: targets,
            event_invite_personalization: $('.event_invite_personalization', dialog).val()
        };
        
        $.ajax({
            url: spec.url + '/invite_to_event_by_group',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('group invite users by groups', params)
        });        
    };
    
    self.get_attendee_info_history_for_course = function(name,success,url){
    	var params = {name: name};
    		
    	$.ajax({
            url:  url +'/get_filled_info_history_for_course',
            type: 'POST',
            data: params,
            success: success,
            error:  my.ajax_error('register courses prefill info', params)
        });
    	
    }
    
    self.remove_attendee_info_history = function(url){

    	$.ajax({
             url: url+"/clear_filled_history",
             type: 'PUT',
             error:  my.ajax_error('clear register courses prefill info')
         }); 
    }
    
    self.delete_attendee=function(id,dialog){
    	var params ={attendee_id:id};
    	var popup = dialog;
    	
    	$.ajax({
            url:  spec.url +'/ajax_delete_attendee',
            type: 'POST',
            data: params,
            success:function (response,popup) {
            		$('.delete_result').html(response.message);	
            		},
            error:  my.ajax_error('delete_attendee', params)
        });
    	
    }
    
    return self;
};

;// Beginning /res/js/v2/models/ss.models.place.js:
SS.models.place = function (spec, my) {
    var self;
    
    my = my || {};
    
    self = SS.models.item(spec, my);
    
    self.create = function (data) {
        $.ajax({
            url: '/places',
            type: 'POST',
            data: data,
            error: my.ajax_error('place create'),
            success: function (response) { $(document).trigger('ss_place_created', [response]); }
        });
    };
    
    self.join = function () {
        $.ajax({
            url: spec.url + '/join',
            type: 'PUT',
            success: function () {$(document).trigger('ss_place_joined_left'); },
            error: my.ajax_error('place join')
        });
    };
    
    self.leave = function () {
        $.ajax({
            url: spec.url + '/leave',
            type: 'DELETE',
            success: function () {$(document).trigger('ss_place_joined_left'); },
            error: my.ajax_error('place leave')
        });
    };
    
    return self;
};

;// Beginning /res/js/v2/models/ss.models.tag.js:
SS.models.tag = function (spec, my) {
    var self;
    
    my = my || {};
    
    self = SS.model(spec, my);
    
    spec.url = '/tags/' + spec.id;
    
    self.follow = function () {
        
        $.ajax({
            url: spec.url + '/follow',
            type: 'PUT',
            error:  my.ajax_error('tag follow')
        });
    };
    
    self.unfollow = function () {
        
        $.ajax({
            url: spec.url + '/follow',
            type: 'DELETE',
            error:  my.ajax_error('tag follow')
        });
    };    
    
    return self;
};

;// Beginning /res/js/v2/models/ss.models.proposal.js:
SS.models.proposal = function (spec, my) {
    var self;
    
    my = my || {};
    
    self = SS.models.item(spec, my);
    
    self.accept = function () {
        $.ajax({
            url: spec.url + '/accept',
            type: 'PUT',
            error: my.ajax_error('proposal accept')
        });
    };
 
    self.reject = function () {
        $.ajax({
            url: spec.url + '/reject',
            type: 'PUT',
            error:  my.ajax_error('proposal reject')
        });        
    };
    
    return self;
};

;// Beginning /res/js/v2/models/ss.models.customization.js:
SS.models.customization = function (spec, my) {
    var self;
    
    my = my || {}; 
    
    self = SS.model(spec, my);
    
    self.get = function (key) {
        return spec[key];
    };
   
    self.edit = function (data) {
        $.ajax({
            url: spec.url,
            type: 'PUT',
            data: data,
            success: function () { $(document).trigger('ss_item_saved'); },
            error:  my.ajax_error('item edit', data)
        });        
    };

    return self;
};

;// Beginning /res/js/v2/models/ss.models.payment.js:
SS.models.payment = function (spec, my) {
    var self;
    
    my = my || {}; 
    
    self = SS.model(spec, my);
    
    self.get = function (key) {
        return spec[key];
    };
   
    self.submit_payment = function (data) {
        var url = '/payment/submit_payment/' + spec.id;
        $.ajax({
            url: url,
            type: 'POST',
            data: data,

            success: function (response) {$(document).trigger('ss_payment_submitted', [response]); },
            error: my.ajax_error('item edit', data)
        });        
    };
    
    self.finalize_payment = function (data) {
        var url = '/payment/finalize_payment/' + spec.id;
        $.ajax({
            url: url,
            type: 'POST',
            data: data,

            success: function (response) {$(document).trigger('ss_payment_finalized', [response]); },

            error: my.ajax_error('item edit', data)
        });        
    };

    return self;
};

;// Beginning /res/js/v2/models/ss.models.admin_payment.js:
SS.models.admin_payment = function (spec, my) {
    var self;
    
    my = my || {}; 
    
    self = SS.model(spec, my);
    
    self.get = function (key) {
        return spec[key];
    };
   
    self.get_ticket_information = function (data) {
        var url = '/admin_payment/get_ticket_information';
        $.ajax({
            url: url,
            type: 'POST',
            data: data,
            success: function (response) { $(document).trigger('ss_admin_payment_ticket_information_fetched', [response]); },
            error: my.ajax_error('item edit', data)
        });        
    };

    self.get_outstanding_balances = function (user_id, success) {
        var url = '/admin_payment/get_outstanding_balances';
        $.ajax({
            url: url,
            type: 'POST',
            data: {user_id:user_id},
            success: success,
            error: my.ajax_error('item edit', user_id)
        });        
    };

    self.submit_payment = function (data, success) {
        var url = '/admin_payment/submit_payment';
        
        $.ajax({
            url: url,
            type: 'POST',
            data: data,
            success: success,
            error: my.ajax_error('item edit', data)
        });        
    };

    return self;
};

;// Beginning /res/js/v2/models/ss.models.report.js:
SS.models.report = function (spec, my) {
    var self;
    
    my = my || {};
    
    self = SS.models.item(spec, my);
    
    self.create = function () {
        $.ajax({
            url: '/reports',
            type: 'POST',
            error: my.ajax_error('report create')
        });
    };

    self.get_report_fields = function (report_type) {
        $.ajax({
            url: '/report/get_report_fields',
            type: 'GET',
            data: {report_type:report_type},
            success: function (report_fields) {$(document).trigger('ss_report_fields_updated', [report_fields]); },
            error: my.ajax_error('fetch report fields')
        });
    };
     self.get_report_table_config = function (report_type) {
        $.ajax({
            url: '/report/get_report_specification',
            type: 'GET',
            data: {report_type:report_type},
            success: function (report_spec) {$(document).trigger('ss_report_config_updated', [report_spec]); },
            error: my.ajax_error('fetch report specification')
        });
    };
   
    return self;
};

;// Beginning /res/js/v2/models/ss.models.network.js:
SS.models.network = function (spec, my) {
    var self;
    
    my = my || {};
    
    self = SS.models.item(spec, my);
    
    self.invite_users = function (email_targets, dialog) {
        var params = {
            email_targets: email_targets,
            network_invite_personalization: $('.network_invite_personalization', dialog).val()
        };
        
        $.ajax({
            url: '/network/invite',
            type: 'PUT',
            data: params,
            error:  my.ajax_error('group invite users', params)
        });        
    };
    
    return self;
};

;// Beginning /res/js/v2/controllers/ss.controller.js:
// this is the base controller which all controllers inherit from
// the my object which all the stuff is attached to is like having
// protected functions, they will be availible to the controllers which
// inherit from this, but not to the public

SS.controller = function (my) {
    my.get_item_element = function ($element) {
        return $element.closest('.item');
    };
    
    // this is really important and useful, it returns the model object for the appropriate item
    my.get_model_object = function ($element) {
        var $item_element = $element.hasClass('item') ? $element : my.get_item_element($element),
            data = $item_element.data(),
            // if an item has its own js model (ie other than just using ss.models.items.js), add it to this lists
            complex_items = ['user', 'company', 'group', 'event', 'place', 'proposal','payment','report'],
            type = _.include(complex_items, data.type) ? data.type : 'item';
        
        return SS.models[type](data);
    };
    
    my.get_plural = function (text) {
        if (_.endsWith(text, 'y')) {
            return _.splice(text, text.length - 1, 1, 'ies');
        } else if (_.endsWith(text, 's')) {
            return text + 'es';
        } else {
            return text + 's';
        }
    };
    
    my.text_url_to_link = function (text) {
        return text.replace(/(\b(https?|ftp|file):\/\/[\-A-Z0-9+&@#\/%?=~_|!:,.;]*[\-A-Z0-9+&@#\/%=~_|])/ig, '<a href="$1">$1</a>'); 
    };
    
    my.newlines_to_br = function (text) {
        return text.replace(/\n/g, '<br>');
    };
    
    my.clean_quotes = function (text) {
        return text.replace(/&#39;/g, "'").replace(/&#34;/g, '"');  
    };
    
    my.name_value_array_to_object = function (array) {
        var object = {};
        _.each(array, function (item) {
            object[item.name] = item.value;
        });
        return object;
    };

    my.queued_items = {};

    /**
     * Run a search or something similar that we want to run once a user
     * has typed something but we don't want it to run on every keystroke
     * only when they've stopped typing for a few hundred milliseconds
     */
    my.queue_to_run = function( key, func, delay ) {
        if (! delay ){
            delay = 500;
        }

        var now = new Date().getTime(),
            target_time = now + delay;

        // add the item to the queue with the appropriate func and delay

        // start a timer to run the item[s] in the queue
        my.queued_items[key] = {func:func, target_time:target_time};

        window.setTimeout(my.run_queued, delay);
    };

    my.run_queued = function(){
        var now = new Date().getTime(),
            queued_item,
            i,
            func;

        for (i in my.queued_items){
            queued_item = my.queued_items[i];

            if ( now >= queued_item.target_time){
                func = queued_item.func;
                delete my.queued_items[i];

                func();
            }
        }
    };

    my.submit_form = function ($form, $this_element, submit_function, root_element) {
        if ($form.valid()) {
            submit_function();
            $(root_element).html('<div class="loading"></div>');
        } else {
            $('<div />', {'class': 'error'})
                .html('Your required fields are not valid. Please review.')
                .insertAfter($this_element)
                .delay(1000)
                .fadeOut();
        } 
    };
 

    return {};
};

;// Beginning /res/js/v2/controllers/ss.controllers.item_clump.js:
SS.controllers.item_clump = (function () {
    var self,
        my = {},
        root_element = '.item_clump',
        number_of_auto_loads = 0,
        get_item_clump_element = function (id) {
            var clump = $('#' + id + '_item_clump');
            
            if (clump.length) {
                return clump;
            } else {
                return $('#' + id);
            }
        },
        load_older = function (id) {
            var clump_element = get_item_clump_element(id),
                older_items_element = $('.item_clump_show_more', clump_element);
                    
            $(older_items_element).after('<li class="item_clump_loading_more loading"></li>');  
            $(older_items_element).remove();
            
            SS.page.models[id].add_older();
        };
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        // this is for the auto loading of more items if you scroll down
        $(document).scroll(function () {
            if (number_of_auto_loads < 2) {
                if ($(window).scrollTop() + $(window).height() >= $(document).height() - 100) {
                    if ($('.item_clump_show_more', root_element).length) { 
                        load_older($(root_element).data('item_clump_id'));
                        number_of_auto_loads += 1;
                    }
                }
            }
        });
        
        $(root_element).parent().delegate('.item_clump_show_more', 'click', function () {
            load_older($(this).parent().data('item_clump_id'));
        });
         
        $(document).bind('ss_item_clump_filters_changed', function (event, id, filters) {
            var clump_element = get_item_clump_element(id);
            
            $('.item_clump_show_more', clump_element).remove();
            SS.page.models[id].filter(filters);
            $(clump_element).html('<div class="item_clump_loading_update loading"></div>');
        });
        
        $(document).bind('ss_item_clump_sub_filters_changed', function (event, id, data) {
            var clump_element = get_item_clump_element(id),
                filters = {};
            
            filters = {};
            filters.sub_filters = data;
            
           $('.item_clump_show_more', clump_element).remove();
            SS.page.models[id].filter(filters);
            $(clump_element).html('<div class="item_clump_loading_update loading"></div>');
        });
        
        $(document).bind('ss_item_clump_updated', function (event, id, clump_content) {
            var clump_element = get_item_clump_element(id);

            $(clump_element).siblings('.item_clump_loading_new_item').remove();
            $(clump_element).after(clump_content.html).remove();
            number_of_auto_loads = 0;
        });

        $(document).bind('ss_item_clump_items_added', function (event, id, item_added) {
            var clump_element = get_item_clump_element(id);
            
            $('.notice', clump_element).remove();
            $('.item_clump_loading_new_item').remove();
            
            //debugger;
            
            if(SS.app.current_network.enable_share_popup == 'true'){
                $(item_added).hide().prependTo(clump_element).slideDown(700).trigger('ss_item_created');
            }else{
                $(item_added).prependTo(clump_element);
            }
        });

        $(document).bind('ss_item_clump_added_older', function (event, id, older_items) {
            var clump_element = get_item_clump_element(id);
            
            $('.item_clump_loading_more', clump_element).remove();
            $(clump_element).append(older_items.html);
        });
        
        $(document).bind('ss_ajax_error', function (event, action_attempted, error_text) {
            $(root_element).siblings('.item_clump_loading_new_item').remove();
        });
    };
    return self;
}()); 

;// Beginning /res/js/v2/controllers/ss.controllers.item_clump_filters.js:
SS.controllers.item_clump_filters = (function () {
    var self,
        my = {},
        root_element = '.item_clump_filters';
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        $(root_element).delegate('a', 'click', function () {
            var group = $(this).closest('ul'),
                action = $(this).data('action'),
                filters = {};
            
            $('.selected', group).removeClass('selected');         
            $(this).addClass('selected');
            
            if ($(group).hasClass('asset_type')) {
                filters.asset_type = action;
            } else {
                filters.sort_type = action;
            }
            $(document).trigger('ss_item_clump_filters_changed', [$(group).closest('.filters').data('item_clump_id'), filters]);
        });

        $(root_element).delegate('.clump_filter', 'change', function () {
            var name = $(this).attr('name'),
                value = $(this).val(),
                filters = {};

            filters[name] = value;
            
            $(document).trigger('ss_item_clump_filters_changed', [$(this).closest('.filters').data('item_clump_id'), filters]);

        });
    };
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.item_clump_sub_filters.js:
SS.controllers.item_clump_sub_filters = (function () {
    var self,
        my = {},
        root_element = '.item_clump_sub_filters',
        filter_input_change = function ($this_element) {
            var $filters_element = $this_element.closest('.item_clump_sub_filters'),
                item_clump_id = $filters_element.data('item_clump_id'),
                data_array = $('.sub_filters_section:not(.unavailable) form', $filters_element).serializeArray() || [],
                asset_type = $this_element.closest('.sub_filters_section').data('asset_type'),
                data_object = {};
                
            if (asset_type) {
                data_object[asset_type] = {};
                
                _.each(data_array, function (filter) {
                    data_object[asset_type][filter.name] = filter.value;
                });
            }
            
            $(document).trigger('ss_item_clump_sub_filters_changed', [item_clump_id, data_object]);
        };
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        $(root_element).delegate('input', 'click', function () {
            $(this).select();
        });
        $(root_element).delegate('select', 'change', function () {
            filter_input_change($(this));
        });
        $(root_element).delegate('input', 'keypress', function () {
            var changed_item = this;
            my.queue_to_run('filter', function() { filter_input_change($(changed_item)); });
        });
        $(root_element).delegate('form', 'submit', function (event) {
            event.preventDefault();
        });
        $(document).bind('ss_item_clump_filters_changed', function (event, clump_id, filters) {
            var $sub_filters_element = $('#' + clump_id + '_item_clump_sub_filters');
            
            if (filters.asset_type) {
                $('.sub_filters_section', $sub_filters_element).addClass('unavailable');
                $('.sub_filters_section[data-asset_type="' + filters.asset_type + '"]', $sub_filters_element)
                    .removeClass('unavailable')
                    .find('form')
                        .trigger('reset');
            }
        });
    };
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.post_new.js:
// post new as in the thingy at the top of the feed which allows you
// to post new items
SS.controllers.post_new = (function () {
    var self,
        my = {},
        root_element = '.post_new', 
        post_form,
        // creates the time options for the event post new
        create_time_options = function (selected_time) { 
            var suffixes = ['am', 'pm'],
                hours = [12].concat(_.range(1, 12)),
                mins = ['00', '15', '30', '45'],
                times = [''].concat(_.flatten(
                    _.map(suffixes, function (suffix) {
                        return _.map(hours, function (hour) {
                            return _.map(mins, function (min) {
                                return hour + ':' + min + suffix;
                            });                   
                        });
                    })));
                
            return _.reduce(times, function (memo, time) {
                var selected = time === selected_time ? ' selected' : '';
                return memo + '<option value="' + time + '"' + selected + '>' + time + '</option>';
            }, '');
        },
        options = {
            discussion: {
                form_text: 'Start a discussion',
                form_include:   '<label>Discussion title:</label><input class="required" type="text" name="discussion:title">' +
                                '<label>Discussion content:</label><textarea name="discussion:summary"></textarea>'
            },
            offer: {
                form_text: 'Post an offer',
                form_include:   '<label>Offer title:</label><input class="required" type="text" name="offer:title">' +
                                '<div class="post_form_two_input">' +
                                '<div><label>Member rate:</label><input class="number required" type="text" name="offer:exclusive_rate"></div>' +
                                '<div><label>Normal non-member rate:</label><input class="number required" type="text" name="offer:market_rate"></div>' +
                                '</div>' +
                                '<label>Offer details:</label><textarea name="offer:description"></textarea>'
            },
            request: {
                form_text: 'Post a request',
                form_include:   '<label>Request title - what do you need?</label><input class="required" type="text" name="request:title">' +
                                '<label>Request details:</label><textarea name="request:summary"></textarea>' +
                                '<input type="hidden" name="request:discussion_type" value="request">'
            },
            document: {
                form_text: 'Post a document',
                form_include:   '<label>Document title:</label><input class="required" type="text" name="document:name">' +
                                '<label>File to upload:</label>' +
                                '<iframe class="post_form_file_upload" src="/upload_iframe/file"></iframe>' +
                                '<input class="required" type="hidden" name="document:file">' +
                                '<label>Document description:</label><textarea name="document:description"></textarea>'
            },
            event: {
                form_text: 'Create an event',
                form_include:   '<label>Event title:</label><input class="required" type="text" name="event:name">' +
                                '<div class="post_form_two_input">' + 
                                '<div><label>Date:</label><input type="text" name="event:event_date" class="date_input required date"></div>' +
                                '<div><label>End date:</label><input type="text" name="event:event_end_date" class="date_input date"></div>' +
                                '</div><div class="post_form_two_input">' + 
                                '<div><label>Start time:</label><select class="post_new_event_time" name="event:start_time">' + create_time_options('6:00pm') + '</select></div>' +
                                '<div><label>End time:</label><select class="post_new_event_time"  name="event:end_time">' + create_time_options('7:00pm') + '</select></div>' +
                                '</div>' +
                                '<label>Event location:</label><input class="required location_input" type="text" name="event:location">' +
                                '<label>Event description:</label><textarea name="event:description"></textarea>',
                form_initializer: function () {
                    var location_autocomplete = SS.widgets.autocomplete_location({
                        input: $('.post_form .location_input'),
                        on_select: function (location_info) {
                            $('.post_form .location_input').val(location_info.address);
                        }
                    });
                        
                    location_autocomplete.init();
                    
                    $('.post_form .date_input').datepicker({
                        dateFormat: 'dd M yy',
                        onClose: function () {$(this).valid(); }
                    });
                }
            },
            video: {
                form_text: 'Embed a video',
                form_include:   '<label>Video title:</label><input class="required" type="text" name="video:title">' +
                                '<label>Video URL:</label><input class="required url" type="text" name="video:video_url">' +
                                '<label>Video description:</label><textarea name="video:summary"></textarea>'
            },
            image: {
                form_text: 'Post an image',
                form_include:   '<label>Image title:</label><input class="required" type="text" name="image:name">' +
                                '<label>Image File:</label>' +
                                '<iframe class="post_form_file_upload" src="/upload_iframe/file"></iframe>' +
                                '<input class="required" type="hidden" name="image:image">' +
                                '<label>Image description:</label><textarea name="image:description"></textarea>'
            },
            link: {
                form_text: 'Post a link',
                form_include:   '<label>Link title:</label><input class="required" type="text" name="link:title">' +
                                '<label>Link URL:</label><input class="required url" type="text" name="link:link_url">' +
                                '<label>Link description:</label><textarea name="link:summary"></textarea>'
            }
        },
        option_selected, 
        get_tags_add_input_width = function () {
            var tags_width = _.reduce($('.tag', post_form), function (memo, tag) {return memo + $(tag).outerWidth(true); }, 0),
                input_width = $(post_form).width() - tags_width - 2;
                
            return input_width > 50 ? input_width : 50;
        },
        init_tags = function () {
            var autocomplete = SS.widgets.autocomplete_tag({
                input: $('.post_form_tags', post_form),
                on_select: function (id, tag_html) {
                    var values = $('.post_form_tag_values', post_form).val() || '',
                        to_insert = values ? id + ',' + values : id;
                    $('.post_form_tag_values', post_form).val(to_insert);
                    $('.post_form_tags', post_form).before(tag_html).width(get_tags_add_input_width()).val('').focus();
                }
            });
                
            autocomplete.init();
        },
        expand_post_form = function () {
            var form_html,
                submit_row,
                post_as_company = $(root_element).data('post_as_company');

            if (!$(post_form).hasClass('expanded')) {
                $(post_form).empty().addClass('expanded');
                
                form_html = '<form class="post_form_form">' + options[option_selected].form_include + '<label>Tags:</label>' +
                    '<input class="post_form_tag_values" type="hidden" name="selected_text"><div><input class="post_form_tags ui-widget" type="text"></form></div>';
                    
                $(post_form).html(form_html);
                
                init_tags();

                $('input:first', post_form).focus();
                
                submit_row = $('<div />', {'class': 'post_form_submit_row'});
                
                if (post_as_company) {
                    $('<label />', {
                        'class': 'post_form_post_as_company'
                    })
                        .appendTo(submit_row)
                        .append($('<input />', {
                            type: 'checkbox'
                        }))
                        .append('Post as your company.');
                }
                
                submit_row.append($('<input />', {
                    'class': 'button post_form_submit',
                    type: 'button',
                    value: options[option_selected].form_text
                }));
                
                $(post_form).append(submit_row);
                
                $('.post_form_form', post_form).validate({ignore:':hidden',focusInvalid: false});
                
                if (options[option_selected].form_initializer) {
                    options[option_selected].form_initializer();
                }
                
                $('.post_form_input', post_form).focus();
                
                $(document).bind('ss_file_uploaded', function (event, file_id) {
                    var $file_input = $('input[name="document:file"]', post_form);
                    if ($file_input.length) {
                        $file_input.val(file_id);
                        $file_input.valid();
                    }
                });
                
                $(document).bind('ss_file_uploaded', function (event, file_id) {
                    var $file_input = $('input[name="image:image"]', post_form);
                    if ($file_input.length) {
                        $file_input.val(file_id);
                        $file_input.valid();  
                    }
                });
            }
        },
        contract_post_form = function () {
            if ($(post_form).hasClass('expanded')) {
                $(post_form).empty().removeClass('expanded');
                $(post_form).html('<input class="post_form_input_capture" type="text" value=" ' + options[option_selected].form_text + '">');
            }
        };
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        var $first_option;
        post_form = $('.post_form', root_element);
        
        $first_option = $('.post_choices a:first', root_element);
        $first_option.addClass('selected').after('<img alt="" class="post_new_nub" src="/res/img/v2/nub_outline_on_white.png">');
        
        option_selected = $first_option.data('option');
        
        if (option_selected) {
            $('.post_form_input_capture', post_form).val(' ' + options[option_selected].form_text);
        }
        
        $('.post_choices', root_element).delegate('a', 'click', function (event) {
            var this_option = $(this).data('option');
                
            if (this_option === option_selected) {
                if ($(post_form).hasClass('expanded')) {
                    contract_post_form(); 
                } else {
                    expand_post_form();   
                }
            } else {
                $('.selected', root_element).removeClass('selected').next('.post_new_nub').remove();
                $(this).addClass('selected').after('<img alt="" class="post_new_nub" src="/res/img/v2/nub_outline_on_white.png">');
                option_selected = this_option;
                contract_post_form();
                expand_post_form();
            }
        });
        $(root_element).delegate('.post_form_input_capture', 'click', function (event) {       
            expand_post_form();
        });
        
        $(root_element).delegate('.post_form_submit', 'click', function (event) {
            var item = SS.models.item({url: '/' + option_selected + 's'}),
                tag_values = $('.post_form_tag_values', post_form).val(),
                extra_tag_values =  $('.post_form_tags', post_form).val(),
                form_data,
                item_clump_id,
                item_clump_params = {},
                post_as_company = !!$('.post_form_post_as_company input:checked', post_form).length && $(root_element).data('post_as_company');
               
            if ($('.post_form_form', post_form).valid()) {
                $('.post_form_tag_values', post_form).val(tag_values + ',' + extra_tag_values);
                
                form_data = $('.post_form_form', root_element).serialize();
                
                if (post_as_company) {
                    form_data += "&post_as_company=True";
                }
                item_clump_id = $(this).closest('.post_new').data('item_clump_id');

                item_clump_params = SS.page.models[item_clump_id].get_params();
                form_data += '&' + $.param(item_clump_params);
                
                item.create(item_clump_id, form_data);
                $(root_element).after('<div class="item_clump_loading_new_item loading"></div>');
                contract_post_form();
            }
            
        });
        
        $(post_form).delegate('.tag .tag_action_remove', 'click', function () {
            var tag_id = $(this).closest('.tag').data('tag_id'),
                tag_values =  $('.post_form_tag_values', post_form).val(),
                tag_values_array = tag_values.split(','),
                tag_values_array_good = _.reject(tag_values_array, function (tag) {return tag === tag_id; }),
                tag_values_good = tag_values_array_good.join(',');
                
            $('.post_form_tag_values', post_form).val(tag_values_good);
              
            $(this).closest('.tag').remove();
            $('.post_form_tags', post_form).width(get_tags_add_input_width()).val('').focus();
        });
    };
    
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.items.js:
// this really needs to be split up into a bunch of files for each different item
SS.controllers.items = (function () {
    var my = {},
        self = SS.controller(my),
        root_element = "#main",
        comment_template = _.template('<li class="comment"><div class="comment_pic"><%= user_pic %></div>' +
                                        '<div class="comment_main"><div class="comment_body"><a class="comment_owner" href="<%= user_link %>"><%= user_name %></a> <%= comment %></div>' +
                                        '<div class="comment_date_actions">1 second ago</div></div></li>'),
        text_url_to_link = my.text_url_to_link,
        newlines_to_br = my.newlines_to_br,
        clean_quotes = my.clean_quotes,
        has_post_button = function (element) {
            return ($('.button', element).length > 0) ? true : false;
        },
        has_likes = function (element) {
            return ($('.likes', element).length > 0) ? true : false; 
        },
        toggle_actions_in_group = function ($this_element) {
            var $action_group_element = $this_element.closest('.item_action_group'),
                targets = $this_element.data('target');
                
            $action_group_element.find('button, a').hide();
            
            _.each(targets, function (target) {
                $('.item_action_' + target, $action_group_element).show().removeClass('unavailable');
            });
        },
        // Stop the dialog from shrinking once it's content is replaced with a 'loading...' message
        freeze_dialog_size = function( dialog_element ){
            var $dialog_content = $('.ui-dialog-content');

            $dialog_content.css( { width: $dialog_content.width(), height: $dialog_content.height() } );
        },
        // Double submissions are bad
        disable_dialog_buttons = function( dialog_element ){
            $(dialog_element).closest('.ui-dialog').find('.ui-dialog-buttonset button').attr('disabled', true);
        },
        like_unlike = function ($this_element, action) {
            var $item_element = my.get_item_element($this_element),
                item = my.get_model_object($item_element),
                liked_by_initial = $('.likes', $item_element).data('likes') || [],
                liked_by = (action === 'like') ? [[SS.app.current_user.name, SS.app.current_user.url]].concat(liked_by_initial) : _.reject(liked_by_initial, function (person) {return person[0] === SS.app.current_user.name; }),   
                other_likes_amount = liked_by.length - 2,
                has_comments = !!$('.comment', $item_element).length,
                has_likes = !!liked_by.length,
                has_comment_reply = !!$('.comment_reply', $item_element).length,
                can_comment = !item.get('disallows_comments'),
                like_text = function () {
                    if (!liked_by || liked_by.length <= 1) {
                        return '<a href="' + liked_by[0][1] + '">' + liked_by[0][0] + '</a> likes this.';
                    } else if (liked_by.length === 2) {
                        return '<a href="' + liked_by[0][1] + '">' + liked_by[0][0] + '</a> and <a href="' + liked_by[1][1] + '">' + liked_by[1][0] + '</a> like this.';
                    } else if (liked_by.length < 5) {
                        return _.reduce(liked_by.slice(0, liked_by.length - 1), function (memo, person) {
                            return memo + '<a href="' + person[1] + '">' + person[0] + '</a>, ';
                        }, '') + ' and <a href="' + _.last(liked_by)[1] + '">' + _.last(liked_by)[0] + '</a> like this.';
                    } else {
                        return '<a href="' + liked_by[0][1] + '">' + liked_by[0][0] + '</a>, <a href="' + liked_by[1][1] + '">' + liked_by[1][0] + '</a>, and <a class="likes_others">' + other_likes_amount + ' other people</a> like this.';    
                    }
                };
    
            item[action](); 
            
            $('.likes', $item_element).remove();
            if (has_comments || has_likes || has_comment_reply) {
                if (has_comments || has_comment_reply) {
                    if (has_likes) {
                        $('.comment_nub', $item_element).after('<li class="likes">' + like_text() + '</li>');
                        $('.likes', $item_element).data('likes', liked_by);
                    }
                } else {
                    $('.item_main', $item_element).append('<ul class="comments"><li class="comment_nub"></li><li class="likes">' + like_text() + '</li></ul>');
                    if (can_comment) {
                        $('.comments', $item_element).append('<li class="comment_reply"><textarea class="comment_box">Post a comment</textarea></li>');
                    }
                    $('.likes', $item_element).data('likes', liked_by);
                }
            } else {
                $('.comments', $item_element).remove();                  
            }
            
            $('.item_action_like', $item_element).toggleClass('availible');
            $('.item_action_unlike', $item_element).toggleClass('availible'); 
        },
        create_comments_base = function ($item_element) {
            $('.item_main', $item_element).append('<ul class="comments"><li class="comment_nub"></li></ul>');
        },
        create_comment_form = function ($item_element) {
            $('.comments', $item_element).append('<li class="comment_reply"><textarea class="comment_box" type="text">Post a comment</textarea><input class="button" type="button" value="Post Comment"></li>');
        },
        expand_comment_form = function ($this_element) {
            var comment_reply,
                $item_element = my.get_item_element($this_element),
                $comment_box = $('.comment_box', $item_element);
            
            if ($comment_box.val() === 'Post a comment') {
                comment_reply = $('.comment_reply', $item_element);
                
                if (!has_post_button(comment_reply)) {
                    $('.comment_box', comment_reply).after('<input class="button" type="button" value="Post Comment">');
                }
                $('.button', comment_reply).show();
                $comment_box.val('').addClass('expanded').focus();
            }
        },
        contract_comment_form = function ($item_element) {
            var $comment_box = $('.comment_box', $item_element);
            
            if (!$comment_box.val()) {
                $('.comment_reply .button', $item_element).hide();
                $comment_box.removeClass('expanded').val('Post a comment');
            }
        },
        add_comment = function ($item_element, comment) {
            $('.comment_reply', $item_element).before(comment_template({user_pic: SS.app.current_user.comment_pic, user_name: SS.app.current_user.name, user_link: SS.app.current_user.url, comment: comment}));
        },
        
        share = function ($item_element) {
            var item = my.get_model_object($item_element),
                item_type = item.get('type'),
                set_char_count = function () {
                    var count_text = '',
                        char_count = $('.share_dialog_message').val().length;
                        
                    if ($('.share_dialog input[value="twitter"]:checked').length) {
                        if (140 - char_count < 0) {
                            count_text = char_count + ' (' + Math.abs(140 - char_count) + ' over)';
                        } else {
                            count_text = char_count + ' (' + (140 - char_count) + ' left)';
                        }
                    } else {
                        count_text = char_count;
                    }
                    $('.share_dialog_count').text(count_text);    
                },
                share_dialog_content =
                    '<textarea class="share_dialog_message">loading text... please wait</textarea><div>' +
                    '<div>Characters: <span class="share_dialog_count">0</span></div>' +
                    '<label><img alt="" src="/res/img/v2/icons/facebook.png"><input type="checkbox" checked value="facebook">Facebook</label>' +
                    '<label><img alt="" src="/res/img/v2/icons/twitter.png"><input type="checkbox" checked value="twitter">Twitter</label>' +
                    '</div>',
                
                share_dialog = SS.widgets.dialog({
                    type: 'share',
                    content: share_dialog_content,
                    title: 'Share this ' + item_type + ' with friends!',
                    buttons: {
                        Share: function () {
                            var share_to = _.map($('.share_dialog input:checked'), function (input) {
                                return $(input).val();
                            });
                                
                            item.share(share_to, $('.share_dialog .share_dialog_message').val());
                            freeze_dialog_size( this );
                            $(this).html('Sharing...');
                            
                            _.delay(function () {
                                $('.share_dialog').dialog('close');
                            }, 300);
                            disable_dialog_buttons( this );
                        }
                    } 
                });
        
            share_dialog.init();
           
            // hack - there shouldn't be ajax in the controllers
            $.ajax({
                url: item.get('url') + '/get_share_text',
                type: 'GET',
                success: function (share_text) {
                    
                    $('.share_dialog').find('textarea').text(clean_quotes(share_text));
                    set_char_count();
                }
            });
            
            $('.share_dialog_message').bind('keyup paste blur focus', function () {
                set_char_count();
            });  
            
            set_char_count();
        },
        user_dialog = function (users, title) {
            var users_html = _.reduce(users, function (memo, person) {
                    return memo + '<a href="' + person[1] + '">' + person[0] + '</a>';
                }, ''),
                users_dialog_widget = SS.widgets.dialog({
                    type: 'users',
                    content: users_html,
                    title: title,
                    buttons: {
                        Close: function () {
                            $(this).dialog('close');
                        }
                    } 
                });
            
            users_dialog_widget.init();
        },
        change_user_counter = function ($item_element, change) {
            var num_users = +$('.num_users', $item_element).first().text();
            
            $('.num_users', $item_element).text(num_users + change);
        },
        follow_unfollow = function ($this_element, action) {
            var $item_element = my.get_item_element($this_element),
                user = my.get_model_object($item_element),
                num_change = action === 'follow' ? 1 : -1;
                
            user[action]();
            change_user_counter($item_element, num_change);
            toggle_actions_in_group($this_element);
        },
        get_tags_and_input_width = function ($item_element) {
            var $item_tags = $('.item_tags', $item_element),
                tags_width,
                input_width;
            
            if ($item_tags.length) {
                tags_width = _.reduce($('.tag', $item_tags), function (memo, tag) {return memo + $(tag).outerWidth(true) + 1; }, 0);
                input_width = $item_tags.width() - tags_width - 3;
                
                return input_width > 70 ? input_width : 70;
            } else {
                return '100%';
            }
        },
        tag = function ($this_element) {
            var $item_element = my.get_item_element($this_element),
                $tags_input_initial = $('.item_add_tags_input', $item_element),
                $tags_input,
                $item_tags = $('.item_tags', $item_element),
                autocomplete,
                item = my.get_model_object($item_element),
                input_html = '<input class="item_add_tags_input ui-widget" type="text">',
                input_width = get_tags_and_input_width($item_element),
                on_select_callback = function (id, tag_html) {
                    item.add_tag(id);
                    $('.item_add_tags_input', $item_element)
                        .before(tag_html)
                        .width(get_tags_and_input_width($item_element))
                        .val('')
                        .focus();
                };
            
            if ($tags_input_initial.length) {
                $tags_input_initial.focus();
            } else {
                if ($item_tags.length) {
                    $item_tags.append(input_html);
                } else {
                    $('<div />', {'class': 'item_tags'})
                        .insertBefore(
                            $this_element
                                .closest('.item_interaction_actions')
                                .parent()
                        )
                        .append(input_html);
                }
                
                $tags_input = $('.item_add_tags_input', $item_element);
                
                $tags_input.width(input_width);

                autocomplete = SS.widgets.autocomplete_tag({
                    input: $tags_input,
                    on_select: on_select_callback
                });
                autocomplete.init();
                
                $tags_input.focus();
            }
        },
        make_delete_handler = function(full_delete){
            return function (event) {
                var $item_element = my.get_item_element($(this));
                var item = my.get_model_object($item_element);
                var item_type = item.get('type');
                
                // We have different text if we're deleting a user.
                if(item_type=='user'){
                    var content = "You will not be able to restore this record and all the history related to this record. Are you sure you want to do this?";
                    var title = "Delete " + item.get('name') + " from the Database";
                } else {
                    var content = 'Would you like to remove this ' + item_type + ', ' + item.get('name') + ', from the database? Removal of the ' + item_type + ' is permanent.';
                    var title = 'Delete this ' + item_type;
                }
                
                var confirm_dialog = SS.widgets.dialog({
                        type: 'confirm',
                        content: content,
                        title: title,
                        buttons: {
                            Cancel: function () {
                                $('.confirm_dialog').dialog('close');
                            },
                            Delete: function () {
                                item.remove(full_delete);
                                
                                if ($item_element.hasClass('item_view_table')) {
                                    $item_element.closest('tr').slideUp(500, function () {
                                        $item_element.closest('tr').remove();    
                                    });
                                } else {
                                    $item_element.slideUp(500, function () {
                                        $item_element.remove();    
                                    });
                                }
                                
                                freeze_dialog_size( this );
                                $(this).html('Deleting...');
                                
                                _.delay(function () {
                                    $('.confirm_dialog').dialog('close');
                                }, 300);
                                disable_dialog_buttons( this );
                            }
                        } 
                    });
                
                confirm_dialog.init();
            };
        };
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        // Generic Item Actions
        $(root_element).delegate('.item_action_follow', 'click', function (event) {
            follow_unfollow($(this), 'follow');
        });
        $(root_element).delegate('.item_action_unfollow', 'click', function (event) {
            follow_unfollow($(this), 'unfollow');
        });
        $(root_element).delegate('.item_action_delete', 'click', make_delete_handler(false));
        $(root_element).delegate('.item_action_destroy', 'click', make_delete_handler(true));
        $(document).bind('ss_group_joined_left ss_event_rsvped_unrsvped ss_place_joined_left', function () {
            if ($('#content').hasClass('item_view_single')) {
                window.location = window.location;
            }
        });

        $(root_element).delegate('.item_pic', 'click', function () {
            var image_dialog,
                img_source = $(this).find('img').attr('src').replace('=', '').replace('/100x100', ''),
                new_image_ending;
                
            if (_.startsWith(img_source, '/image/')) {
                new_image_ending = '/280x280';
            } else if (_.startsWith(img_source, '/res')) {
                new_image_ending = '';
            } else {
                new_image_ending = '=/280x280';
            }
            
            if (my.get_item_element($(this)).hasClass('item_view_single item_view_complex')) {
                image_dialog = SS.widgets.dialog({
                    type: 'image',
                    content: '<img src="' + img_source + new_image_ending + '" alt="Loading...">',
                    title: 'Embiggened Image',
                    buttons: {
                        Close: function () {
                            $('.image_dialog').dialog('close');
                        }
                    } 
                });
            
                image_dialog.init();
            }
        });
        
        $(root_element).delegate('.item', 'ss_item_created', function (event) {
            share(my.get_item_element($(this)));
            event.stopPropagation();
        });
        
        // User Actions
        $(root_element).delegate('.item_action_user_send_message', 'click', function (event) {
            var $item_element = my.get_item_element($(this)),
                target_user = my.get_model_object($item_element),
                message_dialog = SS.widgets.dialog_message({
                    title: 'Send ' + target_user.get('name') + ' a Message',
                    subject: '',
                    send_function: target_user.message
                });

            message_dialog.init();
        });
        $(root_element).delegate('.item_action_user_send_collection_message', 'click', function (event) {
            var $item_element = my.get_item_element($(this)),
                target_user = my.get_model_object($item_element),
                message_dialog = SS.widgets.dialog_message({
                    title: 'Send ' + target_user.get('name') + ' a Message',
                    subject: 'RE: Outstanding Balance',
                    send_function: target_user.message
                });

            message_dialog.init({
                'focus_selector' : '.message_body'
            });
        });
        $(root_element).delegate('.item_action_user_disable', 'click', function (event) {
            var target = my.get_model_object($(this));
            
            target.disable(); 
            toggle_actions_in_group($(this));
        });
        $(root_element).delegate('.item_action_user_enable', 'click', function (event) {
            var target = my.get_model_object($(this));
            
            target.enable(); 
            toggle_actions_in_group($(this));
        });      
        $(root_element).delegate('.item_action_user_reset_password', 'click', function (event) {
            var $item_element = my.get_item_element($(this)),
                user = my.get_model_object($item_element),
                confirm_dialog = SS.widgets.dialog({
                    type: 'confirm',
                    content: 'The following email will be sent: <div class="dialog_message_preview">' +
                    '<h4>Your password has been reset</h4>Dear ' + user.get('name') + ',<br><br>Your password has been reset.<br><br>' +
                    'Your new password is: NEWPASSWORD.<br><br>Thank you, ' + SS.app.current_network.name +  ' Team </div>',
                    title: 'Reset Password',
                    buttons: {
                        Cancel: function () {
                            $('.confirm_dialog').dialog('close');
                        },
                        "Reset Password": function () {
                            freeze_dialog_size( this );
                            $(this).html('Reseting Password...');
                            
                            user.reset_password();
                            
                            _.delay(function () {
                                $('.confirm_dialog').dialog('close');
                            }, 300);
                            disable_dialog_buttons( this );
                        }
                    } 
                });
            
            confirm_dialog.init();           
        });
        $(root_element).delegate('.item_action_user_renewal_help', 'click', function (event) {
            event.preventDefault();
            $.ss.dialog.message("What to do...", "Engage this member.<br/>Invite them personally to a special event, look at their history, what do they like to attend?<br/>Send them a message, make it personal.<br/>Give them a gift, make them feel special.<br/><br/>All too often, membership organizations see each member as a number. Engage them as a friend.");
        });
        
        // Group Actions
        $(root_element).delegate('.item_action_group_join', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                target_group = my.get_model_object($item_element);
                
            change_user_counter($item_element, 1);
            toggle_actions_in_group($(this));
            target_group.join();
        });
        $(root_element).delegate('.item_action_group_join_request', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                target_group = my.get_model_object($item_element);
            
            target_group.join_request();
            $(this).after($('<div />', {'class': 'notice'}).text('Join request has been sent.')).remove();
        });
        $(root_element).delegate('.item_action_group_leave', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                target_group = my.get_model_object($item_element);
                
            change_user_counter($item_element, -1);
            toggle_actions_in_group($(this));
            target_group.leave();
        });
        
        $(root_element).delegate('.item_action_group_message_all', 'click', function () {
            var target = my.get_model_object($(this)),
                message_dialog = SS.widgets.dialog_message({
                    title: 'Send a Message to All Members',
                    subject: '',
                    send_function: target.message_all
                });
                
            message_dialog.init();
        });
        
        $(root_element).delegate('.item_action_group_invite_people', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                target_group = my.get_model_object($item_element),
                group_name = target_group.get('name'),
                invite_dialog = SS.widgets.dialog({
                    type: 'group_invite',
                    content:
                        '<label>Invite by Name</label>' +
                        '<div class="group_invite_targets_display"></div>' +
                        '<input type="text" class="group_invite_targets"><input class="group_invite_targets_value" type="hidden">' +
                        '<label>Invite by Email Address (separate by commas)</label>' +
                        '<input type="text" class="group_invite_targets_email">' +
                        '<label>Optional Personal Message</label>' +
                        '<textarea class="group_invite_personalization">'+$item_element.data('group_invite_personalization_body')+'</textarea>' +
                        '',
                    title: 'Invite People to Join ' + group_name,
                    buttons: {
                        'Send Invite': function () {
                            var that = this;
                            target_group.invite_users($('.group_invite_targets_value', this).val(), $('.group_invite_targets_email', this).val(), this);
                            freeze_dialog_size( this );
                            $(this).html('Sending...');
                            
                            _.delay(function () {
                                $(that).dialog('close');
                            }, 500);
                            disable_dialog_buttons( this );
                        }
                    } 
                }),
                
                autocomplete = null;
            
            invite_dialog.init();
            
            $('.group_invite_dialog').delegate('.group_invite_user_remove', 'click', function () {
                var user_id = $(this).closest('div').data('user_id'),
                    user_values = $('.group_invite_dialog .group_invite_targets_value').val(),
                    user_values_array = user_values.split(','),
                    user_values_array_good = _.reject(user_values_array, function (user) {return user === user_id; }),
                    user_values_good = user_values_array_good.join(',');
                    
                $('.group_invite_dialog .group_invite_targets_value').val(user_values_good);
                
                $(this).closest('div').remove();
            });
            
            autocomplete = SS.widgets.autocomplete_user({
                input: $('.group_invite_dialog .group_invite_targets'),
                on_select: function (user) {       
                    var user_html = '<div data-user_id="' + user.id + '">' +
                                    '<a href="' + user.url + '">' + user.name + '</a> ' +
                                    '<span class="group_invite_user_remove" title="Remove user">x</span>' +
                                    '</div>',
                        values = $('.group_invite_dialog .group_invite_targets_value').val() || '',
                        to_insert = values ? user.id + ',' + values : user.id;
                        
                    $('.group_invite_dialog .group_invite_targets_value').val(to_insert);
                    
                    $('.group_invite_dialog .group_invite_targets').val('').focus();
                    
                    $('.group_invite_dialog .group_invite_targets_display').append(user_html);
                }
            });
            
            autocomplete.init();
        });
        
        $(root_element).delegate('.item_action_group_invite_people_by_membership', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                target_group = my.get_model_object($item_element),
                group_name = target_group.get('name'),
                invite_dialog = SS.widgets.dialog({
                    type: 'group_invite',
                    content:
                        '<label>Invite by Name</label>' +
                        '<div class="group_invite_targets_display"></div>' +
                        '<input type="text" class="group_invite_targets"><input class="group_invite_targets_value" type="hidden">' +
                        '<label>Invite by Email Address (separate by commas)</label>' +
                        '<input type="text" class="group_invite_targets_email">' +
                        '<label>Optional Personal Message</label>' +
                        '<textarea class="group_invite_personalization">'+$item_element.data('group_invite_personalization_body')+'</textarea>' +
                        '',
                    title: 'Invite People to Join ' + group_name,
                    buttons: {
                        'Send Invite': function () {
                            var that = this;
                            target_group.invite_users($('.group_invite_targets_value', this).val(), $('.group_invite_targets_email', this).val(), this);
                            freeze_dialog_size( this );
                            $(this).html('Sending...');
                            
                            _.delay(function () {
                                $(that).dialog('close');
                            }, 500);
                            disable_dialog_buttons( this );
                        }
                    } 
                }),
                
                autocomplete = null;
            
            invite_dialog.init();
            
            $('.group_invite_dialog').delegate('.group_invite_user_remove', 'click', function () {
                var user_id = $(this).closest('div').data('user_id'),
                    user_values = $('.group_invite_dialog .group_invite_targets_value').val(),
                    user_values_array = user_values.split(','),
                    user_values_array_good = _.reject(user_values_array, function (user) {return user === user_id; }),
                    user_values_good = user_values_array_good.join(',');
                    
                $('.group_invite_dialog .group_invite_targets_value').val(user_values_good);
                
                $(this).closest('div').remove();
            });
            
            autocomplete = SS.widgets.autocomplete_user({
                input: $('.group_invite_dialog .group_invite_targets'),
                on_select: function (user) {       
                    var user_html = '<div data-user_id="' + user.id + '">' +
                                    '<a href="' + user.url + '">' + user.name + '</a> ' +
                                    '<span class="group_invite_user_remove" title="Remove user">x</span>' +
                                    '</div>',
                        values = $('.group_invite_dialog .group_invite_targets_value').val() || '',
                        to_insert = values ? user.id + ',' + values : user.id;
                        
                    $('.group_invite_dialog .group_invite_targets_value').val(to_insert);
                    
                    $('.group_invite_dialog .group_invite_targets').val('').focus();
                    
                    $('.group_invite_dialog .group_invite_targets_display').append(user_html);
                }
            });
            
            autocomplete.init();
        });
        
        
        
        
        
        $(root_element).delegate('.group_action_add_leader', 'click', function (event) {
            var autocomplete,
                $add_leader_button = $(this),
                $group_leaders = $add_leader_button.closest('.group_leaders'),
                group = my.get_model_object($group_leaders),
                on_select = function (user) {       
                    var leader_html =   '<li data-user_id="' + user.id + '">' +
                                        '<div><a href="' + user.url + '"><img src="' + user.icon.src + '" width="48" height="48"></a></div>' +
                                        '<div class="group_leader_name"><a href="' + user.url + '">' + user.name + '</a></div>' +
                                        '<div class="group_action_remove_leader" title="Remove leader"></div>' +
                                        '</li>';
                    group.add_leader(user.id);
                    $('.group_leader_add_input').remove();
                    $add_leader_button.show();
                    
                    $('ul', $group_leaders).prepend(leader_html);
                };
            
            
            $('<input type="text" class="group_leader_add_input">').insertAfter($add_leader_button).focus();
            
            autocomplete = SS.widgets.autocomplete_user({input: $('.group_leaders .group_leader_add_input'), on_select: on_select});
            autocomplete.init();           
            
            $add_leader_button.hide();
        });
        
        $(root_element).delegate('.group_action_remove_leader', 'click', function (event) {
            var $group_leader_element = $(this).closest('li'),
                group = my.get_model_object($group_leader_element);
            
            group.remove_leader($group_leader_element.data('user_id'));
            $group_leader_element.fadeOut();
        });
        
        $(root_element).delegate('.group_action_accept_member', 'click', function (event) {
            var $user_element = $(this).closest('li'),
                group = my.get_model_object($user_element);
            
            group.accept_member($user_element.data('user_id'));
            $user_element.html('<div class="notice">Member Accepted</div>').delay(2000).slideUp();
        });
        
        $(root_element).delegate('.group_action_reject_member', 'click', function (event) {
            var $user_element = $(this).closest('li'),
                group = my.get_model_object($user_element);
            
            group.reject_member($user_element.data('user_id'));
            $user_element.slideUp();
        });
        
        // Event Actions
        $(root_element).delegate('.item_action_event_rsvp', 'click', function () {
            var target_event = my.get_model_object($(this));
                
            toggle_actions_in_group($(this));
            target_event.rsvp();
        });
        $(root_element).delegate('.item_action_event_unrsvp', 'click', function () {
            var target_event = my.get_model_object($(this));
                
            toggle_actions_in_group($(this));
            target_event.unrsvp();
        });
        
        $(root_element).delegate('.item_action_event_cancel_ticket', 'click', function () {
            var target_event = my.get_model_object($(this)),
                attendee_id = $(this).data('attendee_id');
                
            target_event.cancel_ticket(attendee_id);
            $(this).remove();
        });
        $(root_element).delegate('.item_action_event_message_attendees', 'click', function () {
            var target = my.get_model_object($(this)),
                message_dialog = SS.widgets.dialog_message({
                    title: 'Send a Message to All Attendees',
                    subject: '',
                    send_function: target.message_attendees
                });
                
            message_dialog.init();
        });
        
        //event attendee csv
        
        $(root_element).delegate('.item_action_attendees', 'click', function(event){
        	
        	event.preventDefault();
            var $target = $(this);
            var url = $target.prop('href');
            
            var $item_element = my.get_item_element($(this));
            var target_event = my.get_model_object($item_element),
                event_name = target_event.get('name'),
            	permaid = $item_element.data('permaid')
            	$target.ssdialog({
            		'title' : 'Attendees/Invitees List',
	                'width' : document.documentElement.offsetWidth,
	                'content' : {
	                    'url' : url   
	                },
	                'save_url' : null,
	                'buttons': {
	                        'Save': null,
	                        'Cancel' : null,
	                        "Close" : function(namespace){
	                            this[namespace]('hide');
	                        },
	                		'Download CSV': function(){
	                			download_url = $item_element.data('url')+"/attendees_export/"+permaid+".csv";
	                			window.location = download_url;
	                		}
	                    }
                
            	});
            	
        });
        
        //dropdown menu
        
        if(!$("#site").data('clicked_dropdown')){
	        $(document).click( function (e) {
	        	
	        	//the following section is for menu dropdown
	        	var button = document.getElementById('dropdown_button_menu');
	        	if(button){
		        	var top = $('#dropdown_button_menu').position().top;
		        	var left = $('#dropdown_button_menu').position().left;
		        	var height= $('#dropdown_button_menu').height();
		        	var width= $('#dropdown_button_menu').width();
		        	
		        	if($(e.target).closest('.dropdown_button').length>0){
		        		
		        		if( $('.account_dropdown:visible').length==0){
				        	$('.account_dropdown').css({'left':left-360+width-9,'top':top+height+7});
		        			$('.account_dropdown').show();
		        			$('.dropdown_button_activated').css({'left':left-1,'top':top-1});
		        			$('.dropdown_button_activated').show()
		        			$('.dropdown_button_activated_back_layer').css({'left':left-1,'top':top-1});
		        			$('.dropdown_button_activated_back_layer').show()
		        			
		        		}else{
		        			$('.account_dropdown').hide();
			        		
			        		$('.dropdown_button_activated').hide();
			        		
		        		}
		        	
		        	}else if($(e.target).closest('.account_dropdown').length > 0){		
		        		
		        	}else{
		        			$('.account_dropdown').hide();
		        			$('.dropdown_button_activated').hide();
		        			$('.dropdown_button_activated_back_layer').hide();
			        		
		        	}
	        	}
	        	
	        	$('#login_button').mouseenter(function(){
	        		$('#login_button').css({'background-color':'#F6F6F6'});
	        		})
	        		
	        		.mouseleave(function(){
	        			if( $('.sign_in_dropdown:visible').length==0){
	        				$('#login_button').css({'background-color':'white'});
	        			}
	        		});
	        
	        	//the following section is for login dropdown
	        	var login_button = document.getElementById('login_button') || document.getElementById('login_button_digibc');
	        	var digibc = false
	        	if(document.getElementById('login_button_digibc')){
	        		digibc = true
	        	}
	        	if(login_button){
	        		
		        	if($(e.target).closest('.sign_in_button').length>0){
		        		
		        		if( $('.sign_in_dropdown:visible').length==0){
		        			
		        			$('.sign_in_dropdown').show();
		        			$('.sign_in_button_activated').show();
		        			$('.sign_in_button_activated_back_layer').show();
		        			
		        			var top = $('.sign_in_ul').position().top;
		        			var left = $('.sign_in_ul').position().left-$('.sign_in_dropdown').width() + $('.sign_in_ul').width()-31;
		        			var height = $('.sign_in_ul').height();
		        			var button_top = $(login_button).position().top ;		        			
		        			var button_left = login_button.offsetLeft;	
		        			var sign_in_dropdown_left = button_left-$('.sign_in_dropdown').width()+$(login_button).width()-11;
		        			if(digibc){
		        				$('.sign_in_dropdown').css({'left':sign_in_dropdown_left-24,'top':top+height-28});
			        			$('.sign_in_button_activated').css({'left':button_left-4,'top':button_top-4});
			        			$('.sign_in_button_activated_back_layer').css({'left':button_left-4,'top':button_top-4});
		        			}else{
			        			$('.sign_in_dropdown').css({'left':sign_in_dropdown_left,'top':top+height-26});
			        			$('.sign_in_button_activated').css({'left':button_left-3,'top':button_top-1});
			        			$('.sign_in_button_activated_back_layer').css({'left':button_left-3,'top':button_top-1});
		        			}


                                                $('.sign_in_form .login_username').focus();
		        	
		        		}else{
		        			$('.sign_in_dropdown').hide();
		        			$('.sign_in_button_activated').hide();
		        			$('.sign_in_button_activated_back_layer').hide();
		        			
		        		}
		        	
		        	}else if($(e.target).closest('.sign_in_dropdown').length > 0){		
		        		
		        	}else{
			        		$('.sign_in_dropdown').hide();
		        			$('.sign_in_button_activated').hide();
		        			$('.sign_in_button_activated_back_layer').hide();
		        			
		        	
		        	}
	        	}
	        });
	        
	        
	        
	        $("#site").data('clicked_dropdown',true);
        }
        
        $('#site').delegate('.item_action_submit_sign_in_form','click',function(){
        	
        	var form = $(this).closest('form');
        		$(form).submit();
        });
        
        $('.sign_in_dropdown').keypress(function(event){
        	if(event.keyCode == 13){
        		
        		var form_dropdown = $('#login_form_dropdown:visible');
        		
        		if(form_dropdown.length == 0)
        			form_dropdown = $('#loginForm');
        		 
        		$(form_dropdown).submit();
            }
        	
        });
        
        
        /*
        $('.admin_hover_dropdown').mouseenter(function(e){
        	
        	if($('#admin_menu_dropdown:visible').length == 0){
        		$('#admin_menu_dropdown').show();  
        		var left =  -1 * $('#admin_menu_dropdown').width();
                $('#admin_menu_dropdown').css({'left':left,'top':-230});
        	}else{
        			
        	}

        }).mouseleave(function(e){
        	$('#admin_menu_dropdown').hide();
        	
        });
        */
        //delete an attendee
        $(root_element).delegate('.item_action_delete_attendee', 'click', function(){
        	 var $item_element = my.get_item_element($(this));
             var target_event = my.get_model_object($item_element),
                     invite_dialog = SS.widgets.dialog({
                     type: 'delete_attendee',
                     content:
                         '<label>Put attendee id in here:</label>' +
                         '<input type="text" class="attende_id">' +
                         '<div class="delete_result">',
                     title: 'Delete an Attendee',
                     buttons: {
                    	 'Close':function(){
                       		$(this).dialog('close');
                       	 },
                         'Confirm': function () {
                             var that = this;
                             
                             freeze_dialog_size( this );
                             target_event.delete_attendee($('.attende_id', this).val(),this);
                             disable_dialog_buttons( this );
                             
                          }
                         
                     } 
                 });
             invite_dialog.init();
        });
        //invite to network
        $(root_element).delegate('.item_action_invite_to_network', 'click', function(){
            var $item_element = my.get_item_element($(this));
            var model = SS.models.network(),
                    invite_dialog = SS.widgets.dialog({
                    type: 'network_invite',
                    content:
                        '<label>Email Address (separate by commas):</label>' +
                        '<input type="text" class="network_invite_targets_email">' +
                        '<label>Add a Message:</label>' +
                        '<textarea class="network_invite_personalization field" placeholder="...enter your custom message here"></textarea>'+
                        '',
                    title: 'Invite to '+SS.app.current_network.name,
                    buttons: {
                        'Send Invite': function () {
                            var that = this;
                           
                            model.invite_users($('.network_invite_targets_email', this).val(), this);
                            freeze_dialog_size( this );
                            $(this).html('Sending...');
                            
                            _.delay(function () {
                                $(that).dialog('close');
                            }, 500);
                            disable_dialog_buttons( this );
                        }
                    } 
                });
            invite_dialog.init();
        
        });
        
        //invite to event
        $(root_element).delegate('.item_action_event_invite_by_membership', 'click', function(event){
            event.preventDefault();
            var $target = $(this);
            var url = $target.prop('href'),
                $item_element = my.get_item_element($(this)),
                target_event = my.get_model_object($item_element),
                event_name = target_event.get('name'),
                total_member_selected = 0;
            $target.ssdialog({
                'title' : 'Invite by Membership Plan',
                'width' : 300,
                'content' : {
                    'url' : url   
                },
                'save_url' : '/events/'+$item_element.data('permaid')+'/invite_plan_users',
                'buttons': {
                        'Save': null,
                        
                        'Send Invite' : function(namespace){
                            this[namespace]('save');
                            
                        }
                    }
                
            });
            
            $('.show_number_of_users').livequery('click', function () {
          
                if($(this).prop('checked')){
                    total_member_selected += $(this).data('total_member');
                    $('.number_selected').remove();
                    $('.number_selected_div').append('<div class ="number_selected">Number of members selected: '+total_member_selected+'</div>')
                 }
                
                if(!$(this).prop('checked')){
                    total_member_selected -= $(this).data('total_member');
                    $('.number_selected').remove();
                    $('.number_selected_div').append('<div class ="number_selected">Number of members selected: '+total_member_selected+'</div>')
                    
                }
                
               
            });
            
            
            
        });
        
        function check_duplicate(object_type,id){
        	 
            element_rows = $('.event_invite_targets_display').children();
            if (object_type == 'group')
            	element_rows = $('.group_invite_targets_display').children();
         	for(count = 0; count<element_rows.length;count++){
         		if ($(element_rows[count]).data(object_type+'_id') == id)
         			return true;
         	}
         	return false;
        }
        
        $(root_element).delegate('.item_action_event_invite_by_prev_event', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                target_event = my.get_model_object($item_element),
                event_name = target_event.get('name'),
                invite_dialog = SS.widgets.dialog({
                    type: 'event_invite',
                    content:
                        '<label>Invite by Event Name</label>' +
                        '<div class="event_invite_targets_display"></div>' +
                        '<input type="text" class="event_invite_targets"><input class="event_invite_targets_value" type="hidden">'+
                        '<label>Send a Custom Message:</label>' +
                        '<textarea class="event_invite_personalization field" placeholder="...enter your custom message here"></textarea>',

                    title: 'Invite from Previous Event',
                    buttons: {
                        'Send Invite': function () {
                            var that = this;
                            target_event.invite_users_by_prev_events($('.event_invite_targets_value', this).val(), this);                     
                            freeze_dialog_size( this );
                            $(this).html('Sending...');
                            
                            _.delay(function () {
                                $(that).dialog('close');
                            }, 500);
                            disable_dialog_buttons( this );
                        }
                    }
                    
                }),
                autocomplete = null;
            
            invite_dialog.init();
            
            $('.event_invite_dialog').delegate('.event_invite_user_remove', 'click', function () {
                var user_id = $(this).closest('div').data('user_id'),
                    user_values = $('.event_invite_dialog .event_invite_targets_value').val(),
                    user_values_array = user_values.split(','),
                    user_values_array_good = _.reject(user_values_array, function (user) {return user === user_id; }),
                    user_values_good = user_values_array_good.join(',');
                    
                $('.event_invite_dialog .event_invite_targets_value').val(user_values_good);
                
                $(this).closest('div').remove();     
               
            });      
            autocomplete = SS.widgets.autocomplete_event({
                input: $('.event_invite_dialog .event_invite_targets'),
                on_select: function (event) {       
                    var event_html = '<div class="element_row" data-event_id="' + event.id +'"data-count = "'+event.attendee_count+'">' +
                                    '<a href="' + event.url + '">' + event.name + '</a> ' +
                                    '<span class="event_invite_user_remove" title="Remove user">x</span>' +
                                    '</div>',
                        values = $('.event_invite_dialog .event_invite_targets_value').val() || '',
                        to_insert = values ? event.id + ',' + values : event.id;
                    if(!check_duplicate('event',event.id)){	
                        $('.event_invite_dialog .event_invite_targets_value').val(to_insert);
                         
                        $('.event_invite_dialog .event_invite_targets').val('').focus();
                        
                        
                        $('.event_invite_dialog .event_invite_targets_display').append(event_html);
                	}   
                }
                
               
            });
            
            autocomplete.init();
            
        });
        
        $(root_element).delegate('.item_action_event_invite_by_group', 'click', function () {
            
        	var $item_element = my.get_item_element($(this)),
                target_event = my.get_model_object($item_element),
                event_name = target_event.get('name'),
                invite_dialog = SS.widgets.dialog({
                    type: 'group_invite',
                    content:
                        '<label>Invite by Group Name</label>' +
                        '<div class="group_invite_targets_display"></div>' +
                        '<input type="text" class="group_invite_targets"><input class="group_invite_targets_value" type="hidden">'+
                        '<label>Send a Custom Message:</label>' +
                        '<textarea class="event_invite_personalization field" placeholder="...enter your custom message here"></textarea>',
                    title: 'Invite a Group',
                    buttons: {
                        'Send Invite': function () {
                            var that = this;
                            target_event.invite_users_by_groups($('.group_invite_targets_value', this).val(), this);
                            freeze_dialog_size( this );
                            $(this).html('Sending...');
                            
                            _.delay(function () {
                                $(that).dialog('close');
                            }, 500);
                            disable_dialog_buttons( this );
                        }
                    }
                    
                }),
                autocomplete = null;
            
            invite_dialog.init();

            $('.group_invite_dialog').delegate('.group_invite_user_remove', 'click', function () {
                var user_id = $(this).closest('div').data('user_id'),
                    user_values = $('.group_invite_dialog .group_invite_targets_value').val(),
                    user_values_array = user_values.split(','),
                    user_values_array_good = _.reject(user_values_array, function (user) {return user === user_id; }),
                    user_values_good = user_values_array_good.join(',');
                    
                $('.group_invite_dialog .group_invite_targets_value').val(user_values_good);
                
                $(this).closest('div').remove();
            });
            
            
            autocomplete_group = SS.widgets.autocomplete_group({
                input: $('.group_invite_dialog .group_invite_targets'),
                on_select: function (group) {       
                    var group_html = '<div class="element_row" data-group_id="' + group.id + '"data-count = "'+group.member_count+'">' +
                                    '<a href="' + group.url + '">' + group.name + '</a> ' +
                                    '<span class="group_invite_user_remove" title="Remove user">x</span>' +
                                    '</div>',
                        values = $('.group_invite_dialog .group_invite_targets_value').val() || '',
                        to_insert = values ? group.id + ',' + values : group.id;
                    
                    if(!check_duplicate('group',group.id)){
                        $('.group_invite_dialog .group_invite_targets_value').val(to_insert);
                        
                        $('.group_invite_dialog .group_invite_targets').val('').focus();
                        
                        $('.group_invite_dialog .group_invite_targets_display').append(group_html);
                    }
                }
            });
            autocomplete_group.init();

            
        });
        
        
        $(root_element).delegate('.item_action_event_invite', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                target_event = my.get_model_object($item_element),
                event_name = target_event.get('name'),
                invite_dialog = SS.widgets.dialog({
                    type: 'event_invite',
                    content:
                        '<label>Invite by Name</label>' +
                        '<div class="event_invite_targets_display"></div>' +
                        '<input type="text" class="event_invite_targets"><input class="event_invite_targets_value" type="hidden">' +
                        '<label>Invite by Email Address (separate by commas)</label>' +
                        '<input type="text" class="event_invite_targets_email">' +
                        '<label>Send a Custom Message:</label>' +
                        '<textarea class="event_invite_personalization field" placeholder="...enter your custom message here"></textarea>'+
                        '',
                    title: 'Invite People to Attend "' + event_name+'"',
                    buttons: {
                        'Send Invite': function () {
                            var that = this;
                            target_event.invite_users($('.event_invite_targets_value', this).val(), $('.event_invite_targets_email', this).val(), this);
                            freeze_dialog_size( this );
                            $(this).html('Sending...');
                            
                            _.delay(function () {
                                $(that).dialog('close');
                            }, 500);
                            disable_dialog_buttons( this );
                        }
                    } 
                }),
                autocomplete = null;
            
            invite_dialog.init();
            
            $('.event_invite_dialog').delegate('.event_invite_user_remove', 'click', function () {
                var user_id = $(this).closest('div').data('user_id'),
                    user_values = $('.event_invite_dialog .event_invite_targets_value').val(),
                    user_values_array = user_values.split(','),
                    user_values_array_good = _.reject(user_values_array, function (user) {return user === user_id; }),
                    user_values_good = user_values_array_good.join(',');
                    
                $('.event_invite_dialog .event_invite_targets_value').val(user_values_good);
                
                $(this).closest('div').remove();
            });
            
            autocomplete = SS.widgets.autocomplete_user({
                input: $('.event_invite_dialog .event_invite_targets'),
                on_select: function (user) {       
                    var user_html = '<div data-user_id="' + user.id + '">' +
                                    '<a href="' + user.url + '">' + user.name + '</a> ' +
                                    '<span class="event_invite_user_remove" title="Remove user">x</span>' +
                                    '</div>',
                        values = $('.event_invite_dialog .event_invite_targets_value').val() || '',
                        to_insert = values ? user.id + ',' + values : user.id;
                    if(!check_duplicate('user',user.id)){
                        $('.event_invite_dialog .event_invite_targets_value').val(to_insert);
                        
                        $('.event_invite_dialog .event_invite_targets').val('').focus();
                        
                        $('.event_invite_dialog .event_invite_targets_display').append(user_html);
                    }
                }
            });
            
            autocomplete.init();
        });
        
        $(root_element).delegate('.item_action_event_edit_admin', 'click', function(event){
            event.preventDefault();
            var $target = $(this);
            var url = $target.prop('href');
            $target.ssdialog({
                'title' : 'Event Admins',
                'width' : 340,
                'content' : {
                    'url' : url
                },
                'refresh_after_save' : true
            });
        });
        
        // Place Actions
        $(root_element).delegate('.item_action_place_join', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                target = my.get_model_object($item_element);
                
            change_user_counter($item_element, 1);
            target.join();
            toggle_actions_in_group($(this));
        });
        
        $(root_element).delegate('.item_action_place_leave', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                target = my.get_model_object($item_element);
                
            change_user_counter($item_element, -1);    
            target.leave();
            toggle_actions_in_group($(this));
        });
        
        // Message Actions
        $(root_element).delegate('.item_action_message_reply ', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                message = my.get_model_object($item_element),
                owner_id = message.get('owner_id'),
                owner_type = message.get('owner_type'),
                owner = SS.models[owner_type]({id: owner_id}),
                message_dialog = SS.widgets.dialog_message({
                    title: 'Reply to message "' + message.get('name') + '"',
                    subject: 'Re: ' + message.get('name'),
                    send_function: owner.message
                });
                
            message_dialog.init();
            
            $('.message_dialog').find('.message_subject').val('Re: ' + clean_quotes(message.get('name')));
        });
        
        // Proposal Actions
        $(root_element).delegate('.item_action_accept_proposal', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                proposal = my.get_model_object($item_element),
                $feed_element = $item_element.closest('.item_clump');
                
            $item_element.find('.item_content').prepend('<div class="item_proposal_accepted">Accepted</div>');
            
            _.each($feed_element.find('.item[data-type="proposal"]:not([data-id="' + proposal.get('id') + '"])'), function (proposal_element) {
                var $proposal_element = $(proposal_element);

                if ($proposal_element.find('.item_proposal_rejected').length < 1) {
                    $proposal_element.find('.item_content').prepend('<div class="item_proposal_rejected">Rejected</div>');
                    $proposal_element.find('.item_actions').hide();
                }
            });
            
            proposal.accept();
            
            toggle_actions_in_group($(this));
        });
        $(root_element).delegate('.item_action_reject_proposal', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                proposal = my.get_model_object($item_element);
                
            $item_element.find('.item_content').prepend('<div class="item_proposal_rejected">Rejected</div>');
            
            proposal.reject();
            
            toggle_actions_in_group($(this));
        });
        
        // Job Actions
        $(root_element).delegate('.item_action_job_apply', 'click', function (event) {
            var job = my.get_model_object($(this)),
                owner_id = job.get('owner_id'),
                owner_type = job.get('owner_type'),
                owner = SS.models[owner_type]({id: owner_id}),
                message_dialog = SS.widgets.dialog_message({
                    title: 'Apply to the Job: ' + job.get('name'),
                    subject: 'Re: Job Posting - ' + job.get('name'),
                    send_function: owner.message
                });

            message_dialog.init();
        });
        $(root_element).delegate('.item_action_job_close', 'click', function (event) {
            var $item_element = my.get_item_element($(this)),
                job = my.get_model_object($item_element);
            
            job.update_state('inactive');
            $item_element.find('.item_byline').text('Job Closed');
            toggle_actions_in_group($(this));
        });
        $(root_element).delegate('.item_action_job_open', 'click', function (event) {
            var $item_element = my.get_item_element($(this)),
                job = my.get_model_object($item_element);
            
            job.update_state('active');
            $item_element.find('.item_byline').text('');
            toggle_actions_in_group($(this));
        });
        
        // Interactions Actions
        $(root_element).delegate('.item_action_tag', 'click', function () {
            tag($(this));
        });
        $(root_element).delegate('.item_action_share', 'click', function () {
            share(my.get_item_element($(this)));
        });
        $(root_element).delegate('.item_action_like', 'click', function () {
            like_unlike($(this), 'like');
        });
        $(root_element).delegate('.item_action_unlike', 'click', function () {
            like_unlike($(this), 'unlike');
        });
        $(root_element).delegate('.item_likes_others', 'click', function (event) {
            var $item_element = my.get_item_element($(this)),
                liked_by = $('.likes', $item_element).data('likes');
                
            user_dialog(liked_by, 'This post was liked by:');
        });       
        $(root_element).delegate('.item_action_comment', 'click', function (event) {
            var $item_element = my.get_item_element($(this));
            
            event.stopPropagation();
            
            if ($('.comment_box', $item_element).length < 1) {
                if (!has_likes($item_element)) {
                    create_comments_base($item_element);
                }
                create_comment_form($item_element);
            }
            expand_comment_form($(this));
        });
        
        // Item Body Actions
        $(root_element).delegate('.item_join_users', 'click', function (event) {
            var users = $(this).data('users');
            user_dialog(users, 'Users who joined:');
        });
        $('.item_tags', root_element).delegate('.tag_action_remove', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                $tag_element = $(this).closest('.tag'),
                item = my.get_model_object($item_element);
                
            item.remove_tag($tag_element.data('tag_id'));
            $tag_element.remove();
            if ($('.item_add_tags_input', $item_element).length) {
                $('.item_add_tags_input', $item_element).width(get_tags_and_input_width($item_element)).focus();
            }
        });
        
        // Comments
        $(root_element).delegate('.comment_box', 'click', function (event) {
            event.stopPropagation();
            expand_comment_form($(this));
        });
        $(root_element).delegate('.comment_reply .button', 'click', function (event) {
            var $item_element = my.get_item_element($(this)),
                item = my.get_model_object($item_element),
                $reply_input = $('.comment_box', $(this).closest('.comment_reply')),
                comment_text = $reply_input.val(),
                comment = newlines_to_br(text_url_to_link(_.escapeHTML(_.trim(comment_text))));
            
            event.stopPropagation();
            
            if (comment) {
                item.post_comment(comment_text);
                $reply_input.val('');
                contract_comment_form($item_element);
                add_comment($item_element, comment);
            }
        });
        $(root_element).delegate('.comment_action_delete', 'click', function (event) {
            var item = my.get_model_object($(this)),
                comment_id = $(this).closest('.comment').data('comment_id');
                
            item.remove_comment(comment_id);
            $(this).closest('.comment').slideUp();  
        });
        $(document).bind('click', function (event) {
            if (event.which === 1) {
                _.each($('.item'), function (item) {
                    contract_comment_form(item);
                });
            }
        });
        
  
    };
    
    return self;
    
    
    
    
}());

;// Beginning /res/js/v2/controllers/ss.controllers.nav.js:
SS.controllers.nav = (function () {
    var self,
        my = {},
        root_element = 'nav';
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        // this is so when a nav link is clicked it changes the classes
        // immediatly so it looks more responsive
        $(root_element).delegate('a', 'click', function () {
            $('.selected', root_element).removeClass('selected');
            $(this).addClass('selected');
        });
    };
    return self;
}());
;// Beginning /res/js/v2/controllers/ss.controllers.search_box.js:
// the simplist controller of all!
SS.controllers.search_box = (function () {
    var self,
        my = {},
        root_element = '#search_box';
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        $(root_element).bind('click', function () {
            $(this).select();
        });
    };
    return self;
}());
;// Beginning /res/js/v2/controllers/ss.controllers.error.js:
// this is for when if there is an error with the ajax, a error message thingy will pop down

SS.controllers.error = (function () {
    var self,
        my = {},
        add_error = function (action_attempted, error_text, data, jqXHR) {
            var error = '<div class="error_title"><img src="/res/img/v2/icons/error.png"> Error:</div><div>',
                debug_url = jqXHR.getResponseHeader('X-Debug-URL');

            error += 'Action attempted: ' + action_attempted + '.';
            
            if (error_text) {
                error += ' Error text: ' + error_text;
            } else {
                error += ' Action failed.';
            }

            if (data) {
                error += '<div>Data sent:</div>';
                if (data.constructor === String){
                    error += '<div>' + data + '</div>';
                }else{
                    _.each(data, function (value, key) {
                        error += '<div>' + key + ': ' + value + '</div>';
                    });
                }
            }

            if ( debug_url ){
                error += '<div><a target="_blank" href="'+ debug_url+'">Debug</a></div>';
            }
            
            error += '</div><div><a class="error_action_dismiss">dismiss</a></div>';

            $('#main_content').prepend('<div class="error">' + error + '</div>');

            $('div.loading').replaceWith('<div class="error">' + error + '</div>');
        };
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        $(document).bind('ss_ajax_error', function (event, action_attempted, error_text, data, jqXHR) {
            add_error(action_attempted, error_text, data, jqXHR);
           
        });
        $('#main_content').delegate('.error_action_dismiss', 'click', function () {
            $(this).closest('.error').slideUp();
        });
    };
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.advanced.js:
// this is for those little links at the bottom that super admins see
SS.controllers.advanced = (function () {
    var self,
        root_element = "footer",
        my = {},
        toggle = function (this_element, action) {
            // HACK - shouldn't be doing ajax in controllers
            var to_change = $(this_element).data('value');
            $.ajax({
                url: '/test/' + action,
                type: 'GET',
                data: {value: to_change},
                success: function () {
                    window.location.reload();
                }
            });    
        };
    
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        $('.toggle_advanced').bind('click', function () {
            toggle(this, 'toggle_advanced');
        });
        $('.toggle_version').bind('click', function () {
            toggle(this, 'toggle_version');
        });
        $('.toggle_admin').bind('click', function () {
            toggle(this, 'toggle_admin');
        });   

        $('.refresh_css').bind('click', function () {
            // Refresh the css with the latest version
            var $css = $('link[href^="/css/sass/screen.css"]');

            $css.attr('href', $css.attr('href')+'x');
        });
    };
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.tags.js:
SS.controllers.tags = (function () {
    var self,
        my = {};
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        $('#site').delegate('.tag input', 'click', function (event) {
            var $tag_follow = $(this),
                $tag_element = $tag_follow.closest('.tag'),
                tag_offset = $tag_element.offset(),
                tag_id = $tag_element.data('tag_id'),
                tag = SS.models.tag({id: tag_id}),
                bubble_message;
            
            if ($tag_follow.is(':checked')) {
                tag.follow();
                $tag_follow.attr('title', 'Unfollow');
                bubble_message = 'Tag Followed';
            } else {
                tag.unfollow();
                $tag_follow.attr('title', 'Follow');
                bubble_message = 'Tag Unfollowed';
            }
            $tag_element.toggleClass('followed');
            
            $('<div class="tag_bubble_message">' + bubble_message + '</div>').insertAfter('#site').hide();
            $('.tag_bubble_message')
                .offset({
                    left: tag_offset.left,
                    top: tag_offset.top + $tag_element.outerHeight()
                })
                .show()
                .delay(300)
                .fadeOut(700, function () {
                    $(this).remove();
                });
        });
    };
    return self;
}());
;// Beginning /res/js/v2/controllers/ss.controllers.map.js:
SS.controllers.map = (function () {
    var self,
        my = {},                        // all of this does NOTHING!
        map,
        root_element = '',
        markers = [], 
        overlays = [], 
        clear_overlays = function () {
            _.each(overlays, function (overlay, key) {
                overlay.setMap(null);
            });
            overlays = [];
        },
        add_marker = function (info) {
            var target = new google.maps.LatLng(info.geo[1], info.geo[0]),
                marker = new google.maps.Marker({
                    position: target, 
                    map: map, 
                    title: info.title
                }),
                infowindow = new google.maps.InfoWindow({
                    content: $(info.window_html).get(0)
                });

            google.maps.event.addListener(marker, 'click', function () {
                clear_overlays();
                infowindow.open(map, marker);
                overlays.push(infowindow);
            });
            
            markers.push(marker);
            // http://code.google.com/apis/maps/documentation/javascript/overlays.html
        },
        add_markers = function (infos) {
            _.each(infos, function (info, key) {
                add_marker(info);
            });
        },
        clear_markers = function () {
            _.each(markers, function (marker, key) {
                marker.setMap(null);
            });
            markers = [];
        };

    
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            // Everything in here goes straight to document, so we don't need
            // to bind for other root_elements. Just ignore the re-initialization.
            return; 
        }
        $(document).bind('ss_map_view_changed', function (event, bounds) {
            var filters = {
                    'geo:north': bounds.getNorthEast().lat(),
                    'geo:south': bounds.getSouthWest().lat(),
                    'geo:west': bounds.getSouthWest().lng(),
                    'geo:east': bounds.getNorthEast().lng()
                };
                
            $(document).trigger('ss_item_clump_filters_changed', ['search_feed', filters]);
        });

        $(document).bind('ss_item_clump_updated', function (event, item_clump_id, data) {
            if (map) {
                clear_markers();
                add_markers(data.items);
            }
        });
        $(document).bind('ss_item_clump_added_older', function (event, item_clump_id, data) {
            if (map) {
                add_markers(data.items);
            }
        });

        //
        // Configure a map
        //
        $(document).bind('ss_map_created', function (event, the_map) {
            var refresh_search;
            map = the_map;

            // http://code.google.com/apis/maps/documentation/javascript/reference.html

            // The idle event is called when the map is initially loaded as well as
            // whenever panning and zooming completes
            google.maps.event.addListener(map, 'idle', function () {
                $(document).trigger('ss_map_view_changed', map.getBounds());
            });
        });
    };
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.more.js:
SS.controllers.more = (function () {
    var self,
        my = {},
        root_element = '#body';
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        // say a content section is shortened, this will automaticaly
        // deal with showing the full content when clicked
        $(root_element).delegate('.see_more', 'click', function () {
            var $container = $(this).parent();
            
            $('.content_short', $container).remove();
            $('.content_all', $container).show();
            $(this).remove();
        });
        
        // this is when you have a list of items and you are hiding
        // some of them, this will show the rest when clicked
        $(root_element).delegate('.see_all', 'click', function () {
            var $container = $(this).parent();
            
            $('.hidden', $container).fadeIn();
            $(this).remove();
        });
    };
    
    return self;
}());
;// Beginning /res/js/v2/controllers/ss.controllers.settings.js:
SS.controllers.settings = (function () {
    var self,
        my = {},
        root_element = '.profile_edit';
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        if (false){
            // Disabled because the notifications all is not equal to having all the sub
            // :(
            // checkboxes checked
            $(root_element).delegate('input[name="notifications:all"]', 'click', function () {
                var inputs,
                    change_to;
                
                if ($(this).is(':checked')) {
                    inputs = $(this).closest('form').find('input').not('[name="notifications:all"], :checked');
                    change_to = true;
                } else {
                    inputs = $(this).closest('form').find('input:checked').not('[name="notifications:all"]');
                    change_to = false;
                }
                _.each(inputs, function (input) {
                    $(input).prop('checked', change_to);
                });
            });
            $(root_element).delegate('input[name!="notifications:all"]', 'click', function () {
                if (!$(this).is(':checked')) {
                    $(this).closest('form').find('input[name="notifications:all"]').prop('checked', false);
                } else {
                    if (_.all($('input[name!="notifications:all"]', root_element), function (input) { return $(input).is(':checked'); })) {
                        $(this).closest('form').find('input[name="notifications:all"]').prop('checked', true);
                    }
                }
            });
        }
    };
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.item_edit.js:
SS.controllers.item_edit =(function () {
    var self,
        my = {},
        root_element = '.item_edit',
        update_relationship_count = function( $section_element, change ){
            var follow_count = +$('h4 .relationship_edit_panel_count', $section_element).text();
            $('h4 .relationship_edit_panel_count', $section_element).text(follow_count + change);
        },
        init_relationship_add = function ($relationship_edit_panel) {
            var rel_data = $relationship_edit_panel.data(),
                type = rel_data.type,
                $relationship_add_input = $relationship_edit_panel.find('.relationship_edit_panel_add'),
                relationship_add_autocomplete = SS.widgets['autocomplete_' + type]({
                    input: $relationship_add_input,
                    on_select: function (info) {
                        var item = my.get_model_object($(root_element)),
                            template = _.template(''+
                                '<li class="item">' +
                                    '<div class="item_pic">' +
                                        '<input type="hidden" name="relation:'+rel_data.relation_id+':'+rel_data.direction+'" value="<%= id %>">' +
                                        '<a href="<%= url %>" title="<%= name %>"><img src="<%= icon.src %>"></a>' +
                                    '</div>' +
                                    '<div class="relationship_edit_panel_item_info">' +
                                        '<div class="item_title" title="<%= name %>"><a href="<%= url %>"><%= name %></a></div>' +
                                        '<button type="button" class="relationship_edit_panel_action_remove">' + rel_data.disconnect_method_text + '</button>' +
                                    '</div>' +
                                '</li>');
                        
                        if( ! item.is_new() ){
                            item.add_relation(info.id, rel_data.relation_id, rel_data.direction);
                        }
                        update_relationship_count( $relationship_edit_panel, 1 );
                        
                        $relationship_edit_panel.find('.notice').remove();
                        $(template(info)).data(info).hide().appendTo($relationship_edit_panel.find('ul')).fadeIn();
                        $relationship_add_input.val('').select();
                    }
                });
            
            relationship_add_autocomplete.init();
        };
       
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        var company_autocomplete,
            tag_autocomplete,
            user_follow_autocomplete,
            $user_follow_input_element = $('.profile_edit_user_follow', root_element),
            $tag_input_element = $('.profile_edit_tag_add', root_element),
            $item_edit_company_autocomplete = $('.item_edit_company_autocomplete', root_element),
            item_edit_company_autocomplete,
            $item_edit_event_autocomplete = $('.item_edit_event_autocomplete', root_element),
            item_edit_event_autocomplete,
            $item_edit_group_autocomplete = $('.item_edit_group_autocomplete', root_element),
            item_edit_group_autocomplete,
            $item_edit_user_autocomplete = $('.item_edit_user_autocomplete', root_element),
            item_edit_user_autocomplete;
        
        $('.profile_edit_form', root_element).validate({ignore:':hidden',focusInvalid: false});
        
        if ($item_edit_company_autocomplete.length) {
            item_edit_company_autocomplete = SS.widgets.autocomplete_company({
                input: $item_edit_company_autocomplete,
                on_select: function (company_params) {
                    $item_edit_company_autocomplete.siblings('input').val(company_params.id);
                    
                    $item_edit_company_autocomplete
                        .after('<div class="autocomplete_choice"><span class="company_name">' + company_params.name + '</span> <span class="autocomplete_choice_remove">X</span></div>')
                        .hide();

                }
            });
            
            item_edit_company_autocomplete.init();
        }
        
        if ($item_edit_group_autocomplete.length) {
            item_edit_group_autocomplete = SS.widgets.autocomplete_group({
                input: $item_edit_group_autocomplete,
                on_select: function (group_params) {
                    $item_edit_group_autocomplete.siblings('input').val(group_params.id);
                    
                    $item_edit_group_autocomplete
                        .after('<div class="autocomplete_choice"><span class="group_name">' + group_params.name + '</span> <span class="autocomplete_choice_remove">X</span></div>')
                        .hide();

                }
            });
            
            item_edit_group_autocomplete.init();
        }
        
        if ($item_edit_user_autocomplete.length) {
            item_edit_user_autocomplete = SS.widgets.autocomplete_user({
                input: $item_edit_user_autocomplete,
                on_select: function (params) {
                    $item_edit_user_autocomplete.siblings('input').val(params.id);
                   
                    $item_edit_user_autocomplete
                        .after('<div class="user_autocomplete_selected autocomplete_choice" data-user_email="' + params.email + '"><span class="user_name">' + params.name + ' </span><span class="autocomplete_choice_remove">X</span></div>')
                        .hide();

                }
            });
            
            item_edit_user_autocomplete.init();
        }
        

        $('.item_edit_user_list_autocomplete', root_element).livequery(function(){
            var $this = $(this);
            var input_name = $this.attr('inputname');
            item_edit_user_autocomplete = SS.widgets.autocomplete_user({
                input: $this,
                on_select: function (params) {
                    
                    var $new_input = $('<input/>', {
                        type : 'hidden',
                        name : input_name,
                        value : params.id
                    });
                    
                    var $new_choice = $('<div class="autocomplete_choice"><span class="autocomplete_choice_list_remove">X</span> ' + params.name + '</div>');
                    $new_choice.append($new_input);
                    
                    $this.parent().append($new_choice);
                    
                    $this.prop('value', '');
                }
            });
            
            item_edit_user_autocomplete.init();
        });
        
        $item_edit_event_autocomplete.livequery(function(){
            item_edit_event_autocomplete = SS.widgets.autocomplete_event({
                input: $(this),
                on_select: function (params,event) {
                    event.target.value=params.id;
                    
                    $(event.target)
                        .after('<div class="autocomplete_choice"><span class="event_name">' + params.name + '</span> <span class="autocomplete_choice_remove">X</span></div>')
                        .hide();
                   
                    $(event.target).parent().parent().find('.error.custom').hide();
                }
            });
            
            item_edit_event_autocomplete.init();   
        });
        
        $('.autocomplete_choice_remove')
            .livequery('click', function () {
            var $field_section = $(this).closest('.field_section');
            
            $field_section.find('.ui-autocomplete-input').show();
            $field_section.find('.autocomplete_choice').remove();
            $field_section.find('input').val('');
        });
        
        // We're using live here instead of delegate because we want to make sure to 
        // catch anything that doesn't exist under the root_element.
        $('.autocomplete_choice_list_remove').live('click', function(event){
            event.preventDefault();
            $(this).closest('.autocomplete_choice').remove();
        });
        
        $(root_element).delegate('.item_edit_clear_professional_history', 'click', function () {
            var user = my.get_model_object($(root_element));
            user.clear_professional_history();
            $('.professional_experience', root_element).remove();
        });

        $(root_element).delegate('.binding_post_on_someones_behalf', 'change', function () {
            var $span = $('input[name="post_as_company"]', root_element).closest('label').find('span');
            
            if ($span.text() === "your") {
                $span.text("the user's");
            } else {
                $span.text('your');
            }
        });
        
        if ($('.company_edit_autocomplete', root_element).length) {
            company_autocomplete = SS.widgets.autocomplete_company({
                input: $('.company_edit_autocomplete', root_element),
                on_select: function (company_params) {
                    var company = SS.models.company(company_params),
                        user = my.get_model_object($('#content'));
                    
                    $('.item_edit_section', root_element).html('<div class="loading"></div>');
                    company.join_company(user.get('id'));

                }
            });
            
            company_autocomplete.init();
        }
        
        if ($tag_input_element.length) {
            tag_autocomplete = SS.widgets.autocomplete_tag({
                input: $tag_input_element,
                on_select: function (tag_id, tag_html) {
                    var tag = SS.models.tag({id: tag_id});
                    
                    tag.follow();
                    $('.tag_list', root_element).append(tag_html);
                    $tag_input_element.val('').focus();
                },
                hide_remove_button: true,
                auto_follow: true
            });
            
            tag_autocomplete.init();
            
            $(root_element).delegate('.tag input', 'click', function () {
                $(this).closest('.tag').fadeOut();
            });
        }
        
        $.each($('.relationship_edit_panel', root_element), function () {
            init_relationship_add($(this));
        });
    
        $(root_element).delegate('.item_edit_action_save', 'click', function () {
            var $form = $('.item_edit_form', root_element),
                data = $form.serialize(),
                item = my.get_model_object($(root_element));
                data+= '&' + $(this).attr("data-status")
                
            my.submit_form($form, $(this), function () {
                item.edit(data);
            }, root_element);
        });
        
        $(root_element).delegate('.item_edit_action_create', 'click', function () {
            var $form = $('.item_edit_form', root_element),
                data = $form.serialize(),
                type = my.get_model_object($(root_element)).get('type'),
                item = SS.models.item({url: '/' + my.get_plural(type)}),
                parent_id = $form.find('input[name="parent_context"]').val(),
                parent_type = $form.find('input[name="parent_type"]').val(),
                parent_url = parent_id ? '/' + my.get_plural(parent_type) + '/' + parent_id : undefined;
                data+= '&' + $(this).attr("data-status")
                
            my.submit_form($form, $(this), function () {
                item.create(false, data, type, parent_url);
            }, root_element);
        });
        
        $(document).bind('ss_item_saved', function (event, inline) {
            if (!inline) {
                window.location = window.location;
            }
        });
        $(document).bind('ss_item_created', function (event, data, type, parent_url) {
            var item_url = $(data).data('url');
            if (data.url){
                window.location = data.url;
            } else if ( item_url ){
                window.location = item_url;
            } else if (parent_url) {
                window.location = parent_url;
            } else {
                window.location = '/' + my.get_plural(type);
            }
        });        

        $(document).bind('ss_company_member_added ss_company_joined ss_profile_unlinked ss_profile_linked ss_profile_membership_cancelled', function () {
            window.location = window.location;
        });
        $(document).bind('ss_profile_settings_saved', function (event, response) {
            if (response.error) {
                $(root_element).html(response.error);
            } else if (response.redirect_to) {
                window.location = response.redirect_to;
            } else {
                window.location = window.location;
            }
        });

        $(root_element).delegate('.profile_settings_action_cancel_membership', 'click', function () {
            var membership_info_id = $(this).data('membership_info_id'),
                user = my.get_model_object($('#content'));

            user.cancel_membership(membership_info_id);
            $(root_element).html('<div class="loading"></div>');
        });
        $(root_element).delegate('.profile_settings_action_save', 'click', function () {
            var $profile_edit_form = $('.profile_edit_form'),
                data = $profile_edit_form.serialize(),
                user = my.get_model_object($('#content'));

            if ($profile_edit_form.valid()) {
                user.save_settings(data);
                $(root_element).html('<div class="loading"></div>');
            }
        });
        
        // Relationships
        $(root_element).delegate('.relationship_edit_panel_action_remove', 'click', function () {
            var $item_element = my.get_item_element($(this)),
                item = my.get_model_object($(root_element)),
                $section_element = $item_element.closest('.relationship_edit_panel'),
                rel_data = $section_element.data(),
                target_data = $item_element.data();
                    
            update_relationship_count( $section_element, -1 );

            if( ! item.is_new() ){
                item.remove_relation(target_data.id, rel_data.relation_id, rel_data.direction);
            }
            $item_element.fadeOut();
        });
        
        // Company Personnel
        $(root_element).delegate('.company_edit_action_remove_member', 'click', function () {
            var $member_element = $(this).closest('li'),
                target_user = my.get_model_object($member_element),
                company = my.get_model_object($('#content'));
                
            company.remove_member(target_user.get('id'));
            $member_element.slideUp(function(){
                // We need to make sure to remove it so that the form elements
                // won't still be on the page.
                $member_element.remove();
            });
        });
        
        $(root_element).delegate('.company_edit_action_add_member', 'click', function () {
            var //company_url = $('.company_edit_url', root_element).val(),
                //company = SS.models.company({url: company_url}),
                company = my.get_model_object($(root_element)),
                $li_element = $(this).closest('li'),
                autocomplete;
            
            $(this).remove();
            $li_element.html('<label>Select User to Add:</label> <input type="text" class="company_edit_action_add_member_input">');
            $('input', $li_element).focus();
            
            autocomplete = SS.widgets.autocomplete_user({
                input: $('.company_edit_action_add_member_input'),
                on_select: function (user_info) {       
                    company.add_member(user_info.id);
                    $li_element.html('<div class="loading"></div>');
                }
            });
            
            autocomplete.init();
        });

        
        // Update the attribute to allow for different css for the checkbox, radio and select lists
        $('.field_type')
            .livequery('change', function () {
                $('.option_list', $(this).closest('.field_info')).attr('option_type', $(this).val());
        });

        $(root_element).delegate('.create_new_user', 'click', function () {
            $('.binding_create_a_new_user').val('True').change();
        });
        $(root_element).delegate('.choose_existing_user', 'click', function () {
            $('.binding_create_a_new_user').val('').change();
        });


 
    };
    
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.permissions.js:
SS.controllers.permissions = (function () {
    var self,
        my = {},
        root_element = '.permissions_table',
        update_options = function ($this_element, check_options) {
            var data = $this_element.data(),
                start_selector = 'input[data-user_type="' + data.user_type + '"]',
                selector;
            
            $(start_selector).prop('checked', false); // uncheck all
            
            if (data.category) {
                selector = start_selector + '[data-categories~="' + data.category + '"]';
            } else {
                selector = start_selector;
            }
            
            $(selector).prop('checked', check_options);
        };
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        $('.permission_action_clear_all', root_element).bind('click', function () {
            update_options($(this), false);
        });
        
        $('.permission_action_check_all', root_element).bind('click', function () {
            update_options($(this), true);
        });
        
        $('.permission_action_check_category', root_element).bind('click', function () {
            update_options($(this), true);
        });
        
    };
    
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.sponsors.js:
// this is for the sponsors panel thing that shows up in the secondary content
// on the home page, which scrolls through the sponsors
SS.controllers.sponsors = (function () {
    var self,
        my = {},
        root_element = '.sponsors';
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        var interval = 10000, // milliseconds, so this is 10 seconds
            slide_to_next_sponsor = function () {
                var $current_sponsor = $(root_element).find('.sponsor:visible'),
                    $next_sponsor = $current_sponsor.next(),
                    $following_sponser = $next_sponsor.length ? $next_sponsor : $(root_element).find('.sponsor:first');
                
                $current_sponsor.slideUp(1000);
                $following_sponser.first().slideDown(1000);
            };
            
        $(root_element).find('.sponsor:not(:first)').hide();
        setInterval(slide_to_next_sponsor, interval);
    };
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.setup.js:
SS.controllers.setup = (function () {
    var self,
        my = {},
        root_element = '.setup';
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        var company_autocomplete;
        if ($('.setup_company_autocomplete', root_element).length) {
            company_autocomplete = SS.widgets.autocomplete_company({
                input: $('.setup_company_autocomplete', root_element),
                on_select: function (company_params) {
                    var company = SS.models.company(company_params),
                        user = my.get_model_object($('#content'));
                    
                    $('.setup_main_section', root_element).html('<div class="loading"></div>');
                    company.join_company(user.get('id'));
                }
            });
            
            company_autocomplete.init();
        }
        
        $(root_element).delegate('.setup_disclaimer_next', 'click', function () {
            var $checkbox = $('.disclaimer_checkbox', root_element);
            
            if ($checkbox.is(':checked')) {
                window.location = "/setup/disclaimer_signed";
            } else {
                $checkbox.closest('label').addClass('error').change(function () {
                    $(this).removeClass('error');
                });
            }
        });
        $(root_element).delegate('.setup_disclaimer_step_button', 'click', function (event) {
            event.preventDefault();
            var $checkbox = $('.disclaimer_checkbox', root_element);
            
            if ($checkbox.is(':checked')) {
                var $form = $('form', root_element);
                $form.append($('<input />', {type: 'hidden', name: 'redirect_url', value: $(this).attr('href')}));
                $form.submit();
            } else {
                $checkbox.closest('label').addClass('error').change(function () {
                    $(this).removeClass('error');
                });
            }
        });
        $(root_element).delegate('.setup_next', 'click', function (event) {
            var $form = $('form', root_element);
            
            if (($('#content').hasClass('setup_profile') || 
                 $('#content').hasClass('setup_basic')||
                 $('#content').hasClass('setup_notification') ||
                 $('#content').hasClass('setup_custom') ||
                 $('#content').hasClass('setup_company')) && $form.is(':visible')) {
                event.preventDefault();
                
                $form.append($('<input />', {type: 'hidden', name: 'redirect_url', value: $(this).attr('href')}));
                $form.submit();
            }
        });
        $(root_element).delegate('.setup_action_new_company', 'click', function () {
            $('.setup_company_pick', root_element).hide();
            $('.setup_form').show();
        });
    };
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.social.js:
SS.controllers.social = (function () {
    var self,
        my = {},
        root_element = '.social';
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        $(root_element).delegate('.social_action_unlink', 'click', function () {
            var $box_element = $(this).closest('.social_box'),
                network = $box_element.data('social_network'),
                user = my.get_model_object($('#content'));
                
            user.unlink(network);
        });
    };
    
    // hack should fix
    self.facebook_link = function () {
        var user = my.get_model_object($('#content'));
        
        user.link('facebook');    
    };
    
    return self;
}());
;// Beginning /res/js/v2/controllers/ss.controllers.calendar.js:
SS.controllers.calendar = (function () {
    var self,
        my = {},
        root_element = '.calendar',
        event_type;
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            // This breaks when trying to initialize with a new root element. This wasn't strictly
            // needed at the time I (Ian) wrote this, and given the lack of time I'm leaving this
            // as-is. If you need this to work rather than just not break, feel free to have a go
            // at it.
            return;
        }
        var $calendar = $(root_element),
            event_src;
        
        if ($calendar.length) {
            event_src = $(root_element).data('event_src');
            
            $(root_element).fullCalendar({
                    editable: false,
                    events: '/event/ajax_' + event_src,
                    timeFormat: 'h(:mm)tt',
                    loading: function (is_loading, view) {
                        if (!is_loading) {
                            // this is a little hack to make it so that if it has no starting time (the data
                            // will show 12am) than we don't show it so that it looks like an all day event
                            _.each($('span.fc-event-time', root_element), function (time) {
                                var $time = $(time);
                                
                                if ($time.text() === '12am') {
                                    $time.remove();
                                }
                            });
                        }
                    }
            });
            

        }
    };
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.customizations.js:
SS.controllers.customizations = (function () {
    var self,
        my = {},
        root_element = '.customization',
        submit_form = function ($form, $this_element, submit_function) {
            if ($form.valid()) {
                submit_function();
                $(root_element).html('<div class="loading"></div>');
            } else {
                $('<div />', {'class': 'error'})
                    .html('Your required fields are not valid. Please review.')
                    .insertAfter($this_element)
                    .delay(1000)
                    .fadeOut();
            } 
        };
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        $(root_element).delegate('.customization_edit_action_save', 'click', function () {
            var $form = $('.customization_form', root_element),
                data = $form.serialize(),
                item = my.get_model_object($(root_element));
                
            submit_form($form, $(this), function () {
                item.edit(data);
            });
        });
        
    };
    
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.payments.js:

SS.controllers.payments = (function () {
    var self,
        my = {},
        root_element = '.payment',
        submit_form = function ($form, $this_element, submit_function) {
            if ($form.valid()) {
                submit_function();
                $(root_element).html('<div class="loading"></div>');
            } else {
                $('<div />', {'class': 'error'})
                    .html('Your required fields are not valid. Please review.')
                    .insertAfter($this_element)
                    .delay(1000)
                    .fadeOut();
            } 
        };
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        var $form = $('.payment_form', root_element);
        
        if ($("#has_at_least_one_ticket_to_buy")){
            if ($("#has_at_least_one_ticket_to_buy").val()=='hide'){
            	
            	$("#show_ticket_panel").addClass('hide_tickets_details');
                $("#show_ticket_table").addClass('hide_tickets_details');
                $("#show_actions_or_not").addClass('hide_tickets_details');
                
            }    
        }
        
        if ($("[name='event:total_tickets_available']")[0]){
            $("[name='event:total_tickets_available']").first().bind('keyup', function() {
                if ($("[name='event:total_tickets_available']")[0].value!==''){
                    if ($($("[name='event:has_no_ticket_limit']")[1]).is(':checked')){
                        $("[name='help_has_no_ticket_limit']").val('2');
                        $($("[name='event:has_no_ticket_limit']")[1]).click();
                    }
                    
                }
                else {
                    $($("[name='event:has_no_ticket_limit']")[1]).prop('checked', true);
                    }
                
            });
        }
        
        if ($($("[name='event:has_no_ticket_limit']")[1])){
            $($("[name='event:has_no_ticket_limit']")[1]).bind("click", function(e){
                if ($($("[name='event:has_no_ticket_limit']")[1]).is(':checked') && ($("[name='help_has_no_ticket_limit']").val()!=='2')){
                   $("[name='event:total_tickets_available']")[0].value='';
                   $($("[name='event:total_tickets_available']")[0]).removeClass('required');
                }
                else if ($($("[name='event:has_no_ticket_limit']")[1]).is(':checked')){
                    $("[name='help_has_no_ticket_limit']").val('3');
                }
                if (!$($("[name='event:has_no_ticket_limit']")[1]).is(':checked')){
                    $($("[name='event:total_tickets_available']")[0]).addClass('required');
                }
            });
        }
       
        if ($form[0]){
            
            if($form[0].x_card_num){
                var card_type;
                $form[0].x_card_num.addEventListener('keyup', function() {
                    // determine the type of card
                    if ($form[0].x_card_num.value.match(/^4/)) {
                        card_type = 'visa';
                    
                    } else if ($form[0].x_card_num.value.match(/^5[1-5]/)){
                          card_type = 'master_card';
                    } 
                      else if ($form[0].x_card_num.value.match(/^3[47]/)){
                          card_type = 'american_express';
                    } 
                      else if ($form[0].x_card_num.value.match(/^6011/)){
                          card_type = 'discover';
                    }
                      else{
                          card_type = null;
                      }
                    
                    $('.card_image').removeClass('active_card');
          
                    if ( card_type ){
                        $("#"+card_type).addClass('active_card');
                    }
                }, false);
            }
        }
        
        $('.tickets').delegate('#show_details', 'click', function () {
            $("#tickets_details").removeClass('hide_tickets_details');
            $("#show_tickets_on_request").addClass('hide_tickets_details');
            $("#hide_tickets_on_request").removeClass('hide_tickets_details');
           
        });
        
        
        $('.tickets').delegate('#hide_details', 'click', function () {
            $("#tickets_details").addClass('hide_tickets_details');
            $("#show_tickets_on_request").removeClass('hide_tickets_details');
            $("#hide_tickets_on_request").addClass('hide_tickets_details');
           
        });
        

        $(root_element).delegate('.payment_action_submit', 'click', function () {
            var $form = $('.payment_form', root_element),
                data = $form.serialize();
            var $root_element = $(root_element);
            
            var item = my.get_model_object($root_element);
                
            submit_form($form, $(this), function () {
                item.submit_payment(data);
            });
        });
        
        $(root_element).delegate('.payment_action_finalize', 'click', function () {
            var $form = $('.payment_form', root_element),
                data = $form.serialize();
                
            var $root_element = $(root_element);
            var item = my.get_model_object($root_element);
                
            submit_form($form, $(this), function () {
                item.finalize_payment(data);
            });
        });
        
        
        $(root_element).delegate('.cvd_link', 'click', function (event, response) {
            event.preventDefault();
            alert("Card Validation Digits are numbers printed on the back of your credit card. Providing this number helps ensure " +
                   "that you are the valid cardholder. If your card does not have these digits, you may leave this field blank.");
        });
        

        $(document).bind('ss_payment_submitted', function (event,response) {
        
            if (response.success.approved){
                $("body").load(response.success.next_url, function() {
                    var input_fields = ["x_card_num", "x_card_code"];
                    $.each(input_fields, function(i,item){
                        if (response.success[item]){
                            $("[name=\""+item+"\"]").val(response.success[item]);
                        }
                    });
                    $("[name='x_exp_date']").val(response.success['x_exp_month']+ response.success['x_exp_year']);
                    var cc_num = response.success['x_card_num'];
                    $('#cc_num_last_4_digits').append('<b>' + cc_num.substr(cc_num.length - 4) +'</b>');
                });
            }
            else {
                $("body").load(response.success.next_url, function() {
                    if ($("[name='trnExpMonth']").length > 0){
                        var input_fields = ["trnCardOwner","ordEmailAddres", "ordName", "ordAddress1", "ordAddress2", "ordCity", "ordCountry",
                                            "ordProvince", "ordPostalCode", "ordPhoneNumber", "trnExpMonth", "trnExpYear", "trnCardCvd"];
                    }
                    else if ($("[name='x_exp_month']").length > 0){
                        var input_fields = ["trnCardOwner", "x_email", "x_phone", "x_first_name", "x_last_name", "x_address", "x_address2",
                                            "x_city", "x_state", "x_country", "x_zip", "x_exp_month", "x_exp_year", "x_card_code"];
                    }
                    $.each(input_fields, function(i,item){
                        $("[name=\""+item+"\"]").val(response.success[item]);
                    });
                    $('.show_error').append("<div class='error'>"+ response.success.message_text + "</div>");
                });
            }
        });
        
        $(document).bind('ss_payment_finalized', function (event,response) {
            $("body").load(response.data.next_url, function() {
                var cc_last_4_digits = response.data.cc_last_4_digits;
                $('#cc_num_last_4_digits').append('<b>' + cc_last_4_digits +'</b>');
            });
        });
       
        $(document).bind('ss_payment_failed', function () {
            alert('payment failed');
        });
    };
    
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.data_table.js:
// this has way to much stuff and should be cleaned up
SS.controllers.data_table = (function () {
    var self,
        my = {},
        root_element = '.data_table';
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        $(root_element).delegate('.item_action_user_membership_info_edit', 'click', function (event) {
            var target = my.get_model_object($(this)),
                $td = $(this).closest('td'),
                $row = $td.closest('tr'),
                membership_edit_dialog = SS.widgets.dialog({
                    type: 'membership_edit',
                    content: $td.find('.admin_section').html(),
                    title: 'Edit ' + target.get('name') + "'s Membership Info",
                    buttons: {
                        'Cancel': function () {
                            $(this).dialog('close');
                        },
                        'Save': function () {
                            var that = this,
                                $form = $(this).find('form'),
                                data = $form.serialize(),
                                data_array = $form.serializeArray(),
                                data_object = my.name_value_array_to_object(data_array);
                                
                            target.edit(data, true);
                            
                            $row.find('span[data-field="expiry_date"]').html(data_object.expiry_date || 'No Expiry');
                            $row.find('span[data-field="created"]').html(data_object.created);
                            $row.find('span[data-field="user_type"]').html(data_object.admin_status === "admin" ? "Admin" : $form.find('option[value="' + data_object.membership_plan + '"]').text());
                            
                            $(this).html('Saving...');
                            
                            _.delay(function () {
                                $(that).dialog('close');
                            }, 500);
                        }
                    } 
                });
            event.preventDefault();
            
            membership_edit_dialog.init();
            
            _.each($('.date_input', '.membership_edit_dialog'), function (date_input) {
                $(date_input).datepicker({
                    dateFormat: 'dd M yy',
                    onClose: function () {$(this).valid(); }
                });
            });
            //attempt to fix this problem but didnt have enough time to dig into it. please ignore the commented code below. Feel free to delete it if you find a solution.
            /*
            _.each($('.date_input', '.membership_edit_dialog').livequery(function () {
            	
            	$(this).removeClass('hasDatepicker');
            	
                $(this).datepicker({
                    dateFormat: 'dd M yy',
                    onClose: function () {$(this).valid(); }
                });
            }));
          	*/
        });
        
        // Controls that provide some of the same functionality as that above attached to .item_action_user_membership_info_edit
        
        $(root_element).delegate('.item_action_user_membership_add_note', 'click', function (event) {
            event.preventDefault();
            var target = my.get_model_object($(this));
            var get_url = target.get('url') + '/manage/add_note';
            var save_url = target.get('url');
            $('<div>').ssdialog({
                'title' : 'Add a Note to ' + target.get('name') + '\'s Membership Record',
                'save_url' : save_url,
                'dynamic_width' : true,
                'content' : {
                    'url' : get_url,
                    'refresh_on_show' : true
                }
            });
        });
        
        $(root_element).delegate('.item_action_user_membership_plan', 'click', function (event) {
            event.preventDefault();
            var target = my.get_model_object($(this));
            var get_url = target.get('url') + '/manage/membership_plan';
            var save_url = target.get('url');
            $('<div>').ssdialog({
                'title' : 'Change Membership for ' + target.get('name'),
                'save_url' : save_url,
                'dynamic_width' : true,
                'content' : {
                    'url' : get_url,
                    'refresh_on_show' : true
                }
            });
        });
        
        $(root_element).delegate('.item_action_user_membership_admin_status_give', 'click', function (event) {
            event.preventDefault();
            var target = my.get_model_object($(this));
            var get_url = target.get('url') + '/manage/admin_status';
            var save_url = target.get('url');
            $('<div>').ssdialog({
                'title' : 'Give ' + target.get('name') + ' Admin Access?',
                'save_url' : save_url,
                'dynamic_width' : true,
                'content' : {
                    'url' : get_url,
                    'refresh_on_show' : true
                },
                save_button_label: 'Yes',
                cancel_button_label: 'No',
                'success_callback' : function(){
                    var $link = $(event.target).closest('a');
                    $link.siblings('a').show();
                    $link.hide();
                }
            });
        });
        
        $(root_element).delegate('.item_action_user_membership_admin_status_remove', 'click', function (event) {
            event.preventDefault();
            var target = my.get_model_object($(this));
            var get_url = target.get('url') + '/manage/admin_status';
            var save_url = target.get('url');
            $('<div>').ssdialog({
                'title' : 'Remove ' + target.get('name') + '\'s Admin Access?',
                'save_url' : save_url,
                'dynamic_width' : true,
                'content' : {
                    'url' : get_url,
                    'refresh_on_show' : true
                },
                'success_callback' : function(){
                    var $link = $(event.target).closest('a');
                    $link.siblings('a').show();
                    $link.hide();
                }
            });
        });
        
        $(root_element).delegate('.item_action_user_membership_cancel_recurring', 'click', function (event) {
            event.preventDefault();
            var target = my.get_model_object($(this));
            var get_url = target.get('url') + '/manage/cancel_recurring';
            var save_url = target.get('url') + '/cancel_recurring_payments';
            $('<div>').ssdialog({
                'title' : 'Cancel ' + target.get('name') + '\'s Recurring Payment',
                'save_url' : save_url,
                'dynamic_width' : true,
                'content' : {
                    'url' : get_url,
                    'refresh_on_show' : true
                },
                'success_callback' : function(){
                    var $link = $(event.target).closest('a');
                    $link.siblings('a').show();
                    $link.hide();
                }
            });
        });
    };

    self.initialize_table = function(table_config, config, $table){
        var $table_div = $table || $(root_element),
            data_fetching_function = function ( sSource, aoData, fnCallback ) {
                    // Add some extra data to the sender
                    var json_field_data = JSON.stringify($table_div.data('config'));
                    aoData.push( { "name": "report_spec", "value": json_field_data } );
                    $.getJSON( sSource, aoData, function (json) { 
                            // Do whatever additional processing you want on the callback, 
                            // then tell DataTables
                            fnCallback(json);
                    } );
                },
            oTable,
            toolbar,
            $wrapper,
            $table_filter_head = $('thead.filter_head', $table_div).clone(),
            header_index = function (th) {
                return $(th).data('column_index');
            },
            refresh_table = function () {
                $wrapper.replaceWith("<table class='data_table' class='display'></table>");
                // reinitialize table with the new set of columns 
                self.initialize_table( table_config, config );
            };

        // Set some defaults
        config = config || {};
        table_config.group_bys = table_config.group_bys || [];


        // store the config for later use
        $table_div.data( 'config', table_config );

        // Clear the old contents
        $table_div.html('');

        oTable = $table_div.dataTable({
                "bJQueryUI": true,
                "sPaginationType": "two_button",
                "aaSorting": table_config.default_sorting,
                "aoColumns": table_config.group_bys.concat(table_config.columns),
                "bDestroy":true,
                "sDom": table_config.config_params + '<"toolbar"><"filter_bar">rt"F"lip',
                "bProcessing": true,
                "bServerSide": true,
                "sAjaxSource": table_config.ajax_source, 
                "fnServerData": data_fetching_function
                //"fnRowCallback": table_config.row_callback
                //"fnHeaderCallback": header_callback,
                //"fnRowCallback": row_callback
            });

        $wrapper = $table_div.closest('.dataTables_wrapper');

        // declared as a global reference for the members javascript onclick callbacks benefit 
        member_table = oTable;

        // initialize the html column headings
        // for now assume they were defined elsewhere and can be just copied in
        if ( $table_filter_head.length ){
            $('thead', $table_div).last().after( $table_filter_head );
        }
        
        // add the add person button and move the toolbar before the horizontally scrolling div
        toolbar = $('div.toolbar');
        toolbar.html($('.add_person_button'));
        $wrapper.before( toolbar );

        $('div.filter_bar').html($('.title_secondary'));

        if ( table_config.export_source ){
            add_export_button( oTable, table_config );
        }

        $('div.toolbar').append($('.add_person_button'));

        $("input.min_range_filter, input.max_range_filter", $table_filter_head).keyup( function() {
            var $th = $(this).closest('th'),
                min = $th.find('.min_range_filter').val(),
                max = $th.find('.max_range_filter').val();

            oTable.fnFilter( min + '-' + max, header_index($(this).closest('th')) );
        });

        $("input.filter", $table_filter_head).change( function() {
            oTable.fnFilter( this.value, header_index($(this).closest('th')) );
        });

        $("select.filter", $table_filter_head).change( function() {
            oTable.fnFilter( this.value, header_index($(this).closest('th')) );
        });

        $(".date_input", $table_filter_head).change(function() {
            oTable.fnFilter( this.value, header_index($(this).closest('th')) );
        }).focus(function () {
            this.select();
        });

        $(document).trigger('ss_data_table_initialized', [$table_div, oTable]);


        if ( config.dynamic_columns ){
        }
    };

    return self;
}());

// old v1 stuff hack fixme 
function add_export_button(oTable, table_config){
    var ajax_params = function(){
        var oSettings = oTable.fnSettings(),
            iColumns = oSettings.aoColumns.length,
            aoData = [],
            i,
            form,
            csv_button = $(this);
        
        /* Paging and general */
        oSettings.iDraw++;
        aoData.push( { "name": "sEcho",          "value": oSettings.iDraw } );
        aoData.push( { "name": "iColumns",       "value": iColumns } );
        aoData.push( { "name": "iDisplayStart",  "value": oSettings._iDisplayStart } );
        aoData.push( { "name": "iDisplayLength", "value": oSettings.oFeatures.bPaginate !== false ?
                oSettings._iDisplayLength : -1 } );
        
        /* Filtering */
        if ( oSettings.oFeatures.bFilter !== false )
        {
                aoData.push( { "name": "sSearch", "value": oSettings.oPreviousSearch.sSearch } );
                aoData.push( { "name": "bRegex",  "value": oSettings.oPreviousSearch.bRegex } );
                for ( i=0 ; i<iColumns ; i++ )
                {
                        aoData.push( { "name": "sSearch_"+i,     "value": oSettings.aoPreSearchCols[i].sSearch } );
                        aoData.push( { "name": "bRegex_"+i,      "value": oSettings.aoPreSearchCols[i].bRegex } );
                        aoData.push( { "name": "bSearchable_"+i, "value": oSettings.aoColumns[i].bSearchable } );
                }
        }
        
        /* Sorting */
        if ( oSettings.oFeatures.bSort !== false )
        {
                var iFixed = oSettings.aaSortingFixed !== null ? oSettings.aaSortingFixed.length : 0;
                var iUser = oSettings.aaSorting.length;
                aoData.push( { "name": "iSortingCols",   "value": iFixed+iUser } );
                for ( i=0 ; i<iFixed ; i++ )
                {
                        aoData.push( { "name": "iSortCol_"+i,  "value": oSettings.aaSortingFixed[i][0] } );
                        aoData.push( { "name": "sSortDir_"+i,  "value": oSettings.aaSortingFixed[i][1] } );
                }
                
                for ( i=0 ; i<iUser ; i++ )
                {
                        aoData.push( { "name": "iSortCol_"+(i+iFixed),  "value": oSettings.aaSorting[i][0] } );
                        aoData.push( { "name": "sSortDir_"+(i+iFixed),  "value": oSettings.aaSorting[i][1] } );
                }
                
                for ( i=0 ; i<iColumns ; i++ )
                {
                        aoData.push( { "name": "bSortable_"+i,  "value": oSettings.aoColumns[i].bSortable } );
                }
        }

        form = $('<form method="post" action="' + table_config.export_source + '"></form>')
        $.each(aoData, function(){
            form.append('<input type="hidden" name="' + this.name + '" value="' + this.value + '"');
        })
        csv_button.after(form);
        form.submit();
    };

    var csv_button = $('<button class="export_div button default success">Export to CSV</div>').click(ajax_params);

    $('div.toolbar').append(csv_button);
};



;// Beginning /res/js/v2/controllers/ss.controllers.report.js:
SS.controllers.report = (function () {
    var self,
        my = {},
        root_element = '.item_edit';

        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        //
        // Configures the second page of the report based on the report type
        //
        if ( false ) {
            // disabled moving to backbone
            $(root_element).delegate('.report_type_chosen', 'click', function () {
                var model = my.get_model_object($(this)),
                    $report_type_pane = $('.report_type_pane', root_element),
                    $report_type = $('select[name="report:report_type"]', $report_type_pane),
                    report_type_name = $('option:selected', $report_type).text(),
                    $details_pane = $('.report_details_pane', $(root_element)),
                    report_type = $report_type.val();

                // why is everything appearing as selected?
                report_type = 'financial';

                // Update the report title
                $('.report_title', $details_pane).html( report_type_name );
                $('[name="report:name"]', $details_pane).val( report_type_name );

                // Initialize the data table
                model.get_report_table_config( report_type );
                model.get_report_fields( report_type );
                
                // Disable the first pane and display the second
                $('button, select', $report_type_pane).attr('disabled', true);
                $(this).hide();
                $details_pane.show();
            });

            $(document).bind('ss_report_config_updated', function(event, report_spec){
                SS.controllers.data_table.initialize_table( report_spec, {dynamic_columns:true, allow_groupings:true} );
            });

            $(document).bind('ss_report_fields_updated', function(event, report_fields){
                var $extra_fields = $('.extra_fields', root_element),
                    $field,
                    $filter_fields,
                    $option,
                    $report_fields;

                // Update the list of fields that can be added
                _.each(report_fields, function(field, index){
                    $field = $("<div class='unbound_field'>" + 
                        //field.data_type + ' - ' + 
                        field.label + 
                        "</div>");
                    $field.data('field_info', field);
                    $extra_fields.append( $field );
                });
                $( ".unbound_field" ).draggable({revert:'invalid'});

                // Update the report field lists
                $report_fields = $('.report_field_list', root_element);
                $report_fields.each( function( filter_index, $filter_field){
                    _.each(report_fields, function(field, index){
                        $('<option></option>').
                            html( field.label ).
                            data('field_info', field).
                            val(field.field_id).
                            appendTo($filter_field);
                    });
                });

            });

            $(document).bind('ss_data_table_initialized', function(event, $table_div, oTable){
            });
        }
    };
    
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.mailchimp.js:
SS.controllers.mailchimp = (function () {
    var my = {},
        self = SS.controller(my),
        root_element = "#main",
        make_submit_handler = function(){
            return function () {
                var $item_element = my.get_item_element($(this)),
                    $form = $(this).closest('form'),
                    item = my.get_model_object($item_element),
                    item_type = item.get('type'),
                    $input_element,
                    confirm_dialog = SS.widgets.dialog({
                        type: 'confirm',
                        content: 'Would you like to add these members to Mailchimp? Adding of the members is not reversable.',
                        title: 'Add Members',
                        buttons: {
                            Cancel: function () {
                                $('.confirm_dialog').dialog('close');
                            },
                            Ok: function () {
                                $('.confirm_dialog').dialog('close');
                                SS.widgets.dialog({
                                    type: 'wait',
                                    content: 'Adding members to MailChimp, it may take up to 20 seconds.',
                                    title: 'Adding members',
                                    buttons:{},
                                    hide_close_button: true
                                }).init();
                                
                                $('body').css('cursor', 'wait');
                                $.ajax({
                                    type: 'POST',
                                    url: $form.prop('action'),
                                    data: $form.serialize(),
                                    timeout: 1000 * 60 * 60 * 24, // This could take a while, so set the timeout very high
                                    success: function(){
                                        window.location.reload();
                                    },
                                    error: function(){
                                        alert("We're sorry, but there was an error processing your request. Please try again later.");
                                        window.location.reload();
                                    }
                                });
                            }
                        } 
                    });
                if($form.valid()){
                   
                   if($item_element.find('.add_by_event.field_section').attr("style") ==="display: block; "){ 
                        if($item_element.find('.autocomplete_choice').length){
                         confirm_dialog.init();
                        }else{
                        
                            $input_element = $item_element.find('.item_edit_event_autocomplete.required.ui-autocomplete-input'); 
                    
                            if($item_element.find('.item_edit_event_autocomplete.required.ui-autocomplete-input.valid')){
                            $input_element.parent().after('<label class="error custom"> Invalid Event Name</label>');
                            $item_element.find('.item_edit_event_autocomplete.required.ui-autocomplete-input').attr('class','item_edit_event_autocomplete required ui-autocomplete-input error') ;   
                    
                           
                    
                        }
                      
                         
                        }
                   }else{
                    confirm_dialog.init();
                   }
                }
            };
        };
        
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
            $(root_element).delegate('.item_action_submit', 'click', make_submit_handler(true));
    };
    
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.fields.js:
SS.controllers.fields = (function () {
    var self,
        my = {},
        root_element = '#site',
        bind_children = function(container) {
            $(container).find('.field, .field_section').each(function(index, field){
            bind_field($(field));
            });
        },
        bind_field = function ($field) {
            var data = $field.data(),
                $bound_to_inputs,
                bound_to_input_data,
                check_bound = function ($bound_to_inputs) {
                    var bound_input_val = $bound_to_inputs.first().attr('type') === 'radio' || $bound_to_inputs.first().attr('type') === 'checkbox' ? $bound_to_inputs.filter(':checked').val() : $bound_to_inputs.first().val(),
                        str_bound_to_value = String(data.bound_to_value),
                        bound_to_value = str_bound_to_value.indexOf(',') > 0 ? str_bound_to_value.split(',') : str_bound_to_value,
                        check_value = function (value) {
                            if (value.indexOf('!') === 0) { // checking if the value starts with !, ie !value, then it does the negative
                                return _.ltrim(value, '!') !== bound_input_val;
                            } else {
                                return value === bound_input_val;
                            }
                        };

                    // Check if both this binding if active and all parent bindings are active
                    if ($field.parents('.disabled_by_binding').length === 0 &&
                        (_.isArray(bound_to_value) ? _.any(bound_to_value, function (value) {
                                return check_value(_.trim(value));
                            }) : check_value(bound_to_value))) {
                        
                        $.each($field.find(':input'), function () {
                            if ( ! $(this).data('disabled') ){
                                $(this).removeAttr('disabled');
                            }
                        });
                        $field.show();
                        $field.removeClass('disabled_by_binding');

                        // recursively apply child bindings
                        bind_children( $field );
                    } else {
                        $.each($field.find(':input'), function () {
                            $(this).attr('disabled',true);
                        });
                        
                        $field.hide();
                        $field.addClass('disabled_by_binding');

                        // recursively apply child bindings
                        bind_children( $field );
                    }
                };

            
            if (data && data.bound_to) {
                $field.hide();
                
                bound_to_input_data = data.bound_to.split('|');
                
                if (bound_to_input_data.length > 1) {
                    $bound_to_inputs = $(bound_to_input_data[1], $field.closest(bound_to_input_data[0]));
                } else {
                    $bound_to_inputs = $(':input[name="' + bound_to_input_data[0] + '"]');
                }

                $bound_to_inputs.livequery( 'change', function () {
                    check_bound($(this));
                });
                check_bound($bound_to_inputs);
            }
        },
        update_indices = function ($list) {
            $list.find('li').each(function () {
                var $list_item = $(this);
                
                $list_item.find('input[name$="index"]').val($list_item.index() + 1);    
            }); 
        };
    self = SS.controller(my); 
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        
        _.each($('.location_input', root_element), function (location_input) {
            var location_autocomplete = SS.widgets.autocomplete_location({
                input: $(location_input),
                on_select: function (location_info) {
                    $(location_input).val(location_info.address);
                }
            });
            
            location_autocomplete.init();    
        }); 

        _.each($('.autocomplete_input', root_element), function (autocomplete_input) {
            var generic_autocomplete = SS.widgets.autocomplete_generic({
                collection: $(autocomplete_input).data('autocomplete_collection'),
                input: $(autocomplete_input),
                on_select: function (autocomplete_result) {
                    $(autocomplete_input).val(autocomplete_result.label);
                }
            });
            
            generic_autocomplete.init();    
        }); 
        	
        $('.date_input', root_element).livequery( function () {
            // Hack for ensuring that datepickers are active after being removed and added to/from the dom
            $(this).removeClass('hasDatepicker');
            $(this).datepicker({
                dateFormat: 'dd M yy',
                onClose: function () {$(this).valid(); }
            });
        });
        
        _.each($('.wysiwyg_input', root_element), function (input, i) {
            $.ss.wysiwyg.create($(input));
        });
        
        _.each($('.color_input', root_element), function (color_input) {
            var $color_input = $(color_input),
                data = $color_input.data(),
                hexFromRGB = function (r, g, b) {
                    var hex = [
                        r.toString( 16 ),
                        g.toString( 16 ),
                        b.toString( 16 )
                    ];
                    
                    $.each( hex, function( nr, val ) {
                        if ( val.length === 1 ) {
                            hex[ nr ] = "0" + val;
                        }
                    });
                    return hex.join( "" ).toUpperCase();
                },
                refreshSwatch = function () {
                    var red = $( ".theme_red", $color_input ).slider( "value" ),
                        green = $( ".theme_green", $color_input ).slider( "value" ),
                        blue = $( ".theme_blue", $color_input ).slider( "value" ),
                        hex = hexFromRGB( red, green, blue );
                            
                    $( ".theme_swatch", $color_input ).css( "background-color", "#" + hex );
                    $( "header").css( "border-color", "#" + hex );
                    $( "nav:not('.reduced_prominence') a.selected").css( "background-color", "#" + hex );
                    
                    $('input[name="theme_red"]', $color_input).val(red);
                    $('input[name="theme_green"]', $color_input).val(green);
                    $('input[name="theme_blue"]', $color_input).val(blue);
                };
                
            $( ".theme_red, .theme_green, .theme_blue", $color_input ).slider({
                    orientation: "horizontal",
                    range: "min",
                    max: 255,
                    value: 127,
                    slide: refreshSwatch,
                    change: refreshSwatch
            });
            $( ".theme_red", $color_input ).slider( "value",  data.red);
            $( ".theme_green", $color_input ).slider( "value", data.green );
            $( ".theme_blue", $color_input ).slider( "value", data.blue);
            
            $('input', $color_input).change(function () {
                $color_input.find('.' + $(this).attr('name')) .slider('value', $(this).val());
            });
        });

        $('.field, .field_section', root_element).livequery(function(){
            bind_field($(this));
        });
	
        // Insert http:// in all url inputs
        $(root_element).delegate('input.url', 'focus', function () {
            var $url_field = $(this);
            if ($url_field.val() === ''){
                $url_field.val('http://').select();
            }
        });
        $(root_element).delegate('input.url', 'focusout', function () {
            var $url_field = $(this);
            if ($url_field.val() === 'http://'){
                $url_field.val('');
            }
        });
        
        // A delete button will tell the server to delete the given row upon saving
        $(root_element).delegate('.field_action_delete_row', 'click', function () {
            var $row = $(this).closest('.indexed_row'),
                delete_path = $(this).data('path'),
                $delete_marker = $('<input type="hidden" name="' + delete_path + '" value="Delete">');

                $delete_marker.insertBefore($(this));
                $row.hide();
        });

    $(root_element).delegate('.field_action_template_add_another', 'click', function () {
            self.render_and_add_template($(this).closest('.field_section'), $(this));
    });
	
	$(root_element).delegate('.field_action_reminder_template_add_another', 'click', function () {
            
	    $field_selection_div = $(this).parent();
	    if($field_selection_div.find(".short_field").length < 10){
		
		if($field_selection_div.find(".short_field").length == 1){
		    $x_mark = $field_selection_div.find('.short_field').find(".reminder_remove");
		    $x_mark.show();
		}
		self.render_and_add_template($(this).closest('.field_section'), $(this));
		
	    }
	   
	    if($field_selection_div.find(".short_field").length == 10){
		$(this).remove();
	    }
	    
	    
	    
	   
        });
	
	$(root_element).delegate('.toggle_uncheck_banner','click',function(){
	    if(!$(this).prop('checked')){
		$('.uncheck_banner').fadeIn('slow', function() {
		})
		
		$hidden_ul = $(this).parent().parent().find(".field_section.reminder_ul");
		for ( i = 1; i < $hidden_ul.find('li').length+1; i ++){
		    $li = $hidden_ul.find('li:nth-of-type('+i+')');
		    
		    $to_delete = $li.find('.input_box.to_delete');
		    $number = $li.find('.reminder_number');
		    $time_unit = $li.find('.reminder_time_unit');
		    $is_before = $li.find('.binding_day_list');
		    
		    if($number){
			if($number.val()){
			    $number.removeAttr('disabled');
			}
		    }
		    if($time_unit){
			$time_unit.removeAttr('disabled');
		    }
		    
		    if($is_before){
			$is_before.removeAttr('disabled');
		    }
		    
		}
	    
	    }
	    if($(this).prop('checked')){
		$('.uncheck_banner').fadeOut('slow', function() {
		})
		
		$hidden_ul = $(this).parent().parent().find(".field_section.reminder_ul");

		
		for ( i = 1; i < $hidden_ul.find('li').length+1; i ++){
		    $li = $hidden_ul.find('li:nth-of-type('+i+')');
		    
		    $to_delete = $li.find('.input_box.to_delete');
		    $number = $li.find('.reminder_number');
		    $time_unit = $li.find('.reminder_time_unit');
		    $is_before = $li.find('.binding_day_list');
		    
		    if($number){
			if($li.find('.binding_day_list').val() == "day_of")
			$number.attr('disabled',true);
		    }
		    if($time_unit){
			if($li.find('.binding_day_list').val() == "day_of")
			$time_unit.attr('disabled',true);
		    }
		    
		       
		    
		}
	    }
	});
        
        //
        // 
        //
        $(root_element).delegate('.field_action_add_another', 'click', function () {
            var $field_section = $(this).closest('.field_section'),
                $duplicate_section = $field_section.children('.field, .fields_two_column, .fields_three_column').last().clone(true);
                
            _.each($duplicate_section.find('input, select, textarea'), function (input) {
                var $input = $(input),
                    incrementor = function (str, num) {
                        return +num + 1;
                    },
                    name_source = $input.attr('name') || $input.data('name'),
                    name = name_source.replace(/([0-9])/g, incrementor);
                
                if ($input.attr('name')) {
                    $input.attr('name', name).val('');
                } else {
                    $input.data('name', name).val('');
                }
            });
            
            $duplicate_section.insertBefore($(this));
            
            //bind_field($duplicate_section);
            
            //_.each($duplicate_section.find('.field, .field_section'), function (field) {
            //    bind_field($(field));
            //});

        });
        
        $('.fields_sortable', root_element).each(function () {
            $(this).sortable({
		placeholder: "ui-state-highlight",
                containment: $(this),
                forcePlaceholderSize: true,
                update: function (event, ui) {
                    update_indices(ui.item.closest('ul'));
                }
	    });
            
            $(this).find('li').each(function () {
                var $fields = $(this),
                    $index_input = $fields.find('input[name$="index"]');
               
                if (!$fields.hasClass('template') && $index_input && +$index_input.val() === -1) {
                    $fields.hide();
                }
            });
        });
        
        $(root_element).delegate('.fields_action_remove', 'click', function () {
	    
	    var $fields = $(this).closest('li'),
                $index_input = $fields.find('input[name$="index"]');
                
            if ($index_input.length) {
                $index_input.val(-1);
                $(':input', $fields).not($index_input).each(function(index, field){
                    $(field).attr('disabled',true);
                });
                $fields.slideUp();
            } else {
                $fields.remove();
            }
	    
        });
	
	$(root_element).delegate('.reminder_remove', 'click', function () {
	    var $fields = $(this).closest('li'),
                $index_input = $fields.find('input[name$="index"]');
                
            if ($index_input.length) {
                $index_input.val(-1);
                $(':input', $fields).not($index_input).each(function(index, field){
                    $(field).attr('disabled',true);
                });
                $fields.slideUp();
            } else {
		
		//$button = $(this).parent().parent().parent().find('.field_action_plan_reminder_template_add_another');
		$ul_div = $fields.parent()
		
		if($ul_div.find('.field_action_reminder_template_add_another').length==0){
		    $ul_div.append('<button type="button" name = "add_reminder_button" class="field_action_reminder_template_add_another">Add Another Reminder</button>')
		}
		$field_selection_div = $(this).parent().parent().parent();
		
		if($field_selection_div.find(".short_field").length > 2){
		    $li = $(this).parent();
		    
		    $li.remove();
		    //$button.removeAttr('disabled');
		    //$button.show();
		}
		if($field_selection_div.find(".short_field").length == 2){
		    
		    $parent_div = $(this).parent().parent().parent();
		    $li = $(this).parent();
		    $li.remove();
		    //$button.show();
		    $first_reminder = $parent_div.find('.reminder_remove');
		    $first_reminder.hide();
		}
		
		$to_delete = $fields.find('.input_box.to_delete');
		$to_delete.val(true);
		
		
            }
           
        });
	
	
        
        $(root_element).delegate('.customization_menu_preexisting_options button', 'click', function () {
            var $item = $(this).closest('li'),
                data = $item.data(),
                $field_section = $('.customization_menu_items', root_element),
                $new_menu_item = self.render_and_add_template($field_section, $field_section.find('.field_action_template_add_another')),
                img_src = $item.find('img').attr('src'),
                img_name = $new_menu_item.find('input[name$="image"]').attr('name') + '.full_url';
            
            $new_menu_item
                .find('input[name$="title"]')
                    .val(data.title)
                    .end()
                .find('input[name$="url"]')
                    .val(data.link)
                    .end()
                .find('input[name$="image"]')
                    .attr('name', img_name)
                    .val(img_src)
                    .end()
                .find('img')
                    .attr('src', img_src)
                    .end()
                .find('iframe')
                    .remove();
                
                    
            update_indices($field_section);
        });
        
       
        $(root_element).delegate('#secondary_content .save_button', 'click', function (event) {
            $('#main_content form', root_element).submit();
        });        
       
        $(document).bind('ss_file_uploaded', function (event, file_id, file_url,size_x,size_y) {
        	var style="";
            $('#hidden_' + file_id).siblings('img').remove();
            if(size_x && size_y){
            	style="style='width:"+size_x+"px;height:"+size_y+"px; float:left;'";
            }
            $('#hidden_' + file_id).before('<img '+style+'src="' + file_url + '">');
            
            //Tony - hack for making sure uploading image still works after delete image is clicked.
            $('#hidden_' + file_id).attr('value', file_id);
            
            //delete validation msg, if there is any
            $('.file_validation').remove();
            
            //enable file uploader button
            $(".ui-dialog-buttonset button:last-child").removeAttr('disabled');
        });

        // Detach the templates from the dom to stop them from being submitted
        $('.template').livequery( function( ){
            // check that this code (or similar) wasn't run again this template already
            if ($(this).data('content_as_children') && $(this).children().length){
                $(this).data('content', $(this).children());
                $(this).children().remove();
            }
        });
        
        //hide binded fields in ticket edit page
        
        $(root_element).delegate('.total_num_of_tickets', 'click', function (event) {
        	if ($(this).is(':checked')){
        		$('input[name="ticket:total_number_of_tickets"][type="hidden"]').each(function() {$(this).remove()})
        	}else{
        		$(this).closest('.field').append('<input class="average required" name="ticket:total_number_of_tickets" value="None" type="hidden">');
        	}
        });
        
        $(root_element).delegate('.max_num', 'click', function (event) {
        	if ($(this).is(':checked')){
        		$('input[name="ticket:max_num_of_tickets_per_user"][type="hidden"]').each(function() {$(this).remove()})
        	}else{
        		$(this).closest('.field').append('<input class="average required" name="ticket:max_num_of_tickets_per_user" value="None" type="hidden">');
        	}
        });
        
        //functions for course registration

        recalculate_price = function(){
        	
        	var	$rows = $("#main ul").children('li').find('.participant_fields'),
        		$ticket_price_div = $('#main .total .ticket_price_total'),
        		ticket_price = $('#main .single_ticket_price').data('ticket_price'),
        		total = 0,
        		count;
        	
        	for(count = 0;count < $rows.length;count++){
	    		//if($($rows[count]).val()!= " "){
	    			total+=ticket_price;
	    		//}
	    	}
        	
        	$('input[name=overide_total_price]').val(total.toFixed(2));
        	
        	$ticket_price_div.text(total.toFixed(2));
        }
        
        $(root_element).delegate('.field_action_prefill_selected_course_attendee_info', 'change', function(){
        	
        	var	url = $('#main .event_url').data('url'),
        		selected_val = $(this).find(':selected').text(),
        		model = SS.models.event(),
        		$form_div = $(this).closest('.participant_row'),
        		index =$form_div.find(".participant_row_index").attr("name");
        	
        	
        		if (!(selected_val == 'Add a New Person')){
        			
        			model.get_attendee_info_history_for_course(selected_val,
                			function(response){
                				var name,$field;
                				
                				for(key in response.success){
                					name = 'attendees['+index+'].additional_info.'+key;
                					$field = $form_div.find('input[name="'+name+'"]');
                					$field.val(response.success[key])
                					
                				}
                			}, url);
        		}else{
        			$form_div.find('input:visible').each(function() {$(this).val('')})
        		}
        		
        		//recalculate_price();
        		
        });
        
        reindex_participant_row = function(){
        	var	$rows = $("#main ul").children('li').find('h4 label'),
        		count;
        	for(count = 0;count < $rows.length;count++){
        		$($rows[count]).text('Participant #'+(count+1)); 
        	}
        };
        

        $(root_element).delegate('.field_action_course_participant_template_add_another', 'click', function () {
        	var restriction=$(this).data('restriction').split(',');
        	var event_has_no_limit = restriction[0];
        	var check_total_num_of_ticket = restriction[1];
        	var check_max_per_user = restriction[2];
        	var ticket_left_per_user = restriction[3];
        	var total_quantity = restriction[4];
        	var max_per_user = restriction[5];
        	var current_tickets = $('ul.participant_ul li').length;
        	var ticket_price = $('table .single_ticket_row').clone()[0];
        	var tablebody = $('table tbody');
        	
        	//logic for restricting users from adding exceeding number of participants
        	if(check_total_num_of_ticket == "False"){
        		total_quantity = current_tickets + 1;
        	}
        	
        	if(check_max_per_user == "False"){
        		max_per_user = current_tickets + 1;
        	}
        	
        	if(event_has_no_limit=="True"){
        		
        	}else{
        		if(ticket_left_per_user > total_quantity){
        			
        		}else{
        			total_quantity = ticket_left_per_user
        		}
        	}
        	
        	if((current_tickets < max_per_user) && (current_tickets < total_quantity)){
        		
            	$(tablebody).prepend(ticket_price);
            	
	        	var $field_selection_div = $(this).parent();
				self.render_and_add_template($(this).closest('.field_section'), $(this));
				reindex_participant_row();
				recalculate_price();
				
				
        	}else{

        		$('.exceed_limit .error').show();
        		$('.exceed_limit').fadeIn('slow');//delay(3000).fadeOut('slow');
        		
        	}
		});
        
        $(root_element).delegate('.field_action_remove_course_register_participant', 'click', function () {
        	$(this).closest('li').remove();
        	reindex_participant_row();
        	$($('table .single_ticket_row')[0]).remove();
        	recalculate_price();
        });
    	
        $(root_element).delegate('.clear_filled_user_history', 'click', function () {
        	var	url = $('#main .event_url').data('url');
        	var model = SS.models.event();
        	
        	model.remove_attendee_info_history(url);
        });
    	
        $(root_element).delegate('.delete_image','click',function(){
        	var $item_element = my.get_item_element($(this)),
        		user = my.get_model_object($item_element);
        	
        	$('.image_section input').attr('value','delete');
        	$('.image_section img').attr('src','/res/img/UnknownProfile.png');
        	$('.article_image img').attr('src','/res/img/Unknown.png');
        });
        
        //Tony - profile setup step image positioning, I admit I have no idea why I did this when implementing this thing in js... gonna remove this and put in css afterwards when I have time
        
        $('#site').ready(function(){
	        	if($('.image_section').length != 0){
	        		
	        		var left = $('.image_div').position().left;
	        		var top = $('.image_div').position().top;
	        		$('.image_section').css({'left':left+100});
	        		$('#image_desc').css({'left':109,'top':45});
	        		
	        	}
	        	
        	}
        );
	
    };

    self.render_and_add_template = function ($field_section, $insert_location, append) {
        var $template = $field_section.children('.template'),
            $template_section,
            next_index = + $template.data('next_index'),
            index_var = $template.data('index_var'),
            replace_template_vars = function($to_replace){
                // Replace the values name fields
                _.each($to_replace.find(':input'), function (input) {
                    var $input = $(input),
                        name_source = $input.attr('name') || $input.data('name') || '',
                        name = name_source.replace(new RegExp('{'+ index_var + '}', 'g'), next_index);
                        name = name.replace('TEMPLATE-','');
                    
                    // Tony - Added a logic for replacing {index} for label of select input
                    if ($input.is('select')){
                    	
	                    var $class_source = $input.parent().parent().find('label'),
	                        class_name = $class_source.text().replace(new RegExp('{'+ index_var + '}', 'g'), next_index);
	                        class_name = class_name.replace('TEMPLATE-','');
	                    
	                    if ( !class_name  ){
	                            // pass don't disable unbound checkboxes
	                    } else{
	                        $class_source.text(class_name)
	                    }
                	}
                        
                    if ( ! name ){
                        // pass don't disable unbound checkboxes
                    } else if ($input.attr('name')) {
                        $input.attr('name', name)
                    } else {
                        $input.data('name', name)
                    }
                    $input.removeAttr('disabled');
                });
                // Recurse into nested templates
                _.each($to_replace.find('.template'), function (nested_template) {
                    var content = $(nested_template).data('content');
                    if (content){
                        content = content.clone(true);
                        replace_template_vars(content);
                        $(nested_template).data('content',content);
                    }
                });

            };

        if ($template.data('content')){
            $template_section = $template.data('content').clone(true);
        }else{
            $template_section = $template.clone(true);
        }

        replace_template_vars($template_section);


        // increment the index for the next insert
        $template.data('next_index', next_index + 1);

        $template_section.removeClass('template');
        
        if ( append ){
            $template_section.appendTo($insert_location);
        } else {
            $template_section.insertBefore($insert_location);
        }
        $template_section.show();
        
        return $template_section;
    };
    
    
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.validations.js:
SS.controllers.validations = (function () {
    var self,
        my = {},
        root_element = '#site';
        
    self = SS.controller(my);
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        
        $('form', root_element).validate({
            
            ignore: ':hidden',
            focusInvalid: false,
            creditcard : true,
            email: true,
            phone: true,
            exp_month: true,
            cvd: true,
            ticket_quantity: true,
            check_number_of_tickets_not_zero: true,
            end_date_grater_then_start_date: true,
            start_date_less_then_end_date: true,
            checkbox_check:true,
            date: true
        });
        
        

        $(root_element).delegate('form', 'submit', function (event) {
            
            if (!$(this).valid()) {
                event.preventDefault();
            }
        });
        
        jQuery.validator.addMethod("ticket_quantity",
            function(quantity, element) {
                var total_num_of_tickets = 0;
                $('.show_error').html("");
                $("#eventForm").find('select').each(function(index, element){
                    
                    if ($(element).value !== 0){
                        total_num_of_tickets += parseInt($(element).val());
                    }
                });
                var success= true;
                var error_showed =false;
                
                
                if ($("#eventForm").find($("#num_of_tickets_available"))[0].value < total_num_of_tickets){
                    $('.error').removeClass('error');
                    success =false;
                    $('.show_error').append("</br><div class='error'>"+ "Sorry, you can only buy <b>" + $("#num_of_tickets_available")[0].value + "</b> tickets in total." + "</div>");
                }
                return success; 
        	},
                function() {
                }
        );
        
        jQuery.validator.addMethod("check_number_of_tickets_not_zero",
                 function(ticket_num, element) {
                    var success = true;
                    var total_num_of_tickets = 0;
                    $("#eventForm").find('select').each(function(index, element){
                        
                        if ($(element).value !== 0){
                            total_num_of_tickets += parseInt($(element).val());
                        }
                    });
                    if(total_num_of_tickets == 0){
                        success = false;
                    }
                    return success; 
                },
                function() {
               
                }
        );
        
        jQuery.validator.addMethod("end_date_grater_then_start_date",
                function(end_date, element) {
                    
                    var ticket_end_date = new Date($("[name='ticket:registration_end_date']").val());
                    if($("[name='ticket:registration_start_date']").val() && $("[name='ticket:registration_end_date']").val()){
                        var ticket_start_date = new Date($("[name='ticket:registration_start_date']").val());
                    
                        return ticket_start_date <= ticket_end_date;
                    }
                    return true;
                    },
                    "Dates not in order"
               
            );
        
        jQuery.validator.addMethod("start_date_less_then_end_date",
                function(end_date, element) {
                    var ticket_start_date = new Date($("[name='ticket:registration_start_date']").val());
                    if($("[name='ticket:registration_start_date']").val() && $("[name='ticket:registration_end_date']").val()){
                        var ticket_end_date = new Date($("[name='ticket:registration_end_date']").val());
                        return ticket_start_date <= ticket_end_date;
                    }
                    return true;
                    },
                    "Dates not in order"
               
            );
        
        jQuery.validator.addMethod("phone",
            function(phone_number, element) {
                phone_number = phone_number.replace(/\s+/g, ""); 
            return this.optional(element) || phone_number.length > 9 && phone_number.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
            },
            "Please specify a valid phone number"
        );
    
        jQuery.validator.addMethod("exp_month",
            function(month, element) {
                return this.optional(element) || month.match(/^0[1-9]$|^1[012]$/);
            },
            "Please specify a valid Exp Month"
        );

        jQuery.validator.addMethod("exp_year",
            function(year, element) {
                return this.optional(element) || year.match(/^201[1-9]$|^202[0-9]$/);
            },
            "Please specify a valid Exp Year"
        );

        jQuery.validator.addMethod("cvd",
            function(cvd, element) {
                return this.optional(element) || cvd.match(/^\d{3}$|^\d{4}$/);
            },
            "Please specify a valid CVD"
        );        

        jQuery.validator.addMethod('place_or_address',
            function( value, element ){
                var $root_form = $(element).closest('form'),
                    $places_panel = $('.relationship_edit_panel[data-type="place"]', $root_form),
                    places_count = $('li.item', $places_panel).length;
                if ( ! value && ! places_count ){
                    return false;
                }
                return true;
            },
            'This item needs either an address or a place'
        );
        
        jQuery.validator.addMethod('validation_no_duplicate_field',
            function( value, element ){
                var duplicate_found = false,
                    $other_custom_fields = $('.custom_field_type', $(element).closest('.custom_field_list')).not(element);

                $other_custom_fields.each( function( index, field){
                    if ( $(field).attr('disabled') !== undefined ){
                        // ignore disabled fields
                    } else if ( $(element).val() === $(field).val() ){
                        duplicate_found = true;
                    }
                });
                return ! duplicate_found;
            },
            'Each field can only be chosen once.'
        );
        
        // This is here to support validation on the imitation of the placeholer attribute that's
        // used in browsers that don't support it. See placeholdersupport.js
        jQuery.validator.addMethod('requiredPlaceholder',
        	function(value, element){
        		var $element = jQuery(element);
        		if($element.hasClass('required') && $element.prop('placeholder')){
        			if($element.prop('value') === $element.prop('placeholder')){
        				return false;
        			}
        		}
        		return true;
        	},
        	'This field is required.'
        );
        
        jQuery.validator.addMethod('validation_no_duplicate_field',
            function( value, element ){
                var duplicate_found = false,
                    $other_custom_fields = $('.custom_field_type', $(element).closest('.custom_field_list')).not(element);

                if ( $(element).val() === 'add_a_new_field' ){
                    // Ignore the special value add a new field
                    return true;
                }

                $other_custom_fields.each( function( index, field) {
                    if ( $(field).attr('disabled') !== undefined ) {
                        // ignore disabled fields
                    } else if ( $(element).val() === $(field).val() ) {
                        duplicate_found = true;
                    }
                });
                return ! duplicate_found;
            },
            'Each field can only be chosen once.'
        );


        jQuery.validator.addMethod('validation_positive',
            function( value, element ){
                var amount = parseFloat( value );

                if ( amount < 0 ){
                    return false;
                }
                return true;
            },
            'Amount must not be less than 0'
        );

        jQuery.validator.addClassRules({
            user_id_available: {
                remote: {url:'/auth/user_id_available'}
            },
            country: {
                remote: {url:'/generic/valid_country'}
            },
            postal_code: {
                remote: {url:'/generic/valid_postal_code'}
            },
            network_name_available: {
                remote: {url:'/network/network_name_available'}
            },
            // doesn't take into account the current value
            field_label_available: {
                remote: {url:'/field_info/field_name_available'}
            },
            legacyPlaceholder: {
            	requiredPlaceholder: true
            }
        });
        
        jQuery.extend(jQuery.validator.messages, {
            remote: jQuery.format('This email address has already been taken. <a class="error_link" href="/auth/login">Sign In</a><a class="error_link" href="/auth/forgotten_password">Forgot your password?</a>')
        });
    };
    
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.admin_payments.js:
SS.controllers.admin_payments = (function () {
    var self,
        my = {},
        root_element = '.admin_payment';
        
    self = SS.controller(my); 
    
    self.init = function (new_root_element) {
        
        if(new_root_element !== undefined){
            root_element = new_root_element;
        }
        var $event_autocomplete = $('.payment_event_autocomplete'),
            event_autocomplete,
            $payment_target = $('.payment_target'),
            $payment_details = $('.admin_payment_details'),
            $payment_confirmation = $('.admin_payment_confirmation'),
            $payment_steps = $('form.payment_form'),
            $member_section = $('.member_section'),
            submit_payment = function( redirect_location ){
                var $form = $('.payment_form', root_element),
                    data = $form.serialize(),
                    model = SS.models.admin_payment(),
                    on_success = function(){
                        window.location = redirect_location;
                    };
                    
                my.submit_form($form, $(this), function () {
                    model.submit_payment(data, on_success);
                }, root_element);
            };

        $payment_steps.validate({ignore: ':hidden'});
        $payment_steps.ss_steps();

        $(root_element).delegate('.admin_payment_complete', 'click', function () {
            submit_payment( '/admin?status_message=Payment+Recorded' );
        });
        
        $(root_element).delegate('.admin_payment_manually_register_complete', 'click', function () {
        	url = $('.event_info').data('event_url')
            submit_payment(url);
        });
        
        $(root_element).delegate('.admin_payment_complete_make_another', 'click', function () {
            submit_payment( '/admin_payment/offline_payment?status_message=Payment+Recorded' );
        });
        
        $(root_element).delegate('.admin_payment_manually_register_complete_make_another', 'click', function () {
        	url = $('.event_info').data('event_url')
            submit_payment(url+"/manually_register_to_event");
        });
        

        $(root_element).delegate('.admin_payment_cancel', 'click', function () {
            var confirm_dialog = SS.widgets.dialog({
                type: 'confirm',
                title: 'Warning!',
                content: 'Do you wish to abandon this offline payment?',
                buttons: {
                    'Cancel': function () {
                        $('.confirm_dialog').dialog('close');
                    },
                    'Ok': function () {
                        $('.confirm_dialog').dialog('close');
                        window.location = '/admin';
                    }
                } 
            });
        
            confirm_dialog.init();
        });

        
        $(root_element).delegate('.admin_payment_manually_register_cancel', 'click', function () {
            var confirm_dialog = SS.widgets.dialog({
                type: 'confirm',
                title: 'Warning!',
                content: 'Do you wish to abandon this offline payment?',
                buttons: {
                    'Cancel': function () {
                        $('.confirm_dialog').dialog('close');
                    },
                    'Ok': function () {
                        $('.confirm_dialog').dialog('close');
                        url = $('.event_info').data('event_url')
                        window.location = url;
                    }
                } 
            });
        
            confirm_dialog.init();
        });

        

        $(root_element).delegate('.admin_payment_next_target', 'click', function () {
            var $details_section = $('.admin_payment_next_details'),
                $outstanding = $('.outstanding_balances'),
                new_user = $member_section.find('.binding_create_a_new_user').val() === 'True',
                name;

            if ( ! $(this).closest('form').valid() ){
                return;
            }
            
            // Fetch the user name and plunk it into the history section
            if ( new_user ){
                name = $('input[name="new_user:first_name"]').val() + ' ' + 
                       $('input[name="new_user:last_name"]').val();
            } else {
                name = $('.autocomplete_choice .user_name').text();
            }
            $('.chosen_user_name').text( name );

            // Fetch the outstanding balances for this user
            if ( new_user ) {
                // Creating a new user, doesn't have existing payments
                $outstanding.html('<div class="error">No outstanding payments for this member</div>');
            } else {
                $outstanding.html('');
                SS.models.admin_payment().get_outstanding_balances(
                    $('[name="curr_user:id"]', $member_section).val(),
                    function(response){
                        $outstanding.html(response.html);
                    }
                );
            }

            $payment_steps.ss_steps('activate_step', $payment_target);
        });
        
        $(root_element).delegate('.admin_payment_event_tickets','click', function(){
	        var $details_section = $('.admin_payment_next_details'),
	        	$outstanding = $('.outstanding_balances'),
	            new_user = $member_section.find('.binding_create_a_new_user').val() === 'True',
	            name;
	
	        if ( ! $(this).closest('form').valid() ){
	            return;
	        }
	        
	        // Fetch the user name and plunk it into the history section
	        if ( new_user ){
	            name = $('input[name="new_user:first_name"]').val() + ' ' + 
	                   $('input[name="new_user:last_name"]').val();
	            
	        } else {
	            name = $('.autocomplete_choice .user_name').text();
	        }
	        $('.chosen_user_name').text( name );
	        
	        // Fetch the outstanding balances for this user
	        if ( new_user ) {
	            // Creating a new user, doesn't have existing payments
	            $outstanding.html('<div class="error">No outstanding payments for this member</div>');
	        } else {
	            $outstanding.html('');
	            SS.models.admin_payment().get_outstanding_balances(
	                $('[name="curr_user:id"]', $member_section).val(),
	                function(response){
	                    $outstanding.html(response.html);
	                }
	            );
	        }
	
	        $payment_steps.ss_steps('activate_step', $payment_target);        	
        });
        
        $(root_element).delegate('.admin_payment_next_details', 'click', function () {
            // Ensure we're ready for the next step
            var payment_for = $('.payment_for').val(),
                total_price = 0,
                $outstanding_summary = $('.outstanding_balance_summary ul'),
                $event_summary = $('.event_ticket_summary'),
                $ticket_list = $event_summary.find('.tickets'),
                total_ticket_count = 0,
                balance_count = 0;
            if ( ! $(this).closest('form').valid() ) {
                return;
            }
            // Determine the total price of the...
            if ( payment_for === 'event' ) {
                $ticket_list.html('');
     
                $('.ticket_section', $(root_element)).each( function ( index, section ) {
                    var ticket_count = parseInt($('.ticket_count', section).val(), 10),
                        unit_price = $(section).data('ticket_price');
                        ticket_price = ticket_count * unit_price;
                    total_price += ticket_price;
                    total_ticket_count += ticket_count;

                    if ( ticket_count ){
                        $ticket_list.append($('<li>').append($('<div class="summary_description">' + 
                                                $(section).data('ticket_name') +
                                                ' - Quantity ' + ticket_count + 
                                                ' - Cost </div>').
                                                append($('<span>'+unit_price+'</span>').formatCurrency()).
                                                append(' Each')).
                                                append($('<div class="summary_price">' + ticket_price + '</div>').formatCurrency()));
                    }
                });
                // abandon this step if no tickets have been chosen
                if (! total_ticket_count ){
                    return;
                }
                $('.event_title', $event_summary).text($('.ticket_section').first().data('event_name'));
                $('.total_ticket_price', $event_summary).text(total_price).formatCurrency();

            } else if ( payment_for === 'membership' ) {
                // Price of the membership plan
                total_price += $('.membership_plan_id').find(':selected').data('price');

                $('.plan_name', '.membership_summary').text($(':input[name="membership:plan_id"] option:selected').text());
                $('.total_plan_price', '.membership_summary').text(total_price).formatCurrency();
            } else if ( payment_for === 'outstanding_balance' ) {
                // Price of the outstanding balances
                $outstanding_summary.html('')

                $('.outstanding_balance:checked').each( function ( index, section ) {
                    var price = $(section).data('outstanding_balance'),
                        summary_line;
                    balance_count += 1;
                    total_price += price;

                    $outstanding_summary.append($('<li><div class="summary_description">' + $(section).data('title') +'</div>').append($('<div class="summary_price">' + price + '</div>').formatCurrency()));
                });
                // don't continue if no balances have been chosen
                if (! balance_count ){
                    return;
                }
            } else if ( payment_for === 'other' ) {
                $('.other_summary .other_description').text( $(':input[name="other:description"]').val() );
            }


            if ( payment_for !== 'other' && total_price === 0 ) {
                // Hide the payment step and skip to the last step
                $payment_steps.ss_steps( 'activate_step', $payment_confirmation );
                $payment_details.hide();
            } else {
                $payment_details.show();
                $payment_steps.ss_steps( 'activate_step', $payment_details );

                $('span.full_amount', $payment_details).text(total_price).formatCurrency();
                //$('.payment_details_amount', $payment_details).val(total_price);
                $(':input.full_amount', $payment_details).val(total_price);
                $payment_details.data('total_price', parseFloat(total_price));

            }

        });
        
        $(root_element).delegate('.admin_payment_manually_register_ticket_detail', 'click', function () {
            // Ensure we're ready for the next step
            var $event_summary = $('.event_ticket_summary'),
                $ticket_list = $event_summary.find('.tickets');
            
            if ( ! $(this).closest('form').valid() ){
	            return;
	        }
            
            attendee = $('.ticket_section .attendee_section:visible');

            if(attendee.length == 0 ){
            	return;
            }
            $ticket_list.children().remove();
            $ticket_list.append($('<div class="register_summary_description">' + $(attendee.parent()).data('ticket_name') + ' - Cost: </div>')
                                         			.append($('<span class="ticket_cost">'+$(attendee.parent()).data('ticket_price')+'</span>').formatCurrency()));
           
            $payment_details.show();
            $payment_steps.ss_steps( 'activate_step', $payment_details );

            $('span.full_amount', $payment_details).text($(attendee.parent()).data('ticket_price')).formatCurrency();
            //$('.payment_details_amount', $payment_details).val($(attendee.parent()).data('ticket_price'));
            $(':input.full_amount', $payment_details).val($(attendee.parent()).data('ticket_price'));
            $payment_details.data('total_price', parseFloat($(attendee.parent()).data('ticket_price')));
        });
        
        $(root_element).delegate('.admin_payment_complimentary_ticket', 'click', function () {
        	 var $event_summary = $('.event_ticket_summary'),
	             $ticket_list = $event_summary.find('.tickets');
	         
	         attendee = $('.ticket_section .attendee_section:visible');
	
	         if(attendee.length == 0 ){
	         	return;
	         }
	         $ticket_list.children().remove();
	         $ticket_list.append($('<div class="register_summary_description">' + $(attendee.parent()).data('ticket_name') + ' - Cost: </div>')
          			.append($('<span class="ticket_cost">'+$(attendee.parent()).data('ticket_price')+'</span>'+'<div class="ticket_is_complimentary">*Ticket is complimentary</div>').formatCurrency()));
	         //$ticket_list.append('<div class="ticket_is_complimentary">*Ticket is complimentary</div>');
	         $payment_steps.ss_steps( 'activate_step', $payment_confirmation );
	
	         $('.payment_amount', $payment_details).text($('span.full_amount').text()).formatCurrency();
	         $payment_details.hide();
	         $ticket_list.append('<input type="hidden" name="is_complimentary" value = True>');
	         $ticket_list.append('<input type="hidden" name="complimentary_price" value ='+$(attendee.parent()).data("ticket_price")+'>');
	         
	    });
        
        $(root_element).delegate('.admin_payment_next_confirmation', 'click', function () {
            if ( ! $(this).closest('form').valid() ) {
                return;
            }
            $payment_steps.ss_steps( 'activate_step', $payment_confirmation );

            $('.payment_type', $payment_details).text($('.payment_method option:selected').text());

            if ($('.pay_in_full').is(':checked')) {
                $('.payment_amount', $payment_details).text($('span.full_amount').text()).formatCurrency();
            } else {
                $('.payment_amount', $payment_details).text($('.payment_details_amount').val()).formatCurrency();
            }

            $('.other_payment_amount', $payment_details).text($('.payment_details_other_amount').val()).formatCurrency();
            $('.payment_difference', $payment_details).text($('.difference').text());
            $('.payment_cheque', $payment_details).text($(':input[name="payment_details:cheque_number"]').val());
            $('.payment_date_received', $payment_details).text($(':input[name="payment_details:date_received"]').val());
            $('.payment_memo', $payment_details ).text($(':input[name="payment_details:memo"]').val());
        });
        
        $(root_element).delegate('.admin_payment_manually_register_next_confirmation', 'click', function () {
            if ( ! $(this).closest('form').valid() ) {
                return;
            }
            $payment_steps.ss_steps( 'activate_step', $payment_confirmation );
            
            pay_now_or_later_radio = $($payment_details).find('.pay_now_or_later:checked');


            //$($payment_details).find('#pay_now_or_later_radio_button').hide();
            if(pay_now_or_later_radio.val() == 'now'){
            	$('.pay_now_summary', $payment_details).show();
            	$('.payment_type', $payment_details).text($('.payment_method option:selected').text());

                if ($('.pay_in_full').is(':checked')) {
                    $('.payment_amount', $payment_details).text($('span.full_amount').text()).formatCurrency();
                } else {
                    $('.payment_amount', $payment_details).text($('.payment_details_amount').val()).formatCurrency();
                }

               
                $('.payment_difference', $payment_details).text($('.difference').text());
                $('.payment_cheque', $payment_details).text($(':input[name="payment_details:cheque_number"]').val());
                $('.payment_date_received', $payment_details).text($(':input[name="payment_details:date_received"]').val());
                $('.payment_memo', $payment_details ).text($(':input[name="payment_details:memo"]').val());
                $('.pay_later_summary', $payment_details).hide();
            }else{

            	$('.pay_now_summary', $payment_details).hide();
            	$('.pay_later_summary', $payment_details).show();
            	$('.amount_due','.pay_later_summary', $payment_details).text('Amount due: '+$('.ticket_cost',$payment_target).text());
            }
            
           
        });

        // When an event is selected we need to list the post
        event_autocomplete = SS.widgets.autocomplete_event({
            input: $event_autocomplete,
            on_select: function (params,event) {
                event.target.value=params.id;
                
                $(event.target)
                    .after('<div class="autocomplete_choice"><span class="event_name">' + params.name + ' </span><span class="autocomplete_choice_remove">X</span></div>')
                    .hide();
                SS.models.admin_payment().get_ticket_information({event_id:params.id});
            }
        });
        event_autocomplete.init();

        $(document).bind('ss_admin_payment_ticket_information_fetched', function( event, ticket_response){
            $('.admin_payment_tickets').html(ticket_response.html);
        });

        $(root_element).delegate('.ticket_count', 'change', function(){
            var $ticket_section = $(this).closest('.ticket_section'),
                ticket_count = parseInt( $(this).val(), 10),
                $attendee_list = $('ul.attendee_info', $ticket_section),
                $existing_attendees = $attendee_list.children(),
                index = 0;

            if ( ticket_count < $existing_attendees.length ) {
                // remove the extra attendees
                $existing_attendees.slice(ticket_count).remove();
            } else {
                index = $existing_attendees.length;
                _.times(ticket_count - $existing_attendees.length, function(){
                    var attendee_section = SS.controllers.fields.render_and_add_template( $ticket_section, $attendee_list, true);

                    if ( index === 0 ){
                        // Default the attendee name and email
                        $('.attendee_name', attendee_section).val($('.chosen_user_name').text() );

                        if ( $member_section.find('.binding_create_a_new_user').val() === 'True' ) {
                            $( '.attendee_email', attendee_section ).val( $('input[name="new_user:email"]').val() );
                        } else {
                            $( '.attendee_email', attendee_section ).val( $('.user_autocomplete_selected').data('user_email') );
                        }
                    }

                    index += 1;
                });
            }
        });
        
        $(root_element).delegate('.ticket_radio_button', 'change', function(){
        	
        	var attendee_list = $('.ticket_section').find('.attendee_section');
        	
        	for(count = 0; count < attendee_list.length;count++){
        		
        		 $('.attendee_name', attendee_list[count]).val($('.chosen_user_name').text() );
        			
                 if ( $member_section.find('.binding_create_a_new_user').val() === 'True' ) {
                     $( '.attendee_email', attendee_list[count] ).val( $('input[name="new_user:email"]').val() );
                 } else {
                     $( '.attendee_email', attendee_list[count] ).val( $('.user_autocomplete_selected').data('user_email') );
                 }
        	}
	            
        });
        
        
        $(root_element).delegate('.payment_details_amount', 'change', function(){
            $('span.difference').text( $payment_details.data('total_price') - parseFloat($(this).val()) ).formatCurrency();
        });
        
        $(root_element).delegate('.admin_payment_rsvp_user', 'click', function(){
        	var model = SS.models.event(),
        		url = $('.event_info').data('event_url'),
        		new_user = $member_section.find('.binding_create_a_new_user').val() === 'True';

        	if ( ! $(this).closest('form').valid() ) {
                return;
            }
        	
        		if ( new_user ){
        		            	first_name = $('input[name="new_user:first_name"]').val(); 
        		                last_name = $('input[name="new_user:last_name"]').val();
        		            	email= $('input[name="new_user:email"]').val();
        		            	model.rsvp_new_user(url,first_name, last_name,email);
        		            	
        		            	$('.create_new_user').attr('disabled',true);
        		            	$('admin_payment_manually_register_cancel').attr('disabled',true);
        		            	$('admin_payment_rsvp_user').attr('disabled',true);
        		            	$('admin_payment_rsvp_user_make_another').attr('disabled',true);
        		            	
        		            } else {
        		                name = $('.autocomplete_choice .user_name').text();
        		                model.rsvp_user(url,$('[name="curr_user:id"]', $member_section).val());
        		                
        		                $('.create_new_user').attr('disabled',true);
        		            	$('admin_payment_manually_register_cancel').attr('disabled',true);
        		            	$('admin_payment_rsvp_user').attr('disabled',true);
        		            	$('admin_payment_rsvp_user_make_another').attr('disabled',true);
        		                
        		            }
        	
        });
        
        $(root_element).delegate('.admin_payment_rsvp_user_make_another', 'click', function () {
        	var model = SS.models.event(),
    		url = $('.event_info').data('event_url'),
    		new_user = $member_section.find('.binding_create_a_new_user').val() === 'True';
        	
        	if ( ! $(this).closest('form').valid() ) {
                return;
            }
        	
    		if ( new_user ){
    		            	first_name = $('input[name="new_user:first_name"]').val(); 
    		                last_name = $('input[name="new_user:last_name"]').val();
    		            	email= $('input[name="new_user:email"]').val();
    		            	model.rsvp_new_user_make_another(url,first_name, last_name,email);
    		            	
    		            	$('.create_new_user').attr('disabled',true);
    		            	$('admin_payment_manually_register_cancel').attr('disabled',true);
    		            	$('admin_payment_rsvp_user').attr('disabled',true);
    		            	$('admin_payment_rsvp_user_make_another').attr('disabled',true);
    		            	
    		            } else {
    		                name = $('.autocomplete_choice .user_name').text();
    		                model.rsvp_user_make_another(url,$('[name="curr_user:id"]', $member_section).val());
    		                
    		                $('.create_new_user').attr('disabled',true);
    		            	$('admin_payment_manually_register_cancel').attr('disabled',true);
    		            	$('admin_payment_rsvp_user').attr('disabled',true);
    		            	$('admin_payment_rsvp_user_make_another').attr('disabled',true);
    		                
    		            }
        });
        

        jQuery.validator.addMethod('validation_offline_payment_amount',
            function( value, element ){
                var amount = parseFloat( value ),
                    full_amount = parseFloat( $('.full_amount').val() );

                if ( amount >= 0 ){
                    // check that amount is less than the full amount
                    if ( amount > full_amount ){
                        return false;//'Amount can not exceed the total' 
                    }
                }
                return true;
            },
            'Amount must not be greater than total amount.'
        );

    };

    
    return self;
}());

;// Beginning /res/js/v2/controllers/ss.controllers.subscription.js:
SS.controllers.subscription = (function () {
    var my = {},
        self = SS.controller(my),
        root_element = "#main",
        check_for_subscription_status = function(){
            function append_subscribe_status(data){
                
                $button = $(root_element).find('.check_sub_button');
                $status_div = $(root_element).find('.sub_status');
                if (data.success.status){
                    $button.hide();
                    $status_div.find('.sub').hide();
                    $status_div.append('<div class="unsub">You will not receive notifications from '+SS.app.current_network.name+'. Would you like to resubscribe?<br></div>');
                    $status_div.append('<button type="button" class = "resubscribe_button">Subscribe to notifications</button>');
                }else{
                    $button.hide();
                    $status_div.find('.resubscribe_button').hide();
                    $status_div.find('.unsub').hide();
                    $status_div.append('<div class="sub">You are currently subscribed to the mailing list.</div>');
                    
                }
            };
            
            $.ajax({
                type: 'POST',
                url: '/user/ajax_check_sub',
                success: append_subscribe_status
            });
            
        };
        
        resubscribe_email = function(){
            $.ajax({
                type: 'POST',
                url: '/user/ajax_resubscribe_current_user',
                success: check_for_subscription_status
            });
        }
        
    self.init = function () {
            $(root_element).delegate('.check_sub_button', 'click', check_for_subscription_status);
            $(root_element).delegate('.resubscribe_button','click', resubscribe_email);
    };
    
    return self;
}());

;// Beginning /res/js/v2/widgets/ss.widget.js:
SS.widget = function (spec, my) {
    return {};
};
;// Beginning /res/js/v2/widgets/ss.widgets.dialog.js:
// spec includes:
// type, content, title, buttons
SS.widgets.dialog = function (spec, my) {
    var self,
        dialog_class = spec.type + '_dialog',
        default_val = {hide_close_button : false};
    
    my = my || {};
    spec = $.extend(default_val,spec);
    
    self = SS.widget(spec, my);
    
    self.init = function (options) {
        $('#site').after('<div class="' + dialog_class + '">' + spec.content + '</div>');
        
        // Override the settings with any user supplied options
        var settings = {
            'focus_selector' : false,
        };
        $.extend(true, settings, options);
        
        if(settings['focus_selector']){
            var create_callback = function(){
                $(this).find(settings['focus_selector']).focus();
            };
        } else {
            var create_callback = function(){};
        }
        
        $('.' + dialog_class).dialog({
            modal: true,
            title: spec.title,
            dialogClass: dialog_class,
            buttons: spec.buttons,
            open: function(event, ui){
                if($.isFunction(create_callback)){
                    create_callback = _.bind(create_callback, this);
                    create_callback(event, ui);
                }
                // Temporary fix to make the last button of the dialog blue and the rest silver
                $(this).parent().find(".ui-dialog-buttonset button:not(:last-child)").addClass('default');
                $(this).parent().find(".ui-dialog-buttonset button").removeClass("ui-button").removeClass("ui-state-default");
            }
        });
        
        
        if(spec.hide_close_button){
           $('.' + dialog_class).find('.ui-icon.ui-icon-closethick').hide();
        }
        
        $('.' + dialog_class).bind('dialogclose', function () { 
                $(this).remove();
        });
    };
    
    return self;
};
;// Beginning /res/js/v2/widgets/ss.widgets.dialog_message.js:
// spec.title, spec.subject, spec.send_function
SS.widgets.dialog_message = function (spec, my) {
    var self,
        params = {
            type: 'message',
            content:
                '<label>Subject</label>' +
                '<input type="text" class="message_subject" value="' + spec.subject + '">' +
                '<label>Message</label>' +
                '<textarea class="message_body"></textarea>',
            title: spec.title,
            buttons: {
                'Cancel': function () {
                    $('.message_dialog').dialog('close');
                },
                'Send': function () {
                    var that = this,
                        $message_dialog = $(this).closest('.message_dialog');

                    // freeze the size of the item
                    $message_dialog.css( { width: $message_dialog.width(), height: $message_dialog.height() } );
                    $message_dialog.closest('.ui-dialog').find('.ui-dialog-buttonset button').attr('disabled', true);

                    spec.send_function($('.message_subject', this).val(), $('.message_body', this).val());
                    $(this).html('Sending...');
                    
                    _.delay(function () {
                        $(that).dialog('close');
                    }, 500);
                }
            }
        };

    my = my || {};
    
    self = SS.widgets.dialog(params, my);
       
    return self;
};

;// Beginning /res/js/v2/widgets/ss.widgets.autocomplete.js:
// spec indludes:
// spec.input - input element to autocomplete
// spec.on_select - on_select
// spec.url - url for data
// optional spec.min_length - min length to start autocompleting
// spec.schema - object key values to describe what to return
SS.widgets.autocomplete = function (spec, my) {
    var self;
    
    my = my || {};
    
    self = SS.widget(spec, my);
    
    self.init = function () {
        $(spec.input)
            // don't navigate away from the field on tab when selecting an item
            .bind('keydown', function (event) {
                if (event.keyCode === $.ui.keyCode.TAB && $(this).data('autocomplete').menu.active) {
                    event.preventDefault();
                }
            })
            .autocomplete({
                source: function (request, response) {
                    $.getJSON(spec.url, {
                        term: request.term
                    }, response);
                },
                minLength: spec.min_length || 1,
                focus: function () {
                    // prevent value inserted on focus
                    return false;
                },
                select: function (event, ui) {
                    var item = {};
                    
                    _.each(spec.schema, function (value, key) {
                        item[key] = ui.item[value];
                    });
                        
                    spec.on_select(item,event);
                    return false;
                },
                autoFocus: true
            });       
    };
    
    return self;
};
;// Beginning /res/js/v2/widgets/ss.widgets.autocomplete_tag.js:
// spec indludes:
// spec.input - input element to autocomplete
// spec.on_select = function on select
// spec.auto_follow - whether to follow the tag from the get go
// spec.hide_remove_button - whether to show the remove button
SS.widgets.autocomplete_tag = function (spec, my) {
    var self;
    
    my = my || {};
    
    self = SS.widget(spec, my); 
    
    self.init = function () {
        $(spec.input)
            // don't navigate away from the field on tab when selecting an item
            .bind ('keydown', function(event) {
                if (event.keyCode === $.ui.keyCode.TAB && $(this).data('autocomplete').menu.active) {
                    event.preventDefault();
                }
            })
            .autocomplete({
                source: function (request, response) {
                    $.getJSON('/topic/auto_complete', {
                        term: request.term
                    }, response);
                },
                minLength: 1,
                focus: function () {
                    // prevent value inserted on focus
                    return false;
                },
                select: function (event, ui) {
                    var tag_data = {
                            id : ui.item.id,
                            name : ui.item.label,
                            url : ui.item.url,
                            followed : ui.item.followed,
                            follow_title : 'Follow',
                            follow_class : '',
                            checked : ''
                        },
                        template_text = '<div class="tag <%= follow_class %>" data-tag_id="<%= id %>">' +
                                        '<div class="tag_follow"><input title="<%= follow_title %>" type="checkbox" <%= checked %>></div>' +
                                        '<div class="tag_info"><a href="<%= url %>" title="Go to tag page: <%= name %>"><%= name %></a>',
                        tag_template;
                        
                    if (!spec.hide_remove_button) {
                        template_text += '<span class="tag_action_remove" title="Remove tag">x</span>';
                    }
                    template_text += '</div></div>';
                        
                    tag_template = _.template(template_text);
                    
                    if (tag_data.followed || spec.auto_follow) {
                        tag_data.follow_class = 'followed';
                        tag_data.checked = 'checked';
                        tag_data.follow = 'Unfollow';
                    }
                    
                    spec.on_select(tag_data.id, tag_template(tag_data));
                    return false;
                },
                autoFocus: true
            });       
    };
    
    return self;
};
;// Beginning /res/js/v2/widgets/ss.widgets.autocomplete_user.js:
// spec indludes:
// spec.input - input element to autocomplete, spec.on_select - on_select
SS.widgets.autocomplete_user = function (spec, my) {
    var self;
    
    my = my || {};
    
    spec.url = '/user/auto_complete';
    spec.schema = {
        id: 'value',
        name: 'label',
        email: 'email',
        url: 'url',
        icon: 'medium_icon'
    };
        
    self = SS.widgets.autocomplete(spec, my);
    
    return self;
};

;// Beginning /res/js/v2/widgets/ss.widgets.autocomplete_company.js:
// spec indludes:
// spec.input - input element to autocomplete, spec.on_select - on_select
SS.widgets.autocomplete_company = function (spec, my) {
    var self;
    
    my = my || {};
    
    spec.url = '/company/auto_complete';
    spec.schema = {
        id: 'value',
        name: 'label',
        icon: 'icon',
        url: 'url'
    };
    
    self = SS.widgets.autocomplete(spec, my);
    
    return self;
};
;// Beginning /res/js/v2/widgets/ss.widgets.autocomplete_location.js:
// spec indludes:
// spec.input - input element to autocomplete, spec.on_select - on_select
SS.widgets.autocomplete_location = function (spec, my) {
    var self;
    
    my = my || {};
    
    spec.url = '/location/auto_complete';
    spec.schema = {
        address: 'label',
        info: 'full',
        lat_long: 'lat_long'
    };
    spec.min_length = 5;
    
    self = SS.widgets.autocomplete(spec, my);
    
    return self;
};
;// Beginning /res/js/v2/widgets/ss.widgets.autocomplete_place.js:
// spec indludes:
// spec.input - input element to autocomplete, spec.on_select - on_select
SS.widgets.autocomplete_place = function (spec, my) {
    var self;
    
    my = my || {};
    
    spec.url = '/place/auto_complete';
    spec.schema = {
        id: 'value',
        name: 'label',
        icon: 'medium_icon',
        url: 'url'
    };
    
    self = SS.widgets.autocomplete(spec, my); 
    
    return self;
};
;// Beginning /res/js/v2/widgets/ss.widgets.autocomplete_generic.js:
// spec indludes:
// spec.input - input element to autocomplete, spec.on_select - on_select
SS.widgets.autocomplete_generic = function (spec, my) {
    var self;
    
    my = my || {};
    
    spec.url = '/generic/autocomplete/' + spec.collection;
    spec.schema = {
        label: 'label'
    };
    spec.min_length = spec.min_length || 2;
    
    self = SS.widgets.autocomplete(spec, my);
    
    return self;
};

;// Beginning /res/js/v2/widgets/ss.widgets.autocomplete_event.js:
// spec indludes:
// spec.input - input element to autocomplete, spec.on_select - on_select
SS.widgets.autocomplete_event = function (spec, my) {
    var self;
    
    my = my || {};
    
    spec.url = '/event/auto_complete';
    spec.schema = {
        id: 'value',
        name: 'label',
        url: 'url',
        icon: 'medium_icon',
        attendee_count : 'attendee_count'
    };
        
    self = SS.widgets.autocomplete(spec, my);
    
    return self;
};
;// Beginning /res/js/v2/widgets/ss.widgets.autocomplete_group.js:
// spec indludes:
// spec.input - input element to autocomplete, spec.on_select - on_select
SS.widgets.autocomplete_group = function (spec, my) {
    var self;
    
    my = my || {};
    
    spec.url = '/chapter/auto_complete'; 
    spec.schema = {
        id: 'value',
        name: 'label',
        url: 'url',
        icon: 'medium_icon',
        member_count : 'member_count'
    };
        
    self = SS.widgets.autocomplete(spec, my);
    
    return self;
};
;// Beginning /res/js/v2/ss/plugins/steps.js:
/**
    Implementation for swapping back and forth between different steps in a process.
    Assumes that we'll be given some html like...

    <form class='steps'>
        <div class='step'>
            First Step
        </div>
        <div class='step'>
            Second Step
        </div>
    </form>

    running $('.steps').ss_steps()
    will grey out the second step and create a button to move from the first step to the second step 
    (greying out the second step in the process)
    In order to move from one step to the next the form must be valid
 */
(function( $ ){

    $.fn.ss_steps = function( method ) {
        var activate = function( step ){
                // Make this div active
                $('.step_history, .step_preview', step).hide();
                $('.step_active', step).show();

                $(step).addClass('step_active').show();
            },
            preview = function( step ){
                // Make this div show only the preview/heading
                $(step).removeClass('step_active').hide();
                $('.step_history, .step_active', step).hide();
                $('.step_preview', step).show();
            },
            history = function( step ){
                // Make this div show the readonly components
                $(step).removeClass('step_active').show();
                $('.step_active, .step_preview', step).hide();
                $('.step_history', step).show();

                $(step).show();
            };

        var methods = {
            init : function( options ) {  
                var settings = {
                    'nothing'         : 'top',
                    'more-background-color' : 'blue'
                };

                return this.each(function() {        
                    // If options exist, lets merge them
                    // with our default settings
                    if ( options ) { 
                        $.extend( settings, options );
                    }

                    // Grey out/hide all steps after the first
                    activate( $(this).find('.step:first') );

                    $(this).find('.step').not(':first').each( function(index, step){
                        preview( step ); 
                    });

                    $(this).delegate('.activate_step', 'click', function(){
                        var step = $(this).closest('.step'),
                            confirm_dialog = SS.widgets.dialog({
                                type: 'confirm',
                                title: 'Warning!',
                                content: '<center>By clicking continue your progress will be lost.<br><br>Do you wish to proceed?</center>',

                                buttons: {
                                    Cancel: function () {
                                        $('.confirm_dialog').dialog('close');
                                    },
                                    Continue: function () {
                                        methods.activate_step( step );
                                        $('.confirm_dialog').dialog('close');
                                    }
                                } 
                        });
                    
                        confirm_dialog.init();

                    });
                });
            },
            activate_step : function( step ) {
                // activate the given step and update the other steps to preview or history
                // status
                $(step).prevAll('.step').each( function( index, step ) {
                    history( step );
                } );
                activate($(step))
                $(step).nextAll('.step').each( function( index, step ) {
                    preview( step );
                } );
            },
            next : function( ) {
                // find the first unblocked step and run that
            },
            back : function( ) {  },
            update : function( content ) {  }
        };

        // Method calling logic
        if ( methods[method] ) {
            return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  method + ' does not exist on jQuery.ss_steps' );
        }
    };
})(jQuery);


//
// Extended jquery plugin for blocking and unblocking items
//
(function( $ ){
    $.fn.ss_block = function( options ) {
        var settings = {
            'nothing'         : 'top',
            'more-background-color' : 'blue'
        };

        return this.each(function() {        
            // If options exist, let's merge them
            // with our default settings
            if ( options ) { 
                $.extend( settings, options );
            }
            $(this).block({message:null}).addClass('blocked');

            return this;
        });
    };
    $.fn.ss_unblock = function( options ) {
        var settings = {
            'nothing'         : 'top',
            'more-background-color' : 'blue'
        };

        return this.each(function() {        
            // If options exist, lets merge them
            // with our default settings
            if ( options ) { 
                $.extend( settings, options );
            }
            $(this).unblock().removeClass('blocked');

            return this;
        });
    };
})(jQuery);

;// Beginning /res/js/v2/ss/plugins/datepicker.js:
/**
    Wrapper to provide defaults for date picker plugin
 */
(function( $ ){

    $.fn.ss_datepicker = function( options ) {
        var settings = { dateFormat: 'dd M yy',
                         onClose: function () {$(this).valid(); }
                       };
        $.extend( options ); 

        this.datepicker( options );
    };
})(jQuery);

function ss_format_date(date){
    if ( ! date ){
        return;
    }

    var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];

    return date.getDate() + ' ' + months[date.getMonth()] + ' ' + date.getFullYear();
}

;// Beginning /res/js/v2/ss/plugins/jflow.plus.js:
/* Copyright (c) 2010 WordImpressed.com jFlow Plus by Devin Walker

 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)

 * jFlow 2.0 (Plus)

 * Version: jFlow Plus

 * Requires: jQuery 1.2+

 */
(function ($) {
    $.fn.jFlow = function (options) {
        var opts = $.extend({}, $.fn.jFlow.defaults, options);
        var randNum = Math.floor(Math.random() * 11);
        var jFC = opts.controller;
        var jFS = opts.slideWrapper;
        var jSel = opts.selectedWrapper;
        var cur = 0;
        var timer;
        var maxi = $(jFC).length;
        //get width of individual slides
        var width = $(opts.slides).children().outerWidth();
        //get current number of slides
        var slidesNum = $(opts.slides).children().size();
        //get the total width
        var totalWidth = width * slidesNum;
        //last slide number
        var lastSlide = (slidesNum - 1);
        // additional container length for 'flow'
        var additionalSlide = slidesNum + 1;
        //defualt pause time between transitions
        var pause = opts.pause;
        // jFlow sliding function which handles the animations
        // current animations: 'rewind' and 'flow'
        var slide = function (dur, i) {
                //hide overflow for slides
                $(opts.slides).children().css({
                    overflow: "hidden"
                });
                //handling iframes
                $(opts.slides + " iframe").hide().addClass("temp_hide");
                //depending of our effect we will do different animations           
                if (opts.effect == "rewind") {
                    //this is our 'rewind' animation where the slide will rewind to first slide in stack
                    $(opts.slides).animate({
                        marginLeft: "-" + (i * $(opts.slides).find(":first-child").width() + "px")
                    }, opts.duration * (dur), opts.easing, function () {
                        $(opts.slides).children().css({
                            overflow: "hidden"
                        });
                        $(".temp_hide").show();
                    });
                }
                // now we need to address the flow effect
                // this is a bit different way of handling the slides
                else if (opts.effect == "flow") {
                    //number of slides
                 
                    //if we are NOT on the last slide
                    if (i != 0) {
                        $("#mySlides").animate({
                            left: -(i * width)
                        }, function () {
                            //if we are on the last slide then move the first slide into position
                            if ((slidesNum - 1) == i) {
                                $(".jFlowSlideContainer").first().css({
                                    //left slide distance is equal to width of slide times number of slides
                                    left: (width * slidesNum)
                                });
                            }
                        });
                        
                        //fire off the paging function 
                        movePagingClass();
                        
                    }
                    // we are DONE with the normal slide login
                    // now if we are on the last slide then
                    // this is the logic to move the first slide into position
                    // along with increasing the slide container width
                    else {
                    
                        //animate the first slide container into position
                        $(".jFlowSlideContainer").first().animate({
                            //left slide distance is equal to width of slide times number of slides     
                            left: (width * slidesNum)
                       });
                   
                        //set the container width to be large enough
                        $(opts.slides).css({
                            // width is equal to the outer width of the container plus width one slide
                            width: (width * additionalSlide)
                         
                        });
                        //animate the slide container to the left 
                        //to create the flow effect
                        $(opts.slides).animate({
                            left: "-"+totalWidth 
                        },
                        //important: we need to reestablish our first slide and container
                        // after the animation is complete
                        function () {
                            //position the slide container element back to start
                            $(this).css('left', '0px');
                            //position the first slide back to start
                            $(".jFlowSlideContainer").first().css('left', '0px');
                      
                      
                        });
                        
                        
                        //move the selected class from the last li to the first
                        $('.jFlowSelected').removeClass('jFlowSelected');
                        $(jFC).first().addClass('jFlowSelected');
                        
                    }
                  
                    
                }
                
                            
             
            }
            
        //pagination class
        var movePagingClass = function() {
                //advance the 'selected' pagination class 
                var thisController = $('.jFlowSelected');
                $(thisController).removeClass('jFlowSelected');
                $(thisController).next().addClass('jFlowSelected');     
        }
        

        //slide animation for pagination
        //also add the jFlowSelected class to the appropriate controller
        $(this).find(jFC).each(function (i) {
            
            //when the first paging item is clicked 
            //handle the animation a bit differently
            //than the other slides
            $(jFC).first().click(function() {
            
                //ensure the first slide is in position
                $('.jFlowSlideContainer').first().css({
                    
                    left: '0px'
                    
                });
                //animate the slide container into position
                $('#mySlides').animate({
                    left: '0px'
                });
                
                
                //move the selected pagination class to the first item
                 $(jFC).removeClass(jSel);
                 $(this).addClass(jSel);
                
                
            });
            
            //controller slide function for the remaining slides
            $(this).click(function () {
                
                //start up the timer
                dotimer();
                
                //if this slide is not animated
                if ($(opts.slides).is(":not(:animated)")) {
                    //slide to the page clicked
                    var dur = Math.abs(cur - i);
                    slide(dur, i);
                    cur = i;
                    
                    
                    //move the selected pagination class to the clicked item
                    $(jFC).removeClass(jSel);
                    $(this).addClass(jSel);
                    
                
                } 
                
                
                
            });
        });     
        
        
        if(lastSlide == 0){
        	$(opts.next).hide();
        	$(opts.prev).hide();
        }
        
        
        //Initiate our jFlow Plus slide
        $(opts.slides).before('<div id="' + jFS.substring(1, jFS.length) + '"></div>').appendTo(jFS);
        //find each of our slide elements and wrap them
        $(opts.slides).find(".slide").each(function () {
            $(this).before('<div class="jFlowSlideContainer"></div>').appendTo($(this).prev());
        });
        //initialize the controller
        $(jFC).eq(cur).addClass(jSel);
        var resize = function (x) {
                $(jFS).css({
                    position: "relative",
                    width: opts.width,
                    height: opts.height,
                    overflow: "hidden"
                });
                //opts.slides or #mySlides container
                $(opts.slides).css({
                    position: "relative",
                    width: $(jFS).width() * $(jFC).length + "px",
                    height: $(jFS).height() + "px",
                    overflow: "hidden"
                });
                // jFlowSlideContainer
                $(opts.slides).children().css({
                    position: "relative",
                    width: $(jFS).width() + "px",
                    height: $(jFS).height() + "px",
                    "float": "left",
                    overflow: "hidden"
                });
                $(opts.slides).css({
                    marginLeft: "-" + (cur * $(opts.slides).find(":eq(0)").width() + "px")
                });
            }
            // sets initial size
            resize();
        // resets size
        $(window).resize(function () {
            resize();
        });
        $(opts.prev).click(function () {
            dotimer();
            //////
            if(cur == 1) {
            	$(opts.prev).hide()
            }
            
            $(opts.next).show()
            ////// delete this chunk to enable circular sliding
            doprev();
        });
        $(opts.next).click(function () {
            dotimer();
            //////
            if(cur == lastSlide-1) {
            	$(opts.next).hide()
            }
            $(opts.prev).show()
            ////// delete this chunk to enable circular sliding
            
            donext();
        });
        
        //The Previous btn function
        var doprev = function (x) {
            
                //using the normal rewind effect
                if (opts.effect == 'rewind') {
                    if ($(opts.slides).is(":not(:animated)")) {
                        var dur = 1;
                        if (cur > 0) {
                            cur--;
                        } else {
                            cur = maxi - 1;
                            dur = cur;
                        }
                        $(jFC).removeClass(jSel);
                        slide(dur, cur);
                        $(jFC).eq(cur).addClass(jSel);
                    }
                }
                // we're using the 'flow' effect so we'll need a slightly different 
                // method of navigating out slides using the previous button
                else if (opts.effect == 'flow') {

                    // Increase the Slide Container Width:
                    // if we are on the last slide and click next btn
                    // ensure that our first slide is in position
                    if(cur == 0) { 
                    
                        
                      $(opts.slides).css({
                            // width is equal to the outer width of the container plus width one slide
                            width: (width * additionalSlide)
                        });
                                        
                        $('.jFlowSlideContainer:last').css({
                            position: "absolute",
                            left: "-"+width+"px"
                        });
                        //add padding to display the last slide
                        //NEED TO MAKE DYMANIC
                        $('#mySlides').animate({
                            paddingLeft: width+"px"
                        });
                        //animate the last slide
                        $('.jFlowSlideContainer:last').animate({
                            left: "0px"
                        }, function () {
                            //change the position of this last slide
                            //to shift to default placement
                            $(this).css({
                                position: "relative",
                                left: ""
                            });
                            //move the slide container position to the last slide
                            //NEED TO MAKE DYMANIC
                            $('#mySlides').css({
                                padding: "0px",
                                left: "-"+(totalWidth - width)+"px"
                            });
                        
                        });
                        
                        //change current slide variable to the last slide number
                         cur = slidesNum - 1;
                         
                        //move the selected class from the last li to the first
                        $('.jFlowSelected').removeClass('jFlowSelected');
                        $(jFC).last().addClass('jFlowSelected');
                         
                    } //else slide as normal
                    else {
                        //if our last slide is out of position
                        //move it to the proper position
                        if($(opts.slides).find(":first-child").css({ left: totalWidth })) {
                            $(opts.slides).find(":first-child").css('left','0px');
                        }

                        $('#mySlides').animate({
                            left: -(width * (cur - 1))
                        }, {
                            queue: false
                        });
                        cur = cur - 1;
                        
                        //advance the 'selected' pagination class 
                        var thisController = $('.jFlowSelected');
                        $(thisController).removeClass('jFlowSelected');
                        $(thisController).prev().addClass('jFlowSelected'); 
                        
                        
                    }
                    //no effect entered so throw alert      
                } else {
                    alert('Error: No effect entered as option!');
                }
            }
            
        // the next button function
        var donext = function (x) {
            
                if(cur == lastSlide) {
                    $(".jFlowSlideContainer").first().css({
                        "left": totalWidth+"px"
                        });
                }
            
                if (opts.effect == 'rewind') {
                    if ($(opts.slides).is(":not(:animated)")) {
                        var dur = 1;
                        if (cur < maxi - 1) cur++;
                        else {
                            cur = 0;
                            dur = maxi - 1;
                        }
                        $(jFC).removeClass(jSel);
                        //$(jFS).fadeOut("fast");
                        slide(dur, cur);
                        //$(jFS).fadeIn("fast");
                        $(jFC).eq(cur).addClass(jSel);
                    }
                }
                // we're using the 'flow' effect so we'll need a slightly different 
                // method of navigating out slides using the previous button
                else if (opts.effect == 'flow') {
                    //check to see which slide we are on and set "cur" variable
                    if ($(opts.slides).is(":not(:animated)")) {
                        var dur = 1;
                        if (cur < maxi - 1) cur++;
                        else {
                            cur = 0;
                            dur = maxi - 1;
                        }
                    }
                    //fire off the slide function
                    //also pass our parameters                  
                    slide(dur, cur);
                } //end: "flow'
            } //end: donext function
            
        //the jFlow Timer
        var dotimer = function (x) {
                if ((opts.auto) == true) {
                    if (timer != null) clearInterval(timer);
                    timer = setInterval(function () {
                        $(opts.next).click();
                    }, pause);
                }
            }
            //Pause/Resume function fires at hover
            dotimer();
        $(opts.slides).hover(

        function () {
            clearInterval(timer);
        }, function () {
            dotimer();
        });
    };
    //end jFlow Plus Functions
    //default jFlow Plus Options
    $.fn.jFlow.defaults = {
        // must be class, use . sign
        controller: ".jFlowControl",
        // must be id, use # sign
        slideWrapper: "#jFlowSlider",
        // the div where all your sliding divs are nested in
        slides: "#mySlides",
        // just pure text, no sign
        selectedWrapper: "jFlowSelected",
        //this is the slide effect (rewind or flow)
        effect: "flow",
        // this is the width for the content-slider
        width: "800px",
        // this is the height for the content-slider
        height: "350px",
        // time in miliseconds to transition one slide
        duration: 400,
        //time to pause between transition
        pause: 5000,
        // next btn: must be class, use . sign
        prev: ".jFlowPrev",
        // prev btn: must be class, use . sign
        next: ".jFlowNext",
        // auto slide option: true or false
        auto: true
    };
})(jQuery);
;// Beginning /res/js/v2/backbone/reports/report.models.js:
$(function(){
    //
    // Details about the target of a report
    //
    window.FieldInfoModel = Backbone.Model.extend({
        defaults: function(){
            return {
                label: null,
                field_type: null,
                data_type: null
            };
        }
    });
    window.FieldInfoCollection = Backbone.Collection.extend({
        "model": FieldInfoModel,
        comparator: function(field_info){ return field_info.get('label'); },
    });
 
    window.TargetSummary = Backbone.Model.extend({
        defaults: function() {
            return {
                target_id: null,
                target_summary: null
            };
        }
    });
    window.EventSummary = Backbone.Model.extend({
        url: function(){return '/events/' + this.id + '/summary'},
        defaults: function(){
            return { 
                event_date:null
            };
        },
        type : 'event'
    });
    window.UserSummary = Backbone.Model.extend({
        url: function(){return '/users/' + this.id + '/summary'},
        defaults: function(){
            return { 
            };
        },
        type : 'user'
    });
    window.ColumnModel = Backbone.Model.extend({
        defaults: function(){
            return {
                "key": null,
                "label": '',
                "field_id": '',
                "aggregate_function": '',
                is_group_by: false
            };

        },
        is_aggregate: function(){
            return this.is_group_by();
        },
        is_group_by: function(){
            return this.get('is_group_by');
        }
    });
    window.ColumnCollection = Backbone.Collection.extend({
        "model": ColumnModel,
        comparator: function(column){ return column.get('sort_index'); },
        renumber: function() {
            // renumber the sort indexes of the columns
            this.each( function( column, index ){
                column.set({sort_index:index});                
            });
        },
        insert_as_first: function( column ){
            column.set({sort_index:-1});
            this.add(column);
            this.sort();
            this.renumber();
        },
        insert_after: function( source, target ){
            this._insert_relative_to( source, target, true );
        },
        insert_before: function( source, target ){
            this._insert_relative_to( source, target, false );
        },
        _insert_relative_to: function( source, target, after ){
            var offset = after? 0.5 : -0.5,
                offset_string = after? 'after':'before';

            // Need to ensure all the indexes as integers for the below -0.5 thing to work
            this.renumber();

            // Inserts a column in front of another column
            source.set({ sort_index:target.get('sort_index') + offset });

            if ( ! this.contains(source) ){
                // Add the item if it hasn't been added already
                this.add( source );
            }
            // Need to keep all the indexes as integers for the above -0.5 thing to work
            this.sort();
            this.renumber();
        },
        add_in_order: function( columns ){
            var number_of_columns = this.length;
            // Since we sort the columns everytime we add one we need to ensure they
            // have the right indexes
            _.each( columns, function( column, index ){
                column.sort_index = index + 1 + number_of_columns;
            });
            this.add( columns );
        }
    });
    window.SortingModel = Backbone.Model.extend({
        defaults: function(){
            return {
                "column_key": null,
                "sort_direction": null
            };

        }
    });
    window.SortingCollection = Backbone.Collection.extend({
        "model": SortingModel,
        add_sortable_column: function( column, direction ){
            var sorting = new SortingModel({column_key:column.get('key'),
                                            sort_direction:direction});
            this.reset( [ sorting ] );
        },
        get_sort_direction: function( column ){
            var sorting = new SortingModel({column_key:column.get('key'),
                                            sort_direction:direction});
            this.reset( [ sorting ] );
        }
    });
    window.GroupByCollection = Backbone.Collection.extend({
        "model": ColumnModel
    });
 
    window.FilterModel = Backbone.Model.extend({
        defaults: function(){
            return {
                "key": null, 
                "field_id": null,
                "filter_type": null,
                "min_range": null,
                "max_range": null,
                "value": null
            };
        }
    });
    window.FilterCollection = Backbone.Collection.extend({
        "model": FilterModel
    });

    window.ReportChartModel = Backbone.Model.extend({
        defaults: function() {
            return {
            };
        }
    });
    window.ReportModel = Backbone.Model.extend({
        urlRoot: '/v2/reports',
        defaults: function() {
            return {
                "name": '',
                "report_type": '',
                "filters": null,
                "field_infos": null,
                "group_bys": null,
                "columns": null,
                "extra_columns": null,
                report_chart: new ReportChartModel()
            };
        },
        initialize: function( options ){
            _.bindAll(this);
        },
        get_column: function( index ) {
            // Fetches the group_by or report_column at the given
            var group_by_count = this.get('group_bys').length;
            if ( index < group_by_count ){
                return this.get('group_bys').at( index );
            } else {
                return this.get('columns').at( index - group_by_count );
            }
        },
        update_with_initial_data: function( report ) {
            this.id = report.id;
            this.set({ report_type: report.report_type,
                       target_type: report.target_type,
                       report_category: report.report_category,
                       target_id: report.target_id,
                       name: report.name
                       });


            this.set({columns: new ColumnCollection});

            this.get('columns').add_in_order( report.columns );
            
            // For now at least, the extra_columns are also added to
            // the columns area since all columns are to be shown
            // since none can be removed or added.
            this.set({extra_columns: new ColumnCollection});
            this.get('extra_columns').add_in_order( report.extra_columns );

            // Some reports start with group bys
            // Need to add these to the report first
            this.set({group_bys: new GroupByCollection});

            if ( report.group_bys ){
                _.each( report.group_bys, _.bind(function(group_by){
                    var column = new ColumnModel( group_by );
                    this.add_group_by( column, true );
                }, this));
            }

            this.set({sortings: new SortingCollection});
            this.get('sortings').add( report.sortings );

            this.set({filters: new FilterCollection});
            this.get('filters').add( report.filters || []);

            this.set({field_infos: new FieldInfoCollection});
            this.get('field_infos').add( report.field_infos || []);

            if ( report.target_summary ){
                this.set({target_summary: new TargetSummary(report.target_summary)});
            }

            // should avoid fetching the data twice, but without fetching data twice
            // the table is the wrong size ( half as wide as it should be )
            this.trigger( 'columns_changed' );
            this.trigger( 'extra_columns_changed' );
            this.trigger( 'report_type_changed' );

            this.trigger( 'report_changed' );
        },
        /**
         * Updates the model with columns, report type...
         */
        update_with_report_spec: function( report_type, report_specification ){
            var report_data = { name: report_specification.get('name'),
                                report_type: report_type,
                                report_category: report_specification.get('report_category'),
                                target_type: report_specification.get('target_type'),
                                target_id: report_specification.get('target_id'),
                                target_summary: report_specification.get('target_summary'),
                                columns: report_specification.get('fields'),
                                extra_columns: report_specification.get('extra_columns'),
                                group_bys: report_specification.get('group_bys'),
                                filters: report_specification.get('filters'),
                                field_infos: report_specification.get('field_infos'),
                                sortings: report_specification.get('sortings') }

            this.update_with_initial_data( report_data );
        },
        update_target: function( target ){
            // updates this report with a new target
            this.set({target_id:target.id,
                      target_summary: target});

            this.trigger( 'report_target_changed' );

            this.trigger( 'report_changed' );
        },
        get_sort_direction: function ( column ) {
            return this.get('sortings').get_sort_direction( column );
        },
        sort_by: function ( column, direction ) {
            this.get('sortings').add_sortable_column( column, direction );
            this.trigger( 'sorting_changed' );
        },
        column_moved: function( source, target, after ) {
            // Called when a column has been added or reordered

            this.get('extra_columns').remove( source );
            this.get('group_bys').remove( source );

            source.set({is_group_by: false});
            this.get('columns')._insert_relative_to(source, target, after);


            this.trigger( 'extra_columns_changed' );
            this.trigger( 'columns_changed' );

            return true;
        },
        column_removed: function( column, quiet ) {
            // Called when a column has been reordered ( or failed to drag into a table from the extra list )
            if ( this.get('extra_columns').contains( column ) ){
                return false;
            }
            column.set({is_group_by: false});

            this.get('columns').remove(column);
            this.get('group_bys').remove( column );

            this.get('extra_columns').add( column );

            if ( ! quiet ){
                this.trigger( 'columns_changed' );
                this.trigger( 'extra_columns_changed' );
            }

            return true;
        },
        add_group_by: function( column, quiet ) {
            var group_bys = this.get('group_bys'),
                old_group_by;
            // Called when a column has been added to the group by section

            // check for the old group by column
            if ( group_bys.length ){
                old_group_by = group_bys.at(0);
                group_bys.remove(old_group_by);

                old_group_by.set({is_group_by: false});
                this.get('columns').insert_as_first( old_group_by );
            }

            // Remove the column from the table if it is there
            this.get('columns').remove(column);
            this.get('extra_columns').remove(column);

            column.set({is_group_by: true});
            group_bys.add( column );
            
            // Set the span that says what we're grouping by.
            // Grouped By should be obvious in looking at the table.

            // $(".group_by_indicator").html("Grouped By " + column.get("label"));

            if ( ! quiet ){
                this.trigger( 'columns_changed' );
                this.trigger( 'extra_columns_changed' );
                this.trigger( 'group_bys_changed' );
            }

            return true;
        },
        remove_group_by: function(){
            var group_bys = this.get('group_bys'),
            old_group_by;
    
            // check for the old group by column
            if ( group_bys.length ){
                old_group_by = group_bys.at(0);
                group_bys.remove(old_group_by);
    
                old_group_by.set({is_group_by: false});
                this.get('columns').add( old_group_by );
            }
            
            // Remove the text from the span that said what we were grouping by.
            $(".group_by_indicator").html("");
            
            this.trigger( 'columns_changed' );
            this.trigger( 'extra_columns_changed' );
            this.trigger( 'group_bys_changed' );
        },
        requires_target: function() {
            return (this.get('target_type') && ! this.get('target_id') );
        },
        /**
         * do we have the info necessary for a table?
         */
        can_display_table: function() {
            return this.get('columns') && this.get('columns').length && ! this.requires_target();
        },
        all_fields: function(){
            return _.union( this.get('group_bys').models,
                            this.get('extra_columns').models,
                            this.get('columns').models );
        }
    });

    // Set constants
    ReportModel['TYPES'] = {
        'good': 0,
        'evil': 1,
        'neutral': 2
    };

    //
    // Represents a type of report including default fields and data source
    window.ReportSpecificationModel = Backbone.Model.extend({
        defaults: function(){
            return {
                "fields": null, 
                "spec": null
            };
        }
    });

    window.ReportSpecificationCollection = Backbone.Collection.extend({
        "model": ReportSpecificationModel,
        url: '/report/report_specifications'
    });
});

;// Beginning /res/js/v2/backbone/reports/report.views.js:
$(function(){
    window.ReportTypeView = Backbone.View.extend({
        events: {
            "click .report_type_chosen": "report_type_chosen"
        },
        initialize: function(options){
            this.model.bind('report_target_changed', this.report_target_changed, this);
        },
        report_type_chosen: function(options){
            // Update the model to reflect the report type
            var $report_type = this.$('.report_type_js:visible'),
                report_type = $report_type.val(),
                report_type_name = $(':selected', $report_type).text(),
                $report_category = this.$('.report_category_js'),
                report_category_id = $(':selected', $report_category).val(),
                report_category_name = $(':selected', $report_category).text(),
                report_model = this.model,
                $el = $(this.el);
            this.model.report_type = report_type;

            if ( ! report_type ){
                // Require a report type be chosen
                return;
            }

            // Update the title with the report name
            $( ".report_title_header_js" ).hide();
            $( ".report_title_js" ).html( report_type_name );
            $( ".report_table .report_type_js" ).html( report_type_name );

            $('.report_type_chosen').hide();

            this.$('.report_type_js, .report_category_js').attr('disabled', true);

            // Trigger a call to fetch the new specification for the given report type
            // Not sure if using a collection to fetch one model object is the right way to go?
            // Once the item is fetched, we should let the parent view know about it and let it
            // configure the filters, table
            //
            report_specifications.fetch(
                {   add:true, 
                    data: {report_type: report_type},
                    success: function( model, response) {
                        var spec = model.get( report_type );
                        spec.set( {report_category: report_category_name } );
                        
                        report_model.update_with_report_spec( report_type, spec );


                        ss.apps.breadcrumbs.update({parents:[{title:'Reports',url:'/reports'},
                                                             {title:report_category_name,url:'/report/new?category='+report_category_id}]
                                                    ,current: report_type_name});

                        if ( ! report_model.requires_target() ) {
                            $el.hide();
                        }
                    }
                }
            );
        },
        report_target_changed: function(options){
            $(this.el).hide();
        }
    });

    window.ReportTargetView = Backbone.View.extend({
        events: {
            "change .report_target_year_js": "year_chosen",
            "change .report_target_month_js": "month_chosen"
        },
        initialize: function(options) {
            this.model.bind('report_type_changed', this.render, this);

            this.target_summary = null;

            _.bindAll(this);
            this.render();
        },
        month_chosen: function(event){
            var month = $(event.target).val(),
                month_text = $(':selected', event.target).text(),
                summary = new TargetSummary({id:month,
                                             month:month_text});

            this.model.update_target( summary );
            this.render();
        },
        year_chosen: function(event){
            var year = $(event.target).val(),
                summary = new TargetSummary({ id:year,
                                              year:year });

            this.model.update_target( summary );

            this.render();
        },
        target_chosen: function(target, ui){
            // Update the model to reflect the new target
            var target_type = this.model.get('target_type'),
                target_summary;

            if ( target_type === 'EVENT' ){
                target_summary = new EventSummary(target);
            } else if ( target_type === 'USER' ){
                target_summary = new UserSummary(target);
            }
            target_summary.fetch({success:this.render});
            this.model.update_target( target_summary );
            this.render();
        },
        render: function(){
            var $el = this.$(this.el),
                target_type = this.model.get('target_type'),
                template,
                template_path,
                target_summary = this.model.get('target_summary');

            if ( this.model.requires_target() ){
                template_path = '#' + target_type.toLowerCase() + '_target_chooser_view';
                template = _.template($(template_path).html());
                $el.html(template());

                if ( target_type === 'EVENT' ){
                    var $event_autocomplete = $('.report_event_autocomplete'),
                        event_autocomplete;

                    event_autocomplete = SS.widgets.autocomplete_event({
                        input: $event_autocomplete,
                        on_select: this.target_chosen
                    });
                    event_autocomplete.init();
                } else if ( target_type === 'USER' ){
                    var $user_autocomplete = $('.report_user_autocomplete'),
                        user_autocomplete;

                    user_autocomplete = SS.widgets.autocomplete_user({
                        input: $user_autocomplete,
                        on_select: this.target_chosen
                    });
                    user_autocomplete.init();                
                } else if ( target_type === 'MONTH' ){
                    // Nothing special needs to be done
                } else if ( target_type === 'YEAR' ){
                    // Nothing special needs to be done
                }
            } else if ( target_summary ) {
                // Render the given target
                // possible we only have partial data and are waiting for more
                // from the model
                template_path = '#' + target_type.toLowerCase() + '_target_view';
                template = _.template($(template_path).html());
                $el.html(template(target_summary.toJSON()));
            } else {
                // Just hide ourselves for now, don't need to choose an item and
                // don't need to display one
                $el.html('');
            }
        }
    });

    window.ReportFilterView = Backbone.View.extend({
        tagName:'li',
        template: _.template($('#report_filter_row').html()),
        events: {
            'change .numeric_filter_type_js': 'numeric_filter_type_changed',
            'change .date_filter_type': 'date_filter_type_changed',
            'change .date_input': 'date_changed',
            'change :input': 'content_changed',
            'click .remove_filter': 'remove_filter'
        },
        initialize: function(options){
            // Render the view for the first time
            _.bindAll(this);

            this.render();
        },
        refresh: function(){
            this.render();
        },
        render: function(){
            // Render the basic filter
            var $el = $(this.el),
                field_id = this.model.get('field_id'),
                field_infos = this.options.report_model.get('field_infos'),
                field_info = field_infos.get(field_id),
                data_type = field_info.get('data_type') || 'text',
                criteria_template = _.template( $('#report_'+data_type+'_filter_options').html() ),
                params = _.extend( {}, field_info.attributes, this.model.attributes ),
                $filter_row = $(this.template(params)),
                criteria_section = criteria_template( params ),
                model = this.model;

            $filter_row.append( criteria_section );

            $el.html($filter_row);

            this.$(':input').each(function( index, input){
                var field = $(input).data('field');
                if ( field ) {
                    $(input).val( model.get(field) );
                }
            });

            this.$('.filter_type').change();
        },
        content_changed: function(event){
            var $target = $(event.target),
                field = $target.data('field'),
                data = {};

            if ( field ){
                data[field] = $target.val();
                this.model.set(data);
            }
            this.options.report_model.trigger('filters_changed');
        },
        date_changed: function(event){
            this.$('.date_filter_type').val('custom');
        },
        numeric_filter_type_changed: function(event){
            var filter_type = this.$('.filter_type').val(),
                $criteria = this.$('.filter_criteria_js');

            $criteria.hide();
            $criteria.filter('.' + filter_type + '_js').show();
        },
        date_filter_type_changed: function(event){
            var filter_type = this.$('.date_filter_type').val(),
                today = new Date(),
                in_the_past = function( options ){
                    var past = new Date( today.getFullYear() - (options.years || 0 ), 
                                         today.getMonth() - (options.months || 0), 
                                         today.getDate() );
                    if ( past.getDate() < today.getDate() ){
                        // handle february not having 31 days
                        past.setDate( 0 );
                    }

                    return past;
                },
                start_date,
                end_date = today;

            if ( filter_type === 'last_year' || ! filter_type){
                start_date = in_the_past( {years:1});
            } else if ( filter_type === 'last_month' ){
                start_date = in_the_past( {months:1});
            } else {
                // custom don't need to do anything
            }

            // only update if something's changed
            if ( start_date ){
                this.$('.start_date').val(ss_format_date(start_date));
                this.$('.end_date').val(ss_format_date(end_date));

                // Keep the model in sync
                this.model.set({start_date:ss_format_date(start_date),
                                end_date:  ss_format_date(end_date)});
            }
        },
        remove_filter: function(event){
            //this.options.report_model.get('filters').remove( this.model );
            this.model.destroy();
            //$(this.el).remove();
            this.options.report_model.trigger('filter_removed');
            this.options.report_model.trigger('filters_changed');
        }
    });

    window.ReportFiltersView = Backbone.View.extend({
        template: _.template($('#report_filters').html()),
        events: {
            "change .add_new_filter_js": "add_new_filter"
        },
        initialize: function(options){
            this.model.bind('report_changed', this.refresh, this);
            this.model.bind('filter_removed', this.refresh, this);

            _.bindAll(this);
            
            // Render the view for the first time
            this.needs_rendering = true;
            this.render();
        },
        refresh: function(){
            this.needs_rendering = true;
            this.render();
        },
        render: function(){
            if ( ! this.model.can_display_table() ){
                $(this.el).hide();
                return;
            }
            $(this.el).show();

            if ( ! this.needs_rendering ){
                return;
            }
            this.needs_rendering = false;

            $(this.el).html(this.template());
            this.fill_new_filter_options();
            this.model.get('filters').each( this.render_filter );
        },
        fill_new_filter_options: function(){
            var $add_new = this.$('.add_new_filter_js'),
                model = this.model;

            $add_new.html('');
            // Add the empty option
            $add_new.append('<option>');

            console.log( 'all fields', this.model.all_fields() );
            _.each(this.model.all_fields(), function(item){
                console.log( 'label', item.get('label') );

            });

            _.each( this.model.all_fields(), function( field, index ) {
                var field_infos = model.get('field_infos'),
                    field_info = field_infos.get(field.get('field_id')),
                    data_type = field_info.get('data_type'),
                    filter_already_added = model.get('filters').any(
                        function(filter){ return filter.get('field_id') === field.get('field_id');});

                console.log( 'field ', data_type, field.get('label'), field_info );
                // Hide any fields that we don't know how to filter for ( month and year right now )
                if ( $('#report_'+data_type+'_filter_options').length && ! filter_already_added ) {
                    $add_new.append( '<option value="' + field.get('field_id') +'">' + field.get('label') );
                } else {
                    console.log( 'field not added', data_type, field.get('label') );
                }
            });
        },
        render_filter: function(filter){
            var filter_view = new ReportFilterView({model:filter, report_model:this.model});
            this.$('.report_filters').append( filter_view.el );
        },
        add_new_filter: function(event){
            // Make a new filter model, view
            // add it to the report model, page
            var filter = new FilterModel({field_id:$(event.target).val()});
            this.model.get('filters').add( filter );

            this.render_filter( filter );

            // reset the filter field list
            this.fill_new_filter_options();
        }
    });

    window.ReportFieldsView = Backbone.View.extend({
        events: {
        },
        initialize: function(options){
            this.model.bind('extra_columns_changed', this.refresh, this);
            this.model.bind('report_changed', this.refresh, this);
            
            // Render the view for the first time
            this.render();
        },
        refresh: function(){
            this.render();
        },
        render: function(){
            if ( ! this.model.can_display_table() ){
                return;
            }
            // display the list of the columns
            var $field_list = this.$('ul'),
                extra_columns = this.model.get('extra_columns'),
                model = this.model;

            $field_list.find('li.potential_field').remove();
            if ( extra_columns ) {
                model.get('extra_columns').each( function( column, index ){
                    var li = $( '<li class="potential_field">' ).
                                 data( 'field_id', column.get('field_id') ).
                                 text( column.get('label') ).
                                 data( 'model', column );
                    li.draggable( field_dragger({draggable:li, report_model:model}) );

                    $field_list.append( li );
                });
            }
        }
    });
    window.ReportChartView = Backbone.View.extend({
    });
    window.ReportChartsView = Backbone.View.extend({
        // Report chart require
        //     a button to add edit charts
        //     and a chart to display
        chart_buttons_template: _.template($('#report_chart_buttons').html()),
        chart_options_template: _.template($('#report_chart_options').html()),
        events: {
            "click .report_action_add_chart": "add_chart"
        },
        initialize: function(options) {
            this.model.bind('report_changed',  this.refresh, this);

            report_chart = this.model.get('report_chart');


            _.bindAll(this);
            
            // Render the view for the first time
            this.render();
        },
        refresh: function() {
            this.render();
        },
        render: function() {
            return;
            var $el = $( this.el );

            $el.html('');
            // Is there a table to be rendered yet?
            if ( ! this.model.can_display_table() ) {
                return;
            }
            $el.append( this.chart_buttons_template() );
        },
        edit_chart: function( ) {
        },
        add_chart: function( ) {
            var $chart_options = this.chart_options_template( ),
                report_model = this.model;

            $('<div>').ssdialog({
                'title' : 'Summarize',
                'dynamic_width' : true,
                'content' : {
                    'html' : $chart_options,
                },
                'buttons': {
                    'Save': null,
                    'Cancel': null,
                    'OK': function(namespace){
                        this[namespace]( 'hide' );
                        // Todo, actually change the chart
                        report_model.trigger( 'report_chart_changed' );
                    }
                }
            });
        },
     });

    window.ReportTableView = Backbone.View.extend({
        events: {
        },
        initialize: function(options) {
            _.bindAll(this);

            this.model.bind('columns_changed', this.refresh, this);
            this.model.bind('sorting_changed', this.refresh, this);
            this.model.bind('report_changed',  this.refresh, this);
            this.model.bind('filters_changed', this.refresh, this);
            
            // Render the view for the first time
            this.render();
        },
        refresh: function() {
            this.render();
        },
        render: function() {
            var $el = this.$(this.el),
                columns = [],
                default_sorting = [],
                model = this.model,
                data_fetching_function = function ( sSource, aoData, fnCallback ) {
                        // Add some extra data to the sender
                        var report_spec = JSON.stringify(model);
                        aoData.push( { "name": "report_spec", "value": report_spec } );
                        $.post( sSource, aoData, function (json) {
                            // Do whatever additional processing you want on the callback,
                            // then tell DataTables to render
                            fnCallback(json);
                        },'json' );
                    },
                $table = $("<table class='data_table' class='display'></table>");

            this.add_table_header($table);
            // Clear the table
            $el.html('').append( $table );

            // Is there a table to be rendered yet?
            if ( ! this.model.can_display_table() ){
                return;
            }

            // field generation was done in assets/report_typeinfo.py before
            // Convert the list of group_bys and columns to a list of fields in data_table speak
            if ( this.model.get('group_bys').length ){
                // add an invisible first column whose sole purpose is to
                // determine whether the column is a group by or not
                columns.push( { bVisible: false } );
                
                this.model.get('group_bys').each( function( group_by ){
                    columns.push( {
                        label: group_by.get('label').replace(/ /g,'&nbsp;'),
                        sTitle: group_by.get('label').replace(/ /g,'&nbsp;'),
                        //sWidth: '150px',
                        data_type: '',
                        sName: '',
                        bSortable: false,
                        field_id: group_by.get('field_id')
                    } );
                });
            } else {
                columns.push( {
                    label: '',
                    sTitle: '',
                    //sWidth: '150px',
                    data_type: '',
                    sName: '',
                    bSortable: false,
                    field_id: ''
                } );                
            }
            
            this.model.get('columns').each( function( column ){
                columns.push( {
                    label: column.get('label').replace(/ /g,'&nbsp;'),
                    sTitle: column.get('label').replace(/ /g,'&nbsp;'),
                    //sWidth: '150px',
                    data_type: '',
                    sName: '',
                    bSortable: false,
                    field_id: column.get('field_id')
                } );
            });


            this.oTable = $table.dataTable({
                "bJQueryUI": true,
                "sPaginationType": "two_button",
                "aaSorting": default_sorting,
                "aoColumns": columns,
                "bDestroy":true,
                "sDom": '<"toolbar"><"filter_bar">rt"F"lip',
                "bProcessing": true,
                "bServerSide": true,
                // "bAutoWidth": false,
                //"sScrollX": '1000px',
                //"sScrollY": '100%',
                "iDisplayLength": 100,
                "sAjaxSource": "/report/report_data",
                "fnServerData": data_fetching_function,
                "fnHeaderCallback": _.bind(this.header_callback, this),
                "fnRowCallback": _.bind(this.row_callback, this),
                "fnDrawCallback": _.bind(this.draw_callback, this)
            });
            // Disable the first pane and display the second
            //$('button, select', $report_type_pane).attr('disabled', true);
            //$(this).hide();
            //this.oTable.fnAdjustColumnSizing();

            $el.closest('.report_details_pane').show();
            $el.show();
        },
        add_table_header: function( $table ){
            if (false){
            var template = _.template($('#report_table_header').html());
            $table.append( template() );
            }
        },
        clickRemove: function(event) {
            event.preventDefault();
            this.destroyModel(true);
        },
        destroyModel: function( promptUser ){
        },
        draw_callback: function( data_table ) {
            // Add a drop in column to group by row
            var $table = $( data_table.nTable ),
                $body =  $( 'tbody', $table ),
                grouping_row_template = _.template( $('#report_add_a_grouping_row').html() ),
                $grouping_row = grouping_row_template( {colspan:this.model.get('columns').length} ),
                columns = this.model.get('columns'),
                group_bys = this.model.get('group_bys'),
                group_by_width = group_bys.length ? 200 : 0,
                scrollbar_width = 30, // tweaked to try and minize likelihood of a horizontal scroll bar
                minimum_column_width = ( $('.report .report_data_wrapper').width() - group_by_width - scrollbar_width ) / columns.length ;

            if ( group_bys.length === 0 ) {
                $body.prepend( $grouping_row );
            }

            // Double up on the grouping rows
            if ( group_bys.length ) {
                $( 'tr.grouping_row', $body ).each( function( index, tr ) {
                    var $grouped_rows = $(tr).nextUntil( '.grouping_row'),
                        rows_in_grouping =$grouped_rows.length,
                        grouping_column = $(tr).find('td').first().clone().show()
                                              .attr( 'colspan',columns.length + 1 ); // +1 for group by
                        // Don't have the grouping show twice
                        $(tr).find('td').first().text('');

                        if ( rows_in_grouping ) {
                            if ( ! grouping_column.text() ) {
                                grouping_column.prepend('Blank');
                            }
                            grouping_column.prepend('<span class="grouping_label">' + group_bys.models[0].get('label')+': </span>')
                                .append('<span> ('+ rows_in_grouping +' Record' + (rows_in_grouping === 1?'':'s')+')</span>');
                        } else {
                            grouping_column.prepend('<span>All: </span>');
                        }

                    // Make one row for the grouping and another for the summaries
                    $('<tr class="grouping_row grouping_title"></tr>').append( grouping_column )
                                                       .insertBefore( tr );

                    $(tr).addClass('report_summaries_row');

                    // Add a empty column beside all grouped rows
                    if ( rows_in_grouping ){
                        $grouped_rows.find('td:first-child').hide();
                        $grouped_rows.first().prepend(
                            $('<td>').attr('rowspan',rows_in_grouping)
                                     .addClass('grouping_indent')
                            );
                    }
                } );
            }

            // Add minimum widths to the table headers
            // Needed because when dragging an extra div element gets added which messes up
            // All the column widths
            $( '.DataTables_sort_wrapper', $table ).each( function( index, th_content ) {
                var $el = $(th_content),
                    padding = $el.outerWidth() - $el.width(),
                    min_width = minimum_column_width - padding - 10; // -10 for the th padding
                $(th_content).css({'min-width': min_width });
            });

        },
        row_callback: function ( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
            var group_by_count = this.model.get('group_bys').length,
                all_data       = this.oTable.fnGetData(),
                model = this.model;

            // apply field ids to the columns
            $('td', nRow).each( function( index, td ){
                var field_index = group_by_count ? index : index -1,
                    column = model.get_column( field_index );
                if (column){
                $(td).attr( 'field_id', column.get('field_id') );
                }
            });

            // apply grouped column class to grouping rows
            if ( aData[0] === 'true' ) {
                $(nRow).addClass('grouping_row');
                $('td', nRow).each( function( index, td ){
                    $(td).addClass('grouped_column');
                });

                if ( group_by_count ) {
                    // $('td', nRow).first().text('');
                } else {
                    // Still hide the original
                    $('td', nRow).first().hide();
                }
            } else {
                // Not a group by row hide when there is no group by
                if ( group_by_count === 0 ) {
                    $('td', nRow).first().hide();
                } else {
                    // handled in the draw callback
                }
            }

            return nRow;
           
        },
        header_callback: function( nHead, aasData, iStart, iEnd, aiDisplay ) {
            var model = this.model,
                group_bys = model.get('group_bys'),
                columns = model.attributes.columns,
                group_by_count = group_bys.length,
                $th,
                $aggregate_button,
                $aggregate_div,
                field_info;

            if ( $(nHead).data('decorated') ){
                // We've already decorated this header, no need to repeat
                return;
            }
            $(nHead).data('decorated', true);

            $('th', nHead).each( function (index, th) {
                // Handle the group by column differently
                if ( group_by_count === 0 ){
                    if ( index === 0 ){
                        $(th).remove();
                        return;
                    }
                    index -= 1;
                }
                var header,
                    column;

                column = model.get_column(index);
                
                if ( column ){
                    if ( column.is_group_by() ){
                        header = new ReportGroupByHeaderView({ el: th, model:column, report_model: model});
                    } else {
                        header = new ReportColumnHeaderView({ el: th, model:column, report_model: model});
                    }
                }
            });

            // Identify the primary header row
            $(nHead).addClass('main_header_row');

            return nHead;
        }
    });

    window.ReportGroupByHeaderView = Backbone.View.extend({
        events: {
            "click .column_options": "toggle_column_options",
            "click .sort_ascending_js": "sort_ascending",
            "click .sort_descending_js": "sort_descending",
            "click .remove_group_by_js": "remove_group_by"
        },
        // Controllers additional rendering and behaviour associated with this column
        initialize: function(options){
            var $aggregate_div,
                $th = $(this.el),
                $column_options;

            _.bindAll(this);

            $th.html('<span class="grouping_header_label">Grouped&nbsp;By').addClass('grouping_header');

            // Add Drop down for sorting, summarizing
            $column_options = $('<img class="column_options" src="/res/img/v2/icons/dropdown.png">');
            
            $th.append( $column_options );


            // Render the view
            this.render();
        },
        toggle_column_options: function (event) {
            var report_column_options_template = _.template( $('#report_group_by_options').html() ),
                $report_column_options = $(report_column_options_template()),
                first_click = true;

            this.$('.column_options').addClass('options_shown');

            if ( this.hide_menu ) {
                // Hide the old menu
                this.hide_menu();
                //event.preventDefault();
                return;
            }
            this.hide_menu = function(event){
                if ( first_click ){
                    // Handle the first mouse click event with care since it's the event
                    // that started displaying the menu
                    first_click = false;
                    return;
                }
                if ( event && $(event.target).closest($report_column_options).length ){
                    // Click occurred inside the menu, no need to hide it
                    return;
                }


                this.$('.column_options').removeClass('options_shown');

                $report_column_options.remove();
                $(document).unbind( 'click', this.hide_menu);

                this.hide_menu = null;
            };
            this.hide_menu = _.bind(this.hide_menu, this);

            $(this.el).append( $report_column_options );

            $report_column_options.position( 
                         { of: event.target,
                           my: 'right top',
                           at: 'right bottom',
                           offset: '6 2'      } ); // magic numbers, lining up the columns isn't trivial

            $(document).bind( 'click', this.hide_menu);
        },
        sort: function( direction ){
            if ( this.hide_menu ){
                this.hide_menu();
            }
            // TODO make sure the sorting by group by works
            this.options.report_model.sort_by(this.model, direction);
        },
        sort_ascending: function (){
            this.sort('ascending');
        },
        sort_descending: function (){
            this.sort('descending');
        },
        remove_group_by: function() {
            var report_model = this.options.report_model;
            // Dragging a column and ending outside of the report table
            if ( this.hide_menu ){
                this.hide_menu();
            }
            report_model.column_removed( this.model, true );
            report_model.get('columns').insert_as_first( this.model );

            report_model.trigger( 'columns_changed' );
        }
    });
    window.ReportColumnHeaderView = Backbone.View.extend({
        events: {
            "click .column_options": "toggle_column_options",
            "click .sort_ascending_js": "sort_ascending",
            "click .sort_descending_js": "sort_descending",
            "click .remove_column_js": "remove_column",
            "click .summarize_column_js": "summarize_column",
            "click .group_by_js": "group_by"
        },
        // Controllers additional rendering and behaviour associated with this column
        initialize: function(options){
            var $aggregate_div,
                $th = $(this.el),
                $column_options;

            _.bindAll(this);

            $th.addClass('column')
               .attr( 'field_id', this.model.get('field_id') )
               .data('model', this.model)
               .draggable( field_dragger({draggable:$th, report_model:options.report_model}) );

            // Add Drop down for sorting, summarizing
            $column_options = $('<img class="column_options" src="/res/img/v2/icons/dropdown.png">');
            
            $th.find( '.DataTables_sort_wrapper' ).append( $column_options );


            // Render the view
            this.render();
        },
        toggle_column_options: function (event) {
            var report_column_options_template = _.template( $('#report_column_options').html() ),
                $report_column_options = $(report_column_options_template()),
                first_click = true;


            this.$('.column_options').addClass('options_shown');

            if ( this.hide_menu ) {
                // Hide the old menu
                this.hide_menu();
                //event.preventDefault();
                return;
            }
            this.hide_menu = function(event){
                if ( first_click ){
                    // Handle the first mouse click event with care since it's the event
                    // that started displaying the menu
                    first_click = false;
                    return;
                }
                if ( event && $(event.target).closest($report_column_options).length ){
                    // Click occurred inside the menu, no need to hide it
                    return;
                }

                this.$('.column_options').removeClass('options_shown');


                $report_column_options.remove();
                $(document).unbind( 'click', this.hide_menu);

                this.hide_menu = null;
            };
            this.hide_menu = _.bind(this.hide_menu, this);

            $(this.el).append( $report_column_options );

            $report_column_options.position( 
                         { of: event.target,
                           my: 'right top',
                           at: 'right bottom',
                           offset: '6 2'      } ); // magic numbers, lining up the columns isn't trivial

            $(document).bind( 'click', this.hide_menu);
        },
        hide_dragging_columns: function () {
        },
        sort: function( direction ){
            if ( this.hide_menu ){
                this.hide_menu();
            }
            this.options.report_model.sort_by(this.model, direction);
        },
        sort_ascending: function (){
            this.sort('ascending');
        },
        sort_descending: function (){
            this.sort('descending');
        },
        remove_column: function (){
            this.options.report_model.column_removed( this.model );
            if ( this.hide_menu ){
                this.hide_menu();
            }
        },
        summarize_column: function (){
            var $content = $('<ul></ul>'),
                add_radio = function(label, value){
                    $content.append('<li><input name="aggregate_function" type="radio" class="summarize_type" value="'+value+'"><label>' + label +'</label>');
                },
                aggregate_function = this.model.get('aggregate_function'),
                model = this.model,
                report_model = this.options.report_model,
                field_infos = this.options.report_model.get('field_infos'),
                field_info = field_infos.get(model.get('field_id'));

            if ( this.hide_menu ){
                this.hide_menu();
            }

            add_radio('None','');
            add_radio('Count','count');
            if ( field_info.get('data_type') === 'numeric' ||
                 field_info.get('data_type') === 'currency'){
                add_radio('Sum','sum');
                add_radio('Average','average');
                add_radio('Min','min');
                add_radio('Max','max');
            }
            if ( field_info.get('data_type') === 'boolean' ){
                add_radio('Sum','sum');
            }


            if ( aggregate_function ) {
                $content.find('input[value="' + aggregate_function+ '"]').attr('checked', true);
            } else {
                $content.find('input').first().attr('checked', true);
            }


            $('<div>').ssdialog({
                'title' : 'Summarize',
                'dynamic_width' : true,
                'content' : {
                    'html' : $content,
                },
                'buttons': {
                    'Save': null,
                    'Cancel': null,
                    'OK': function(namespace){
                        this[namespace]('hide');
                        model.set({'aggregate_function': $content.find('input:checked').val()});
                        report_model.trigger('columns_changed');
                    }
                }
            });
        },
        group_by: function(){
            var report_model = this.options.report_model;
            report_model.add_group_by(this.model);
        }


    });

    window.ReportColumnView = Backbone.View.extend({
        initialize: function(options){
            _.bindAll(this, "clickRemove");
            
            // Render the view
            this.render();
        },
    });

    window.ReportAppView = Backbone.View.extend({
        // template: _.template($('#enrollment_flow_page_view').html()),
        // className: "enrollment_flow_app_view",
        events: {
            "click .report_action_save": "save_report",
            "click .report_action_create": "create_report",
            "click .report_action_download_csv": "download_csv",
            "click .report_title_edit_js": "edit_report_name",

            "change input[name='report:name']": "report_name_changed"
        },
        initialize: function(options){
            _.bind(this.report_name_changed, this);

            // Create a source of report specs
            window.report_specifications = new ReportSpecificationCollection;

            this.model = new ReportModel;

            this.model.bind('report_changed', this.render, this);

            this.report_type_view = new ReportTypeView({
                el: this.$('.report_type_pane'),
                model: this.model
            });

            this.report_target_view = new ReportTargetView({
                el: this.$('.report_target_pane'),
                model: this.model
            });

            this.report_filters_view = new ReportFiltersView({
                el: this.$('.report_filters_pane'),
                model: this.model
            });

            this.report_fields_view = new ReportFieldsView({
                el: this.$('.report_fields'),
                model: this.model
            });

            this.report_table_view = new ReportTableView({
                el: this.$('.data_table'),
                model: this.model
            });

            this.report_chart_view = new ReportChartsView({
                el: this.$('.report_chart_pane'),
                model: this.model
            });

            console.log(this.$(this.el).closest('form'));
            this.$(this.el).closest('form').submit( function(){
                // Stop this form from being submitted when a user clicks enter on a filter element
                return false;
            }); 

            // Check if we start with a report spec on the page
            if ( ss_context.report ){
                this.model.update_with_initial_data( ss_context.report );
            }

            this.render();
        },
        edit_report_name: function( ) {
            var report_model = this.model;
            $.ss.dialog.input("What is the new name of the report?", function(){
                report_model.set({name:this.value});
                $(".report_title_js").html(this.value);
                $( ".report_table .report_type_js" ).html( this.value );
            }, this.model.get('name'));
        },
        save_report: function( ) {
            this.model.save( {}, {
                success: function(model, response){
                    window.location = window.location;
                },
                error: function(model, response){
                }
            });
        },
        create_report: function( ) {
            var report_model = this.model;
            $.ss.dialog.input("What is the name of the report?", function(){
                report_model.set({name:this.value});
                report_model.save( {}, {
                    success: function(model, response){
                        window.location = '/reports/' + model.id +'/edit';
                    },
                    error: function(model, response){
                    }
                });
            }, this.model.get('name'));
        },
        download_csv: function( ) {
            // Make a top level form so that we can submit it and get the
            // report in csv form
            var now = new Date(),
                now_str = now.getFullYear() + '_' + ( now.getMonth() + 1 ) + '_' + now.getDate() +
                          '_' + now.getHours() + '_' + now.getMinutes(),
                report_name = encodeURIComponent(this.model.get('name') || 'report') + 
                                '_' + now_str,
                report_spec = JSON.stringify(this.model),
                $form = $('<form method="post" action="/report/'+report_name+'.csv"></form>')
                            .append($('<input type="hidden" name="report_spec">').val(report_spec));

            $('body').append( $form );
            $form.submit();


        },
        report_name_changed: function( event ) {
            this.model.set( {name:$(event.target).val() } );
        },
        render: function(){
            // update the name field with the report name

            if ( this.model.can_display_table() ){
                $( ".report_title_header_js" ).show();
            }
        }
    });
});


function field_dragger(options) {
    var $current_target_th,
        current_insert_before,
        $moving_helper,
        target_model,
        insert_before,
        hovering_over_group_by,
        hovering_over_extra_columns,
        row_position,
        initial_th_position,
        initial_event,
        create_moving_helper = function(){
            var moving_helper = $('<div></div>').
                                addClass('moving_helper').
                                addClass('column').
                                addClass('ui-state-default').
                                html( options.draggable.html() ).
                                width( options.draggable.width()).
                                height( options.draggable.height() ).
                                appendTo($('html')),
                $moving_content = moving_helper.find('.DataTables_sort_wrapper');

            // Hack to account for the table headers wrapper their content
            // in DataTables_sort_wrapper divs
            if ( $moving_content.length ){
                moving_helper.html( $moving_content.html() );
            }

            
            $('.column_options', moving_helper).remove();



            // Define a Function
            moving_helper.data('reset', function(){
                moving_helper.animate({top:initial_th_position.top,
                                       left:initial_th_position.left,
                                       opacity:0},
                                       function(){
                                            $('.moving_helper').remove();
                                            moving_helper.remove();
                                       });
            });

            moving_helper.data('completed', function(){
                $('.moving_helper').remove();
                moving_helper.remove();
            });

            return moving_helper;
        };
    
    self = {
        helper: function() {
            var helper = $('<div></div>')
                            .width(options.draggable.width());
            
            return helper;
        },
        drag: function( event, ui ) {
            var $drop_target = $('.drop_target.ui-state-hover'),
                $target_th = $drop_target.closest('th'),
                $helper = ui.helper,
                helper_position = {left:event.pageX - initial_event.pageX + initial_th_position.left, 
                                   top:event.pageY - initial_event.pageY + initial_th_position.top},
                $insert_column;

            hovering_over_group_by = $('.ui-add-grouping-hover').length;
            hovering_over_extra_columns = $('.ui-extra_columns-hover').length;

            $moving_helper.css('top', helper_position.top );
            $moving_helper.css('left', helper_position.left );

            // If we're hovering over a group by we'll pretend
            // we arent' hovering over an extended header as well
            if ( hovering_over_group_by ){
                $target_th = null;
            }

            if ( $drop_target ){
                insert_before = $drop_target.data('before');
            }

            // check if we're in the correct dragging state already
            if ( $target_th && 
                 $current_target_th && 
                 $current_target_th.is( $target_th ) &&
                 current_insert_before === insert_before) {
                return;
            }
            $current_target_th = $target_th;
            current_insert_before = insert_before;

            // store /clear for later use
            target_model = $target_th && $target_th.data('model');

            // remove the old column marker
            $('.insert_bar_wrapper').remove();

            if ( target_model ) {
                // Target has been acquired

                $insert_column = $( '<div class="insert_bar_wrapper"><div class="insert_bar"></div></div>' );

                $target_th.append( $insert_column );


                if ( current_insert_before ){
                    $insert_column.position( { of: $target_th.find('.DataTables_sort_wrapper'),
                                               my: 'left top',
                                               at: 'left top',
                                               offset: '-13 -5'} );
                } else {
                    $insert_column.position( { of: $target_th.find('.DataTables_sort_wrapper'),
                                               my: 'right top',
                                               at: 'right top',
                                               offset: '1 -5'} );
                }
            } else {
                // Target has been lost
            }

        },
        start: function( event, ui ) {
            //$(this).show();
            row_position = $('.report tr.main_header_row th:first').position();
            initial_th_position = $(this).position();
            initial_event = event;

            // created the helpers
            $moving_helper = create_moving_helper();

            // create droppable hover targets for the remaining column headers
            $( '.report_table thead .main_header_row th').each( 
                function(index, th){
                    var $drop_wrapper = $('<div class="drop_wrapper"></div>')
                                           .width($(th).width()),
                        $left_drop_target = $('<div class="drop_target"></div>')
                                            .width($(th).outerWidth()/2),
                        $right_drop_target = $left_drop_target.clone( true );

                    $left_drop_target.data('before', true).
                                      css({float:'left'})
                                      .droppable({ hoverClass: "ui-state-hover",
                                                   greedy: true});
                    $right_drop_target.data('before', false)
                                      .css({float:'left', 'margin-right':-20})
                                      .droppable({ hoverClass: "ui-state-hover",
                                                   greedy: true});

                    $(th).append( $drop_wrapper.append($left_drop_target)
                                               .append($right_drop_target) );
            });

            $( '.report_fields')
                .droppable({
                    hoverClass: "ui-extra_columns-hover",
                    greedy: true});

            $( '.add_grouping_row_js')
                .droppable({
                    hoverClass: "ui-add-grouping-hover",
                    greedy: true});

        },
        stop: function( event, ui ) {
            var source = $(this).data('model'),
                completed = false;

            // Hide all the drag related components
            $('.drop_wrapper').remove();

            // Unhide the column ( unless it was actually moved? )
            $(this).show();
            $('td[field_id="' + $(this).attr('field_id') + '"]').show();

            if ( hovering_over_group_by ){
                // Dragging a column into the grouping section
                completed = options.report_model.add_group_by( source );
            } else if ( target_model ){
                // Dragging a column and ending in the report table
                completed = options.report_model.column_moved( source, target_model, !insert_before ); 
            } else if ( hovering_over_extra_columns ){
                // Dragging a column and ending outside of the report table
                completed = options.report_model.column_removed( source);
            } else {
                completed = false;
            }

            if ( completed ) {
                $moving_helper.data('completed')();
            } else {
                $moving_helper.data('reset')();
            }

            // clear the target model now that this drag has completed
            target_model = null;
        },
        distance: 15
    }
    return self;
}

;// Beginning /res/js/v2/backbone/enrollment_flow/backbone.models.enrollmentflow.js:
$(function(){
    
    window.PageModel = Backbone.Model.extend({
        defaults: function(){
            return {
                "title": '',
                "path": '',
                "page_key": '',
                "draggable": true,
                "removable": false,
                "editable": false,
                "custom": false,
                "homeContainer": null // PageCollection
            };
        }
    });
    
    window.PageCollection = Backbone.Collection.extend({
        "model": PageModel
    });
    
    window.EnrollmentFlowStepHolderModel = Backbone.Model.extend({
        defaults: function(){
            return {
                "pages": null, // PageCollection
                "warning": '',
                "showWarning": false,
                "canShowWarning": true
            };
        }
    });
    
    window.EnrollmentFlowCustomSelectorModel = Backbone.Model.extend({
        defaults: function(){
            return {
                "pages": null, // PageCollection
                "title": '',
                "help": '',
                "showHelp": true
            };
        }
    });
    
    window.EnrollmentFlowCustomModel = Backbone.Model.extend({
        defaults: function(){
            return {
                "customFlowModel": null, // EnrollmentFlowCustomSelectorModel
                "presetStepsModel": null, // EnrollmentFlowStepHolderModel
                "customStepsModel": null, // EnrollmentFlowStepHolderModel
                "pageModels": null, // PageCollection
                "presets": null // Dictionary with keys of EnrollmentFlowOptionModel types. Each value
                                // is a dictionary with keys of "selectedPages", "unselectedRegularPages",
                                // "unselectedCustomPages" and values of PageCollection.
            };
        }
    });
    
    window.EnrollmentFlowOptionModel = Backbone.Model.extend({
        defaults: function(){
            return {
                "selected": false,
                "type": 0,
                "title": "Highest Conversion",
                "pages": ["Signup Page", "Payment", "Personal Profile", "Finished"]
            };
        }
    });
    // Set constants
    EnrollmentFlowOptionModel['TYPES'] = {
        'highest': 0,
        'detailed': 1,
        'custom': 2
    };
    
    window.EnrollmentFlowOptionCollection = Backbone.Collection.extend({
        "model": EnrollmentFlowOptionModel
    });
    
    window.EnrollmentFlowAppModel = Backbone.Model.extend({
        defaults: function(){
            return {
                "custom": false,
                "selectorModel": null, // EnrollmentFlowSelectorModel
                "customPaneModel": null // EnrollmentFlowCustomModel
            };
        }
    });
    
    window.EnrollmentFlowSelectorModel = Backbone.Model.extend({
        defaults: function(){
            return {
                "selected": null, // EnrollmentFlowOptionModel
                "options": null // EnrollmentFlowOptionCollection
            }
        }
    });
});
;// Beginning /res/js/v2/backbone/enrollment_flow/backbone.views.enrollmentflow.js:
$(function(){
    
    function dismissMessage($message, callbackFun){
        
        // This method is necessary because if the $message is
        // contained within something hidden then calling .slideUp 
        // won't actually make sure that $message is hidden when
        // the ancestor becomes visible. However, we still want to
        // use .slideUp in case $message can be seen and we want a 
        // nifty animation.
        function hideFix(){
            $message.hide()
            if(callbackFun){
                callbackFun();
            }
        }
        
        $message.slideUp('fast', hideFix);
    }
    
    function draggedAwayHelper(data, pages){
        
        // Remove the model from the collection. If we're removing it from the
        // same collection we're adding it to (i.e. to change its position) then
        // do the change silently so we don't needlessly render the pages twice.
        //
        // Note also that the jQuery draggable plugin will throw an exception
        // because it will try to do something without expecting the dragged
        // DOM element to have been removed. This doesn't seem to cause any
        // issues but be aware of this.
        var model = data["model"];
        var options = pages == data["collectionAdd"] ? {"silent": true} : {};
        pages.remove(model, options);
        
        // Add the model to the target collection.
        var collectionAdd = data["collectionAdd"];
        var insertionPoint = collectionAdd.indexOf(data["modelBefore"]) + 1;
        data["collectionAdd"].add(model, {"at": insertionPoint});
    }
    
    function draggedHomeHelper(data){
        var model = data["model"];
        var collectionRemove = data["collectionRemove"];
        var collectionAdd = model.get("homeContainer");
        
        var modelAlreadyHome = !!collectionAdd.getByCid(model.cid);
        
        if(!modelAlreadyHome){
            collectionRemove.remove(model);
            collectionAdd.add(model);
        }
    }
    
    window.PageView = Backbone.View.extend({
        template: _.template($('#page_view').html()),
        className: "page_view page_view_js",
        events: {
            "click .remove_js": "clickRemove",
            "click .edit_button_js": "clickEdit",
            "click .view_button_js": "clickView"
        },
        initialize: function(options){
            
            _.bindAll(this, "clickRemove", "clickEdit", "clickView");
            
            // Render the view
            this.render();
        },
        render: function(){
            var $el = this.$(this.el);
            $el.html(this.template(this.model.toJSON()));
            
            // Make sure this is draggable, if it should be
            var model = this.model;
            if(model.get("draggable")){
                $el.draggable({
                    // Clone is necessary since otherwise the element can get stuck if its contained within
                    // a div with scrollbars. Stuck as in it can't be dragged out of the div.
                    "helper": "clone",
                    "start": function(event, ui){
                        // Since we're cloning the helper, we'll have to explicitly set its width to make
                        // sure it's correct.
                        var $this = $(this);
                        ui.helper.css("width", $this.width());
                        
                        // Hide the original element and any following arrows if necessary.
                        $this.hide();
                        var $next = $this.next();
                        if($next.length && $next.find(".flow_arrow_js").length){
                            $next.hide();
                        }
                        
                        // Trigger the custom event for dragging starting
                        $el.trigger("draggingStart.enrollment_flow", {"model": model});
                    },
                    "stop": function(event, ui){
                        // Make sure to show the original element and the adjacent arrow if need be
                        var $this = $(this);
                        $this.show();
                        var $next = $this.next();
                        if($next.length && $next.find(".flow_arrow_js").length){
                            $next.show();
                        }
                    },
                    "scroll": false,
                    "handle": ".page_view_js",
                    "distance": 3,
                    "iframeFix": true,
                    "zIndex": 1000,
                    "revert": true,
                    "revertDuration": 0
                });
            }
        },
        clickRemove: function(event){
            event.preventDefault();
            this.destroyModel(true);
        },
        destroyModel: function(promptUser){
            if(promptUser === undefined){
                promptUser = true;
            }
            
            var shouldDelete = true;
            if(promptUser){
                shouldDelete = confirm("Warning: Deleting this page is permanent an cannot be undone. Do you wish to continue?");
            }
            
            if(shouldDelete){
                // HACK: Call destroy once will remove the model from two of the three collections,
                // calling it again removes it from the third. When called the first time the event
                // doesn't appear to be triggered at all in the third collection, rather than the
                // callback just failing. I (Ian) spent a while on this but don't have anymore time
                // to look at this now. We should come back to this if it becomes a problem.
                this.model.destroy();
                this.model.destroy();
            }
        },
        clickEdit: function(event){
            event.preventDefault();
            this.editPage();
        },
        editPage: function(){
            var url = "/customizations/enrollment/edit/" + this.model.get("page_key")
            $('<div>').ssdialog({
                'title' : this.model.get("title"),
                'width' : 'auto',
                'save_url' : url,
                'content' : {
                    'url' : url,
                    'refresh_on_show': true
                },
                'buttons' : {
                    "Save" : null,
                    "Save and Close" : function(namespace){
                        this[namespace]('save');
                    }
                }
            });
        },
        clickView: function(event){
            event.preventDefault();
            this.viewPage();
        },
        viewPage: function(){
            
            var title = this.model.get("title");
            
            $('<div>').ssdialog({
                'title' : title,
                'dynamic_width' : true,
                'content' : {
                    'url' : this.model.get("path") + "?view=true",
                    'refresh_on_show': true,
                    'disabled' : true
                },
                'buttons': {
                    'Save': null,
                    'Cancel': null,
                    'OK': function(namespace){
                        this[namespace]('hide');
                    }
                }
            });
        }
    });
    
    window.EnrollmentFlowStepHolderView = Backbone.View.extend({
        template: _.template($('#enrollment_flow_step_holder_view').html()),
        className: "enrollment_flow_step_holder_view enrollment_flow_step_holder_view_js",
        events: {
            "click .dismiss": "clickDismiss"
        },
        warningShowing: false,
        initialize: function(options){
            
            _.bindAll(this, "clickDismiss", "draggedAway", "draggedHome");
            
            options = options || {};
            var settings = {
                "warningCheckFuns": []
            };
            $.extend(true, settings, options);
            this.settings = settings;
            
            // Bind the "pages"' various change events to render
            var pages = this.model.get("pages");
            pages.bind("reset", this.render, this);
            pages.bind("change", this.render, this);
            pages.bind("add", this.render, this);
            pages.bind("remove", this.render, this);
            
            // Bind to the dragging on the collection
            pages.bind("draggedAway.enrollment_flow", this.draggedAway);
            pages.bind("draggedHome.enrollment_flow", this.draggedHome);
            
            // Render the view
            this.render();
        },
        render: function(){
            var $el = this.$(this.el);
            $el.html(this.template(this.model.toJSON()));
            
            // Create the child views
            this.views = {"pageViews": []};
            var context = this;
            this.model.get("pages").forEach(function(pageModel){
                var pageView = new PageView({"model": pageModel});
                context.views["pageViews"].push(pageView);
            });
            
            // Make sure to hide the help section if need be
            if(!this.model.get("canShowWarning") || !this.model.get("showWarning")){
                this.$("warning_js").hide();
            }
            
            // Render the child views
            var $steps = this.$(".steps_js");
            $.each(this.views["pageViews"], function(i, pageView){
                $steps.append(pageView.el);
            });
            
            // Make sure to set this as a droppable target
            $steps.droppable({
                "drop": function(event, ui){
                    $el.trigger("dropped.enrollment_flow");
                },
                "accept": ".page_view_js",
                "tolerance": "pointer",
                "hoverClass": "hovered"
            });
            
            // Make sure to hide or display the warning section
            this.checkWarningConditions();
        },
        clickDismiss: function(event){
            event.preventDefault();
            this.dismissWarning();
        },
        dismissWarning: function(permanent){
            
            if(permanent===undefined){
                permanent = true;
            }
            
            var $warning = this.$(".holder_warning");
            var $stepsContainer = this.$('.steps_js');
            dismissMessage($warning, function(){
                $stepsContainer.removeClass("warning_showing");
            });
            this.warningShowing = false;
            
            // We don't want to show the warning again, but set this silently
            // since we just hid the warning with an animation and we don't
            // want to rerender.
            if(permanent){
                this.model.set({"canShowWarning": false}, {"silent": true});
            }
        },
        showWarning: function(){
            if(this.model.get("canShowWarning")){
                var $warning = this.$(".holder_warning");
                var $stepsContainer = this.$('.steps_js');
                $stepsContainer.addClass("warning_showing");
                if(this.warningShowing){
                    // The warning was already showing, so just show it quickly
                    // so it doesn't appear to disappear and then slide down again.
                    $warning.show();
                } else {
                    $warning.slideDown("fast", function(){
                        // This callback is necessary because if this slides down
                        // while hidden it won't be visible in all browsers.
                        $warning.show();
                    });
                }
                this.warningShowing = true;
            }
        },
        addWarningCheckFun: function(warningCheckFun){
            this.settings["warningCheckFuns"].push(warningCheckFun);
        },
        checkWarningConditions: function(){
            var showWarning = false;
            var context = this;
            $.each(this.settings["warningCheckFuns"], function(i, checkFun){
                checkFun = _.bind(checkFun, context);
                showWarning = showWarning || checkFun();
            });
            if(showWarning){
                this.showWarning();
            } else {
                this.dismissWarning(false);
            }
        },
        draggedAway: function(model, data, options){
            draggedAwayHelper(data, this.model.get("pages"));
        },
        draggedHome: function(model, data, options){
            draggedHomeHelper(data);
        }
    });
    
    window.EnrollmentFlowCustomSelectorView = Backbone.View.extend({
        template: _.template($('#enrollment_flow_custom_selector_view').html()),
        className: "enrollment_flow_custom_selector_view enrollment_flow_custom_selector_view_js",
        events: {
            "click .dismiss" : "clickDismiss"
        },
        initialize: function(options){
            
            _.bindAll(this, "clickDismiss", "draggedAway", "draggedHome");
            
            // Bind the "pages"' various change events to render
            var pages = this.model.get("pages");
            pages.bind("reset", this.render, this);
            pages.bind("change", this.render, this);
            pages.bind("add", this.render, this);
            pages.bind("remove", this.render, this);
            
            // Bind to the dragging on the collection
            this.model.get("pages").bind("draggedAway.enrollment_flow", this.draggedAway);
            this.model.get("pages").bind("draggedHome.enrollment_flow", this.draggedHome);
            
            // Render the view
            this.render();
        },
        render: function(){
            var $el = this.$(this.el);
            $el.html(this.template(this.model.toJSON()));
            var model = this.model;
            
            // Make sure to hide the help section if need be
            if(!model.get("showHelp")){
                this.$(".custom_flow_help_js").hide();
            }
            
            // Create the child views
            this.views = {"pageViews": []};
            var context = this;
            model.get("pages").forEach(function(pageModel){
                var pageView = new PageView({"model": pageModel});
                context.views["pageViews"].push(pageView);
            });
            
            // Render the child views
            var $steps = this.$(".steps_js");
            var numSteps = this.views["pageViews"].length;
            $.each(this.views["pageViews"], function(i, pageView){
                $steps.append(pageView.el);
                var pageModel = pageView.model;
                
                // Append the arrows between steps
                if(i+1<numSteps){
                    
                    // You may want to consider moving the definition of the HTML contents of $arrow to template
                    var $arrow = $('<div class="droppable_js droppable_target droppable_target_js"></div><div class="droppable_js second_droppable_target second_droppable_target_js"></div><div class="flow_arrow flow_arrow_js"></div><div class="draggable_hidden"><div class="draggable_ghost"></div><div class="flow_arrow"></div></div>');
                    var $container = $('<div class="draggable_container draggable_container_js">');
                    $container.append($arrow);
                    var $droppable = $container.find(".droppable_target_js");
                    
                    var $secondDroppable = $container.find(".second_droppable_target_js");
                    
                    $container.bind("try_drop.enrollment_flow", function(event, data){
                        if($(this).hasClass("hovered")){
                            $el.trigger("dropped.enrollment_flow", {"modelBefore": pageModel, "collection": model.get("pages")});
                        }
                    });
                    
                    /*
                     * The code here for drag and drop can be a bit confusing. The issue is that as a draggable hovers over
                     * something that can be dropped upon, the area that can be dropped upon needs to expand (we show an
                     * outline where the draggable can go, and if you hover over that area it should still count as something
                     * that can be dropped upon). However, when a droppable area would expand, the jQuery plugin didn't update
                     * where the draggable could be dropped.
                     * 
                     * This was solved by having two droppable areas for each place something could be dropped; one representing
                     * the unexpanded area and the other representing the expanded area. Something to be aware of is that these
                     * two areas can overlap for different containers. 
                     * 
                     * As a development note, it can help when working with this code to give these two areas 0.5 opacity and
                     * different background colours to see what's going on.
                     */
                    
                    $droppable.droppable({
                        "drop": function(event, ui, stop){
                            context.$(".draggable_container_js").trigger("try_drop.enrollment_flow");
                        },
                        "accept": ".page_view_js",
                        "tolerance": "pointer",
                        "over": function(event, ui){
                            var $containers = context.$(".draggable_container_js");
                            $previousContainers = $container.prevAll(".draggable_container_js");
                            if(!$previousContainers.hasClass("hovered")){
                                $containers.removeClass("hovered");
                                $container.addClass("hovered");
                            }
                        },
                        "out": function(event, ui){
                            var contained = false;
                            var $droppables = context.$(".droppable_js");
                            $droppables.each(function(i, elem){
                                var $elem = $(elem);
                                contained = contained || $.ss.util.within_box(event.pageX, event.pageY, $elem);
                            });
                            if(!contained){
                                context.$(".draggable_container_js").removeClass("hovered");
                            }
                        }
                    });
                    
                    $secondDroppable.droppable({
                        "drop": function(event, ui, stop){
                            context.$(".draggable_container_js").trigger("try_drop.enrollment_flow");
                        },
                        "accept": ".page_view_js",
                        "tolerance": "pointer",
                        "over": function(event, ui){
                            var $containers = context.$(".draggable_container_js");
                            var $previousContainers = $container.prevAll(".draggable_container_js");
                            if($previousContainers.hasClass("hovered") || $container.hasClass("hovered")){
                                $containers.removeClass("hovered");
                                $container.addClass("hovered");
                            }
                        },
                        "out": function(event, ui){
                            var contained = false;
                            var $droppables = context.$(".droppable_js");
                            $droppables.each(function(i, elem){
                                var $elem = $(elem);
                                contained = contained || $.ss.util.within_box(event.pageX, event.pageY, $elem);
                            });
                            if(!contained){
                                context.$(".draggable_container_js").removeClass("hovered");
                            }
                        }
                    });
                    
                    $steps.append($container);
                }
            });
        },
        clickDismiss: function(event){
            event.preventDefault();
            this.dismissHelp();
        },
        dismissHelp: function(){
            var $help = this.$('.custom_flow_help_js');
            dismissMessage($help);
            
            // We don't want to show the help again, but set this silently
            // since we just hid the help with an animation and we don't
            // want to rerender.
            this.model.set({"showHelp": false}, {"silent": true});
        },
        draggedAway: function(model, data, options){
            draggedAwayHelper(data, this.model.get("pages"));
        },
        draggedHome: function(model, data, options){
            draggedHomeHelper(data);
        }
    });
    
    window.EnrollmentFlowCustomView = Backbone.View.extend({
        template: _.template($('#enrollment_flow_custom_view').html()),
        events: {
            "click .new_custom_steps_js": "clickNewStep"
        },
        initialize: function(options){
            
            _.bindAll(this, "clickNewStep");
            
            // Create the child views
            this.views = {
                "customFlowView": new EnrollmentFlowCustomSelectorView({"model":this.model.get("customFlowModel")}),
                "presetStepsView": new EnrollmentFlowStepHolderView({
                    "model": this.model.get("presetStepsModel"),
                    "warningCheckFuns": [function(){
                        // Show the warning if this contains the payment page
                        
                        var containsPayment = false;
                        var pageModels = this.model.get("pages").models;
                        for(var i in pageModels){
                            var pageModel = pageModels[i];
                            if(pageModel.get("title").toLowerCase() == "payment"){
                                containsPayment = true;
                                break;
                            }
                        }
                        
                        return containsPayment;
                    }]
                }),
                "customStepsView": new EnrollmentFlowStepHolderView({"model": this.model.get("customStepsModel")})
            };
            
            // Render the view
            this.render();
        },
        render: function(){
            this.$(this.el).html(this.template(this.model.toJSON()));
            
            // Render the child views
            this.$(".custom_location_js").html(this.views["customFlowView"].el);
            this.$(".preset_steps_js").html(this.views["presetStepsView"].el);
            this.$(".custom_steps_js").html(this.views["customStepsView"].el);
        },
        applyPreset: function(option){
            var preset = this.model.get("presets")[option];
            if(preset && option != EnrollmentFlowOptionModel['TYPES']['custom']){
                // Change the contents of the customFlowModel, presetStepModel, and customStepModel
                // to reflect one of the presets being applied. Note that we don't apply the change if
                // custom is selected because we want custom to be set to whichever preset was set last.
                this.model.get("customFlowModel").get("pages").reset(preset["selectedPages"].models);
                this.model.get("presetStepsModel").get("pages").reset(preset["unselectedRegularPages"].models);
                this.model.get("customStepsModel").get("pages").reset(preset["unselectedCustomPages"].models);
            }
        },
        clickNewStep: function(event){
            event.preventDefault();
            this.askNewButton();
        },
        askNewButton: function(){
              var context = this;
            
            var url = '/customizations/custom_page';
            $('<div>').ssdialog({
                'title' : "What is the name of the new step?",
                'width' : 'auto',
                'save_url' : url,
                'focus_input' : true,
                'save_on_enter' : true,
                'success_callback' : function(data){
                    if(data.success && (data.success.success === undefined || data.success.success)){
                        context.createNewButton(data.success.title, data.success.id, data.success.page_key);
                    } else {
                        alert(data.success.error);
                    }
                },
                'content' : {
                    'url' : url,
                    'refresh_on_show': true
                }
            });
        },
        createNewButton: function(title, id, page_key){
            // Make the new page
            var customStepsHolder = this.model.get("customStepsModel").get("pages");
            var newPage = new PageModel({
                "id": id,
                "title": title, 
                "draggable": true, 
                "removable": true, 
                "editable": true,
                "page_key": page_key,
                "homeContainer": customStepsHolder
            });
            newPage.urlRoot = "/customizations/custom_page_delete";
            
            // Make sure to add the new page to the presets
            var presets = this.model.get("presets");
            var highestCustomPages = presets[EnrollmentFlowOptionModel.TYPES["highest"]]["unselectedCustomPages"];
            var detailedCustomPages = presets[EnrollmentFlowOptionModel.TYPES["detailed"]]["unselectedCustomPages"];
            highestCustomPages.add(newPage);
            detailedCustomPages.add(newPage);
            
            // Add the new page to the custom steps holder
            customStepsHolder.add(newPage);
        }
    });
    
    window.EnrollmentFlowOptionView = Backbone.View.extend({
        selectedClass: "selected",
        className: "enrollment_flow_option_view",
        template: _.template($('#enrollment_flow_option_view').html()),
        events: {
            "click": "clickCallback"
        },
        initialize: function(options){
            
            // Add 'this' context for event callbacks
            _.bindAll(this, "clickCallback", "selectedChange");
            
            // Bind to 'selected' being changed
            this.model.bind("change:selected", this.selectedChange);
            
            // Render the view
            this.render();
        },
        render: function(){
            var $el = this.$(this.el);
            $el.html(this.template(this.model.toJSON()));
            
            // Make sure to set the selected class if necessary
            if(this.model.get("selected")){
                $el.addClass(this.selectedClass);
            }
            
            return this;
        },
        selectedChange: function(){
            var $el = this.$(this.el);
            if(this.model.get("selected")){
                $el.addClass(this.selectedClass);
            } else {
                $el.removeClass(this.selectedClass);
            }
        },
        clickCallback: function(event){
            // This is a hackish way of finding this, but under time constraints it works. Revise later if you want.
            var customSelected = this.$(this.el).parent().find(".enrollment_flow_option_view:last-child").hasClass("selected");
            
            if(this.model.get("type") != EnrollmentFlowOptionModel['TYPES']['custom'] && customSelected) {
                // The user is going from customized to another view, so confirm they want to do this.
                var confirmed = confirm("Switching to a preset flow will remove any changes you made to the customized flow. Do you wish to continue?");
                if(confirmed){
                    this.model.set({"selected":true});
                }
            } else {
                this.model.set({"selected":true}); 
            }
            
        }
    });
    
    window.EnrollmentFlowSelectorView = Backbone.View.extend({
        template: _.template($('#enrollment_flow_selector_view').html()),
        className: "enrollment_flow_selector_view",
        initialize: function(options){
            var context = this;
            // Make child views from the collection of EnrollmentFlowOptionModels and make sure
            // to bind to their selected change event.
            this.views = {"optionViews": []};
            this.model.get("options").forEach(function(optionModel){
                var optionView = new EnrollmentFlowOptionView({
                    "model": optionModel
                });
                context.views["optionViews"].push(optionView);
                optionModel.bind("change:selected", function(model, selected){
                    if(selected){
                        // Save the model of the selected view
                        context.model.set({"selected":model});
                        
                        // Make sure to set the others models as unselected. Note that we're triggering
                        // a change event within a callback for the event we're triggering, so be careful
                        // that you make no infinite loops. This change isn't done silently since the
                        // option views need to know if they're unselected.
                        context.model.get("options").map(function(model){
                            if(optionModel != model){
                                model.set({"selected":false});
                            }
                        });
                    }
                });
            });
            
            // Render the view
            this.render();
        },
        render: function(){
            this.$(this.el).html(this.template(this.model.toJSON()));
            var context = this;
            
            // Render the child views
            $.each(this.views["optionViews"], function(i, optionView){
                context.$(context.el).append(optionView.el);
            });
            
            return this;
        }
    });
    
    window.EnrollmentFlowAppView = Backbone.View.extend({
        template: _.template($('#enrollment_flow_page_view').html()),
        className: "enrollment_flow_app_view",
        events: {
            "draggingStart.enrollment_flow": "draggingStart",
            "dropped.enrollment_flow .enrollment_flow_custom_selector_view_js": "droppedAdded",
            "dropped.enrollment_flow .enrollment_flow_step_holder_view_js": "droppedRemoved"
        },
        draggedModel: null,
        initialize: function(options){
            
            _.bindAll(this, "optionSelected", "draggingStart", "droppedAdded", "droppedRemoved");
            
            // Models for the EnrollmentFlowStepHolderViews.
            // Note that the pages in the preset steps should be all of and only the pages not used in
            // customFlowModel.
            var presetStepsModel = new EnrollmentFlowStepHolderModel({
                "pages": new PageCollection(), 
                "warning": "To generate revenue, it is best to have the pay pane in the setup process.",
                "showWarning": false
            });
            var customStepsModel = new EnrollmentFlowStepHolderModel({
                "pages": new PageCollection(),
                "showWarning": false
            });
            
            var buildSteps = function(contextSteps, homeContainerPreset, homeContainerCustom){
                var steps = [];
                for(var i in contextSteps){
                    var stepJson = contextSteps[i];
                    if(stepJson.custom){
                        var urlRoot = "/customizations/custom_page_delete";
                    } else {
                        var urlRoot = "";
                    }
                    var pageModel = new PageModel({
                        "title": stepJson.title, 
                        "id": stepJson.id, 
                        "custom": stepJson.custom, 
                        "draggable": stepJson.draggable, 
                        "homeContainer": stepJson.custom ? homeContainerCustom : homeContainerPreset,
                        "removable": stepJson.custom,
                        "editable": stepJson.editable,
                        "page_key": stepJson.page_key,
                        "path": stepJson.path
                    });
                    pageModel.urlRoot = urlRoot;
                    steps.push(pageModel);
                }
                return steps;
            };
            
            var buildCollections = function(flowSteps, allSteps, homeContainerPreset, homeContainerCustom){
                var presetSteps = [];
                var unselectedRegular = [];
                var unselectedCustom = [];
                
                var isStepIn = function(step, testSteps){
                    var isIn = false;
                    for(var i in testSteps){
                        var testStep = testSteps[i];
                        if(testStep.id == step.id){
                            isIn = true;
                            break;
                        }
                    }
                    return isIn;
                };
                
                for(var i in allSteps){
                    var testStep = allSteps[i];
                    if(!isStepIn(testStep, flowSteps)){
                        if(testStep.get("custom")){
                            unselectedCustom.push(testStep);
                        } else {
                            unselectedRegular.push(testStep);
                        }
                    }
                }
                
                return [buildSteps(flowSteps, homeContainerPreset, homeContainerCustom), unselectedRegular, unselectedCustom];
            };
            
            // Models for the pages
            
            var presetPagesContainer = presetStepsModel.get("pages");
            var customStepsContainer = customStepsModel.get("pages");
            var allPresetSteps = buildSteps(ss_context.preset_steps, presetPagesContainer, customStepsContainer);
            var allCustomSteps = buildSteps(ss_context.custom_steps, presetPagesContainer, customStepsContainer);
            var allSteps = allPresetSteps.concat(allCustomSteps);
            
            // Preset Flows
            
            var stepHolder;
            
            stepHolder = buildCollections(ss_context.highest.steps, allSteps, presetPagesContainer, customStepsContainer);
            var highestPreset = new PageCollection(stepHolder[0]);
            var highestUnselectedRegular = new PageCollection(stepHolder[1]);
            var highestUnselectedCustom = new PageCollection(stepHolder[2]);
            
            stepHolder = buildCollections(ss_context.detailed.steps, allSteps, presetPagesContainer, customStepsContainer);
            var detailedPreset = new PageCollection(stepHolder[0]);
            var detailedUnselectedRegular = new PageCollection(stepHolder[1]);
            var detailedUnselectedCustom = new PageCollection(stepHolder[2]);
            
            stepHolder = buildCollections(ss_context.custom.steps, allSteps, presetPagesContainer, customStepsContainer);
            var customPreset = new PageCollection(stepHolder[0]);
            var customUnselectedRegular = new PageCollection(stepHolder[1]);
            var customUnselectedCustom = new PageCollection(stepHolder[2]);
            
            // Model for the EnrollmentFlowCustomSelectorView
            var customFlowModel = new EnrollmentFlowCustomSelectorModel({
                "pages": new PageCollection(),
                "title": "Custom Flow",
                "help": "Drag and drop sections to rearrange the list. Pull new steps from the right. Steps can't be put before the signup page or after the finished page.",
                "showHelp": true
            });
            
            // Model for the EnrollmentFlowCustomView
            var presets = {};
            presets[EnrollmentFlowOptionModel["TYPES"]["highest"]] = {
                "selectedPages": highestPreset,
                "unselectedRegularPages": highestUnselectedRegular,
                "unselectedCustomPages": highestUnselectedCustom
            };
            presets[EnrollmentFlowOptionModel["TYPES"]["detailed"]] = {
                "selectedPages": detailedPreset,
                "unselectedRegularPages": detailedUnselectedRegular,
                "unselectedCustomPages": detailedUnselectedCustom
            };
            presets[EnrollmentFlowOptionModel["TYPES"]["custom"]] = {
                "selectedPages": customPreset,
                "unselectedRegularPages": customUnselectedRegular,
                "unselectedCustomPages": customUnselectedCustom
            };
            var customPaneModel = new EnrollmentFlowCustomModel({
                "customFlowModel": customFlowModel,
                "presetStepsModel": presetStepsModel,
                "customStepsModel": customStepsModel,
                "pageModels": new PageCollection(),
                "presets": presets
            });
            
            // Models for the EnrollmentFlowOptionViews
            var highestModel = new EnrollmentFlowOptionModel({
                "selected": ss_context.current_selected_id == ss_context.highest.id,
                "type": EnrollmentFlowOptionModel.TYPES['highest'],
                "id": ss_context.highest.id,
                "title": "Highest Conversion",
                "pages": ["Signup Page", "Payment", "Personal Profile", "Finished"]
            });
            var detailedModel = new EnrollmentFlowOptionModel({
                "selected": ss_context.current_selected_id == ss_context.detailed.id,
                "type": EnrollmentFlowOptionModel.TYPES['detailed'],
                "id": ss_context.detailed.id,
                "title": "Most Detailed",
                "pages": ["Signup Page", "Personal Profile", "Connect", "Payment", "Finished"]
            });
            var customizedModel = new EnrollmentFlowOptionModel({
                "selected": ss_context.current_selected_id == ss_context.custom.id,
                "type": EnrollmentFlowOptionModel.TYPES['custom'],
                "id": ss_context.custom.id,
                "title": "Customized",
                "pages": ["Signup Page", "...", "...", "...", "Finished"]
            });
            var optionCollection = new EnrollmentFlowOptionCollection([highestModel, detailedModel, customizedModel]);
            
            var selectedEnrollmentFlowOptionModel;
            if(highestModel.get("selected")){
                presetStepsModel.get("pages").reset(highestUnselectedRegular.models);
                customStepsModel.get("pages").reset(highestUnselectedCustom.models);
                customFlowModel.get("pages").reset(highestPreset.models);
                selectedEnrollmentFlowOptionModel = highestModel;
            } else if(detailedModel.get("selected")){
                presetStepsModel.get("pages").reset(detailedUnselectedRegular.models);
                customStepsModel.get("pages").reset(detailedUnselectedCustom.models);
                customFlowModel.get("pages").reset(detailedPreset.models);
                selectedEnrollmentFlowOptionModel = detailedModel;
            } else if(customizedModel.get("selected")){
                presetStepsModel.get("pages").reset(customUnselectedRegular.models);
                customStepsModel.get("pages").reset(customUnselectedCustom.models);
                customFlowModel.get("pages").reset(customPreset.models);
                selectedEnrollmentFlowOptionModel = customizedModel;
            }
            
            // Model for the EnrollmentFlowSelectorView
            var selectorModel = new EnrollmentFlowSelectorModel({
                "selected": selectedEnrollmentFlowOptionModel,
                "options": optionCollection
            });
            
            // Creates the model for this view
            this.model = new EnrollmentFlowAppModel({
                "custom": customizedModel.get("selected"),
                "selectorModel": selectorModel,
                "customPaneModel": customPaneModel
            });
            
            // Update the child views
            this.views = {
                "selectorView" : new EnrollmentFlowSelectorView({
                    "model": selectorModel
                }),
                "customPaneView" : new EnrollmentFlowCustomView({
                    "model": customPaneModel
                })
            };
            
            // Binds to a change in the value of custom
            this.model.bind("change:custom", this.setCustomSectionVisibility, this);
            
            // Binds to the selected option changing
            var context = this;
            this.model.get("selectorModel").bind("change:selected", function(selectorModel, optionModel){
                this.optionSelected(optionModel.get("type"));
            }, this);
            
            // Binds to a change in the selected option
            var context = this;
            optionCollection.forEach(function(optionModel){
                optionModel.bind("change:selected", function(model, selected){
                    if(model.get("type") == EnrollmentFlowOptionModel.TYPES['custom'] && selected){
                        context.model.set({"custom":true});
                    } else {
                        context.model.set({"custom":false});
                    }
                });
            });
            
            // Render the view
            this.render();
        },
        render: function(){
            $(this.el).html(this.template(this.model.toJSON()));
            this.setCustomSectionVisibility();
            
            // Render the child views
            this.$(".flow_selectors_js").html(this.views["selectorView"].el);
            this.$(".custom_flow_js").html(this.views["customPaneView"].el);
            
            return this;
        },
        setCustomSectionVisibility: function(){
            var $customSection = this.$('.enrollment_custom_js');
            if(!this.model.get('custom')){
                $customSection.hide();
            } else {
                $customSection.show();
            }
            return this;
        },
        save: function(){
            var data = {
                "selected": this.model.get("selectorModel").get("selected").id,
                "flow": this.model.get("customPaneModel").get("customFlowModel").get("pages").pluck("id")
            };
            
            // Add the loading animation
            $("#main_content").html("<div class='loading'></div>");
            
            $.ajax({
                url: document.URL,
                type: 'PUT',
                data: data,
                success: function(){
                    window.location.reload();
                },
                error:  function(){
                    alert("We're sorry, but there was an error processing your request. Please try again later.");
                    window.location.reload();
                }
            });
        },
        optionSelected: function(option){
            this.views["customPaneView"].applyPreset(option);
        },
        draggingStart: function(event, data){
            var model = data['model'];
            this.draggedModel = model;
        },
        droppedAdded: function(event, data){
            var collection = this.model.get("customPaneModel").get("customFlowModel").get("pages");
            var draggedModel = this.draggedModel;
            draggedModel.trigger("draggedAway.enrollment_flow", draggedModel, {
                "collectionAdd": collection,
                "modelBefore": data["modelBefore"],
                "model": draggedModel
            }, {});
        },
        droppedRemoved: function(event, data){
            var collection = this.model.get("customPaneModel").get("customFlowModel").get("pages");
            var draggedModel = this.draggedModel;
            draggedModel.trigger("draggedHome.enrollment_flow", draggedModel, {
                "collectionRemove": collection,
                "model": draggedModel
            });
        }
    });
});
;// Beginning /res/js/v2/backbone/multitable/backbone.models.multitable.js:
$(function(){
    window.MultitableAppModel = Backbone.Model.extend({
        
        defaults: function(){
            return {
                selected: 1,
                menu_items: {
                    1 : "Placeholder"
                }
            };
        }
        
    });
});
;// Beginning /res/js/v2/backbone/multitable/backbone.views.multitable.js:
$(function(){
    
    window.MultitableAppView = Backbone.View.extend({
        template: _.template($('#multitable_view').html()),
        currentlyChangingTables: false,
        events: {
            "click .selectors a": "clickSelector"
        },
        initialize: function(options){
            _.bindAll(this, "selectedChanged", "clickSelector");
            this.model.bind("change:selected", this.selectedChanged, this);
            var context = this;
            
            // Set a callback function for dynamically changing the width of the table
            // columns so that if the table is smaller than the container they will
            // expand. This callback is added to each dataTable by a bit of a roundabout
            // way since there's no exposed API to set the draw callback after initialization.
            this.$(".data_table").each(function(){
                var $this = $(this);
                
                // The callback function for resizing the columns and container height
                var resize_columns_and_height = function(){
                    // The check for fnGetData is a bit of a hack to try and guess if the table's been
                    // rendered yet.
                    if(!$this.data("multitable.setting_width") && $this.fnGetData){
                        
                        // Make sure the height of the container never shrinks
                        var $table_container = $this.closest(".table_container");
                        var $data_table_wrapper = $this.parent();
                        if($data_table_wrapper.outerHeight() > $table_container.height()){
                            $table_container.css("min-height", $data_table_wrapper.outerHeight());
                        }
                        
                        $this.data("multitable.setting_width", true);
                        var desired_width = context.$(".table").width();
                        var headers = $this.find('th');
                        var current_width = $this.width();
                        if(current_width < desired_width){
                            // The columns are too small to fill the table, so make them bigger
                            var needed = desired_width - current_width;
                            var added_to_each = Math.floor(needed / headers.length);
                            var extra_pixels = needed % headers.length;
                            
                            // If the table is not displayed initally we can't find the current width.
                            // Instead, make sure to use this correction that represents the difference
                            // in width between the th and the containing div. Also, if hidden we'll need
                            // to make sure to add another extra_pixel to make up for the missing border
                            // on the far right.
                            var hidden_correction = current_width ? 0:-(headers.outerWidth()-1);
                            if(current_width==0){
                                extra_pixels++;
                            }
                            
                            
                            headers.each(function(){
                                var div_for_width = $(this).children();
                                var new_width = div_for_width.width() + added_to_each + hidden_correction;
                                if(extra_pixels){
                                    new_width++;
                                    extra_pixels--;
                                }
                                div_for_width.width(new_width);
                            });
                        }
                        $this.data("multitable.setting_width", false);
                    }
                };
                
                // The table may or may not even be initialized at this point, so check until
                // it is and then add the callback.
                var interval = 200;
                var t = setInterval(function(){
                    if($this.dataTableSettings){
                        
                        // Run the callback once here to make sure the columns are initialized. The
                        // callback might be run naturally anyway, but we can't depend on the timing
                        // of that.
                        resize_columns_and_height();
                        
                        // Set the callback
                        var data_table = $this.dataTable();
                        data_table.fnSettings().aoDrawCallback.push({
                            "sName": "multitable_col_and_height_fixer",
                            "fn": resize_columns_and_height
                        });
                        
                        // Stop running this function periodically
                        clearInterval(t);
                    }
                }, interval);
            });
            
            this.render();
        },
        render: function(){
            var $content = $(this.template(this.model.toJSON()));
            var $el = $(this.el);
            var $tables = this.$(".table").detach();
            
            $el.html($content);
            $el.find(".table_container").html($tables);
            
            // Hide the 'processing' div because it isn't removed properly, but I don't want to
            // change the logic of how all the tables are rendered. -Ian hack
            this.$(".dataTables_processing").hide();
            
            // Give each table a class corresponding to the menu_item key
            var keys = [];
            var selected = this.model.get("selected");
            var menu_items = this.model.get("menu_items");
            for(var i in menu_items){
                keys.push(i);
            }
            this.$(".table").each(function(i){
                $(this).addClass("multitable_" + keys[i]);
                
                // Mark as selected if needed
                if(keys[i] == selected){
                    $(this).addClass("selected");
                }
            });
            
            return this;
        },
        clickSelector: function(event){
            event.preventDefault();
            if(!this.currentlyChangingTables){
                var $target = $(event.target);
                var key = $target.prop("id");
                this.$(".selectors li").removeClass("selected");
                $target.closest("li").addClass("selected");
                this.model.set({"selected": key});
            }
            return this;
        },
        selectedChanged: function(model, selected){
            // We fade out one table then fade the other in, making sure to
            // set the min-height of the parent so it doesn't shrink oddly when switching
            // between tables and that the page doesn't jump around. We also set 
            // 'currentlyChangingTables' while the animations
            // are happening to disable the user trying to go to another table too quickly.
            var $el = this.$(this.el);
            var context = this;
            context.currentlyChangingTables = true;
            var tempHeight = this.$(".table.selected").height();
            
            var current_min_height = $el.css("min-height") ? parseInt($el.css("min-height"), 10) : 0;
            if(current_min_height < tempHeight){
                $el.css("min-height", tempHeight);
            }
            
            this.$(".table.selected").children().fadeOut("fast", function(){
                $(this).parent().removeClass("selected");
                context.$(".table.multitable_" + selected).addClass("selected");
                context.$(".table.multitable_" + selected).children().fadeIn("fast", function(){
                    context.currentlyChangingTables = false;
                });
            });
            
            return this;
        }
    });
});
;// Beginning /res/js/v2/backbone/input_options/backbone.models.inputoptions.js:
$(function(){
    window.InputOptionsAppModel = Backbone.Model.extend({
        
        defaults: function(){
            return {
                selected: 0, // The index of the selected input in 'inputs', starting with 0
                inputs: $(), // jQuery object representing the 'input' objects
                descriptions: [] // Descriptions for the inputs; a parallel array with 'inputs'
            };
        }
        
    });
});
;// Beginning /res/js/v2/backbone/input_options/backbone.views.inputoptions.js:
$(function(){
    
    window.InputOptionsAppView = Backbone.View.extend({
        template: _.template($('#input_options_view').html()),
        className: "input_options_view",
        events: {
            "click .input_container": "_click_input_container"
        },
        initialize: function(options){
            
            _.bindAll(this, "_click_input_container");
            
            // We expect that the 'input's and 'span's are already in
            // the element so we pull them out and put them in our model,
            // then we're free to call our render function.
            this.model = new InputOptionsAppModel({
                selected: 0,
                inputs: this.$("input, select"),
                descriptions: this.$("span")
            });
            
            // Bind the render function to a change in selected
            this.model.bind("change:selected", this.render, this);
            
            // Render the view
            this.render();
            
            return this;
        },
        render: function(){
            // Render the template and put the result in the DOM
            $(this.el).html(this.template(this.model.toJSON()));
            
            // Add the inputs back in and set the value of the radio button
            var model = this.model;
            this.$(".input_container").each(function(i, elem){
                var $this = $(this);
                var $input = $(model.get("inputs").get(i));
                var $input_container = $this.find(".input_container_input");
                var $radio = $this.find("input[name=input_options_app_selected]");
                var selected = model.get("selected");
                
                // Prepare the input
                if(selected == i){
                    $input.prop("disabled", false);
                    if($input.prop("type") != "select-one"){
                        $input.addClass("required");
                    }
                } else {
                    $input.prop("disabled", true);
                    $input.removeClass("required").removeClass("error");
                }
                
                // Add the input
                $input_container.empty();
                if(selected != i){
                    // Clicking on a disabled input will eat the click event and it won't
                    // propagate. We want to be able to catch the event when the user clicks
                    // on it, so we put a transparent and absolutely positioned div over it
                    // that can be clicked instead.
                    $input_container.html($("<div class='disabling_div'></div>"));
                }
                $input_container.append($input);
                
                // Set the value of the radio button
                var radio_value = "selected_" + $input.prop("name");
                $radio.prop("value", radio_value);
            });
            
            return this;
        },
        set_selected_option: function(selected){
            this.model.set({"selected":selected});
        },
        _click_input_container: function(event){
            var selected = $(event.target).closest(".input_container").index();
            this.set_selected_option(selected);
        }
    });
    
});
;// Beginning /res/js/v2/backbone/breadcrumbs/breadcrumb.views.js:
$(function(){
    window.ss = window.ss || {};
    window.ss.views = window.ss.views || {};
    window.ss.apps = window.ss.apps || {};

    var views = window.ss.views;

    views.BreadCrumbs = Backbone.View.extend({
        // template: _.template($('#enrollment_flow_page_view').html()),
        // className: "enrollment_flow_app_view",
        events: {
        },
        initialize: function(options){
            this.el = $('ul.breadcrumbs');
            this.render();
        },
        update: function(options){
            this.options = options;
            this.render();
        },
        render: function(){
            var $el = $(this.el);

            $el.empty();

            _.each( this.options.parents || [], function(parent){
                $el.append( '<li><a href="' + parent.url + '">' + parent.title + '</a> &gt; ')
            });
            $el.append( '<li>' + this.options.current )
        }
    });
});

;// Beginning /res/js/v2/backbone/file_upload_panel/backbone.models.fileuploadpanel.js:
$(function(){
    window.FileRow = Backbone.Model.extend({
    	defaults: function(){
    		return {
    			'key':'',
                'url':'',
                'user_name':'',
                'time':'',
                'file_name':'',
                'file_key':'',
                'file_key_name':'',
                'file_size':'',
                'file_bucket_name':'',
                'title':'',
                'user_url':'',
                'save_url':'',
                'template_type':'normal',
                'selected':false
    		};
    	}
    });
});
;// Beginning /res/js/v2/backbone/file_upload_panel/backbone.collections.fileuploadpanel.js:
$(function(){
	window.FileCollection = Backbone.Collection.extend({
		model: FileRow,
		save_url: '',
		template_type: 'normal'
	});
});
;// Beginning /res/js/v2/backbone/file_upload_panel/backbone.views.fileuploadpanel.js:
$(function(){
	window.FileRowView = Backbone.View.extend({
    	
    	events:{
    		"click .delete_file" : "delete_a_file"
    	},
    	
    	initialize: function(options){
    		this.render();
    	},
    	
    	delete_a_file:function(){
    		var this_view = this;
    		var template; 
 	        template = _.template($('#deleteFile').html());
 	        var save_url = this.model.get('save_url') || window.location.pathname;
    		
            $('<div>').ssdialog({
                'title' : 'Delete a File',
                'width' : '200',
                'save_url' : save_url,
                'content' : {
                    'html' : template(this.model.toJSON())
                   
                },
                'buttons' : {
                    "Save" : null,
                    "Delete" : function(namespace){
                        this[namespace]('save');
                    }
                },
                'success_callback':function(response){
                    ss_context.file_info = response.file_array;
                	this_view.model.destroy();
                	if($('.existing_file_div').children().length == 0){
                	   $('.existing_file_div').append('<i class="no_file_yet">No files uploaded yet.</i>');
                	}
                }
            });
            $(".ui-dialog-buttonset button:last-child").addClass('danger');	
    	},
    	
	    render: function(){
	        var $el = this.$(this.el);
	        var template;
	        
	        template = _.template($('#uploaded_file_single_view').html());
	        
	        $el.html(template(this.model.toJSON()));
	     
	        return this;
	    }
    });
	
    window.DocumentPanelView = Backbone.View.extend({
    	
    	events:{
    		"click .upload_file_popup" : "upload_file_popup" 
    	},
    	
    	initialize: function(options){
    		this.collection.bind('change',this.render,this);
    		this.collection.bind('add',this.render,this);
    		this.collection.bind('remove',this.render,this);
    		
    		may_modify = options['may_modify'];
            panel_icon_url = options['panel_icon_url'];
            target_type = options['target_type'];
    		this.render();
    	},
    	
    	upload_file_popup: function(event){
    	    event.preventDefault();
            var url = ss_context.target_url+'/upload_a_file'; 
            var save_url = this.collection.save_url || window.location.pathname;
            var template_type = this.collection.template_type;
            var this_view = this;
            $('.upload_file_popup').ssdialog({
                'title' : 'Upload a File',
                'width' : '300',
                'save_url' : save_url,
                'content' : {
                    'url' : url,
                    'refresh_on_show': true
                },
                'buttons' : {
                    "Save" : null,
                    "Upload" : function(namespace){
                        
                        var has_file = false;
                        var valid_form = $('.upload_form').valid();
                        
                        if($('.file_input').find('img').length == 0){
                            $('.file_input').append('<label class="error file_validation">Please select a file or wait until the file has been uploaded.</label>');
                        }else{
                            has_file = true;
                        }

                        if(valid_form && has_file){
                            this[namespace]('save');
                        }
                    }
                },
                'success_callback':function(response){
                	var files = response.file_array
                    ss_context.file_info = files;
                    var new_file;
                     
                    files.forEach(function(file){ 
                        if(file['key'] == response.new_file_key){
                            file.selected = false;
                            file.template_type = template_type;
                            file.save_url = save_url;
                            new_file = new FileRow(file,id = file['key']);
                        }
	                });
                    
                    this_view.collection.each(function(model){
                        model.set({"selected":false}, {"silent":true});
                    });
                    new_file.set({"selected":true}, {"silent":true});
                    this_view.collection.add(new_file,{at: 0})
                    //this_view.render();
                }

            });
            
            $(".ui-dialog-buttonset button:last-child").attr('disabled','true');

    	},
    	
	    render: function(){
	        var $el = this.$(this.el);
	        var template;

	        template = _.template($('#document_panel_view').html());
	        $el.html(template());

	        var container = $('.existing_file_div');
	        
	        // If no rows are selected then select the first one.
	        var selected = this.collection.any(function(model){
	            return model.get("selected");
	        });
	        if(!selected && this.collection.length){
	            this.collection.at(0).set({"selected":true}, {"silent":true});
	        }
	        
	        this.collection.each(
		        	function(model){
		        		var a_row = new FileRowView({'model':model,'el':'<li class="file_row">'});
		        		container.append(a_row.el);
		        		$('.no_file_yet').html('');
		        	}
		    );
	        
	        return this;
		        
	       
	    }
    });

  //  window.a_view = new DocumentPanelView({'collection':a_collection,'el':$('.document_panel')});
});
;// Beginning /res/js/v2/backbone/widgets/article_slider.js:
$(function(){
    window.ArticleSliderApp = Backbone.View.extend({
        events: {
            "click li": "article_chosen"
        },
        initialize: function(options){
            //this.model.bind('report_target_changed', this.report_target_changed, this);

            // read in our data from the
            this.render();
        },
        render: function() {
            var $el = this.$(this.el);
            var $articles = $el.children('li');
            var fade_duration = 3000;
            var display_duration = 3000;

        
            // Start by displaying all the articles but hiding the first one
            $articles.first().show();
            $articles.slice(1).hide();

            // Next...fade outthe current item and fade in the next item
            var transition = function( $current ){
                // Determine the next item
                var $next = $current.next('li');
                if ( ! $next.length ) {
                    $next = $articles.first();
                }

                var wait_and_reset = function() {
                    // console.log('waiting and reseting');
                    // skip the waiting part for now

                    $current.hide();
                    setTimeout(function(){
                        transition( $next );
                    }, display_duration);
                    
                };

                var fade_next_in = function() {
                    // console.log('fading the next one in');

                    $next.find('.article_footer').show();
                    $next.show().css({'z-index':5}).find('img')
                         .css({opacity:0})
                         .animate( { opacity:1 },
                                   { duration: fade_duration,
                                     complete: wait_and_reset});
                };
                var fade_current_out = function() {
                    // console.log('fading the current one out');

                    // fade out the current one
                    $current.find('.article_footer').hide();
                    $current.css({'z-index':2})
                    $current.children('img')
                                    .animate({ opacity:0},
                                     { duration:fade_duration
                                       //, complete: fade_next_in
                                       //, complete: function(){ $current.hide(); }
                                     });
                };
                
                fade_next_in();
                fade_current_out();
            };
            setTimeout(function(){
                transition( $articles.first() );
            }, display_duration);
        },
        article_chosen: function( event ){
            var url = $(event.target).closest('li').data('url');

            window.location = url;
        }
    });
});

