
/** File: javascript/date.js **/

/*
 * Date prototype extensions. Doesn't depend on any
 * other code. Doens't overwrite existing methods.
 *
 * Adds dayNames, abbrDayNames, monthNames and abbrMonthNames static properties and isLeapYear,
 * isWeekend, isWeekDay, getDaysInMonth, getDayName, getMonthName, getDayOfYear, getWeekOfYear,
 * setDayOfYear, addYears, addMonths, addDays, addHours, addMinutes, addSeconds methods
 *
 * Copyright (c) 2006 Jörn Zaefferer and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 *
 * Additional methods and properties added by Kelvin Luck: firstDayOfWeek, dateFormat, zeroTime, asString, fromString -
 * I've added my name to these methods so you know who to blame if they are broken!
 * 
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * An Array of day names starting with Sunday.
 * 
 * @example dayNames[0]
 * @result 'Sunday'
 *
 * @name dayNames
 * @type Array
 * @cat Plugins/Methods/Date
 */
Date.dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

/**
 * An Array of abbreviated day names starting with Sun.
 * 
 * @example abbrDayNames[0]
 * @result 'Sun'
 *
 * @name abbrDayNames
 * @type Array
 * @cat Plugins/Methods/Date
 */
Date.abbrDayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

/**
 * An Array of month names starting with Janurary.
 * 
 * @example monthNames[0]
 * @result 'January'
 *
 * @name monthNames
 * @type Array
 * @cat Plugins/Methods/Date
 */
Date.monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

/**
 * An Array of abbreviated month names starting with Jan.
 * 
 * @example abbrMonthNames[0]
 * @result 'Jan'
 *
 * @name monthNames
 * @type Array
 * @cat Plugins/Methods/Date
 */
Date.abbrMonthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

/**
 * The first day of the week for this locale.
 *
 * @name firstDayOfWeek
 * @type Number
 * @cat Plugins/Methods/Date
 * @author Kelvin Luck
 */
Date.firstDayOfWeek = 1;

/**
 * The format that string dates should be represented as (e.g. 'dd/mm/yyyy' for UK, 'mm/dd/yyyy' for US, 'yyyy-mm-dd' for Unicode etc).
 *
 * @name format
 * @type String
 * @cat Plugins/Methods/Date
 * @author Kelvin Luck
 */
Date.format = 'dd/mm/yyyy';
//Date.format = 'mm/dd/yyyy';
//Date.format = 'yyyy-mm-dd';
//Date.format = 'dd mmm yy';

(function() {

	/**
	 * Adds a given method under the given name 
	 * to the Date prototype if it doesn't
	 * currently exist.
	 *
	 * @private
	 */
	function add(name, method) {
		if( !Date.prototype[name] ) {
			Date.prototype[name] = method;
		}
	};
	
	/**
	 * Checks if the year is a leap year.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.isLeapYear();
	 * @result true
	 *
	 * @name isLeapYear
	 * @type Boolean
	 * @cat Plugins/Methods/Date
	 */
	add("isLeapYear", function() {
		var y = this.getFullYear();
		return (y%4==0 && y%100!=0) || y%400==0;
	});
	
	/**
	 * Checks if the day is a weekend day (Sat or Sun).
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.isWeekend();
	 * @result false
	 *
	 * @name isWeekend
	 * @type Boolean
	 * @cat Plugins/Methods/Date
	 */
	add("isWeekend", function() {
		return this.getDay()==0 || this.getDay()==6;
	});
	
	/**
	 * Check if the day is a day of the week (Mon-Fri)
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.isWeekDay();
	 * @result false
	 * 
	 * @name isWeekDay
	 * @type Boolean
	 * @cat Plugins/Methods/Date
	 */
	add("isWeekDay", function() {
		return !this.isWeekend();
	});
	
	/**
	 * Gets the number of days in the month.
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getDaysInMonth();
	 * @result 31
	 * 
	 * @name getDaysInMonth
	 * @type Number
	 * @cat Plugins/Methods/Date
	 */
	add("getDaysInMonth", function() {
		return [31,(this.isLeapYear() ? 29:28),31,30,31,30,31,31,30,31,30,31][this.getMonth()];
	});
	
	/**
	 * Gets the name of the day.
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getDayName();
	 * @result 'Saturday'
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getDayName(true);
	 * @result 'Sat'
	 * 
	 * @param abbreviated Boolean When set to true the name will be abbreviated.
	 * @name getDayName
	 * @type String
	 * @cat Plugins/Methods/Date
	 */
	add("getDayName", function(abbreviated) {
		return abbreviated ? Date.abbrDayNames[this.getDay()] : Date.dayNames[this.getDay()];
	});

	/**
	 * Gets the name of the month.
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getMonthName();
	 * @result 'Janurary'
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getMonthName(true);
	 * @result 'Jan'
	 * 
	 * @param abbreviated Boolean When set to true the name will be abbreviated.
	 * @name getDayName
	 * @type String
	 * @cat Plugins/Methods/Date
	 */
	add("getMonthName", function(abbreviated) {
		return abbreviated ? Date.abbrMonthNames[this.getMonth()] : Date.monthNames[this.getMonth()];
	});

	/**
	 * Get the number of the day of the year.
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getDayOfYear();
	 * @result 11
	 * 
	 * @name getDayOfYear
	 * @type Number
	 * @cat Plugins/Methods/Date
	 */
	add("getDayOfYear", function() {
		var tmpdtm = new Date("1/1/" + this.getFullYear());
		return Math.floor((this.getTime() - tmpdtm.getTime()) / 86400000);
	});
	
	/**
	 * Get the number of the week of the year.
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getWeekOfYear();
	 * @result 2
	 * 
	 * @name getWeekOfYear
	 * @type Number
	 * @cat Plugins/Methods/Date
	 */
	add("getWeekOfYear", function() {
		return Math.ceil(this.getDayOfYear() / 7);
	});

	/**
	 * Set the day of the year.
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.setDayOfYear(1);
	 * dtm.toString();
	 * @result 'Tue Jan 01 2008 00:00:00'
	 * 
	 * @name setDayOfYear
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("setDayOfYear", function(day) {
		this.setMonth(0);
		this.setDate(day);
		return this;
	});
	
	/**
	 * Add a number of years to the date object.
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.addYears(1);
	 * dtm.toString();
	 * @result 'Mon Jan 12 2009 00:00:00'
	 * 
	 * @name addYears
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("addYears", function(num) {
		this.setFullYear(this.getFullYear() + num);
		return this;
	});
	
	/**
	 * Add a number of months to the date object.
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.addMonths(1);
	 * dtm.toString();
	 * @result 'Tue Feb 12 2008 00:00:00'
	 * 
	 * @name addMonths
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("addMonths", function(num) {
		var tmpdtm = this.getDate();
		
		this.setMonth(this.getMonth() + num);
		
		if (tmpdtm > this.getDate())
			this.addDays(-this.getDate());
		
		return this;
	});
	
	/**
	 * Add a number of days to the date object.
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.addDays(1);
	 * dtm.toString();
	 * @result 'Sun Jan 13 2008 00:00:00'
	 * 
	 * @name addDays
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("addDays", function(num) {
		this.setDate(this.getDate() + num);
		return this;
	});
	
	/**
	 * Add a number of hours to the date object.
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.addHours(24);
	 * dtm.toString();
	 * @result 'Sun Jan 13 2008 00:00:00'
	 * 
	 * @name addHours
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("addHours", function(num) {
		this.setHours(this.getHours() + num);
		return this;
	});

	/**
	 * Add a number of minutes to the date object.
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.addMinutes(60);
	 * dtm.toString();
	 * @result 'Sat Jan 12 2008 01:00:00'
	 * 
	 * @name addMinutes
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("addMinutes", function(num) {
		this.setMinutes(this.getMinutes() + num);
		return this;
	});
	
	/**
	 * Add a number of seconds to the date object.
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.addSeconds(60);
	 * dtm.toString();
	 * @result 'Sat Jan 12 2008 00:01:00'
	 * 
	 * @name addSeconds
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("addSeconds", function(num) {
		this.setSeconds(this.getSeconds() + num);
		return this;
	});
	
	/**
	 * Sets the time component of this Date to zero for cleaner, easier comparison of dates where time is not relevant.
	 * 
	 * @example var dtm = new Date();
	 * dtm.zeroTime();
	 * dtm.toString();
	 * @result 'Sat Jan 12 2008 00:01:00'
	 * 
	 * @name zeroTime
	 * @type Date
	 * @cat Plugins/Methods/Date
	 * @author Kelvin Luck
	 */
	add("zeroTime", function() {
		this.setMilliseconds(0);
		this.setSeconds(0);
		this.setMinutes(0);
		this.setHours(0);
		return this;
	});
	
	/**
	 * Returns a string representation of the date object according to Date.format.
	 * (Date.toString may be used in other places so I purposefully didn't overwrite it)
	 * 
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.asString();
	 * @result '12/01/2008' // (where Date.format == 'dd/mm/yyyy'
	 * 
	 * @name asString
	 * @type Date
	 * @cat Plugins/Methods/Date
	 * @author Kelvin Luck
	 */
	add("asString", function() {
		var r = Date.format;
		return r
			.split('yyyy').join(this.getFullYear())
			.split('yy').join(this.getYear())
			.split('mmm').join(this.getMonthName(true))
			.split('mm').join(_zeroPad(this.getMonth()+1))
			.split('dd').join(_zeroPad(this.getDate()));
	});
	
	/**
	 * Returns a new date object created from the passed String according to Date.format or false if the attempt to do this results in an invalid date object
	 * (We can't simple use Date.parse as it's not aware of locale and I chose not to overwrite it incase it's functionality is being relied on elsewhere)
	 *
	 * @example var dtm = Date.fromString("12/01/2008");
	 * dtm.toString();
	 * @result 'Sat Jan 12 2008 00:00:00' // (where Date.format == 'dd/mm/yyyy'
	 * 
	 * @name fromString
	 * @type Date
	 * @cat Plugins/Methods/Date
	 * @author Kelvin Luck
	 */
	Date.fromString = function(s)
	{
		var f = Date.format;
		var d = new Date('01/01/1977');
		var iY = f.indexOf('yyyy');
		if (iY > -1) {
			d.setFullYear(Number(s.substr(iY, 4)));
		} else {
			// TODO - this doesn't work very well - are there any rules for what is meant by a two digit year?
			d.setYear(Number(s.substr(f.indexOf('yy'), 2)));
		}
		var iM = f.indexOf('mmm');
		if (iM > -1) {
			var mStr = s.substr(iM, 3);
			for (var i=0; i<Date.abbrMonthNames.length; i++) {
				if (Date.abbrMonthNames[i] == mStr) break;
			}
			d.setMonth(i);
		} else {
			d.setMonth(Number(s.substr(f.indexOf('mm'), 2)) - 1);
		}
		d.setDate(Number(s.substr(f.indexOf('dd'), 2)));
		if (isNaN(d.getTime())) return false;
		return d;
	}
	
	// utility method
	var _zeroPad = function(num) {
		var s = '0'+num;
		return s.substring(s.length-2)
		//return ('0'+num).substring(-2); // doesn't work on IE :(
	};
	
})();

/** File: javascript/jquery.js **/

/*
 * jQuery JavaScript Library v1.3.2
 * http://jquery.com/
 *
 * Copyright (c) 2009 John Resig
 * Dual licensed under the MIT and GPL licenses.
 * http://docs.jquery.com/License
 *
 * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
 * Revision: 6246
 */
(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
/*
 * Sizzle CSS Selector Engine - v0.9.3
 *  Copyright 2009, The Dojo Foundation
 *  Released under the MIT, BSD, and GPL Licenses.
 *  More information: http://sizzlejs.com/
 */
(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML='   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();

/** File: javascript/jquery.dimensions.js **/

/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-12-20 08:46:55 -0600 (Thu, 20 Dec 2007) $
 * $Rev: 4259 $
 *
 * Version: 1.2
 *
 * Requires: jQuery 1.2+
 */

(function($){
	
$.dimensions = {
	version: '1.2'
};

// Create innerHeight, innerWidth, outerHeight and outerWidth methods
$.each( [ 'Height', 'Width' ], function(i, name){
	
	// innerHeight and innerWidth
	$.fn[ 'inner' + name ] = function() {
		if (!this[0]) return;
		
		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
		
		return this.is(':visible') ? this[0]['client' + name] : num( this, name.toLowerCase() ) + num(this, 'padding' + torl) + num(this, 'padding' + borr);
	};
	
	// outerHeight and outerWidth
	$.fn[ 'outer' + name ] = function(options) {
		if (!this[0]) return;
		
		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
		
		options = $.extend({ margin: false }, options || {});
		
		var val = this.is(':visible') ? 
				this[0]['offset' + name] : 
				num( this, name.toLowerCase() )
					+ num(this, 'border' + torl + 'Width') + num(this, 'border' + borr + 'Width')
					+ num(this, 'padding' + torl) + num(this, 'padding' + borr);
		
		return val + (options.margin ? (num(this, 'margin' + torl) + num(this, 'margin' + borr)) : 0);
	};
});

// Create scrollLeft and scrollTop methods
$.each( ['Left', 'Top'], function(i, name) {
	$.fn[ 'scroll' + name ] = function(val) {
		if (!this[0]) return;
		
		return val != undefined ?
		
			// Set the scroll offset
			this.each(function() {
				this == window || this == document ?
					window.scrollTo( 
						name == 'Left' ? val : $(window)[ 'scrollLeft' ](),
						name == 'Top'  ? val : $(window)[ 'scrollTop'  ]()
					) :
					this[ 'scroll' + name ] = val;
			}) :
			
			// Return the scroll offset
			this[0] == window || this[0] == document ?
				self[ (name == 'Left' ? 'pageXOffset' : 'pageYOffset') ] ||
					$.boxModel && document.documentElement[ 'scroll' + name ] ||
					document.body[ 'scroll' + name ] :
				this[0][ 'scroll' + name ];
	};
});

$.fn.extend({
	position: function() {
		var left = 0, top = 0, elem = this[0], offset, parentOffset, offsetParent, results;
		
		if (elem) {
			// Get *real* offsetParent
			offsetParent = this.offsetParent();
			
			// Get correct offsets
			offset       = this.offset();
			parentOffset = offsetParent.offset();
			
			// Subtract element margins
			offset.top  -= num(elem, 'marginTop');
			offset.left -= num(elem, 'marginLeft');
			
			// Add offsetParent borders
			parentOffset.top  += num(offsetParent, 'borderTopWidth');
			parentOffset.left += num(offsetParent, 'borderLeftWidth');
			
			// Subtract the two offsets
			results = {
				top:  offset.top  - parentOffset.top,
				left: offset.left - parentOffset.left
			};
		}
		
		return results;
	}
});

function num(el, prop) {
	return parseInt($.curCSS(el.jquery?el[0]:el,prop,true))||0;
};

})(jQuery);

/** File: javascript/jquery.bgiframe.js **/

/* Copyright (c) 2006 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.
 *
 * $LastChangedDate$
 * $Rev$
 *
 * Version 2.1.1
 */

(function($){

/**
 * The bgiframe is chainable and applies the iframe hack to get 
 * around zIndex issues in IE6. It will only apply itself in IE6 
 * and adds a class to the iframe called 'bgiframe'. The iframe
 * is appeneded as the first child of the matched element(s) 
 * with a tabIndex and zIndex of -1.
 * 
 * By default the plugin will take borders, sized with pixel units,
 * into account. If a different unit is used for the border's width,
 * then you will need to use the top and left settings as explained below.
 *
 * NOTICE: This plugin has been reported to cause perfromance problems
 * when used on elements that change properties (like width, height and
 * opacity) a lot in IE6. Most of these problems have been caused by 
 * the expressions used to calculate the elements width, height and 
 * borders. Some have reported it is due to the opacity filter. All 
 * these settings can be changed if needed as explained below.
 *
 * @example $('div').bgiframe();
 * @before <div><p>Paragraph</p></div>
 * @result <div><iframe class="bgiframe".../><p>Paragraph</p></div>
 *
 * @param Map settings Optional settings to configure the iframe.
 * @option String|Number top The iframe must be offset to the top
 * 		by the width of the top border. This should be a negative 
 *      number representing the border-top-width. If a number is 
 * 		is used here, pixels will be assumed. Otherwise, be sure
 *		to specify a unit. An expression could also be used. 
 * 		By default the value is "auto" which will use an expression 
 * 		to get the border-top-width if it is in pixels.
 * @option String|Number left The iframe must be offset to the left
 * 		by the width of the left border. This should be a negative 
 *      number representing the border-left-width. If a number is 
 * 		is used here, pixels will be assumed. Otherwise, be sure
 *		to specify a unit. An expression could also be used. 
 * 		By default the value is "auto" which will use an expression 
 * 		to get the border-left-width if it is in pixels.
 * @option String|Number width This is the width of the iframe. If
 *		a number is used here, pixels will be assume. Otherwise, be sure
 * 		to specify a unit. An experssion could also be used.
 *		By default the value is "auto" which will use an experssion
 * 		to get the offsetWidth.
 * @option String|Number height This is the height of the iframe. If
 *		a number is used here, pixels will be assume. Otherwise, be sure
 * 		to specify a unit. An experssion could also be used.
 *		By default the value is "auto" which will use an experssion
 * 		to get the offsetHeight.
 * @option Boolean opacity This is a boolean representing whether or not
 * 		to use opacity. If set to true, the opacity of 0 is applied. If
 *		set to false, the opacity filter is not applied. Default: true.
 * @option String src This setting is provided so that one could change 
 *		the src of the iframe to whatever they need.
 *		Default: "javascript:false;"
 *
 * @name bgiframe
 * @type jQuery
 * @cat Plugins/bgiframe
 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 */
$.fn.bgIframe = $.fn.bgiframe = function(s) {
	// This is only for IE6
	if ( $.browser.msie && /6.0/.test(navigator.userAgent) ) {
		s = $.extend({
			top     : 'auto', // auto == .currentStyle.borderTopWidth
			left    : 'auto', // auto == .currentStyle.borderLeftWidth
			width   : 'auto', // auto == offsetWidth
			height  : 'auto', // auto == offsetHeight
			opacity : true,
			src     : 'javascript:false;'
		}, s || {});
		var prop = function(n){return n&&n.constructor==Number?n+'px':n;},
		    html = '<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+
		               'style="display:block;position:absolute;z-index:-1;'+
			               (s.opacity !== false?'filter:Alpha(Opacity=\'0\');':'')+
					       'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+
					       'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+
					       'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+
					       'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+
					'"/>';
		return this.each(function() {
			if ( $('> iframe.bgiframe', this).length == 0 )
				this.insertBefore( document.createElement(html), this.firstChild );
		});
	}
	return this;
};

})(jQuery);

/** File: javascript/jquery.form.js **/

/*!
 * jQuery Form Plugin
 * version: 2.43 (12-MAR-2010)
 * @requires jQuery v1.3.2 or later
 *
 * Examples and documentation at: http://malsup.com/jquery/form/
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */
;(function($) {

/*
	Usage Note:
	-----------
	Do not use both ajaxSubmit and ajaxForm on the same form.  These
	functions are intended to be exclusive.  Use ajaxSubmit if you want
	to bind your own submit handler to the form.  For example,

	$(document).ready(function() {
		$('#myForm').bind('submit', function() {
			$(this).ajaxSubmit({
				target: '#output'
			});
			return false; // <-- important!
		});
	});

	Use ajaxForm when you want the plugin to manage all the event binding
	for you.  For example,

	$(document).ready(function() {
		$('#myForm').ajaxForm({
			target: '#output'
		});
	});

	When using ajaxForm, the ajaxSubmit function will be invoked for you
	at the appropriate time.
*/

/**
 * ajaxSubmit() provides a mechanism for immediately submitting
 * an HTML form using AJAX.
 */
$.fn.ajaxSubmit = function(options) {
	// fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
	if (!this.length) {
		log('ajaxSubmit: skipping submit process - no element selected');
		return this;
	}

	if (typeof options == 'function')
		options = { success: options };

	var url = $.trim(this.attr('action'));
	if (url) {
		// clean url (don't include hash vaue)
		url = (url.match(/^([^#]+)/)||[])[1];
   	}
   	url = url || window.location.href || '';

	options = $.extend({
		url:  url,
		type: this.attr('method') || 'GET',
		iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
	}, options || {});

	// hook for manipulating the form data before it is extracted;
	// convenient for use with rich editors like tinyMCE or FCKEditor
	var veto = {};
	this.trigger('form-pre-serialize', [this, options, veto]);
	if (veto.veto) {
		log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
		return this;
	}

	// provide opportunity to alter form data before it is serialized
	if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
		log('ajaxSubmit: submit aborted via beforeSerialize callback');
		return this;
	}

	var a = this.formToArray(options.semantic);
	if (options.data) {
		options.extraData = options.data;
		for (var n in options.data) {
		  if(options.data[n] instanceof Array) {
			for (var k in options.data[n])
			  a.push( { name: n, value: options.data[n][k] } );
		  }
		  else
			 a.push( { name: n, value: options.data[n] } );
		}
	}

	// give pre-submit callback an opportunity to abort the submit
	if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
		log('ajaxSubmit: submit aborted via beforeSubmit callback');
		return this;
	}

	// fire vetoable 'validate' event
	this.trigger('form-submit-validate', [a, this, options, veto]);
	if (veto.veto) {
		log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
		return this;
	}

	var q = $.param(a);

	if (options.type.toUpperCase() == 'GET') {
		options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
		options.data = null;  // data is null for 'get'
	}
	else
		options.data = q; // data is the query string for 'post'

	var $form = this, callbacks = [];
	if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
	if (options.clearForm) callbacks.push(function() { $form.clearForm(); });

	// perform a load on the target only if dataType is not provided
	if (!options.dataType && options.target) {
		var oldSuccess = options.success || function(){};
		callbacks.push(function(data) {
			var fn = options.replaceTarget ? 'replaceWith' : 'html';
			$(options.target)[fn](data).each(oldSuccess, arguments);
		});
	}
	else if (options.success)
		callbacks.push(options.success);

	options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
		for (var i=0, max=callbacks.length; i < max; i++)
			callbacks[i].apply(options, [data, status, xhr || $form, $form]);
	};

	// are there files to upload?
	var files = $('input:file', this).fieldValue();
	var found = false;
	for (var j=0; j < files.length; j++)
		if (files[j])
			found = true;

	var multipart = false;
//	var mp = 'multipart/form-data';
//	multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);

	// options.iframe allows user to force iframe mode
	// 06-NOV-09: now defaulting to iframe mode if file input is detected
   if ((files.length && options.iframe !== false) || options.iframe || found || multipart) {
	   // hack to fix Safari hang (thanks to Tim Molendijk for this)
	   // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
	   if (options.closeKeepAlive)
		   $.get(options.closeKeepAlive, fileUpload);
	   else
		   fileUpload();
	   }
   else
	   $.ajax(options);

	// fire 'notify' event
	this.trigger('form-submit-notify', [this, options]);
	return this;


	// private function for handling file uploads (hat tip to YAHOO!)
	function fileUpload() {
		var form = $form[0];

		if ($(':input[name=submit]', form).length) {
			alert('Error: Form elements must not be named "submit".');
			return;
		}

		var opts = $.extend({}, $.ajaxSettings, options);
		var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);

		var id = 'jqFormIO' + (new Date().getTime());
		var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ opts.iframeSrc +'" onload="(jQuery(this).data(\'form-plugin-onload\'))()" />');
		var io = $io[0];

		$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });

		var xhr = { // mock object
			aborted: 0,
			responseText: null,
			responseXML: null,
			status: 0,
			statusText: 'n/a',
			getAllResponseHeaders: function() {},
			getResponseHeader: function() {},
			setRequestHeader: function() {},
			abort: function() {
				this.aborted = 1;
				$io.attr('src', opts.iframeSrc); // abort op in progress
			}
		};

		var g = opts.global;
		// trigger ajax global events so that activity/block indicators work like normal
		if (g && ! $.active++) $.event.trigger("ajaxStart");
		if (g) $.event.trigger("ajaxSend", [xhr, opts]);

		if (s.beforeSend && s.beforeSend(xhr, s) === false) {
			s.global && $.active--;
			return;
		}
		if (xhr.aborted)
			return;

		var cbInvoked = false;
		var timedOut = 0;

		// add submitting element to data if we know it
		var sub = form.clk;
		if (sub) {
			var n = sub.name;
			if (n && !sub.disabled) {
				opts.extraData = opts.extraData || {};
				opts.extraData[n] = sub.value;
				if (sub.type == "image") {
					opts.extraData[n+'.x'] = form.clk_x;
					opts.extraData[n+'.y'] = form.clk_y;
				}
			}
		}

		// take a breath so that pending repaints get some cpu time before the upload starts
		function doSubmit() {
			// make sure form attrs are set
			var t = $form.attr('target'), a = $form.attr('action');

			// update form attrs in IE friendly way
			form.setAttribute('target',id);
			if (form.getAttribute('method') != 'POST')
				form.setAttribute('method', 'POST');
			if (form.getAttribute('action') != opts.url)
				form.setAttribute('action', opts.url);

			// ie borks in some cases when setting encoding
			if (! opts.skipEncodingOverride) {
				$form.attr({
					encoding: 'multipart/form-data',
					enctype:  'multipart/form-data'
				});
			}

			// support timout
			if (opts.timeout)
				setTimeout(function() { timedOut = true; cb(); }, opts.timeout);

			// add "extra" data to form if provided in options
			var extraInputs = [];
			try {
				if (opts.extraData)
					for (var n in opts.extraData)
						extraInputs.push(
							$('<input type="hidden" name="'+n+'" value="'+opts.extraData[n]+'" />')
								.appendTo(form)[0]);

				// add iframe to doc and submit the form
				$io.appendTo('body');
				$io.data('form-plugin-onload', cb);
				form.submit();
			}
			finally {
				// reset attrs and remove "extra" input elements
				form.setAttribute('action',a);
				t ? form.setAttribute('target', t) : $form.removeAttr('target');
				$(extraInputs).remove();
			}
		};

		if (opts.forceSync)
			doSubmit();
		else
			setTimeout(doSubmit, 10); // this lets dom updates render
	
		var domCheckCount = 100;

		function cb() {
			if (cbInvoked) 
				return;

			var ok = true;
			try {
				if (timedOut) throw 'timeout';
				// extract the server response from the iframe
				var data, doc;

				doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
				
				var isXml = opts.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
				log('isXml='+isXml);
				if (!isXml && (doc.body == null || doc.body.innerHTML == '')) {
				 	if (--domCheckCount) {
						// in some browsers (Opera) the iframe DOM is not always traversable when
						// the onload callback fires, so we loop a bit to accommodate
				 		log('requeing onLoad callback, DOM not available');
						setTimeout(cb, 250);
						return;
					}
					log('Could not access iframe DOM after 100 tries.');
					return;
				}

				log('response detected');
				cbInvoked = true;
				xhr.responseText = doc.body ? doc.body.innerHTML : null;
				xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
				xhr.getResponseHeader = function(header){
					var headers = {'content-type': opts.dataType};
					return headers[header];
				};

				if (opts.dataType == 'json' || opts.dataType == 'script') {
					// see if user embedded response in textarea
					var ta = doc.getElementsByTagName('textarea')[0];
					if (ta)
						xhr.responseText = ta.value;
					else {
						// account for browsers injecting pre around json response
						var pre = doc.getElementsByTagName('pre')[0];
						if (pre)
							xhr.responseText = pre.innerHTML;
					}			  
				}
				else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
					xhr.responseXML = toXml(xhr.responseText);
				}
				data = $.httpData(xhr, opts.dataType);
			}
			catch(e){
				log('error caught:',e);
				ok = false;
				xhr.error = e;
				$.handleError(opts, xhr, 'error', e);
			}

			// ordering of these callbacks/triggers is odd, but that's how $.ajax does it
			if (ok) {
				opts.success(data, 'success');
				if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
			}
			if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
			if (g && ! --$.active) $.event.trigger("ajaxStop");
			if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');

			// clean up
			setTimeout(function() {
				$io.removeData('form-plugin-onload');
				$io.remove();
				xhr.responseXML = null;
			}, 100);
		};

		function toXml(s, doc) {
			if (window.ActiveXObject) {
				doc = new ActiveXObject('Microsoft.XMLDOM');
				doc.async = 'false';
				doc.loadXML(s);
			}
			else
				doc = (new DOMParser()).parseFromString(s, 'text/xml');
			return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
		};
	};
};

/**
 * ajaxForm() provides a mechanism for fully automating form submission.
 *
 * The advantages of using this method instead of ajaxSubmit() are:
 *
 * 1: This method will include coordinates for <input type="image" /> elements (if the element
 *	is used to submit the form).
 * 2. This method will include the submit element's name/value data (for the element that was
 *	used to submit the form).
 * 3. This method binds the submit() method to the form for you.
 *
 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
 * passes the options argument along after properly binding events for submit elements and
 * the form itself.
 */
$.fn.ajaxForm = function(options) {
	return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) {
		e.preventDefault();
		$(this).ajaxSubmit(options);
	}).bind('click.form-plugin', function(e) {
		var target = e.target;
		var $el = $(target);
		if (!($el.is(":submit,input:image"))) {
			// is this a child element of the submit el?  (ex: a span within a button)
			var t = $el.closest(':submit');
			if (t.length == 0)
				return;
			target = t[0];
		}
		var form = this;
		form.clk = target;
		if (target.type == 'image') {
			if (e.offsetX != undefined) {
				form.clk_x = e.offsetX;
				form.clk_y = e.offsetY;
			} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
				var offset = $el.offset();
				form.clk_x = e.pageX - offset.left;
				form.clk_y = e.pageY - offset.top;
			} else {
				form.clk_x = e.pageX - target.offsetLeft;
				form.clk_y = e.pageY - target.offsetTop;
			}
		}
		// clear form vars
		setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
	});
};

// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function() {
	return this.unbind('submit.form-plugin click.form-plugin');
};

/**
 * formToArray() gathers form element data into an array of objects that can
 * be passed to any of the following ajax functions: $.get, $.post, or load.
 * Each object in the array has both a 'name' and 'value' property.  An example of
 * an array for a simple login form might be:
 *
 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 *
 * It is this array that is passed to pre-submit callback functions provided to the
 * ajaxSubmit() and ajaxForm() methods.
 */
$.fn.formToArray = function(semantic) {
	var a = [];
	if (this.length == 0) return a;

	var form = this[0];
	var els = semantic ? form.getElementsByTagName('*') : form.elements;
	if (!els) return a;
	for(var i=0, max=els.length; i < max; i++) {
		var el = els[i];
		var n = el.name;
		if (!n) continue;

		if (semantic && form.clk && el.type == "image") {
			// handle image inputs on the fly when semantic == true
			if(!el.disabled && form.clk == el) {
				a.push({name: n, value: $(el).val()});
				a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
			}
			continue;
		}

		var v = $.fieldValue(el, true);
		if (v && v.constructor == Array) {
			for(var j=0, jmax=v.length; j < jmax; j++)
				a.push({name: n, value: v[j]});
		}
		else if (v !== null && typeof v != 'undefined')
			a.push({name: n, value: v});
	}

	if (!semantic && form.clk) {
		// input type=='image' are not found in elements array! handle it here
		var $input = $(form.clk), input = $input[0], n = input.name;
		if (n && !input.disabled && input.type == 'image') {
			a.push({name: n, value: $input.val()});
			a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
		}
	}
	return a;
};

/**
 * Serializes form data into a 'submittable' string. This method will return a string
 * in the format: name1=value1&amp;name2=value2
 */
$.fn.formSerialize = function(semantic) {
	//hand off to jQuery.param for proper encoding
	return $.param(this.formToArray(semantic));
};

/**
 * Serializes all field elements in the jQuery object into a query string.
 * This method will return a string in the format: name1=value1&amp;name2=value2
 */
$.fn.fieldSerialize = function(successful) {
	var a = [];
	this.each(function() {
		var n = this.name;
		if (!n) return;
		var v = $.fieldValue(this, successful);
		if (v && v.constructor == Array) {
			for (var i=0,max=v.length; i < max; i++)
				a.push({name: n, value: v[i]});
		}
		else if (v !== null && typeof v != 'undefined')
			a.push({name: this.name, value: v});
	});
	//hand off to jQuery.param for proper encoding
	return $.param(a);
};

/**
 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
 *
 *  <form><fieldset>
 *	  <input name="A" type="text" />
 *	  <input name="A" type="text" />
 *	  <input name="B" type="checkbox" value="B1" />
 *	  <input name="B" type="checkbox" value="B2"/>
 *	  <input name="C" type="radio" value="C1" />
 *	  <input name="C" type="radio" value="C2" />
 *  </fieldset></form>
 *
 *  var v = $(':text').fieldValue();
 *  // if no values are entered into the text inputs
 *  v == ['','']
 *  // if values entered into the text inputs are 'foo' and 'bar'
 *  v == ['foo','bar']
 *
 *  var v = $(':checkbox').fieldValue();
 *  // if neither checkbox is checked
 *  v === undefined
 *  // if both checkboxes are checked
 *  v == ['B1', 'B2']
 *
 *  var v = $(':radio').fieldValue();
 *  // if neither radio is checked
 *  v === undefined
 *  // if first radio is checked
 *  v == ['C1']
 *
 * The successful argument controls whether or not the field element must be 'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.  If this value is false the value(s)
 * for each element is returned.
 *
 * Note: This method *always* returns an array.  If no valid value can be determined the
 *	   array will be empty, otherwise it will contain one or more values.
 */
$.fn.fieldValue = function(successful) {
	for (var val=[], i=0, max=this.length; i < max; i++) {
		var el = this[i];
		var v = $.fieldValue(el, successful);
		if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
			continue;
		v.constructor == Array ? $.merge(val, v) : val.push(v);
	}
	return val;
};

/**
 * Returns the value of the field element.
 */
$.fieldValue = function(el, successful) {
	var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
	if (typeof successful == 'undefined') successful = true;

	if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
		(t == 'checkbox' || t == 'radio') && !el.checked ||
		(t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
		tag == 'select' && el.selectedIndex == -1))
			return null;

	if (tag == 'select') {
		var index = el.selectedIndex;
		if (index < 0) return null;
		var a = [], ops = el.options;
		var one = (t == 'select-one');
		var max = (one ? index+1 : ops.length);
		for(var i=(one ? index : 0); i < max; i++) {
			var op = ops[i];
			if (op.selected) {
				var v = op.value;
				if (!v) // extra pain for IE...
					v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
				if (one) return v;
				a.push(v);
			}
		}
		return a;
	}
	return el.value;
};

/**
 * Clears the form data.  Takes the following actions on the form's input fields:
 *  - input text fields will have their 'value' property set to the empty string
 *  - select elements will have their 'selectedIndex' property set to -1
 *  - checkbox and radio inputs will have their 'checked' property set to false
 *  - inputs of type submit, button, reset, and hidden will *not* be effected
 *  - button elements will *not* be effected
 */
$.fn.clearForm = function() {
	return this.each(function() {
		$('input,select,textarea', this).clearFields();
	});
};

/**
 * Clears the selected form elements.
 */
$.fn.clearFields = $.fn.clearInputs = function() {
	return this.each(function() {
		var t = this.type, tag = this.tagName.toLowerCase();
		if (t == 'text' || t == 'password' || tag == 'textarea')
			this.value = '';
		else if (t == 'checkbox' || t == 'radio')
			this.checked = false;
		else if (tag == 'select')
			this.selectedIndex = -1;
	});
};

/**
 * Resets the form data.  Causes all form elements to be reset to their original value.
 */
$.fn.resetForm = function() {
	return this.each(function() {
		// guard against an input with the name of 'reset'
		// note that IE reports the reset function as an 'object'
		if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
			this.reset();
	});
};

/**
 * Enables or disables any matching elements.
 */
$.fn.enable = function(b) {
	if (b == undefined) b = true;
	return this.each(function() {
		this.disabled = !b;
	});
};

/**
 * Checks/unchecks any matching checkboxes or radio buttons and
 * selects/deselects and matching option elements.
 */
$.fn.selected = function(select) {
	if (select == undefined) select = true;
	return this.each(function() {
		var t = this.type;
		if (t == 'checkbox' || t == 'radio')
			this.checked = select;
		else if (this.tagName.toLowerCase() == 'option') {
			var $sel = $(this).parent('select');
			if (select && $sel[0] && $sel[0].type == 'select-one') {
				// deselect all other options
				$sel.find('option').selected(false);
			}
			this.selected = select;
		}
	});
};

// helper fn for console logging
// set $.fn.ajaxSubmit.debug to true to enable debug logging
function log() {
	if ($.fn.ajaxSubmit.debug) {
		var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
		if (window.console && window.console.log)
			window.console.log(msg);
		else if (window.opera && window.opera.postError)
			window.opera.postError(msg);
	}
};

})(jQuery);


/** File: javascript/jquery.blockui.js **/

/*
 * jQuery blockUI plugin
 * Version 2.10 (10/22/2008)
 * @requires jQuery v1.2.3 or later
 *
 * Examples at: http://malsup.com/jquery/block/
 * Copyright (c) 2007-2008 M. Alsup
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Thanks to Amir-Hossein Sobhi for some excellent contributions!
 */

;(function($) {

if (/1\.(0|1|2)\.(0|1|2)/.test($.fn.jquery) || /^1.1/.test($.fn.jquery)) {
    alert('blockUI requires jQuery v1.2.3 or later!  You are using v' + $.fn.jquery);
    return;
}

// global $ methods for blocking/unblocking the entire page
$.blockUI   = function(opts) { install(window, opts); };
$.unblockUI = function(opts) { remove(window, opts); };

// plugin method for blocking element content
$.fn.block = function(opts) {
    return this.each(function() {
        if ($.css(this,'position') == 'static')
            this.style.position = 'relative';
        if ($.browser.msie) 
            this.style.zoom = 1; // force 'hasLayout'
        install(this, opts);
    });
};

// plugin method for unblocking element content
$.fn.unblock = function(opts) {
    return this.each(function() {
        remove(this, opts);
    });
};

$.blockUI.version = 2.09; // 2nd generation blocking at no extra cost!

// override these in your code to change the default behavior and style
$.blockUI.defaults = {
    // message displayed when blocking (use null for no message)
    message:  '',
    
    // styles for the message when blocking; if you wish to disable
    // these and use an external stylesheet then do this in your code:
    // $.blockUI.defaults.css = {};
    css: { 
        padding:        0,
        margin:         0,
        width:          '30%', 
        top:            '40%', 
        left:           '35%', 
        textAlign:      'center', 
        color:          '#000', 
        border:         '3px solid #aaa',
        backgroundColor:'#fff',
        cursor:         'wait'
    },
    
    // styles for the overlay
    overlayCSS:  { 
        backgroundColor:'#FFF', 
        opacity:        '0.7' 
    },
    
    // z-index for the blocking overlay
    baseZ: 1000,
    
    // set these to true to have the message automatically centered
    centerX: true, // <-- only effects element blocking (page block controlled via css above)
    centerY: true,
    
    // allow body element to be stetched in ie6; this makes blocking look better
    // on "short" pages.  disable if you wish to prevent changes to the body height
    allowBodyStretch: true,
    
    // be default blockUI will supress tab navigation from leaving blocking content;
    constrainTabKey: true,
    
    // fadeOut time in millis; set to 0 to disable fadeout on unblock
    fadeOut:  400,
    
    // if true, focus will be placed in the first available input field when
    // page blocking
    focusInput: true,
    
    // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
    applyPlatformOpacityRules: true,
    
    // callback method invoked when unblocking has completed; the callback is
    // passed the element that has been unblocked (which is the window object for page
    // blocks) and the options that were passed to the unblock call:
    //     onUnblock(element, options)
    onUnblock: null,
    
    // don't ask (if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493)
    quirksmodeOffsetHack: 4
};

// private data and functions follow...

var ie6 = $.browser.msie && /MSIE 6.0/.test(navigator.userAgent);
var pageBlock = null;
var pageBlockEls = [];

function install(el, opts) {
    var full = (el == window);
    var msg = opts && opts.message !== undefined ? opts.message : undefined;
    opts = $.extend({}, $.blockUI.defaults, opts || {});
    opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
    var css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
    msg = msg === undefined ? opts.message : msg;

    // remove the current block (if there is one)
    if (full && pageBlock) 
        remove(window, {fadeOut:0}); 
    
    // if an existing element is being used as the blocking content then we capture
    // its current place in the DOM (and current display style) so we can restore
    // it when we unblock
    if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
        var node = msg.jquery ? msg[0] : msg;
        var data = {};
        $(el).data('blockUI.history', data);
        data.el = node;
        data.parent = node.parentNode;
        data.display = node.style.display;
        data.position = node.style.position;
        data.parent.removeChild(node);
    }
    
    var z = opts.baseZ;
    
    // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
    // layer1 is the iframe layer which is used to supress bleed through of underlying content
    // layer2 is the overlay layer which has opacity and a wait cursor
    // layer3 is the message content that is displayed while blocking
    
    var lyr1 = ($.browser.msie) ? $('<iframe class="blockUI" style="z-index:'+ z++ +';border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="javascript:false;"></iframe>')
                                : $('<div class="blockUI" style="display:none"></div>');
    var lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ z++ +';cursor:wait;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
    var lyr3 = full ? $('<div class="blockUI blockMsg blockPage" style="z-index:'+z+';position:fixed"></div>')
                    : $('<div class="blockUI blockMsg blockElement" style="z-index:'+z+';display:none;position:absolute"></div>');

    // if we have a message, style it
    if (msg) 
        lyr3.css(css);

    // style the overlay
    if (!opts.applyPlatformOpacityRules || !($.browser.mozilla && /Linux/.test(navigator.platform))) 
        lyr2.css(opts.overlayCSS);
    lyr2.css('position', full ? 'fixed' : 'absolute');
    
    // make iframe layer transparent in IE
    if ($.browser.msie) 
        lyr1.css('opacity','0.0');

    $([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
    
    // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
    var expr = $.browser.msie && (!$.boxModel || $('object,embed', full ? null : el).length > 0);
    if (ie6 || expr) {
        // give body 100% height
        if (full && opts.allowBodyStretch && $.boxModel)
            $('html,body').css('height','100%');

        // fix ie6 issue when blocked element has a border width
        if ((ie6 || !$.boxModel) && !full) {
            var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
            var fixT = t ? '(0 - '+t+')' : 0;
            var fixL = l ? '(0 - '+l+')' : 0;
        }

        // simulate fixed position
        $.each([lyr1,lyr2,lyr3], function(i,o) {
            var s = o[0].style;
            s.position = 'absolute';
            if (i < 2) {
                full ? s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"')
                     : s.setExpression('height','this.parentNode.offsetHeight + "px"');
                full ? s.setExpression('width','jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"')
                     : s.setExpression('width','this.parentNode.offsetWidth + "px"');
                if (fixL) s.setExpression('left', fixL);
                if (fixT) s.setExpression('top', fixT);
            }
            else if (opts.centerY) {
                if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
                s.marginTop = 0;
            }
        });
    }
    
    // show the message
    lyr3.append(msg).show();
    if (msg && (msg.jquery || msg.nodeType))
        $(msg).show();

    // bind key and mouse events
    bind(1, el, opts);
        
    if (full) {
        pageBlock = lyr3[0];
        pageBlockEls = $(':input:enabled:visible',pageBlock);
        if (opts.focusInput)
            setTimeout(focus, 20);
    }
    else
        center(lyr3[0], opts.centerX, opts.centerY);
};

// remove the block
function remove(el, opts) {
    var full = el == window;
    var data = $(el).data('blockUI.history');
    opts = $.extend({}, $.blockUI.defaults, opts || {});
    bind(0, el, opts); // unbind events
    var els = full ? $('body').children().filter('.blockUI') : $('.blockUI', el);
    
    if (full) 
        pageBlock = pageBlockEls = null;

    if (opts.fadeOut) {
        els.fadeOut(opts.fadeOut);
        setTimeout(function() { reset(els,data,opts,el); }, opts.fadeOut);
    }
    else
        reset(els, data, opts, el);
};

// move blocking element back into the DOM where it started
function reset(els,data,opts,el) {
    els.each(function(i,o) {
        // remove via DOM calls so we don't lose event handlers
        if (this.parentNode) 
            this.parentNode.removeChild(this);
    });
    if (data && data.el) {
        data.el.style.display = data.display;
        data.el.style.position = data.position;
        data.parent.appendChild(data.el);
        $(data.el).removeData('blockUI.history');
    }
    if (typeof opts.onUnblock == 'function')
        opts.onUnblock(el,opts);
};

// bind/unbind the handler
function bind(b, el, opts) {
    var full = el == window, $el = $(el);
    
    // don't bother unbinding if there is nothing to unbind
    if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) 
        return;
    if (!full) 
        $el.data('blockUI.isBlocked', b);
        
    // bind anchors and inputs for mouse and key events
    var events = 'mousedown mouseup keydown keypress click';
    b ? $(document).bind(events, opts, handler) : $(document).unbind(events, handler);

// former impl...
//    var $e = $('a,:input');
//    b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
};

// event handler to suppress keyboard/mouse events when blocking
function handler(e) {
    // allow tab navigation (conditionally)
    if (e.keyCode && e.keyCode == 9) {
        if (pageBlock && e.data.constrainTabKey) {
            var els = pageBlockEls;
            var fwd = !e.shiftKey && e.target == els[els.length-1];
            var back = e.shiftKey && e.target == els[0];
            if (fwd || back) {
                setTimeout(function(){focus(back)},10);
                return false;
            }
        }
    }
    // allow events within the message content
    if ($(e.target).parents('div.blockMsg').length > 0)
        return true;
        
    // allow events for content that is not being blocked
    return $(e.target).parents().children().filter('div.blockUI').length == 0;
};

function focus(back) {
    if (!pageBlockEls) 
        return;
    var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
    if (e) 
        e.focus();
};

function center(el, x, y) {
    var p = el.parentNode, s = el.style;
    var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
    var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
    if (x) s.left = l > 0 ? (l+'px') : '0';
    if (y) s.top  = t > 0 ? (t+'px') : '0';
};

function sz(el, p) { 
    return parseInt($.css(el,p))||0; 
};

})(jQuery);


/** File: javascript/jquery.jeditable.js **/

/*
+-----------------------------------------------------------------------+
| Copyright (c) 2006-2007 Mika Tuupola, Dylan Verheul                   |
| All rights reserved.                                                  |
|                                                                       |
| Redistribution and use in source and binary forms, with or without    |
| modification, are permitted provided that the following conditions    |
| are met:                                                              |
|                                                                       |
| o Redistributions of source code must retain the above copyright      |
|   notice, this list of conditions and the following disclaimer.       |
| o Redistributions in binary form must reproduce the above copyright   |
|   notice, this list of conditions and the following disclaimer in the |
|   documentation and/or other materials provided with the distribution.|
|                                                                       |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
|                                                                       |
+-----------------------------------------------------------------------+
*/

/* $Id: jquery.jeditable.js 134 2007-03-13 17:29:52Z tuupola $ */

/**
  * jQuery inplace editor plugin (version 1.2.1)  
  *
  * Based on editable by Dylan Verheul <dylan@dyve.net>
  * http://www.dyve.net/jquery/?editable
  *
  * @name  jEditable
  * @type  jQuery
  * @param String  target             POST URL or function name to send edited content
  * @param Hash    settings            additional options 
  * @param String  settings[name]      POST parameter name of edited content
  * @param String  settings[id]        POST parameter name of edited div id
  * @param String  settings[type]      text, textarea or select
  * @param Integer settings[rows]      number of rows if using textarea
  * @param Integer settings[cols]      number of columns if using textarea
  * @param String  settings[loadurl]   URL to fetch content before editing
  * @param String  settings[loadtype]  Request type for load url. Should be GET or POST.
  * @param String  settings[data]      Or content given as paramameter.
  * @param String  settings[indicator] indicator html to show when saving
  * @param String  settings[tooltip]   optional tooltip text via title attribute
  * @param String  settings[event]     jQuery event such as 'click' of 'dblclick'
  * @param String  settings[onblur]    'cancel', 'submit' or 'ignore'
  * @param String  settings[submit]    submit button value, empty means no button
  * @param String  settings[cancel]    cancel button value, empty means no button
  * @param String  settings[cssclass]  CSS class to apply to input form. 'inherit' to copy from parent.
  * @param String  settings[style]     Style to apply to input form 'inherit' to copy from parent.
  * @param String  settings[select]    true or false, when true text is highlighted
  *             
  */

jQuery.fn.editable = function(target, settings) {

    /* prevent elem has no properties error */
    if (this.length == 0) { 
        return(this); 
    };
    
    settings = jQuery.extend({
      target      : target,
      name        : 'value',
      id          : 'id',
      type        : 'text',
      event       : 'dblclick',
      onblur      : 'cancel',
      loadtype    : 'POST',
      field_class : null
    }, settings);
      
    jQuery(this).attr('title', settings.tooltip);

    jQuery(this)[settings.event](function(e) {

        /* save this to self because this changes when scope changes */
        var self = this;

        /* prevent throwing an exeption if edit field is clicked again */
        if (self.editing) {
            return;
        }

        self.editing    = true;
        self.revert     = jQuery(self).html();
        self.innerHTML  = '';

        /* create the form object */
        var f = document.createElement('form');
        
        /* apply css or style or both */
        if (settings.cssclass) {
            if ('inherit' == settings.cssclass) {
                jQuery(f).attr('class', jQuery(self).attr('class'));
            } else {
                jQuery(f).attr('class', settings.cssclass);
            }
        }
        
        if (settings.style) {
            if ('inherit' == settings.style) {
                jQuery(f).attr('style', jQuery(self).attr('style'));
            } else {
                jQuery(f).attr('style', settings.style);
            }
        }
        
        /*  main input element */
        var i;
        switch (settings.type) {
            case 'textarea':
                i = document.createElement('textarea');
                break;
            case 'select':
                i = document.createElement('select');
                break;
            default:
                i = document.createElement('input');
                i.type  = settings.type;
                /* https://bugzilla.mozilla.org/show_bug.cgi?id=236791 */
                i.setAttribute('autocomplete','off');
        }
        
        if(settings.field_class) {
          $(i).addClass(settings.field_class);
        }
        
        /* maintain bc with 1.1.1 and earlier versions */        
        if (settings.getload) {
            settings.loadurl    = settings.getload;
            settings.loadtype = 'GET';
        } else if (settings.postload) {
            settings.loadurl    = settings.postload;
            settings.loadtype = 'POST';
        }

        /* set input content via POST, GET, given data or existing value */
        if (settings.loadurl) {
            var data = {};
            data[settings.id] = self.id;
            jQuery.ajax({
               type : settings.loadtype,
               url  : settings.loadurl,
               data : data,
               success: function(str) {
                  setInputContent(str);
               }
            });
        } else if (settings.data) {
            setInputContent(settings.data);
        } else { 
            setInputContent(self.revert);
        }

        i.name  = settings.name;
        f.appendChild(i);
        
        /** Buttons div **/
        var buttons = $(document.createElement('div'));
        buttons.addClass('editableButtons');
        
        /** Submit button **/
        var submit_button = $(document.createElement('button'));
        submit_button.attr('type', 'submit');
        submit_button.html(settings.submit ? settings.submit : '<span>Submit</span>');
        
        /** Cancel button **/
        var cancel_button = $(document.createElement('button'));
        cancel_button.attr('type', 'button');
        cancel_button.html(settings.cancel ? settings.cancel : '<span>Cancel</span>');
        cancel_button.click(function() {
          reset();
        });
        
        /** And build **/
        buttons.append(submit_button);
        buttons.append(' ');
        buttons.append(cancel_button);
        
        $(f).append(buttons);

        /* add created form to self */
        self.appendChild(f);

        i.focus();
        
        /* highlight input contents when requested */
        if (settings.select) {
            i.select();
        }
         
        /* discard changes if pressing esc */
        jQuery(i).keydown(function(e) {
            if (e.keyCode == 27) {
                e.preventDefault();
                reset();
            }
        });

        /* discard, submit or nothing with changes when clicking outside */
        /* do nothing is usable when navigating with tab */
        var t;
        if ('cancel' == settings.onblur) {
            jQuery(i).blur(function(e) {
                t = setTimeout(reset, 500)
            });
        /* TODO: does not currently work */
        } else if ('submit' == settings.onblur) {
            jQuery(i).blur(function(e) {
                jQuery(f).submit();
            });
        } else {
            jQuery(i).blur(function(e) {
              /* TODO: maybe something here */
            });
        }

        jQuery(f).submit(function(e) {

            if (t) { 
                clearTimeout(t);
            }

            /* do no submit */
            e.preventDefault(); 

            /* check if given target is function */
            if (Function == settings.target.constructor) {
                var str = settings.target.apply(self, [jQuery(i).val()]);
                self.innerHTML = str;
                self.editing = false;
            } else {
                /* add edited content and id of edited element to POST */           
                var p = {'submitted' : 'submitted'};
                p[i.name] = jQuery(i).val();
                p[settings.id] = self.id;

                /* show the saving indicator */
                jQuery(self).html(settings.indicator);
                jQuery.post(settings.target, p, function(str) {
                    self.innerHTML = str;
                    self.editing = false;
                });
            }
            return false;
        });

        function reset() {
            self.innerHTML = self.revert;
            self.editing   = false;
        };
        
        function setInputContent(str) {
            switch (settings.type) { 	 
                case 'select': 	 
                    if (String == str.constructor) { 	 
                        eval ("var json = " + str);
                        for (var key in json) {
                            if ('selected' == key) {
                                continue;
                            } 
                            o = document.createElement('option'); 	 
                            o.value = key;
                            var text = document.createTextNode(json[key]);
                            o.appendChild(text)
                            if (key == json['selected']) {
                                o.selected = true;
                            }
                            i.appendChild(o); 	 
                        }
                    } 	 
                    break; 	 
                default: 	 
                    i.value = str; 	 
                    break; 	 
            } 	 
        }

    });

    return(this);
}


/** File: javascript/jquery.uni-form.js **/

/**
 * Uniform module
 */
UniForm = function() {
  
  /**
   * Counter used for form ID generation
   *
   * @var integer
   */
  var form_counter = 0;
  
  /**
   * Forms that are initialized
   *
   * @var Object
   */
  var forms = {};
  
  /**
   * Supported validators
   *
   * @var Object
   */
  var validators = {
    
    /**
     * Check if value of specific field is present
     *
     * @param jQuery field
     * @param string caption
     */
    required : function(field, caption) {
      if(jQuery.trim(field.val()) == '') {
        return App.lang('Required');
      } else {
        return true;
      }
    },
    
    /**
     * Validate is value of given field is shorter than supported
     *
     * @param jQuery field
     * @param sting caption
     */
    validate_minlength : function(field, caption) {
      var min_length = 0;
      var classes = field.attr('class').split(' ');
      
      for(var i = 0; i < classes.length; i++) {
        if(classes[i] == 'validate_minlength') {
          if((classes[i + 1] != 'undefined') && !isNaN(classes[i + 1])) {
            min_length = parseInt(classes[i + 1]);
            break;
          } // if
        } // if
      } // for
      
      if((min_length > 0) && (field.val().length < min_length)) {
        return App.lang('Min :min characters long', { min : min_length });
      } else {
        return true;
      } // if
    },
    
    /**
     * Validate if field value is longer than allowed
     *
     * @param jQuery field
     * @param string caption
     */
    validate_maxlength : function(field, caption) {
      var max_length = 0;
      var classes = field.attr('class').split(' ');
      
      for(var i = 0; i < classes.length; i++) {
        if(classes[i] == 'validate_maxlength') {
          if((classes[i + 1] != 'undefined') && !isNaN(classes[i + 1])) {
            max_length = parseInt(classes[i + 1]);
            break;
          } // if
        } // if
      } // for
      
      if((max_length > 0) && (field.val().length > max_length)) {
        return App.lang('Max :max characters long', { max : max_length });
      } else {
        return true;
      } // if
    },
    
    /**
     * Make sure that field has same value as the value of target field
     *
     * @param jQuery field
     * @param string caption
     */
    validate_same_as : function(field, caption) {
      var classes = field.attr('class').split(' ');
      var target_field_name = '';
      
      for(var i = 0; i < classes.length; i++) {
        if(classes[i] == 'validate_same_as') {
          if(classes[i + 1] != 'undefined') {
            target_field_name = classes[i + 1];
            break;
          } // if
        } // if
      } // for
      
      if(target_field_name) {
        var target_field = jQuery('#' + target_field_name);
        if(target_field.length > 0) {
          var target_field_caption = field_caption($('#' + target_field_name));
          
          if(target_field.val() != field.val()) {
            return App.lang('Values do not match');
          } // if
        } // if
      } // if
      
      return true;
    },
    
    /**
     * Validate if provided value is valid email address
     *
     * @param jQuery field
     * @param string caption
     */
    validate_email : function(field, caption) {
      if(field.val().match(/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i)) {
        return true;
      } else {
        return App.lang('Invalid address format');
      }
    },
    
    /**
     * Validate if provided value is valid URL
     *
     * @param jQuery field
     * @param string caption
     */
    validate_url : function(field, caption) {
      if(field.val().match(/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i)) {
        return true;
      } else {
        return App.lang('Invalid URL format');
      }
    }, 
    
    /**
     * Number is only valid value (integers and floats)
     *
     * @param jQuery field
     * @param string caption
     */
    validate_number : function(field, caption) {
      if(field.val().match(/(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/)) {
        return true;
      } else {
        return App.lang('Value need to be a number');
      }
    },
    
    /**
     * Whole numbers are allowed
     *
     * @param jQuery field
     * @param string caption
     */
    validate_integer : function(field, caption) {
      if(field.val().match(/(^-?\d\d*$)/)) {
        return true;
      } else {
        return App.lang('Value need to be a whole number');
      }
    },
    
    /**
     * Letters only
     *
     * @param jQuery field
     * @param string caption
     */
    validate_alpha : function(field, caption) {
      if(field.val().match(/^[a-zA-Z]+$/)) {
        return true;
      } else {
        return App.lang('Value should contain only letters');
      }
    },
    
    /**
     * Letters and numbers
     *
     * @param jQuery field
     * @param string caption
     */
    validate_alphanum : function(field, caption) {
      if(field.val().match(/\W/)) {
        return App.lang('Value should contain only numbers and letters');
      } else {
        return true;
      }
    },
    
    /**
     * Callback validator
     *
     * Lets you define your own validators. Usage:
     *
     * <input name="myinput" class="validate_callback my_callback" />
     *
     * This will result in UniForm searching for window.my_callback funciton and 
     * executing it with field and caption arguments. Sample implementation:
     *
     * window.my_callback = function(field, caption) {
     *   if(field.val() == 'A51') {
     *     return true;
     *   } else {
     *     return caption + ' value should be "A51"!';
     *   }
     * }
     *
     * @param jQuery field
     * @param caption
     */
    validate_callback : function(field, caption) {
      var classes = field.attr('class').split(' ');
      var callback_function = '';
      
      for(var i = 0; i < classes.length; i++) {
        if(classes[i] == 'validate_callback') {
          if(classes[i + 1] != 'undefined') {
            callback_function = classes[i + 1];
            break;
          } // if
        } // if
      } // for
      
      if(window[callback_function] != 'undefined' && (typeof window[callback_function] == 'function')) {
        return window[callback_function](field, caption);
      } // if
      
      //return 'Failed to validate ' + caption + ' field. Validator function (' + callback_function + ') is not defined!';
      return true;
    }
    
  };
  
  /**
   * Go through form fields and validate their values
   *
   * @param jQuery for_form
   * @param boolean all_fields If true all fields will be validated. If not only 
   *   fields user focused will be validated
   * @param boolean
   */
  var validate_form = function(for_form, all_fields) {
    var result = true;
    
    forms[for_form.attr('id')]['is_valid'] = true;
    
    if(typeof(forms[for_form.attr('id')]['validation']) == 'object') {
      for(var field_name in forms[for_form.attr('id')]['validation']) {
      
        if(all_fields || forms[for_form.attr('id')]['focused_fields'][field_name]) {
          var field = forms[for_form.attr('id')]['validation'][field_name]['field'];
          var field_caption = forms[for_form.attr('id')]['validation'][field_name]['caption'];
          var field_validators = forms[for_form.attr('id')]['validation'][field_name]['validators'];
          
          for(var validator in field_validators) {
            var validation_result = validators[validator](field, field_caption, for_form);
        
            if(typeof(validation_result) == 'string') {
              if(forms[for_form.attr('id')]['show_errors']) {
                set_field_error(field, validation_result);
              } else {
                set_field_error(field, false);
              } // if
              
              result = false;
              break;
            } else {
              remove_field_error(field);
            } // if
          } // for
        } // if
        
      }  // if
    } // if
    
    forms[for_form.attr('id')]['is_valid'] = result;
    return result;
  };
  
  /**
   * Set field error
   *
   * @param jQuery for_field
   * @param string error_message
   * @return void
   */
  var set_field_error = function(for_field, error_message) {
    var holder = find_field_holder(for_field);
    if(holder === false) {
      return;
    } // if
    
    holder.removeClass('error').find('p.errorField').remove();
    if(error_message) {
      holder.addClass('error').prepend('<p class="errorField"><strong>' + error_message + '</strong></p>');
    } else {
      holder.addClass('error');
    } // if
  };

  /**
   * Remove error div for a given field
   *
   * @param jQuery for_field
   * @return void
   */
  var remove_field_error = function(for_field) {
    var holder = find_field_holder(for_field);
    if(holder === false) {
      return;
    } // if
    
    holder.removeClass('error').find('p.errorField').remove();
  };
  
  /**
   * Return holder DIV for a given field
   *
   * @param jQuery for_field
   * @return jQuery or false if holder is not found
   */
  var find_field_holder = function(for_field) {
    var parent = for_field.parent();
      
    while(typeof(parent) == 'object') {
      if((parent[0].nodeName == 'FORM') || (parent[0].nodeName == 'BODY')) {
        return false; // exit on FORM or BODY
      } // if
      
      if(parent[0].className.indexOf('ctrlHolder') >= 0) {
        return parent;
      } // if
      parent = jQuery(parent.parent());
    } // while
    
    return false;
  };
  
  /**
   * Mark a specific field as forcused
   *
   * @param jQuery for_form
   * @param jQuery for_field
   * @return void
   */
  var mark_as_focused = function(for_form, for_field) {
    remove_field_error(for_field);
    
    if(typeof(forms[for_form.attr('id')]['focused_fields'][for_field.attr('name')]) == 'undefined') {
      forms[for_form.attr('id')]['focused_fields'][for_field.attr('name')] = true;
    } // if
    
    var holder = find_field_holder(for_field);
    if(typeof(holder) == 'object') {
      if(holder.attr('class').indexOf('focused') == -1) {
        for_form.find('.' + 'focused').removeClass('focused'); // everything else should lose focus
        holder.addClass('focused'); // and we should focus this element
      } // if
    } // if
  };
  
  /**
   * Get caption for a given field (extract it from label)
   *
   * @param jQuery for_field
   * @return string
   */
  var field_caption = function(for_field) {
    var field_id = for_field.attr('id');
    if(field_id) {
      var label = jQuery('label[for=' + field_id + ']');
      if(typeof(label) == 'object') {
        var text = label.text();
        if(text.substr(text.length - 1, 1) == '*') {
          return text.substring(0, text.length - 1);
        } else {
          return text;
        } // if
      } // if
    } // if
    return 'Field';
  };
  
  /**
   * Prepare form ID for a given form if it is not already set by the user
   *
   * @param jQuery for_form
   * @return string
   */
  var get_form_id = function(for_form) {
    var form_id = for_form.attr('id');
      
    if(!form_id) {
      form_counter++;
      form_id = 'uniform_form_' + form_counter;
      for_form.attr('id', form_id);
    } // if
    
    return form_id;
  };
  
  /**
   * Attach onunload event that will show confirmation dialog if something is 
   * changed in the form
   *
   * @param jQuery for_form
   * @return void
   */
  var ask_on_leave = function(for_form) {
    var func = function() {
      // this fixes problems with serializing tinyMCEs
      if (App.isset(window.tinyMCE) && App.isset(window.tinyMCE.activeEditor)) {
        var mce_current_raw_content = tinyMCE.activeEditor.getContent({format : 'raw'});
        if ((mce_current_raw_content == '<br mce_bogus="1">') || (mce_current_raw_content=='<br>')) {
          window.tinyMCE.activeEditor.setContent('');
        } // if
      } // if
      window.tinyMCE.activeEditor.save();
      if(!forms[for_form.attr('id')]['ok_to_submit']) {
        if(for_form.serialize() != forms[for_form.attr('id')]['initial_data']) {
          return App.lang('All changes you have made to this page will be lost!');
        } // if
      } // if
    };
        
    var oldOnBeforeUnload = window.onbeforeunload;
    if(typeof(window.onbeforeunload) != 'function') {
      window.onbeforeunload = func;
    } else {
      window.onbeforeunload = function() {
        oldOnBeforeUnload();
        func();
      } // function
    } // if
  };
  
  /**
   * Public interface
   */
  return {
    
    /**
     * Initialize form
     *
     * @param jQuery form
     * @return void
     */
    init : function(form) {
      var fields = form.find('input, select, textarea');
      var form_id = get_form_id(form);
      
      // Register form
      forms[form_id] = {
        'form'           : form,
        'fields'         : fields,
        'initial_data'   : form.serialize(),
        'validation'     : {},
        'focused_fields' : {},
        'show_errors'    : form.attr('class').indexOf('showErrors') != -1,
        'is_valid'       : true,
        'ok_to_submit'   : false
      };
      
      // Attach on unload behavior
      if(form.attr('class').indexOf('askOnLeave') != -1) {
        ask_on_leave(form);
      } // if
      
      // Walk through defined validators and maku sure that they do their trick
      for(validator in validators) {
        form.find('.' + validator).each(function() {
          var field = $(this);
          var field_name = field.attr('name');
          
          if(typeof forms[form_id]['validation'][field_name] != 'object') {
            forms[form_id]['validation'][field_name] = {
              'field'      : field,
              'caption'    : field_caption(field),
              'validators' : {}
            };
          } // if
          
          forms[form_id]['validation'][field_name]['validators'][validator] = validators[validator];
        });
      } // for
      
      fields.focus(function() {
        mark_as_focused(form, $(this));
      }).blur(function() {
        validate_form(form, false);
      });
      
      // Form submission handler
      form.submit(function(event) {
        var is_valid = validate_form(form, true);
        if(is_valid) {
          forms[form.attr('id')]['ok_to_submit'] = true;
          return true;
        } else {
          return false;
        } // if
      });
      
      if(form.attr('class').indexOf('focusFirstField') != -1) {
        UniForm.focus_first_field(form);
      } // if
      
      // ctrlHolder toggler behaviour
      form.find('.ctrlHolderToggler').each(function () {
        var holder_toggler_button = $(this);
        var holder_parent = holder_toggler_button.parent();
        if (holder_parent.is('.ctrlHolderContainer')) {
          var holder_toggled = holder_parent.find('.ctrlHolderToggled');
          if (holder_toggled.length > 0) {
            holder_toggled.hide();
          } else {
            holder_parent.find(':not(.form_ctr_holder_toggler):not(script)').hide();
          } // if         
          holder_toggler_button.show();
          
          holder_toggler_button.click(function () {
            if (holder_toggled.length > 0) {
              holder_toggled.show();
            } else {
              holder_parent.find(':not(.form_ctr_holder_toggler):not(script)').show();
            } // if  
            $(this).remove();
            return false;
          });
        } else {
          holder_toggler_button.remove();
        } // if
      });      
      
    }, // init
    
    /**
     * Returns true if specific form is inited
     *
     * @param string form_id
     * @return boolean
     */
    is_inited : function(form_id) {
      return typeof(forms[form_id]) == 'object';
    },
    
    /**
     * Focust first field in a given form
     *
     * @param jQuery form
     * @return void
     */
    focus_first_field : function(form) {
      var first_field = form.find('input, select, textarea').get(0);
      if(first_field) {
        first_field.focus();
      } // if
    }, // focus_first_field
    
    /**
     * Clear error messages in a given form
     *
     * @param jQuery form
     * @return void
     */
    clear_error_messages : function(form) {
      form.find('.ctrlHolder.error').removeClass('error').find('p.errorField').remove();
    }, // clear_error_messages
    
    /**
     * Go through form and do the validation
     *
     * @param jQuery form
     * @param boolean all_fields
     * @return boolean
     */
    validate : function(form, all_fields) {
      return validate_form(form, all_fields);
    }, // validate
    
    /**
     * Returns true if form is valid
     *
     * If form is not validated true will be returned because this function does 
     * not know whether form is valid or not
     *
     * @param jQuery form
     * @return boolean
     */
    is_valid : function(form) {
      if(typeof(forms[form.attr('id')]) == 'object') {
        return forms[form.attr('id')]['is_valid'];
      } else {
        return true;
      } // if
    }, // is_valid
    
    /**
     * Mark given field as focused
     *
     * @param jQuery form
     * @param jQuery field
     * @return void
     */
    focus_field : function(form, field) {
      mark_as_focused(form, field);
    } // focus_field
    
  };
  
}();

/**
 * Register jQuery plugin
 */
jQuery.fn.uniform = function() {
  return this.each(function() {
    UniForm.init($(this));
  });
}; // uniform

/**
 * Focus first field in selected forms
 */
jQuery.fn.focusFirstField = function() {
  return this.each(function() {
    UniForm.focus_first_field($(this));
  });
}; //focusFirstField

/**
 * Clear error messages in selected forms
 */
jQuery.fn.clearErrorMessages = function() {
  return this.each(function() {
    UniForm.clear_error_messages($(this));
  });
};

/** File: javascript/jquery.checkboxes.js **/

/**
 * Build behavior that is required for a group of checkboxes, action select box 
 * and submit button to work as expected
 *
 * Settings:
 *
 * - master_checkbox_class - class of master checkbox
 * - slave_checkbox_class - class that slave checkboxe use
 * - select_action_class - class of select action box (needs to be SELECT element)
 * - submit_action_class - class of submit button box (needs to be BUTTON element)
 */
jQuery.fn.checkboxes = function(settings) {
  settings = jQuery.extend({
    master_checkbox_class : 'master_checkbox',
    slave_checkbox_class  : 'slave_checkbox'
  }, settings);
  
  return this.each(function() {
    var parent = $(this);
    
    var master_checkbox = parent.find('input.' + settings.master_checkbox_class);
    var slave_checkboxes = parent.find('input.' + settings.slave_checkbox_class);
    var select_action = jQuery('#' + parent.attr('id') + '_action');
    var submit_action = jQuery('#' + parent.attr('id') + '_submit');
    
    /**
     * Simple handler that is called when we change something to see if submit 
     * button needs to be enabled or disabled
     */
    var enabled_disable_submit_button = function() {
      var submit_enabled = (select_action.val() != '') && (parent.find('input.' + settings.slave_checkbox_class + ':checked').length > 0);
      if(submit_enabled) {
        submit_action.attr('disabled', '').removeClass('button_disabled');
      } else {
        submit_action.attr('disabled', 'submit').addClass('button_disabled');
      } // if
    } // enabled_disable_submit_button
    
    // execute button disable function on initialisation
    enabled_disable_submit_button();
    
    /**
     * Click on master checkbox checks or unchecks all slave checkboxes (plus 
     * submit disabled / enabled value needs to be refreshed)
     */
    master_checkbox.click(function() {
      if(this.checked) {
        slave_checkboxes.checkCheckboxes();
      } else {
        slave_checkboxes.uncheckCheckboxes();
      } // if
      enabled_disable_submit_button();
    });
    
    /**
     * Click on slave checkbox can change checked value of master checkbox
     */
    slave_checkboxes.click(function() {
      var all_checked = true;
      slave_checkboxes.each(function() {
        if(!this.checked) {
          all_checked = false;
        } // if
      });
      
      master_checkbox[0].checked = all_checked;
      enabled_disable_submit_button();
    });
    
    /**
     * Select box change also results in recheck whether submit button needs to 
     * be enabled or disabled
     */
    select_action
      .change(enabled_disable_submit_button)
      .click(enabled_disable_submit_button)
      .keypress(enabled_disable_submit_button);
    
  }); // each
};

/**
 * Mark all checkboxes as checked
 */
jQuery.fn.checkCheckboxes = function() {
  return this.each(function() {
    this.checked = true;
  });
};

/**
 * Mark all checkboxes as unchecked
 */
jQuery.fn.uncheckCheckboxes = function() {
  return this.each(function() {
    this.checked = false;
  });
};

/** File: javascript/jquery.datepicker.js **/

/**
 * Copyright (c) 2008 Kelvin Luck (http://www.kelvinluck.com/)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $Id: jquery.datePicker.js 18 2008-12-23 23:37:34Z kelvin.luck $
 **/

(function($){
    
	$.fn.extend({
/**
 * Render a calendar table into any matched elements.
 * 
 * @param Object s (optional) Customize your calendars.
 * @option Number month The month to render (NOTE that months are zero based). Default is today's month.
 * @option Number year The year to render. Default is today's year.
 * @option Function renderCallback A reference to a function that is called as each cell is rendered and which can add classes and event listeners to the created nodes. Default is no callback.
 * @option Number showHeader Whether or not to show the header row, possible values are: $.dpConst.SHOW_HEADER_NONE (no header), $.dpConst.SHOW_HEADER_SHORT (first letter of each day) and $.dpConst.SHOW_HEADER_LONG (full name of each day). Default is $.dpConst.SHOW_HEADER_SHORT.
 * @option String hoverClass The class to attach to each cell when you hover over it (to allow you to use hover effects in IE6 which doesn't support the :hover pseudo-class on elements other than links). Default is dp-hover. Pass false if you don't want a hover class.
 * @type jQuery
 * @name renderCalendar
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('#calendar-me').renderCalendar({month:0, year:2007});
 * @desc Renders a calendar displaying January 2007 into the element with an id of calendar-me.
 *
 * @example
 * var testCallback = function($td, thisDate, month, year)
 * {
 * if ($td.is('.current-month') && thisDate.getDay() == 4) {
 *		var d = thisDate.getDate();
 *		$td.bind(
 *			'click',
 *			function()
 *			{
 *				alert('You clicked on ' + d + '/' + (Number(month)+1) + '/' + year);
 *			}
 *		).addClass('thursday');
 *	} else if (thisDate.getDay() == 5) {
 *		$td.html('Friday the ' + $td.html() + 'th');
 *	}
 * }
 * $('#calendar-me').renderCalendar({month:0, year:2007, renderCallback:testCallback});
 * 
 * @desc Renders a calendar displaying January 2007 into the element with an id of calendar-me. Every Thursday in the current month has a class of "thursday" applied to it, is clickable and shows an alert when clicked. Every Friday on the calendar has the number inside replaced with text.
 **/
		renderCalendar  :   function(s)
		{
			var dc = function(a)
			{
				return document.createElement(a);
			};

			s = $.extend({}, $.fn.datePicker.defaults, s);
			
			if (s.showHeader != $.dpConst.SHOW_HEADER_NONE) {
				var headRow = $(dc('tr'));
				for (var i=Date.firstDayOfWeek; i<Date.firstDayOfWeek+7; i++) {
					var weekday = i%7;
					var day = Date.dayNames[weekday];
					headRow.append(
						jQuery(dc('th')).attr({'scope':'col', 'abbr':day, 'title':day, 'class':(weekday == 0 || weekday == 6 ? 'weekend' : 'weekday')}).html(s.showHeader == $.dpConst.SHOW_HEADER_SHORT ? day.substr(0, 1) : day)
					);
				}
			};
			
			var calendarTable = $(dc('table'))
									.attr(
										{
											'cellspacing':2,
											'className':'jCalendar'
										}
									)
									.append(
										(s.showHeader != $.dpConst.SHOW_HEADER_NONE ? 
											$(dc('thead'))
												.append(headRow)
											:
											dc('thead')
										)
									);
			var tbody = $(dc('tbody'));
			
			var today = (new Date()).zeroTime();
			
			var month = s.month == undefined ? today.getMonth() : s.month;
			var year = s.year || today.getFullYear();
			
			var currentDate = new Date(year, month, 1);
			
			
			var firstDayOffset = Date.firstDayOfWeek - currentDate.getDay() + 1;
			if (firstDayOffset > 1) firstDayOffset -= 7;
			var weeksToDraw = Math.ceil(( (-1*firstDayOffset+1) + currentDate.getDaysInMonth() ) /7);
			currentDate.addDays(firstDayOffset-1);
			
			var doHover = function()
			{
				if (s.hoverClass) {
					$(this).addClass(s.hoverClass);
				}
			};
			var unHover = function()
			{
				if (s.hoverClass) {
					$(this).removeClass(s.hoverClass);
				}
			};	
			
			var w = 0;
			while (w++<weeksToDraw) {
				var r = jQuery(dc('tr'));
				for (var i=0; i<7; i++) {
					var thisMonth = currentDate.getMonth() == month;
					var d = $(dc('td'))
								.text(currentDate.getDate() + '')
								.attr('className', (thisMonth ? 'current-month ' : 'other-month ') +
													(currentDate.isWeekend() ? 'weekend ' : 'weekday ') +
													(thisMonth && currentDate.getTime() == today.getTime() ? 'today ' : '')
								)
								.hover(doHover, unHover)
							;
					if (s.renderCallback) {
						s.renderCallback(d, currentDate, month, year);
					}
					r.append(d);
					currentDate.addDays(1);
				}
				tbody.append(r);
			}
			calendarTable.append(tbody);
			
			return this.each(
				function()
				{
					$(this).empty().append(calendarTable);
				}
			);
		},
/**
 * Create a datePicker associated with each of the matched elements.
 *
 * The matched element will receive a few custom events with the following signatures:
 *
 * dateSelected(event, date, $td, status)
 * Triggered when a date is selected. event is a reference to the event, date is the Date selected, $td is a jquery object wrapped around the TD that was clicked on and status is whether the date was selected (true) or deselected (false)
 * 
 * dpClosed(event, selected)
 * Triggered when the date picker is closed. event is a reference to the event and selected is an Array containing Date objects.
 *
 * dpMonthChanged(event, displayedMonth, displayedYear)
 * Triggered when the month of the popped up calendar is changed. event is a reference to the event, displayedMonth is the number of the month now displayed (zero based) and displayedYear is the year of the month.
 *
 * dpDisplayed(event, $datePickerDiv)
 * Triggered when the date picker is created. $datePickerDiv is the div containing the date picker. Use this event to add custom content/ listeners to the popped up date picker.
 *
 * @param Object s (optional) Customize your date pickers.
 * @option Number month The month to render when the date picker is opened (NOTE that months are zero based). Default is today's month.
 * @option Number year The year to render when the date picker is opened. Default is today's year.
 * @option String startDate The first date date can be selected.
 * @option String endDate The last date that can be selected.
 * @option Boolean inline Whether to create the datePicker as inline (e.g. always on the page) or as a model popup. Default is false (== modal popup)
 * @option Boolean createButton Whether to create a .dp-choose-date anchor directly after the matched element which when clicked will trigger the showing of the date picker. Default is true.
 * @option Boolean showYearNavigation Whether to display buttons which allow the user to navigate through the months a year at a time. Default is true.
 * @option Boolean closeOnSelect Whether to close the date picker when a date is selected. Default is true.
 * @option Boolean displayClose Whether to create a "Close" button within the date picker popup. Default is false.
 * @option Boolean selectMultiple Whether a user should be able to select multiple dates with this date picker. Default is false.
 * @option Boolean clickInput If the matched element is an input type="text" and this option is true then clicking on the input will cause the date picker to appear.
 * @option Number verticalPosition The vertical alignment of the popped up date picker to the matched element. One of $.dpConst.POS_TOP and $.dpConst.POS_BOTTOM. Default is $.dpConst.POS_TOP.
 * @option Number horizontalPosition The horizontal alignment of the popped up date picker to the matched element. One of $.dpConst.POS_LEFT and $.dpConst.POS_RIGHT.
 * @option Number verticalOffset The number of pixels offset from the defined verticalPosition of this date picker that it should pop up in. Default in 0.
 * @option Number horizontalOffset The number of pixels offset from the defined horizontalPosition of this date picker that it should pop up in. Default in 0.
 * @option (Function|Array) renderCallback A reference to a function (or an array of seperate functions) that is called as each cell is rendered and which can add classes and event listeners to the created nodes. Each callback function will receive four arguments; a jquery object wrapping the created TD, a Date object containing the date this TD represents, a number giving the currently rendered month and a number giving the currently rendered year. Default is no callback.
 * @option String hoverClass The class to attach to each cell when you hover over it (to allow you to use hover effects in IE6 which doesn't support the :hover pseudo-class on elements other than links). Default is dp-hover. Pass false if you don't want a hover class.
 * @type jQuery
 * @name datePicker
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('input.date-picker').datePicker();
 * @desc Creates a date picker button next to all matched input elements. When the button is clicked on the value of the selected date will be placed in the corresponding input (formatted according to Date.format).
 *
 * @example demo/index.html
 * @desc See the projects homepage for many more complex examples...
 **/
		datePicker : function(s)
		{			
			if (!$.event._dpCache) $.event._dpCache = [];
			
			// initialise the date picker controller with the relevant settings...
			s = $.extend({}, $.fn.datePicker.defaults, s);
			
			return this.each(
				function()
				{
					var $this = $(this);
					var alreadyExists = true;
					
					if (!this._dpId) {
						this._dpId = $.event.guid++;
						$.event._dpCache[this._dpId] = new DatePicker(this);
						alreadyExists = false;
					}
					
					if (s.inline) {
						s.createButton = false;
						s.displayClose = false;
						s.closeOnSelect = false;
						$this.empty();
					}
					
					var controller = $.event._dpCache[this._dpId];
					
					controller.init(s);
					
					if (!alreadyExists && s.createButton) {
						// create it!
						controller.button = $('<a href="#" class="dp-choose-date" title="' + $.dpText.TEXT_CHOOSE_DATE + '">' + $.dpText.TEXT_CHOOSE_DATE + '</a>')
								.bind(
									'click',
									function()
									{
									  var parents = $this.parents('.form_right_col');									  
									  if (($('body').innerWidth() < 1190) && (parents.length > 0)) {
									    $this.dpSetPosition($.dpConst.POS_TOP, $.dpConst.POS_RIGHT);
									  } else {
									    $this.dpSetPosition($.dpConst.POS_TOP, $.dpConst.POS_LEFT);
									  } // if
										$this.dpDisplay(this);
										this.blur();
										return false;
									}
								);
						$this.after(controller.button);
					}
					
					if (!alreadyExists && $this.is(':text')) {
						$this
							.bind(
								'dateSelected',
								function(e, selectedDate, $td)
								{
									this.value = selectedDate.asString();
								}
							).bind(
								'change',
								function()
								{
									if (this.value != '') {
										var d = Date.fromString(this.value);
										if (d) {
											controller.setSelected(d, true, true);
										}
									}
								}
							);
						if (s.clickInput) {
							$this.bind(
								'click',
								function()
								{
									$this.dpDisplay();
								}
							);
						}
						var d = Date.fromString(this.value);
						if (this.value != '' && d) {
							controller.setSelected(d, true, true);
						}
					}
					
					$this.addClass('dp-applied');
					
				}
			)
		},
/**
 * Disables or enables this date picker
 *
 * @param Boolean s Whether to disable (true) or enable (false) this datePicker
 * @type jQuery
 * @name dpSetDisabled
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('.date-picker').datePicker();
 * $('.date-picker').dpSetDisabled(true);
 * @desc Prevents this date picker from displaying and adds a class of dp-disabled to it (and it's associated button if it has one) for styling purposes. If the matched element is an input field then it will also set the disabled attribute to stop people directly editing the field.
 **/
		dpSetDisabled : function(s)
		{
			return _w.call(this, 'setDisabled', s);
		},
/**
 * Updates the first selectable date for any date pickers on any matched elements.
 *
 * @param String d A string representing the first selectable date (formatted according to Date.format).
 * @type jQuery
 * @name dpSetStartDate
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('.date-picker').datePicker();
 * $('.date-picker').dpSetStartDate('01/01/2000');
 * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the first selectable date for each of these to the first day of the millenium.
 **/
		dpSetStartDate : function(d)
		{
			return _w.call(this, 'setStartDate', d);
		},
/**
 * Updates the last selectable date for any date pickers on any matched elements.
 *
 * @param String d A string representing the last selectable date (formatted according to Date.format).
 * @type jQuery
 * @name dpSetEndDate
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('.date-picker').datePicker();
 * $('.date-picker').dpSetEndDate('01/01/2010');
 * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the last selectable date for each of these to the first Janurary 2010.
 **/
		dpSetEndDate : function(d)
		{
			return _w.call(this, 'setEndDate', d);
		},
/**
 * Gets a list of Dates currently selected by this datePicker. This will be an empty array if no dates are currently selected or NULL if there is no datePicker associated with the matched element.
 *
 * @type Array
 * @name dpGetSelected
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('.date-picker').datePicker();
 * alert($('.date-picker').dpGetSelected());
 * @desc Will alert an empty array (as nothing is selected yet)
 **/
		dpGetSelected : function()
		{
			var c = _getController(this[0]);
			if (c) {
				return c.getSelected();
			}
			return null;
		},
/**
 * Selects or deselects a date on any matched element's date pickers. Deselcting is only useful on date pickers where selectMultiple==true. Selecting will only work if the passed date is within the startDate and endDate boundries for a given date picker.
 *
 * @param String d A string representing the date you want to select (formatted according to Date.format).
 * @param Boolean v Whether you want to select (true) or deselect (false) this date. Optional - default = true.
 * @param Boolean m Whether you want the date picker to open up on the month of this date when it is next opened. Optional - default = true.
 * @type jQuery
 * @name dpSetSelected
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('.date-picker').datePicker();
 * $('.date-picker').dpSetSelected('01/01/2010');
 * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the selected date on these date pickers to the first Janurary 2010. When the date picker is next opened it will display Janurary 2010.
 **/
		dpSetSelected : function(d, v, m)
		{
			if (v == undefined) v=true;
			if (m == undefined) m=true;
			return _w.call(this, 'setSelected', Date.fromString(d), v, m, true);
		},
/**
 * Sets the month that will be displayed when the date picker is next opened. If the passed month is before startDate then the month containing startDate will be displayed instead. If the passed month is after endDate then the month containing the endDate will be displayed instead.
 *
 * @param Number m The month you want the date picker to display. Optional - defaults to the currently displayed month.
 * @param Number y The year you want the date picker to display. Optional - defaults to the currently displayed year.
 * @type jQuery
 * @name dpSetDisplayedMonth
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('.date-picker').datePicker();
 * $('.date-picker').dpSetDisplayedMonth(10, 2008);
 * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the selected date on these date pickers to the first Janurary 2010. When the date picker is next opened it will display Janurary 2010.
 **/
		dpSetDisplayedMonth : function(m, y)
		{
			return _w.call(this, 'setDisplayedMonth', Number(m), Number(y), true);
		},
/**
 * Displays the date picker associated with the matched elements. Since only one date picker can be displayed at once then the date picker associated with the last matched element will be the one that is displayed.
 *
 * @param HTMLElement e An element that you want the date picker to pop up relative in position to. Optional - default behaviour is to pop up next to the element associated with this date picker.
 * @type jQuery
 * @name dpDisplay
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('#date-picker').datePicker();
 * $('#date-picker').dpDisplay();
 * @desc Creates a date picker associated with the element with an id of date-picker and then causes it to pop up.
 **/
		dpDisplay : function(e)
		{
			return _w.call(this, 'display', e);
		},
/**
 * Sets a function or array of functions that is called when each TD of the date picker popup is rendered to the page
 *
 * @param (Function|Array) a A function or an array of functions that are called when each td is rendered. Each function will receive four arguments; a jquery object wrapping the created TD, a Date object containing the date this TD represents, a number giving the currently rendered month and a number giving the currently rendered year.
 * @type jQuery
 * @name dpSetRenderCallback
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('#date-picker').datePicker();
 * $('#date-picker').dpSetRenderCallback(function($td, thisDate, month, year)
 * {
 * 	// do stuff as each td is rendered dependant on the date in the td and the displayed month and year
 * });
 * @desc Creates a date picker associated with the element with an id of date-picker and then creates a function which is called as each td is rendered when this date picker is displayed.
 **/
		dpSetRenderCallback : function(a)
		{
			return _w.call(this, 'setRenderCallback', a);
		},
/**
 * Sets the position that the datePicker will pop up (relative to it's associated element)
 *
 * @param Number v The vertical alignment of the created date picker to it's associated element. Possible values are $.dpConst.POS_TOP and $.dpConst.POS_BOTTOM
 * @param Number h The horizontal alignment of the created date picker to it's associated element. Possible values are $.dpConst.POS_LEFT and $.dpConst.POS_RIGHT
 * @type jQuery
 * @name dpSetPosition
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('#date-picker').datePicker();
 * $('#date-picker').dpSetPosition($.dpConst.POS_BOTTOM, $.dpConst.POS_RIGHT);
 * @desc Creates a date picker associated with the element with an id of date-picker and makes it so that when this date picker pops up it will be bottom and right aligned to the #date-picker element.
 **/
		dpSetPosition : function(v, h)
		{
			return _w.call(this, 'setPosition', v, h);
		},
/**
 * Sets the offset that the popped up date picker will have from it's default position relative to it's associated element (as set by dpSetPosition)
 *
 * @param Number v The vertical offset of the created date picker.
 * @param Number h The horizontal offset of the created date picker.
 * @type jQuery
 * @name dpSetOffset
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('#date-picker').datePicker();
 * $('#date-picker').dpSetOffset(-20, 200);
 * @desc Creates a date picker associated with the element with an id of date-picker and makes it so that when this date picker pops up it will be 20 pixels above and 200 pixels to the right of it's default position.
 **/
		dpSetOffset : function(v, h)
		{
			return _w.call(this, 'setOffset', v, h);
		},
/**
 * Closes the open date picker associated with this element.
 *
 * @type jQuery
 * @name dpClose
 * @cat plugins/datePicker
 * @author Kelvin Luck (http://www.kelvinluck.com/)
 *
 * @example $('.date-pick')
 *		.datePicker()
 *		.bind(
 *			'focus',
 *			function()
 *			{
 *				$(this).dpDisplay();
 *			}
 *		).bind(
 *			'blur',
 *			function()
 *			{
 *				$(this).dpClose();
 *			}
 *		);
 * @desc Creates a date picker and makes it appear when the relevant element is focused and disappear when it is blurred.
 **/
		dpClose : function()
		{
			return _w.call(this, '_closeCalendar', false, this[0]);
		},
		// private function called on unload to clean up any expandos etc and prevent memory links...
		_dpDestroy : function()
		{
			// TODO - implement this?
		}
	});
	
	// private internal function to cut down on the amount of code needed where we forward
	// dp* methods on the jQuery object on to the relevant DatePicker controllers...
	var _w = function(f, a1, a2, a3, a4)
	{
		return this.each(
			function()
			{
				var c = _getController(this);
				if (c) {
					c[f](a1, a2, a3, a4);
				}
			}
		);
	};
	
	function DatePicker(ele)
	{
		this.ele = ele;
		
		// initial values...
		this.displayedMonth		=	null;
		this.displayedYear		=	null;
		this.startDate			=	null;
		this.endDate			=	null;
		this.showYearNavigation	=	null;
		this.closeOnSelect		=	null;
		this.displayClose		=	null;
		this.selectMultiple		=	null;
		this.verticalPosition	=	null;
		this.horizontalPosition	=	null;
		this.verticalOffset		=	null;
		this.horizontalOffset	=	null;
		this.button				=	null;
		this.renderCallback		=	[];
		this.selectedDates		=	{};
		this.inline				=	null;
		this.context			=	'#dp-popup';
	};
	$.extend(
		DatePicker.prototype,
		{	
			init : function(s)
			{
				this.setStartDate(s.startDate);
				this.setEndDate(s.endDate);
				this.setDisplayedMonth(Number(s.month), Number(s.year));
				this.setRenderCallback(s.renderCallback);
				this.showYearNavigation = s.showYearNavigation;
				this.closeOnSelect = s.closeOnSelect;
				this.displayClose = s.displayClose;
				this.selectMultiple = s.selectMultiple;
				this.verticalPosition = s.verticalPosition;
				this.horizontalPosition = s.horizontalPosition;
				this.hoverClass = s.hoverClass;
				this.setOffset(s.verticalOffset, s.horizontalOffset);
				this.inline = s.inline;
				if (this.inline) {
					this.context = this.ele;
					this.display();
				}
			},
			setStartDate : function(d)
			{
				if (d) {
					this.startDate = Date.fromString(d);
				}
				if (!this.startDate) {
					this.startDate = (new Date()).zeroTime();
				}
				this.setDisplayedMonth(this.displayedMonth, this.displayedYear);
			},
			setEndDate : function(d)
			{
				if (d) {
					this.endDate = Date.fromString(d);
				}
				if (!this.endDate) {
					this.endDate = (new Date('12/31/2999')); // using the JS Date.parse function which expects mm/dd/yyyy
				}
				if (this.endDate.getTime() < this.startDate.getTime()) {
					this.endDate = this.startDate;
				}
				this.setDisplayedMonth(this.displayedMonth, this.displayedYear);
			},
			setPosition : function(v, h)
			{
				this.verticalPosition = v;
				this.horizontalPosition = h;
			},
			setOffset : function(v, h)
			{
				this.verticalOffset = parseInt(v) || 0;
				this.horizontalOffset = parseInt(h) || 0;
			},
			setDisabled : function(s)
			{
				$e = $(this.ele);
				$e[s ? 'addClass' : 'removeClass']('dp-disabled');
				if (this.button) {
					$but = $(this.button);
					$but[s ? 'addClass' : 'removeClass']('dp-disabled');
					$but.attr('title', s ? '' : $.dpText.TEXT_CHOOSE_DATE);
				}
				if ($e.is(':text')) {
					$e.attr('disabled', s ? 'disabled' : '');
				}
			},
			setDisplayedMonth : function(m, y, rerender)
			{
				if (this.startDate == undefined || this.endDate == undefined) {
					return;
				}
				var s = new Date(this.startDate.getTime());
				s.setDate(1);
				var e = new Date(this.endDate.getTime());
				e.setDate(1);
				
				var t;
				if ((!m && !y) || (isNaN(m) && isNaN(y))) {
					// no month or year passed - default to current month
					t = new Date().zeroTime();
					t.setDate(1);
				} else if (isNaN(m)) {
					// just year passed in - presume we want the displayedMonth
					t = new Date(y, this.displayedMonth, 1);
				} else if (isNaN(y)) {
					// just month passed in - presume we want the displayedYear
					t = new Date(this.displayedYear, m, 1);
				} else {
					// year and month passed in - that's the date we want!
					t = new Date(y, m, 1)
				}
				// check if the desired date is within the range of our defined startDate and endDate
				if (t.getTime() < s.getTime()) {
					t = s;
				} else if (t.getTime() > e.getTime()) {
					t = e;
				}
				var oldMonth = this.displayedMonth;
				var oldYear = this.displayedYear;
				this.displayedMonth = t.getMonth();
				this.displayedYear = t.getFullYear();

				if (rerender && (this.displayedMonth != oldMonth || this.displayedYear != oldYear))
				{
					this._rerenderCalendar();
					$(this.ele).trigger('dpMonthChanged', [this.displayedMonth, this.displayedYear]);
				}
			},
			setSelected : function(d, v, moveToMonth, dispatchEvents)
			{
				if (v == this.isSelected(d)) // this date is already un/selected
				{
					return;
				}
				if (this.selectMultiple == false) {
					this.selectedDates = {};
					$('td.selected', this.context).removeClass('selected');
				}
				if (moveToMonth && this.displayedMonth != d.getMonth()) {
					this.setDisplayedMonth(d.getMonth(), d.getFullYear(), true);
				}
				this.selectedDates[d.toString()] = v;
				
				var selectorString = 'td.';
				selectorString += d.getMonth() == this.displayedMonth ? 'current-month' : 'other-month';
				selectorString += ':contains("' + d.getDate() + '")';
				var $td;
				$(selectorString, this.ele).each(
					function()
					{
						if ($(this).text() == d.getDate())
						{
							$td = $(this);
							$td[v ? 'addClass' : 'removeClass']('selected');
						}
					}
				);
				
				if (dispatchEvents)
				{
					var s = this.isSelected(d);
					$e = $(this.ele);
					var dClone = Date.fromString(d.asString());
					$e.trigger('dateSelected', [dClone, $td, s]);
					$e.trigger('change');
				}
			},
			isSelected : function(d)
			{
				return this.selectedDates[d.toString()];
			},
			getSelected : function()
			{
				var r = [];
				for(s in this.selectedDates) {
					if (this.selectedDates[s] == true) {
						r.push(Date.parse(s));
					}
				}
				return r;
			},
			display : function(eleAlignTo)
			{
				if ($(this.ele).is('.dp-disabled')) return;
				
				eleAlignTo = eleAlignTo || this.ele;
				var c = this;
				var $ele = $(eleAlignTo);
				var eleOffset = $ele.offset();
				
				var $createIn;
				var attrs;
				var attrsCalendarHolder;
				var cssRules;
				
				if (c.inline) {
					$createIn = $(this.ele);
					attrs = {
						'id'		:	'calendar-' + this.ele._dpId,
						'className'	:	'dp-popup dp-popup-inline'
					};
					cssRules = {
					};
				} else {
					$createIn = $('body');
					attrs = {
						'id'		:	'dp-popup',
						'className'	:	'dp-popup'
					};
					cssRules = {
						'top'	:	eleOffset.top + c.verticalOffset,
						'left'	:	eleOffset.left + c.horizontalOffset
					};
					
					var _checkMouse = function(e)
					{
						var el = e.target;
						var cal = $('#dp-popup')[0];
						
						while (true){
							if (el == cal) {
								return true;
							} else if (el == document) {
								c._closeCalendar();
								return false;
							} else {
								el = $(el).parent()[0];
							}
						}
					};
					this._checkMouse = _checkMouse;
				
					this._closeCalendar(true);
				}
				
				
				$createIn
					.append(
						$('<div></div>')
							.attr(attrs)
							.css(cssRules)
							.append(
								$('<h2></h2>'),
								$('<div class="dp-nav-prev"></div>')
									.append(
										$('<a class="dp-nav-prev-year" href="#" title="' + $.dpText.TEXT_PREV_YEAR + '">&lt;&lt;</a>')
											.bind(
												'click',
												function()
												{
													return c._displayNewMonth.call(c, this, 0, -1);
												}
											),
										$('<a class="dp-nav-prev-month" href="#" title="' + $.dpText.TEXT_PREV_MONTH + '">&lt;</a>')
											.bind(
												'click',
												function()
												{
													return c._displayNewMonth.call(c, this, -1, 0);
												}
											)
									),
								$('<div class="dp-nav-next"></div>')
									.append(
										$('<a class="dp-nav-next-year" href="#" title="' + $.dpText.TEXT_NEXT_YEAR + '">&gt;&gt;</a>')
											.bind(
												'click',
												function()
												{
													return c._displayNewMonth.call(c, this, 0, 1);
												}
											),
										$('<a class="dp-nav-next-month" href="#" title="' + $.dpText.TEXT_NEXT_MONTH + '">&gt;</a>')
											.bind(
												'click',
												function()
												{
													return c._displayNewMonth.call(c, this, 1, 0);
												}
											)
									),
								$('<div></div>')
									.attr('className', 'dp-calendar')
							)
							.bgIframe()
						);
					
				var $pop = this.inline ? $('.dp-popup', this.context) : $('#dp-popup');
				
				if (this.showYearNavigation == false) {
					$('.dp-nav-prev-year, .dp-nav-next-year', c.context).css('display', 'none');
				}
				if (this.displayClose) {
					$pop.append(
						$('<a href="#" id="dp-close">' + $.dpText.TEXT_CLOSE + '</a>')
							.bind(
								'click',
								function()
								{
									c._closeCalendar();
									return false;
								}
							)
					);
				}
				c._renderCalendar();
				
				$(this.ele).trigger('dpDisplayed', $pop);
				
				if (!c.inline) {
					if (this.verticalPosition == $.dpConst.POS_BOTTOM) {
						$pop.css('top', eleOffset.top + $ele.height() - $pop.height() + c.verticalOffset);
					}
					if (this.horizontalPosition == $.dpConst.POS_RIGHT) {
						$pop.css('left', eleOffset.left + $ele.width() - $pop.width() + c.horizontalOffset);
					}
					$(document).bind('mousedown', this._checkMouse);
				}
			},
			setRenderCallback : function(a)
			{
				if (a == null) return;
				if (a && typeof(a) == 'function') {
					a = [a];
				}
				this.renderCallback = this.renderCallback.concat(a);
			},
			cellRender : function ($td, thisDate, month, year) {
				var c = this.dpController;
				var d = new Date(thisDate.getTime());
				
				// add our click handlers to deal with it when the days are clicked...
				
				$td.bind(
					'click',
					function()
					{
						var $this = $(this);
						if (!$this.is('.disabled')) {
							c.setSelected(d, !$this.is('.selected') || !c.selectMultiple, false, true);
							if (c.closeOnSelect) {
								c._closeCalendar();
							}
						}
					}
				);
				
				if (c.isSelected(d)) {
					$td.addClass('selected');
				}
				
				// call any extra renderCallbacks that were passed in
				for (var i=0; i<c.renderCallback.length; i++) {
					c.renderCallback[i].apply(this, arguments);
				}
				
				
			},
			// ele is the clicked button - only proceed if it doesn't have the class disabled...
			// m and y are -1, 0 or 1 depending which direction we want to go in...
			_displayNewMonth : function(ele, m, y) 
			{
				if (!$(ele).is('.disabled')) {
					this.setDisplayedMonth(this.displayedMonth + m, this.displayedYear + y, true);
				}
				ele.blur();
				return false;
			},
			_rerenderCalendar : function()
			{
				this._clearCalendar();
				this._renderCalendar();
			},
			_renderCalendar : function()
			{
				// set the title...
				$('h2', this.context).html(Date.monthNames[this.displayedMonth] + ' ' + this.displayedYear);
				
				// render the calendar...
				$('.dp-calendar', this.context).renderCalendar(
					{
						month			: this.displayedMonth,
						year			: this.displayedYear,
						renderCallback	: this.cellRender,
						dpController	: this,
						hoverClass		: this.hoverClass
					}
				);
				
				// update the status of the control buttons and disable dates before startDate or after endDate...
				// TODO: When should the year buttons be disabled? When you can't go forward a whole year from where you are or is that annoying?
				if (this.displayedYear == this.startDate.getFullYear() && this.displayedMonth == this.startDate.getMonth()) {
					$('.dp-nav-prev-year', this.context).addClass('disabled');
					$('.dp-nav-prev-month', this.context).addClass('disabled');
					$('.dp-calendar td.other-month', this.context).each(
						function()
						{
							var $this = $(this);
							if (Number($this.text()) > 20) {
								$this.addClass('disabled');
							}
						}
					);
					var d = this.startDate.getDate();
					$('.dp-calendar td.current-month', this.context).each(
						function()
						{
							var $this = $(this);
							if (Number($this.text()) < d) {
								$this.addClass('disabled');
							}
						}
					);
				} else {
					$('.dp-nav-prev-year', this.context).removeClass('disabled');
					$('.dp-nav-prev-month', this.context).removeClass('disabled');
					var d = this.startDate.getDate();
					if (d > 20) {
						// check if the startDate is last month as we might need to add some disabled classes...
						var sd = new Date(this.startDate.getTime());
						sd.addMonths(1);
						if (this.displayedYear == sd.getFullYear() && this.displayedMonth == sd.getMonth()) {
							$('dp-calendar td.other-month', this.context).each(
								function()
								{
									var $this = $(this);
									if (Number($this.text()) < d) {
										$this.addClass('disabled');
									}
								}
							);
						}
					}
				}
				if (this.displayedYear == this.endDate.getFullYear() && this.displayedMonth == this.endDate.getMonth()) {
					$('.dp-nav-next-year', this.context).addClass('disabled');
					$('.dp-nav-next-month', this.context).addClass('disabled');
					$('.dp-calendar td.other-month', this.context).each(
						function()
						{
							var $this = $(this);
							if (Number($this.text()) < 14) {
								$this.addClass('disabled');
							}
						}
					);
					var d = this.endDate.getDate();
					$('.dp-calendar td.current-month', this.context).each(
						function()
						{
							var $this = $(this);
							if (Number($this.text()) > d) {
								$this.addClass('disabled');
							}
						}
					);
				} else {
					$('.dp-nav-next-year', this.context).removeClass('disabled');
					$('.dp-nav-next-month', this.context).removeClass('disabled');
					var d = this.endDate.getDate();
					if (d < 13) {
						// check if the endDate is next month as we might need to add some disabled classes...
						var ed = new Date(this.endDate.getTime());
						ed.addMonths(-1);
						if (this.displayedYear == ed.getFullYear() && this.displayedMonth == ed.getMonth()) {
							$('.dp-calendar td.other-month', this.context).each(
								function()
								{
									var $this = $(this);
									if (Number($this.text()) > d) {
										$this.addClass('disabled');
									}
								}
							);
						}
					}
				}
			},
			_closeCalendar : function(programatic, ele)
			{
				if (!ele || ele == this.ele)
				{
					$(document).unbind('mousedown', this._checkMouse);
					this._clearCalendar();
					$('#dp-popup a').unbind();
					$('#dp-popup').empty().remove();
					if (!programatic) {
						$(this.ele).trigger('dpClosed', [this.getSelected()]);
					}
				}
			},
			// empties the current dp-calendar div and makes sure that all events are unbound
			// and expandos removed to avoid memory leaks...
			_clearCalendar : function()
			{
				// TODO.
				$('.dp-calendar td', this.context).unbind();
				$('.dp-calendar', this.context).empty();
			}
		}
	);
	
	// static constants
	$.dpConst = {
		SHOW_HEADER_NONE	:	0,
		SHOW_HEADER_SHORT	:	1,
		SHOW_HEADER_LONG	:	2,
		POS_TOP				:	0,
		POS_BOTTOM			:	1,
		POS_LEFT			:	0,
		POS_RIGHT			:	1
	};
	// localisable text
	$.dpText = {
		TEXT_PREV_YEAR		:	'Previous year',
		TEXT_PREV_MONTH		:	'Previous month',
		TEXT_NEXT_YEAR		:	'Next year',
		TEXT_NEXT_MONTH		:	'Next month',
		TEXT_CLOSE			:	'Close',
		TEXT_CHOOSE_DATE	:	'Choose date'
	};
	// version
	$.dpVersion = '$Id: jquery.datePicker.js 18 2008-12-23 23:37:34Z kelvin.luck $';

	$.fn.datePicker.defaults = {
		month				: undefined,
		year				: undefined,
		showHeader			: $.dpConst.SHOW_HEADER_SHORT,
		startDate			: undefined,
		endDate				: undefined,
		inline				: false,
		renderCallback		: null,
		createButton		: true,
		showYearNavigation	: true,
		closeOnSelect		: true,
		displayClose		: false,
		selectMultiple		: false,
		clickInput			: false,
		verticalPosition	: $.dpConst.POS_TOP,
		horizontalPosition	: $.dpConst.POS_LEFT,
		verticalOffset		: 0,
		horizontalOffset	: 0,
		hoverClass			: 'dp-hover'
	};

	function _getController(ele)
	{
		if (ele._dpId) return $.event._dpCache[ele._dpId];
		return false;
	};
	
	// make it so that no error is thrown if bgIframe plugin isn't included (allows you to use conditional
	// comments to only include bgIframe where it is needed in IE without breaking this plugin).
	if ($.fn.bgIframe == undefined) {
		$.fn.bgIframe = function() {return this; };
	};


	// clean-up
	$(window)
		.bind('unload', function() {
			var els = $.event._dpCache || [];
			for (var i in els) {
				$(els[i].ele)._dpDestroy();
			}
		});
		
	
})(jQuery);


/** File: javascript/jquery.scrollTo.js **/

/**
 * jQuery.ScrollTo
 * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Date: 2/19/2008
 *
 * @projectDescription Easy element scrolling using jQuery.
 * Tested with jQuery 1.2.1. On FF 2.0.0.11, IE 6, Opera 9.22 and Safari 3 beta. on Windows.
 *
 * @author Ariel Flesler
 * @version 1.3.3
 *
 * @id jQuery.scrollTo
 * @id jQuery.fn.scrollTo
 * @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements.
 *	  The different options for target are:
 *		- A number position (will be applied to all axes).
 *		- A string position ('44', '100px', '+=90', etc ) will be applied to all axes
 *		- A jQuery/DOM element ( logically, child of the element to scroll )
 *		- A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc )
 *		- A hash { top:x, left:y }, x and y can be any kind of number/string like above.
 * @param {Number} duration The OVERALL length of the animation, this argument can be the settings object instead.
 * @param {Object} settings Hash of settings, optional.
 *	 @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'.
 *	 @option {Number} duration The OVERALL length of the animation.
 *	 @option {String} easing The easing method for the animation.
 *	 @option {Boolean} margin If true, the margin of the target element will be deducted from the final position.
 *	 @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }.
 *	 @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes.
 *	 @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends.
 *	 @option {Function} onAfter Function to be called after the scrolling ends. 
 *	 @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends.
 * @return {jQuery} Returns the same jQuery object, for chaining.
 *
 * @example $('div').scrollTo( 340 );
 *
 * @example $('div').scrollTo( '+=340px', { axis:'y' } );
 *
 * @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } );
 *
 * @example var second_child = document.getElementById('container').firstChild.nextSibling;
 *			$('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){
 *				alert('scrolled!!');																   
 *			}});
 *
 * @example $('div').scrollTo( { top: 300, left:'+=200' }, { offset:-20 } );
 *
 * Notes:
 *  - jQuery.scrollTo will make the whole window scroll, it accepts the same arguments as jQuery.fn.scrollTo.
 *	- If you are interested in animated anchor navigation, check http://jquery.com/plugins/project/LocalScroll.
 *	- The options margin, offset and over are ignored, if the target is not a jQuery object or a DOM element.
 *	- The option 'queue' won't be taken into account, if only 1 axis is given.
 */
;(function( $ ){

	var $scrollTo = $.scrollTo = function( target, duration, settings ){
		$scrollTo.window().scrollTo( target, duration, settings );
	};

	$scrollTo.defaults = {
		axis:'y',
		duration:1
	};

	//returns the element that needs to be animated to scroll the window
	$scrollTo.window = function(){
		return $( $.browser.safari ? 'body' : 'html' );
	};

	$.fn.scrollTo = function( target, duration, settings ){
		if( typeof duration == 'object' ){
			settings = duration;
			duration = 0;
		}
		settings = $.extend( {}, $scrollTo.defaults, settings );
		duration = duration || settings.speed || settings.duration;//speed is still recognized for backwards compatibility
		settings.queue = settings.queue && settings.axis.length > 1;//make sure the settings are given right
		if( settings.queue )
			duration /= 2;//let's keep the overall speed, the same.
		settings.offset = both( settings.offset );
		settings.over = both( settings.over );

		return this.each(function(){
			var elem = this, $elem = $(elem),
				t = target, toff, attr = {},
				win = $elem.is('html,body');
			switch( typeof t ){
				case 'number'://will pass the regex
				case 'string':
					if( /^([+-]=)?\d+(px)?$/.test(t) ){
						t = both( t );
						break;//we are done
					}
					t = $(t,this);// relative selector, no break!
				case 'object':
					if( t.is || t.style )//DOM/jQuery
						toff = (t = $(t)).offset();//get the real position of the target 
			}
			$.each( settings.axis.split(''), function( i, axis ){
				var Pos	= axis == 'x' ? 'Left' : 'Top',
					pos = Pos.toLowerCase(),
					key = 'scroll' + Pos,
					act = elem[key],
					Dim = axis == 'x' ? 'Width' : 'Height',
					dim = Dim.toLowerCase();

				if( toff ){//jQuery/DOM
					attr[key] = toff[pos] + ( win ? 0 : act - $elem.offset()[pos] );

					if( settings.margin ){//if it's a dom element, reduce the margin
						attr[key] -= parseInt(t.css('margin'+Pos)) || 0;
						attr[key] -= parseInt(t.css('border'+Pos+'Width')) || 0;
					}
					
					attr[key] += settings.offset[pos] || 0;//add/deduct the offset
					
					if( settings.over[pos] )//scroll to a fraction of its width/height
						attr[key] += t[dim]() * settings.over[pos];
				}else
					attr[key] = t[pos];//remove the unnecesary 'px'

				if( /^\d+$/.test(attr[key]) )//number or 'number'
					attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max(Dim) );//check the limits

				if( !i && settings.queue ){//queueing each axis is required					
					if( act != attr[key] )//don't waste time animating, if there's no need.
						animate( settings.onAfterFirst );//intermediate animation
					delete attr[key];//don't animate this axis again in the next iteration.
				}
			});			
			animate( settings.onAfter );			

			function animate( callback ){
				$elem.animate( attr, duration, settings.easing, callback && function(){
					callback.call(this, target);
				});
			};
			function max( Dim ){
				var el = win ? $.browser.opera ? document.body : document.documentElement : elem;
				return el['scroll'+Dim] - el['client'+Dim];
			};
		});
	};

	function both( val ){
		return typeof val == 'object' ? val : { top:val, left:val };
	};

})( jQuery );

/** File: javascript/jquery.scrollTo.js **/

/**
 * jQuery.ScrollTo
 * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Date: 2/19/2008
 *
 * @projectDescription Easy element scrolling using jQuery.
 * Tested with jQuery 1.2.1. On FF 2.0.0.11, IE 6, Opera 9.22 and Safari 3 beta. on Windows.
 *
 * @author Ariel Flesler
 * @version 1.3.3
 *
 * @id jQuery.scrollTo
 * @id jQuery.fn.scrollTo
 * @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements.
 *	  The different options for target are:
 *		- A number position (will be applied to all axes).
 *		- A string position ('44', '100px', '+=90', etc ) will be applied to all axes
 *		- A jQuery/DOM element ( logically, child of the element to scroll )
 *		- A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc )
 *		- A hash { top:x, left:y }, x and y can be any kind of number/string like above.
 * @param {Number} duration The OVERALL length of the animation, this argument can be the settings object instead.
 * @param {Object} settings Hash of settings, optional.
 *	 @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'.
 *	 @option {Number} duration The OVERALL length of the animation.
 *	 @option {String} easing The easing method for the animation.
 *	 @option {Boolean} margin If true, the margin of the target element will be deducted from the final position.
 *	 @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }.
 *	 @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes.
 *	 @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends.
 *	 @option {Function} onAfter Function to be called after the scrolling ends. 
 *	 @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends.
 * @return {jQuery} Returns the same jQuery object, for chaining.
 *
 * @example $('div').scrollTo( 340 );
 *
 * @example $('div').scrollTo( '+=340px', { axis:'y' } );
 *
 * @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } );
 *
 * @example var second_child = document.getElementById('container').firstChild.nextSibling;
 *			$('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){
 *				alert('scrolled!!');																   
 *			}});
 *
 * @example $('div').scrollTo( { top: 300, left:'+=200' }, { offset:-20 } );
 *
 * Notes:
 *  - jQuery.scrollTo will make the whole window scroll, it accepts the same arguments as jQuery.fn.scrollTo.
 *	- If you are interested in animated anchor navigation, check http://jquery.com/plugins/project/LocalScroll.
 *	- The options margin, offset and over are ignored, if the target is not a jQuery object or a DOM element.
 *	- The option 'queue' won't be taken into account, if only 1 axis is given.
 */
;(function( $ ){

	var $scrollTo = $.scrollTo = function( target, duration, settings ){
		$scrollTo.window().scrollTo( target, duration, settings );
	};

	$scrollTo.defaults = {
		axis:'y',
		duration:1
	};

	//returns the element that needs to be animated to scroll the window
	$scrollTo.window = function(){
		return $( $.browser.safari ? 'body' : 'html' );
	};

	$.fn.scrollTo = function( target, duration, settings ){
		if( typeof duration == 'object' ){
			settings = duration;
			duration = 0;
		}
		settings = $.extend( {}, $scrollTo.defaults, settings );
		duration = duration || settings.speed || settings.duration;//speed is still recognized for backwards compatibility
		settings.queue = settings.queue && settings.axis.length > 1;//make sure the settings are given right
		if( settings.queue )
			duration /= 2;//let's keep the overall speed, the same.
		settings.offset = both( settings.offset );
		settings.over = both( settings.over );

		return this.each(function(){
			var elem = this, $elem = $(elem),
				t = target, toff, attr = {},
				win = $elem.is('html,body');
			switch( typeof t ){
				case 'number'://will pass the regex
				case 'string':
					if( /^([+-]=)?\d+(px)?$/.test(t) ){
						t = both( t );
						break;//we are done
					}
					t = $(t,this);// relative selector, no break!
				case 'object':
					if( t.is || t.style )//DOM/jQuery
						toff = (t = $(t)).offset();//get the real position of the target 
			}
			$.each( settings.axis.split(''), function( i, axis ){
				var Pos	= axis == 'x' ? 'Left' : 'Top',
					pos = Pos.toLowerCase(),
					key = 'scroll' + Pos,
					act = elem[key],
					Dim = axis == 'x' ? 'Width' : 'Height',
					dim = Dim.toLowerCase();

				if( toff ){//jQuery/DOM
					attr[key] = toff[pos] + ( win ? 0 : act - $elem.offset()[pos] );

					if( settings.margin ){//if it's a dom element, reduce the margin
						attr[key] -= parseInt(t.css('margin'+Pos)) || 0;
						attr[key] -= parseInt(t.css('border'+Pos+'Width')) || 0;
					}
					
					attr[key] += settings.offset[pos] || 0;//add/deduct the offset
					
					if( settings.over[pos] )//scroll to a fraction of its width/height
						attr[key] += t[dim]() * settings.over[pos];
				}else
					attr[key] = t[pos];//remove the unnecesary 'px'

				if( /^\d+$/.test(attr[key]) )//number or 'number'
					attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max(Dim) );//check the limits

				if( !i && settings.queue ){//queueing each axis is required					
					if( act != attr[key] )//don't waste time animating, if there's no need.
						animate( settings.onAfterFirst );//intermediate animation
					delete attr[key];//don't animate this axis again in the next iteration.
				}
			});			
			animate( settings.onAfter );			

			function animate( callback ){
				$elem.animate( attr, duration, settings.easing, callback && function(){
					callback.call(this, target);
				});
			};
			function max( Dim ){
				var el = win ? $.browser.opera ? document.body : document.documentElement : elem;
				return el['scroll'+Dim] - el['client'+Dim];
			};
		});
	};

	function both( val ){
		return typeof val == 'object' ? val : { top:val, left:val };
	};

})( jQuery );

/** File: javascript/jquery.scalebigimages.js **/

/**
 * Walk through images in a wrapper and make sure that they are not wider than 
 * the wrapper itself
 */
jQuery.fn.scaleBigImages = function() {
  return this.each(function() {
    var wrapper = $(this);
    var wrapper_width = wrapper.width();
    
    wrapper.find('img').each(function() {
      var image = $(this);
      
      image.load(function () {
        var width = image.width();
        
        if(width > wrapper_width) {
          if (image.parents('a').length == 0) {
            var link = $('<a></a>')
              .attr('href', image.attr('src'))
              .attr('title', App.lang('Open Full Size (:widthx:heightpx)', { 'width' : image.width(), 'height' : image.height() }))
              .click(function() {
                window.open($(this).attr('href'), App.lang('Full Size Image'));
                return false;
              });
            
            image.after(link).appendTo(link);
          } // if
          
          var scale = wrapper_width / width;
          
          image.css('height', Math.round(image.height() * scale));
          image.css('width', wrapper_width);
        } // if
      });
    });
  });
};

/** File: javascript/jquery.ui.js **/

/*
 * jQuery UI 1.7
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI
 */jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.7",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n||!j.element[0].parentNode){return}for(var m=0;m<n.length;m++){if(j.options[n[m][0]]){n[m][1].apply(j.element,k)}}}},contains:function(k,j){return document.compareDocumentPosition?k.compareDocumentPosition(j)&16:k!==j&&k.contains(j)},hasScroll:function(m,k){if(c(m).css("overflow")=="hidden"){return false}var j=(k&&k=="left")?"scrollLeft":"scrollTop",l=false;if(m[j]>0){return true}m[j]=1;l=(m[j]>0);m[j]=0;return l},isOverAxis:function(k,j,l){return(k>j)&&(k<(j+l))},isOver:function(o,k,n,m,j,l){return c.ui.isOverAxis(o,n,j)&&c.ui.isOverAxis(k,m,l)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,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}};if(d){var f=c.attr,e=c.fn.removeAttr,h="http://www.w3.org/2005/07/aaa",a=/^aria-/,b=/^wairole:/;c.attr=function(k,j,l){var m=l!==undefined;return(j=="role"?(m?f.call(this,k,j,"wairole:"+l):(f.apply(this,arguments)||"").replace(b,"")):(a.test(j)?(m?k.setAttributeNS(h,j.replace(a,"aaa:"),l):f.call(this,k,j.replace(a,"aaa:"))):f.apply(this,arguments)))};c.fn.removeAttr=function(j){return(a.test(j)?this.each(function(){this.removeAttributeNS(h,j.replace(a,""))}):e.call(this,j))}}c.fn.extend({remove:function(){c("*",this).add(this).each(function(){c(this).triggerHandler("remove")});return i.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},scrollParent:function(){var j;if((c.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){j=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(c.curCSS(this,"position",1))&&(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}else{j=this.parents().filter(function(){return(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!j.length?c(document):j}});c.extend(c.expr[":"],{data:function(l,k,j){return !!c.data(l,j[3])},focusable:function(k){var l=k.nodeName.toLowerCase(),j=c.attr(k,"tabindex");return(/input|select|textarea|button|object/.test(l)?!k.disabled:"a"==l||"area"==l?k.href||!isNaN(j):!isNaN(j))&&!c(k)["area"==l?"parents":"closest"](":hidden").length},tabbable:function(k){var j=c.attr(k,"tabindex");return(isNaN(j)||j>=0)&&c(k).is(":focusable")}});function g(m,n,o,l){function k(q){var p=c[m][n][q]||[];return(typeof p=="string"?p.split(/,?\s+/):p)}var j=k("getter");if(l.length==1&&typeof l[0]=="string"){j=j.concat(k("getterSetter"))}return(c.inArray(o,j)!=-1)}c.widget=function(k,j){var l=k.split(".")[0];k=k.split(".")[1];c.fn[k]=function(p){var n=(typeof p=="string"),o=Array.prototype.slice.call(arguments,1);if(n&&p.substring(0,1)=="_"){return this}if(n&&g(l,k,p,o)){var m=c.data(this[0],k);return(m?m[p].apply(m,o):undefined)}return this.each(function(){var q=c.data(this,k);(!q&&!n&&c.data(this,k,new c[l][k](this,p))._init());(q&&n&&c.isFunction(q[p])&&q[p].apply(q,o))})};c[l]=c[l]||{};c[l][k]=function(o,n){var m=this;this.namespace=l;this.widgetName=k;this.widgetEventPrefix=c[l][k].eventPrefix||k;this.widgetBaseClass=l+"-"+k;this.options=c.extend({},c.widget.defaults,c[l][k].defaults,c.metadata&&c.metadata.get(o)[k],n);this.element=c(o).bind("setData."+k,function(q,p,r){if(q.target==o){return m._setData(p,r)}}).bind("getData."+k,function(q,p){if(q.target==o){return m._getData(p)}}).bind("remove",function(){return m.destroy()})};c[l][k].prototype=c.extend({},c.widget.prototype,j);c[l][k].getterSetter="option"};c.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName).removeClass(this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").removeAttr("aria-disabled")},option:function(l,m){var k=l,j=this;if(typeof l=="string"){if(m===undefined){return this._getData(l)}k={};k[l]=m}c.each(k,function(n,o){j._setData(n,o)})},_getData:function(j){return this.options[j]},_setData:function(j,k){this.options[j]=k;if(j=="disabled"){this.element[k?"addClass":"removeClass"](this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").attr("aria-disabled",k)}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(l,m,n){var p=this.options[l],j=(l==this.widgetEventPrefix?l:this.widgetEventPrefix+l);m=c.Event(m);m.type=j;if(m.originalEvent){for(var k=c.event.props.length,o;k;){o=c.event.props[--k];m[o]=m.originalEvent[o]}}this.element.trigger(m,n);return !(c.isFunction(p)&&p.call(this.element[0],m,n)===false||m.isDefaultPrevented())}};c.widget.defaults={disabled:false};c.ui.mouse={_mouseInit:function(){var j=this;this.element.bind("mousedown."+this.widgetName,function(k){return j._mouseDown(k)}).bind("click."+this.widgetName,function(k){if(j._preventClickEvent){j._preventClickEvent=false;k.stopImmediatePropagation();return false}});if(c.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(c.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(l){l.originalEvent=l.originalEvent||{};if(l.originalEvent.mouseHandled){return}(this._mouseStarted&&this._mouseUp(l));this._mouseDownEvent=l;var k=this,m=(l.which==1),j=(typeof this.options.cancel=="string"?c(l.target).parents().add(l.target).filter(this.options.cancel).length:false);if(!m||j||!this._mouseCapture(l)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){k.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(l)&&this._mouseDelayMet(l)){this._mouseStarted=(this._mouseStart(l)!==false);if(!this._mouseStarted){l.preventDefault();return true}}this._mouseMoveDelegate=function(n){return k._mouseMove(n)};this._mouseUpDelegate=function(n){return k._mouseUp(n)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);(c.browser.safari||l.preventDefault());l.originalEvent.mouseHandled=true;return true},_mouseMove:function(j){if(c.browser.msie&&!j.button){return this._mouseUp(j)}if(this._mouseStarted){this._mouseDrag(j);return j.preventDefault()}if(this._mouseDistanceMet(j)&&this._mouseDelayMet(j)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,j)!==false);(this._mouseStarted?this._mouseDrag(j):this._mouseUp(j))}return !this._mouseStarted},_mouseUp:function(j){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=(j.target==this._mouseDownEvent.target);this._mouseStop(j)}return false},_mouseDistanceMet:function(j){return(Math.max(Math.abs(this._mouseDownEvent.pageX-j.pageX),Math.abs(this._mouseDownEvent.pageY-j.pageY))>=this.options.distance)},_mouseDelayMet:function(j){return this.mouseDelayMet},_mouseStart:function(j){},_mouseDrag:function(j){},_mouseStop:function(j){},_mouseCapture:function(j){return true}};c.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);;/*
 * jQuery UI Draggable 1.7
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Draggables
 *
 * Depends:
 *	ui.core.js
 */(function(a){a.widget("ui.draggable",a.extend({},a.ui.mouse,{_init:function(){if(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")){return}this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy()},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle")){return false}this.handle=this._getHandle(b);if(!this.handle){return false}return true},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b);this._cacheHelperProportions();if(a.ui.ddmanager){a.ui.ddmanager.current=this}this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=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._generatePosition(b);this.originalPageX=b.pageX;this.originalPageY=b.pageY;if(c.cursorAt){this._adjustOffsetFromHelper(c.cursorAt)}if(c.containment){this._setContainment()}this._trigger("start",b);this._cacheHelperProportions();if(a.ui.ddmanager&&!c.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,b)}this.helper.addClass("ui-draggable-dragging");this._mouseDrag(b,true);return true},_mouseDrag:function(b,d){this.position=this._generatePosition(b);this.positionAbs=this._convertPositionTo("absolute");if(!d){var c=this._uiHash();this._trigger("drag",b,c);this.position=c.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"}if(a.ui.ddmanager){a.ui.ddmanager.drag(this,b)}return false},_mouseStop:function(c){var d=false;if(a.ui.ddmanager&&!this.options.dropBehaviour){d=a.ui.ddmanager.drop(this,c)}if(this.dropped){d=this.dropped;this.dropped=false}if((this.options.revert=="invalid"&&!d)||(this.options.revert=="valid"&&d)||this.options.revert===true||(a.isFunction(this.options.revert)&&this.options.revert.call(this.element,d))){var b=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){b._trigger("stop",c);b._clear()})}else{this._trigger("stop",c);this._clear()}return false},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?true:false;a(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==b.target){c=true}});return c},_createHelper:function(c){var d=this.options;var b=a.isFunction(d.helper)?a(d.helper.apply(this.element[0],[c])):(d.helper=="clone"?this.element.clone():this.element);if(!b.parents("body").length){b.appendTo((d.appendTo=="parent"?this.element[0].parentNode:d.appendTo))}if(b[0]!=this.element[0]&&!(/(fixed|absolute)/).test(b.css("position"))){b.css("position","absolute")}return b},_adjustOffsetFromHelper:function(b){if(b.left!=undefined){this.offset.click.left=b.left+this.margins.left}if(b.right!=undefined){this.offset.click.left=this.helperProportions.width-b.right+this.margins.left}if(b.top!=undefined){this.offset.click.top=b.top+this.margins.top}if(b.bottom!=undefined){this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top}},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();if(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 b=this.element.position();return{top:b.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else{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)}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e=this.options;if(e.containment=="parent"){e.containment=this.helper[0].parentNode}if(e.containment=="document"||e.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(e.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(e.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]}if(!(/^(document|window|parent)$/).test(e.containment)&&e.containment.constructor!=Array){var c=a(e.containment)[0];if(!c){return}var d=a(e.containment).offset();var b=(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+(b?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+(b?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]}else{if(e.containment.constructor==Array){this.containment=e.containment}}},_convertPositionTo:function(f,h){if(!h){h=this.position}var c=f=="absolute"?1:-1;var e=this.options,b=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(b[0].tagName);return{top:(h.top+this.offset.relative.top*c+this.offset.parent.top*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(g?0:b.scrollTop()))*c)),left:(h.left+this.offset.relative.left*c+this.offset.parent.left*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:b.scrollLeft())*c))}},_generatePosition:function(e){var h=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,i=(/(html|body)/i).test(b[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0])){this.offset.relative=this._getRelativeOffset()}var d=e.pageX;var c=e.pageY;if(this.originalPosition){if(this.containment){if(e.pageX-this.offset.click.left<this.containment[0]){d=this.containment[0]+this.offset.click.left}if(e.pageY-this.offset.click.top<this.containment[1]){c=this.containment[1]+this.offset.click.top}if(e.pageX-this.offset.click.left>this.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:(!(g-this.offset.click.top<this.containment[1])?g-h.grid[1]:g+h.grid[1])):g;var f=this.originalPageX+Math.round((d-this.originalPageX)/h.grid[0])*h.grid[0];d=this.containment?(!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:(!(f-this.offset.click.left<this.containment[0])?f-h.grid[0]:f+h.grid[0])):f}}return{top:(c-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():(i?0:b.scrollTop())))),left:(d-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():i?0:b.scrollLeft())))}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");if(this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval){this.helper.remove()}this.helper=null;this.cancelHelperRemoval=false},_trigger:function(b,c,d){d=d||this._uiHash();a.ui.plugin.call(this,b,[c,d]);if(b=="drag"){this.positionAbs=this._convertPositionTo("absolute")}return a.widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(b){return{helper:this.helper,position:this.position,absolutePosition:this.positionAbs,offset:this.positionAbs}}}));a.extend(a.ui.draggable,{version:"1.7",eventPrefix:"drag",defaults:{addClasses:true,appendTo:"parent",axis:false,cancel:":input,option",connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,delay:0,distance:1,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false}});a.ui.plugin.add("draggable","connectToSortable",{start:function(c,e){var d=a(this).data("draggable"),f=d.options,b=a.extend({},e,{item:d.element});d.sortables=[];a(f.connectToSortable).each(function(){var g=a.data(this,"sortable");if(g&&!g.options.disabled){d.sortables.push({instance:g,shouldRevert:g.options.revert});g._refreshItems();g._trigger("activate",c,b)}})},stop:function(c,e){var d=a(this).data("draggable"),b=a.extend({},e,{item:d.element});a.each(d.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;d.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert){this.instance.options.revert=true}this.instance._mouseStop(c);this.instance.options.helper=this.instance.options._helper;if(d.options.helper=="original"){this.instance.currentItem.css({top:"auto",left:"auto"})}}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",c,b)}})},drag:function(c,f){var e=a(this).data("draggable"),b=this;var d=function(i){var n=this.offset.click.top,m=this.offset.click.left;var g=this.positionAbs.top,k=this.positionAbs.left;var j=i.height,l=i.width;var p=i.top,h=i.left;return a.ui.isOver(g+n,k+m,p,h,j,l)};a.each(e.sortables,function(g){this.instance.positionAbs=e.positionAbs;this.instance.helperProportions=e.helperProportions;this.instance.offset.click=e.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=a(b).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return f.helper[0]};c.target=this.instance.currentItem[0];this.instance._mouseCapture(c,true);this.instance._mouseStart(c,true,true);this.instance.offset.click.top=e.offset.click.top;this.instance.offset.click.left=e.offset.click.left;this.instance.offset.parent.left-=e.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=e.offset.parent.top-this.instance.offset.parent.top;e._trigger("toSortable",c);e.dropped=this.instance.element;e.currentItem=e.element;this.instance.fromOutside=e}if(this.instance.currentItem){this.instance._mouseDrag(c)}}else{if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",c,this.instance._uiHash(this.instance));this.instance._mouseStop(c,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();if(this.instance.placeholder){this.instance.placeholder.remove()}e._trigger("fromSortable",c);e.dropped=false}}})}});a.ui.plugin.add("draggable","cursor",{start:function(c,d){var b=a("body"),e=a(this).data("draggable").options;if(b.css("cursor")){e._cursor=b.css("cursor")}b.css("cursor",e.cursor)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._cursor){a("body").css("cursor",d._cursor)}}});a.ui.plugin.add("draggable","iframeFix",{start:function(b,c){var d=a(this).data("draggable").options;a(d.iframeFix===true?"iframe":d.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:1000}).css(a(this).offset()).appendTo("body")})},stop:function(b,c){a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});a.ui.plugin.add("draggable","opacity",{start:function(c,d){var b=a(d.helper),e=a(this).data("draggable").options;if(b.css("opacity")){e._opacity=b.css("opacity")}b.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._opacity){a(c.helper).css("opacity",d._opacity)}}});a.ui.plugin.add("draggable","scroll",{start:function(c,d){var b=a(this).data("draggable");if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){b.overflowOffset=b.scrollParent.offset()}},drag:function(d,e){var c=a(this).data("draggable"),f=c.options,b=false;if(c.scrollParent[0]!=document&&c.scrollParent[0].tagName!="HTML"){if(!f.axis||f.axis!="x"){if((c.overflowOffset.top+c.scrollParent[0].offsetHeight)-d.pageY<f.scrollSensitivity){c.scrollParent[0].scrollTop=b=c.scrollParent[0].scrollTop+f.scrollSpeed}else{if(d.pageY-c.overflowOffset.top<f.scrollSensitivity){c.scrollParent[0].scrollTop=b=c.scrollParent[0].scrollTop-f.scrollSpeed}}}if(!f.axis||f.axis!="y"){if((c.overflowOffset.left+c.scrollParent[0].offsetWidth)-d.pageX<f.scrollSensitivity){c.scrollParent[0].scrollLeft=b=c.scrollParent[0].scrollLeft+f.scrollSpeed}else{if(d.pageX-c.overflowOffset.left<f.scrollSensitivity){c.scrollParent[0].scrollLeft=b=c.scrollParent[0].scrollLeft-f.scrollSpeed}}}}else{if(!f.axis||f.axis!="x"){if(d.pageY-a(document).scrollTop()<f.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()-f.scrollSpeed)}else{if(a(window).height()-(d.pageY-a(document).scrollTop())<f.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()+f.scrollSpeed)}}}if(!f.axis||f.axis!="y"){if(d.pageX-a(document).scrollLeft()<f.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()-f.scrollSpeed)}else{if(a(window).width()-(d.pageX-a(document).scrollLeft())<f.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()+f.scrollSpeed)}}}}if(b!==false&&a.ui.ddmanager&&!f.dropBehaviour){a.ui.ddmanager.prepareOffsets(c,d)}}});a.ui.plugin.add("draggable","snap",{start:function(c,d){var b=a(this).data("draggable"),e=b.options;b.snapElements=[];a(e.snap.constructor!=String?(e.snap.items||":data(draggable)"):e.snap).each(function(){var g=a(this);var f=g.offset();if(this!=b.element[0]){b.snapElements.push({item:this,width:g.outerWidth(),height:g.outerHeight(),top:f.top,left:f.left})}})},drag:function(u,p){var g=a(this).data("draggable"),q=g.options;var y=q.snapTolerance;var x=p.offset.left,w=x+g.helperProportions.width,f=p.offset.top,e=f+g.helperProportions.height;for(var v=g.snapElements.length-1;v>=0;v--){var s=g.snapElements[v].left,n=s+g.snapElements[v].width,m=g.snapElements[v].top,A=m+g.snapElements[v].height;if(!((s-y<x&&x<n+y&&m-y<f&&f<A+y)||(s-y<x&&x<n+y&&m-y<e&&e<A+y)||(s-y<w&&w<n+y&&m-y<f&&f<A+y)||(s-y<w&&w<n+y&&m-y<e&&e<A+y))){if(g.snapElements[v].snapping){(g.options.snap.release&&g.options.snap.release.call(g.element,u,a.extend(g._uiHash(),{snapItem:g.snapElements[v].item})))}g.snapElements[v].snapping=false;continue}if(q.snapMode!="inner"){var c=Math.abs(m-e)<=y;var z=Math.abs(A-f)<=y;var j=Math.abs(s-w)<=y;var k=Math.abs(n-x)<=y;if(c){p.position.top=g._convertPositionTo("relative",{top:m-g.helperProportions.height,left:0}).top-g.margins.top}if(z){p.position.top=g._convertPositionTo("relative",{top:A,left:0}).top-g.margins.top}if(j){p.position.left=g._convertPositionTo("relative",{top:0,left:s-g.helperProportions.width}).left-g.margins.left}if(k){p.position.left=g._convertPositionTo("relative",{top:0,left:n}).left-g.margins.left}}var h=(c||z||j||k);if(q.snapMode!="outer"){var c=Math.abs(m-f)<=y;var z=Math.abs(A-e)<=y;var j=Math.abs(s-x)<=y;var k=Math.abs(n-w)<=y;if(c){p.position.top=g._convertPositionTo("relative",{top:m,left:0}).top-g.margins.top}if(z){p.position.top=g._convertPositionTo("relative",{top:A-g.helperProportions.height,left:0}).top-g.margins.top}if(j){p.position.left=g._convertPositionTo("relative",{top:0,left:s}).left-g.margins.left}if(k){p.position.left=g._convertPositionTo("relative",{top:0,left:n-g.helperProportions.width}).left-g.margins.left}}if(!g.snapElements[v].snapping&&(c||z||j||k||h)){(g.options.snap.snap&&g.options.snap.snap.call(g.element,u,a.extend(g._uiHash(),{snapItem:g.snapElements[v].item})))}g.snapElements[v].snapping=(c||z||j||k||h)}}});a.ui.plugin.add("draggable","stack",{start:function(b,c){var e=a(this).data("draggable").options;var d=a.makeArray(a(e.stack.group)).sort(function(g,f){return(parseInt(a(g).css("zIndex"),10)||e.stack.min)-(parseInt(a(f).css("zIndex"),10)||e.stack.min)});a(d).each(function(f){this.style.zIndex=e.stack.min+f});this[0].style.zIndex=e.stack.min+d.length}});a.ui.plugin.add("draggable","zIndex",{start:function(c,d){var b=a(d.helper),e=a(this).data("draggable").options;if(b.css("zIndex")){e._zIndex=b.css("zIndex")}b.css("zIndex",e.zIndex)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._zIndex){a(c.helper).css("zIndex",d._zIndex)}}})})(jQuery);;/*
 * jQuery UI Droppable 1.7
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Droppables
 *
 * Depends:
 *	ui.core.js
 *	ui.draggable.js
 */(function(a){a.widget("ui.droppable",{_init:function(){var c=this.options,b=c.accept;this.isover=0;this.isout=1;this.options.accept=this.options.accept&&a.isFunction(this.options.accept)?this.options.accept:function(e){return e.is(b)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};a.ui.ddmanager.droppables[this.options.scope]=a.ui.ddmanager.droppables[this.options.scope]||[];a.ui.ddmanager.droppables[this.options.scope].push(this);(this.options.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++){if(b[c]==this){b.splice(c,1)}}this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable")},_setData:function(b,c){if(b=="accept"){this.options.accept=c&&a.isFunction(c)?c:function(e){return e.is(accept)}}else{a.widget.prototype._setData.apply(this,arguments)}},_activate:function(c){var b=a.ui.ddmanager.current;if(this.options.activeClass){this.element.addClass(this.options.activeClass)}(b&&this._trigger("activate",c,this.ui(b)))},_deactivate:function(c){var b=a.ui.ddmanager.current;if(this.options.activeClass){this.element.removeClass(this.options.activeClass)}(b&&this._trigger("deactivate",c,this.ui(b)))},_over:function(c){var b=a.ui.ddmanager.current;if(!b||(b.currentItem||b.element)[0]==this.element[0]){return}if(this.options.accept.call(this.element[0],(b.currentItem||b.element))){if(this.options.hoverClass){this.element.addClass(this.options.hoverClass)}this._trigger("over",c,this.ui(b))}},_out:function(c){var b=a.ui.ddmanager.current;if(!b||(b.currentItem||b.element)[0]==this.element[0]){return}if(this.options.accept.call(this.element[0],(b.currentItem||b.element))){if(this.options.hoverClass){this.element.removeClass(this.options.hoverClass)}this._trigger("out",c,this.ui(b))}},_drop:function(c,d){var b=d||a.ui.ddmanager.current;if(!b||(b.currentItem||b.element)[0]==this.element[0]){return false}var e=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var f=a.data(this,"droppable");if(f.options.greedy&&a.ui.intersect(b,a.extend(f,{offset:f.element.offset()}),f.options.tolerance)){e=true;return false}});if(e){return false}if(this.options.accept.call(this.element[0],(b.currentItem||b.element))){if(this.options.activeClass){this.element.removeClass(this.options.activeClass)}if(this.options.hoverClass){this.element.removeClass(this.options.hoverClass)}this._trigger("drop",c,this.ui(b));return this.element}return false},ui:function(b){return{draggable:(b.currentItem||b.element),helper:b.helper,position:b.position,absolutePosition:b.positionAbs,offset:b.positionAbs}}});a.extend(a.ui.droppable,{version:"1.7",eventPrefix:"drop",defaults:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"}});a.ui.intersect=function(q,j,o){if(!j.offset){return false}var e=(q.positionAbs||q.position.absolute).left,d=e+q.helperProportions.width,n=(q.positionAbs||q.position.absolute).top,m=n+q.helperProportions.height;var g=j.offset.left,c=g+j.proportions.width,p=j.offset.top,k=p+j.proportions.height;switch(o){case"fit":return(g<e&&d<c&&p<n&&m<k);break;case"intersect":return(g<e+(q.helperProportions.width/2)&&d-(q.helperProportions.width/2)<c&&p<n+(q.helperProportions.height/2)&&m-(q.helperProportions.height/2)<k);break;case"pointer":var h=((q.positionAbs||q.position.absolute).left+(q.clickOffset||q.offset.click).left),i=((q.positionAbs||q.position.absolute).top+(q.clickOffset||q.offset.click).top),f=a.ui.isOver(i,h,p,g,j.proportions.height,j.proportions.width);return f;break;case"touch":return((n>=p&&n<=k)||(m>=p&&m<=k)||(n<p&&m>k))&&((e>=g&&e<=c)||(d>=g&&d<=c)||(e<g&&d>c));break;default:return false;break}};a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,g){var b=a.ui.ddmanager.droppables[e.options.scope];var f=g?g.type:null;var h=(e.currentItem||e.element).find(":data(droppable)").andSelf();droppablesLoop:for(var d=0;d<b.length;d++){if(b[d].options.disabled||(e&&!b[d].options.accept.call(b[d].element[0],(e.currentItem||e.element)))){continue}for(var c=0;c<h.length;c++){if(h[c]==b[d].element[0]){b[d].proportions.height=0;continue droppablesLoop}}b[d].visible=b[d].element.css("display")!="none";if(!b[d].visible){continue}b[d].offset=b[d].element.offset();b[d].proportions={width:b[d].element[0].offsetWidth,height:b[d].element[0].offsetHeight};if(f=="mousedown"){b[d]._activate.call(b[d],g)}}},drop:function(b,c){var d=false;a.each(a.ui.ddmanager.droppables[b.options.scope],function(){if(!this.options){return}if(!this.options.disabled&&this.visible&&a.ui.intersect(b,this,this.options.tolerance)){d=this._drop.call(this,c)}if(!this.options.disabled&&this.visible&&this.options.accept.call(this.element[0],(b.currentItem||b.element))){this.isout=1;this.isover=0;this._deactivate.call(this,c)}});return d},drag:function(b,c){if(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){return}var e=a.ui.intersect(b,this,this.options.tolerance);var g=!e&&this.isover==1?"isout":(e&&this.isover==0?"isover":null);if(!g){return}var f;if(this.options.greedy){var d=this.element.parents(":data(droppable):eq(0)");if(d.length){f=a.data(d[0],"droppable");f.greedyChild=(g=="isover"?1:0)}}if(f&&g=="isover"){f.isover=0;f.isout=1;f._out.call(f,c)}this[g]=1;this[g=="isout"?"isover":"isout"]=0;this[g=="isover"?"_over":"_out"].call(this,c);if(f&&g=="isout"){f.isout=0;f.isover=1;f._over.call(f,c)}})}}})(jQuery);;/*
 * jQuery UI Resizable 1.7
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Resizables
 *
 * Depends:
 *	ui.core.js
 */(function(c){c.widget("ui.resizable",c.extend({},c.ui.mouse,{_init:function(){var e=this,j=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(j.aspectRatio),aspectRatio:j.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:j.helper||j.ghost||j.animate?j.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){if(/relative/.test(this.element.css("position"))&&c.browser.opera){this.element.css({position:"relative",top:"auto",left:"auto"})}this.element.wrap(c('<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=true;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=j.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{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"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var k=this.handles.split(",");this.handles={};for(var f=0;f<k.length;f++){var h=c.trim(k[f]),d="ui-resizable-"+h;var g=c('<div class="ui-resizable-handle '+d+'"></div>');if(/sw|se|ne|nw/.test(h)){g.css({zIndex:++j.zIndex})}if("se"==h){g.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[h]=".ui-resizable-"+h;this.element.append(g)}}this._renderAxis=function(p){p=p||this.element;for(var m in this.handles){if(this.handles[m].constructor==String){this.handles[m]=c(this.handles[m],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var n=c(this.handles[m],this.element),o=0;o=/sw|ne|nw|se|n|s/.test(m)?n.outerHeight():n.outerWidth();var l=["padding",/ne|nw|n/.test(m)?"Top":/se|sw|s/.test(m)?"Bottom":/^e$/.test(m)?"Right":"Left"].join("");p.css(l,o);this._proportionallyResize()}if(!c(this.handles[m]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!e.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}e.axis=i&&i[1]?i[1]:"se"}});if(j.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){c(this).removeClass("ui-resizable-autohide");e._handles.show()},function(){if(!e.resizing){c(this).addClass("ui-resizable-autohide");e._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var d=function(f){c(f).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){d(this.element);var e=this.element;e.parent().append(this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")})).end().remove()}this.originalElement.css("resize",this.originalResizeStyle);d(this.originalElement)},_mouseCapture:function(e){var f=false;for(var d in this.handles){if(c(this.handles[d])[0]==e.target){f=true}}return this.options.disabled||!!f},_mouseStart:function(f){var i=this.options,e=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(d.is(".ui-draggable")||(/absolute/).test(d.css("position"))){d.css({position:"absolute",top:e.top,left:e.left})}if(c.browser.opera&&(/relative/).test(d.css("position"))){d.css({position:"relative",top:"auto",left:"auto"})}this._renderProxy();var j=b(this.helper.css("left")),g=b(this.helper.css("top"));if(i.containment){j+=c(i.containment).scrollLeft()||0;g+=c(i.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:j,top:g};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:j,top:g};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:f.pageX,top:f.pageY};this.aspectRatio=(typeof i.aspectRatio=="number")?i.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var h=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",h=="auto"?this.axis+"-resize":h);d.addClass("ui-resizable-resizing");this._propagate("start",f);return true},_mouseDrag:function(d){var g=this.helper,f=this.options,l={},p=this,i=this.originalMousePosition,m=this.axis;var q=(d.pageX-i.left)||0,n=(d.pageY-i.top)||0;var h=this._change[m];if(!h){return false}var k=h.apply(this,[d,q,n]),j=c.browser.msie&&c.browser.version<7,e=this.sizeDiff;if(this._aspectRatio||d.shiftKey){k=this._updateRatio(k,d)}k=this._respectSize(k,d);this._propagate("resize",d);g.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(k);this._trigger("resize",d,this.ui());return false},_mouseStop:function(g){this.resizing=false;var h=this.options,l=this;if(this._helper){var f=this._proportionallyResizeElements,d=f.length&&(/textarea/i).test(f[0].nodeName),e=d&&c.ui.hasScroll(f[0],"left")?0:l.sizeDiff.height,j=d?0:l.sizeDiff.width;var m={width:(l.size.width-j),height:(l.size.height-e)},i=(parseInt(l.element.css("left"),10)+(l.position.left-l.originalPosition.left))||null,k=(parseInt(l.element.css("top"),10)+(l.position.top-l.originalPosition.top))||null;if(!h.animate){this.element.css(c.extend(m,{top:k,left:i}))}l.helper.height(l.size.height);l.helper.width(l.size.width);if(this._helper&&!h.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",g);if(this._helper){this.helper.remove()}return false},_updateCache:function(d){var e=this.options;this.offset=this.helper.offset();if(a(d.left)){this.position.left=d.left}if(a(d.top)){this.position.top=d.top}if(a(d.height)){this.size.height=d.height}if(a(d.width)){this.size.width=d.width}},_updateRatio:function(g,f){var h=this.options,i=this.position,e=this.size,d=this.axis;if(g.height){g.width=(e.height*this.aspectRatio)}else{if(g.width){g.height=(e.width/this.aspectRatio)}}if(d=="sw"){g.left=i.left+(e.width-g.width);g.top=null}if(d=="nw"){g.top=i.top+(e.height-g.height);g.left=i.left+(e.width-g.width)}return g},_respectSize:function(k,f){var i=this.helper,h=this.options,q=this._aspectRatio||f.shiftKey,p=this.axis,s=a(k.width)&&h.maxWidth&&(h.maxWidth<k.width),l=a(k.height)&&h.maxHeight&&(h.maxHeight<k.height),g=a(k.width)&&h.minWidth&&(h.minWidth>k.width),r=a(k.height)&&h.minHeight&&(h.minHeight>k.height);if(g){k.width=h.minWidth}if(r){k.height=h.minHeight}if(s){k.width=h.maxWidth}if(l){k.height=h.maxHeight}var e=this.originalPosition.left+this.originalSize.width,n=this.position.top+this.size.height;var j=/sw|nw|w/.test(p),d=/nw|ne|n/.test(p);if(g&&j){k.left=e-h.minWidth}if(s&&j){k.left=e-h.maxWidth}if(r&&d){k.top=n-h.minHeight}if(l&&d){k.top=n-h.maxHeight}var m=!k.width&&!k.height;if(m&&!k.left&&k.top){k.top=null}else{if(m&&!k.top&&k.left){k.left=null}}return k},_proportionallyResize:function(){var j=this.options;if(!this._proportionallyResizeElements.length){return}var f=this.helper||this.element;for(var e=0;e<this._proportionallyResizeElements.length;e++){var g=this._proportionallyResizeElements[e];if(!this.borderDif){var d=[g.css("borderTopWidth"),g.css("borderRightWidth"),g.css("borderBottomWidth"),g.css("borderLeftWidth")],h=[g.css("paddingTop"),g.css("paddingRight"),g.css("paddingBottom"),g.css("paddingLeft")];this.borderDif=c.map(d,function(k,m){var l=parseInt(k,10)||0,n=parseInt(h[m],10)||0;return l+n})}if(c.browser.msie&&!(!(c(f).is(":hidden")||c(f).parents(":hidden").length))){continue}g.css({height:(f.height()-this.borderDif[0]-this.borderDif[2])||0,width:(f.width()-this.borderDif[1]-this.borderDif[3])||0})}},_renderProxy:function(){var e=this.element,h=this.options;this.elementOffset=e.offset();if(this._helper){this.helper=this.helper||c('<div style="overflow:hidden;"></div>');var d=c.browser.msie&&c.browser.version<7,f=(d?1:0),g=(d?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+g,height:this.element.outerHeight()+g,position:"absolute",left:this.elementOffset.left-f+"px",top:this.elementOffset.top-f+"px",zIndex:++h.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(f,e,d){return{width:this.originalSize.width+e}},w:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{left:h.left+e,width:f.width-e}},n:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{top:h.top+d,height:f.height-d}},s:function(f,e,d){return{height:this.originalSize.height+d}},se:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},sw:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[f,e,d]))},ne:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},nw:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[f,e,d]))}},_propagate:function(e,d){c.ui.plugin.call(this,e,[d,this.ui()]);(e!="resize"&&this._trigger(e,d,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}}}));c.extend(c.ui.resizable,{version:"1.7",eventPrefix:"resize",defaults:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,cancel:":input,option",containment:false,delay:0,distance:1,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000}});c.ui.plugin.add("resizable","alsoResize",{start:function(e,f){var d=c(this).data("resizable"),g=d.options;_store=function(h){c(h).each(function(){c(this).data("resizable-alsoresize",{width:parseInt(c(this).width(),10),height:parseInt(c(this).height(),10),left:parseInt(c(this).css("left"),10),top:parseInt(c(this).css("top"),10)})})};if(typeof(g.alsoResize)=="object"&&!g.alsoResize.parentNode){if(g.alsoResize.length){g.alsoResize=g.alsoResize[0];_store(g.alsoResize)}else{c.each(g.alsoResize,function(h,i){_store(h)})}}else{_store(g.alsoResize)}},resize:function(f,h){var e=c(this).data("resizable"),i=e.options,g=e.originalSize,k=e.originalPosition;var j={height:(e.size.height-g.height)||0,width:(e.size.width-g.width)||0,top:(e.position.top-k.top)||0,left:(e.position.left-k.left)||0},d=function(l,m){c(l).each(function(){var p=c(this),q=c(this).data("resizable-alsoresize"),o={},n=m&&m.length?m:["width","height","top","left"];c.each(n||["width","height","top","left"],function(r,t){var s=(q[t]||0)+(j[t]||0);if(s&&s>=0){o[t]=s||null}});if(/relative/.test(p.css("position"))&&c.browser.opera){e._revertToRelativePosition=true;p.css({position:"absolute",top:"auto",left:"auto"})}p.css(o)})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.nodeType){c.each(i.alsoResize,function(l,m){d(l,m)})}else{d(i.alsoResize)}},stop:function(e,f){var d=c(this).data("resizable");if(d._revertToRelativePosition&&c.browser.opera){d._revertToRelativePosition=false;el.css({position:"relative"})}c(this).removeData("resizable-alsoresize-start")}});c.ui.plugin.add("resizable","animate",{stop:function(h,m){var n=c(this).data("resizable"),i=n.options;var g=n._proportionallyResizeElements,d=g.length&&(/textarea/i).test(g[0].nodeName),e=d&&c.ui.hasScroll(g[0],"left")?0:n.sizeDiff.height,k=d?0:n.sizeDiff.width;var f={width:(n.size.width-k),height:(n.size.height-e)},j=(parseInt(n.element.css("left"),10)+(n.position.left-n.originalPosition.left))||null,l=(parseInt(n.element.css("top"),10)+(n.position.top-n.originalPosition.top))||null;n.element.animate(c.extend(f,l&&j?{top:l,left:j}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var o={width:parseInt(n.element.css("width"),10),height:parseInt(n.element.css("height"),10),top:parseInt(n.element.css("top"),10),left:parseInt(n.element.css("left"),10)};if(g&&g.length){c(g[0]).css({width:o.width,height:o.height})}n._updateCache(o);n._propagate("resize",h)}})}});c.ui.plugin.add("resizable","containment",{start:function(e,q){var s=c(this).data("resizable"),i=s.options,k=s.element;var f=i.containment,j=(f instanceof c)?f.get(0):(/parent/.test(f))?k.parent().get(0):f;if(!j){return}s.containerElement=c(j);if(/document/.test(f)||f==document){s.containerOffset={left:0,top:0};s.containerPosition={left:0,top:0};s.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var m=c(j),h=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){h[p]=b(m.css("padding"+o))});s.containerOffset=m.offset();s.containerPosition=m.position();s.containerSize={height:(m.innerHeight()-h[3]),width:(m.innerWidth()-h[1])};var n=s.containerOffset,d=s.containerSize.height,l=s.containerSize.width,g=(c.ui.hasScroll(j,"left")?j.scrollWidth:l),r=(c.ui.hasScroll(j)?j.scrollHeight:d);s.parentData={element:j,left:n.left,top:n.top,width:g,height:r}}},resize:function(f,p){var s=c(this).data("resizable"),h=s.options,e=s.containerSize,n=s.containerOffset,l=s.size,m=s.position,q=h._aspectRatio||f.shiftKey,d={top:0,left:0},g=s.containerElement;if(g[0]!=document&&(/static/).test(g.css("position"))){d=n}if(m.left<(s._helper?n.left:0)){s.size.width=s.size.width+(s._helper?(s.position.left-n.left):(s.position.left-d.left));if(q){s.size.height=s.size.width/h.aspectRatio}s.position.left=h.helper?n.left:0}if(m.top<(s._helper?n.top:0)){s.size.height=s.size.height+(s._helper?(s.position.top-n.top):s.position.top);if(q){s.size.width=s.size.height*h.aspectRatio}s.position.top=s._helper?n.top:0}s.offset.left=s.parentData.left+s.position.left;s.offset.top=s.parentData.top+s.position.top;var k=Math.abs((s._helper?s.offset.left-d.left:(s.offset.left-d.left))+s.sizeDiff.width),r=Math.abs((s._helper?s.offset.top-d.top:(s.offset.top-n.top))+s.sizeDiff.height);var j=s.containerElement.get(0)==s.element.parent().get(0),i=/relative|absolute/.test(s.containerElement.css("position"));if(j&&i){k-=s.parentData.left}if(k+s.size.width>=s.parentData.width){s.size.width=s.parentData.width-k;if(q){s.size.height=s.size.width/h.aspectRatio}}if(r+s.size.height>=s.parentData.height){s.size.height=s.parentData.height-r;if(q){s.size.width=s.size.height*h.aspectRatio}}},stop:function(e,m){var p=c(this).data("resizable"),f=p.options,k=p.position,l=p.containerOffset,d=p.containerPosition,g=p.containerElement;var i=c(p.helper),q=i.offset(),n=i.outerWidth()-p.sizeDiff.width,j=i.outerHeight()-p.sizeDiff.height;if(p._helper&&!f.animate&&(/relative/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}if(p._helper&&!f.animate&&(/static/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}}});c.ui.plugin.add("resizable","ghost",{start:function(f,g){var d=c(this).data("resizable"),h=d.options,e=d.size;d.ghost=d.originalElement.clone();d.ghost.css({opacity:0.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof h.ghost=="string"?h.ghost:"");d.ghost.appendTo(d.helper)},resize:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost){d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})}},stop:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost&&d.helper){d.helper.get(0).removeChild(d.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(d,l){var n=c(this).data("resizable"),g=n.options,j=n.size,h=n.originalSize,i=n.originalPosition,m=n.axis,k=g._aspectRatio||d.shiftKey;g.grid=typeof g.grid=="number"?[g.grid,g.grid]:g.grid;var f=Math.round((j.width-h.width)/(g.grid[0]||1))*(g.grid[0]||1),e=Math.round((j.height-h.height)/(g.grid[1]||1))*(g.grid[1]||1);if(/^(se|s|e)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e}else{if(/^(ne)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e}else{if(/^(sw)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.left=i.left-f}else{n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e;n.position.left=i.left-f}}}}});var b=function(d){return parseInt(d,10)||0};var a=function(d){return !isNaN(parseInt(d,10))}})(jQuery);;/*
 * jQuery UI Sortable 1.7
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Sortables
 *
 * Depends:
 *	ui.core.js
 */(function(a){a.widget("ui.sortable",a.extend({},a.ui.mouse,{_init:function(){var b=this.options;this.containerCache={};this.element.addClass("ui-sortable");this.refresh();this.floating=this.items.length?(/left|right/).test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--){this.items[b].item.removeData("sortable-item")}},_mouseCapture:function(e,f){if(this.reverting){return false}if(this.options.disabled||this.options.type=="static"){return false}this._refreshItems(e);var d=null,c=this,b=a(e.target).parents().each(function(){if(a.data(this,"sortable-item")==c){d=a(this);return false}});if(a.data(e.target,"sortable-item")==c){d=a(e.target)}if(!d){return false}if(this.options.handle&&!f){var g=false;a(this.options.handle,d).find("*").andSelf().each(function(){if(this==e.target){g=true}});if(!g){return false}}this.currentItem=d;this._removeCurrentsFromItems();return true},_mouseStart:function(e,f,b){var g=this.options,c=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(e);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:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(e);this.originalPageX=e.pageX;this.originalPageY=e.pageY;if(g.cursorAt){this._adjustOffsetFromHelper(g.cursorAt)}this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};if(this.helper[0]!=this.currentItem[0]){this.currentItem.hide()}this._createPlaceholder();if(g.containment){this._setContainment()}if(g.cursor){if(a("body").css("cursor")){this._storedCursor=a("body").css("cursor")}a("body").css("cursor",g.cursor)}if(g.opacity){if(this.helper.css("opacity")){this._storedOpacity=this.helper.css("opacity")}this.helper.css("opacity",g.opacity)}if(g.zIndex){if(this.helper.css("zIndex")){this._storedZIndex=this.helper.css("zIndex")}this.helper.css("zIndex",g.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){this.overflowOffset=this.scrollParent.offset()}this._trigger("start",e,this._uiHash());if(!this._preserveHelperProportions){this._cacheHelperProportions()}if(!b){for(var d=this.containers.length-1;d>=0;d--){this.containers[d]._trigger("activate",e,c._uiHash(this))}}if(a.ui.ddmanager){a.ui.ddmanager.current=this}if(a.ui.ddmanager&&!g.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,e)}this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(e);return true},_mouseDrag:function(f){this.position=this._generatePosition(f);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs){this.lastPositionAbs=this.positionAbs}if(this.options.scroll){var g=this.options,b=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if((this.overflowOffset.top+this.scrollParent[0].offsetHeight)-f.pageY<g.scrollSensitivity){this.scrollParent[0].scrollTop=b=this.scrollParent[0].scrollTop+g.scrollSpeed}else{if(f.pageY-this.overflowOffset.top<g.scrollSensitivity){this.scrollParent[0].scrollTop=b=this.scrollParent[0].scrollTop-g.scrollSpeed}}if((this.overflowOffset.left+this.scrollParent[0].offsetWidth)-f.pageX<g.scrollSensitivity){this.scrollParent[0].scrollLeft=b=this.scrollParent[0].scrollLeft+g.scrollSpeed}else{if(f.pageX-this.overflowOffset.left<g.scrollSensitivity){this.scrollParent[0].scrollLeft=b=this.scrollParent[0].scrollLeft-g.scrollSpeed}}}else{if(f.pageY-a(document).scrollTop()<g.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()-g.scrollSpeed)}else{if(a(window).height()-(f.pageY-a(document).scrollTop())<g.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()+g.scrollSpeed)}}if(f.pageX-a(document).scrollLeft()<g.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()-g.scrollSpeed)}else{if(a(window).width()-(f.pageX-a(document).scrollLeft())<g.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()+g.scrollSpeed)}}}if(b!==false&&a.ui.ddmanager&&!g.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,f)}}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 d=this.items.length-1;d>=0;d--){var e=this.items[d],c=e.item[0],h=this._intersectsWithPointer(e);if(!h){continue}if(c!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=c&&!a.ui.contains(this.placeholder[0],c)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],c):true)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(e)){this._rearrange(f,e)}else{break}this._trigger("change",f,this._uiHash());break}}this._contactContainers(f);if(a.ui.ddmanager){a.ui.ddmanager.drag(this,f)}this._trigger("sort",f,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(c,d){if(!c){return}if(a.ui.ddmanager&&!this.options.dropBehaviour){a.ui.ddmanager.drop(this,c)}if(this.options.revert){var b=this;var e=b.placeholder.offset();b.reverting=true;a(this.helper).animate({left:e.left-this.offset.parent.left-b.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-b.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){b._clear(c)})}else{this._clear(c,d)}return false},cancel:function(){var b=this;if(this.dragging){this._mouseUp();if(this.options.helper=="original"){this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}for(var c=this.containers.length-1;c>=0;c--){this.containers[c]._trigger("deactivate",null,b._uiHash(this));if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",null,b._uiHash(this));this.containers[c].containerCache.over=0}}}if(this.placeholder[0].parentNode){this.placeholder[0].parentNode.removeChild(this.placeholder[0])}if(this.options.helper!="original"&&this.helper&&this.helper[0].parentNode){this.helper.remove()}a.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});if(this.domPosition.prev){a(this.domPosition.prev).after(this.currentItem)}else{a(this.domPosition.parent).prepend(this.currentItem)}return true},serialize:function(d){var b=this._getItemsAsjQuery(d&&d.connected);var c=[];d=d||{};a(b).each(function(){var e=(a(d.item||this).attr(d.attribute||"id")||"").match(d.expression||(/(.+)[-=_](.+)/));if(e){c.push((d.key||e[1]+"[]")+"="+(d.key&&d.expression?e[1]:e[2]))}});return c.join("&")},toArray:function(d){var b=this._getItemsAsjQuery(d&&d.connected);var c=[];d=d||{};b.each(function(){c.push(a(d.item||this).attr(d.attribute||"id")||"")});return c},_intersectsWith:function(m){var e=this.positionAbs.left,d=e+this.helperProportions.width,k=this.positionAbs.top,j=k+this.helperProportions.height;var f=m.left,c=f+m.width,n=m.top,i=n+m.height;var o=this.offset.click.top,h=this.offset.click.left;var g=(k+o)>n&&(k+o)<i&&(e+h)>f&&(e+h)<c;if(this.options.tolerance=="pointer"||this.options.forcePointerForContainers||(this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>m[this.floating?"width":"height"])){return g}else{return(f<e+(this.helperProportions.width/2)&&d-(this.helperProportions.width/2)<c&&n<k+(this.helperProportions.height/2)&&j-(this.helperProportions.height/2)<i)}},_intersectsWithPointer:function(d){var e=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,d.top,d.height),c=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,d.left,d.width),g=e&&c,b=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();if(!g){return false}return this.floating?(((f&&f=="right")||b=="down")?2:1):(b&&(b=="down"?2:1))},_intersectsWithSides:function(e){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,e.top+(e.height/2),e.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,e.left+(e.width/2),e.width),b=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();if(this.floating&&f){return((f=="right"&&d)||(f=="left"&&!d))}else{return b&&((b=="down"&&c)||(b=="up"&&!c))}},_getDragVerticalDirection:function(){var b=this.positionAbs.top-this.lastPositionAbs.top;return b!=0&&(b>0?"down":"up")},_getDragHorizontalDirection:function(){var b=this.positionAbs.left-this.lastPositionAbs.left;return b!=0&&(b>0?"right":"left")},refresh:function(b){this._refreshItems(b);this.refreshPositions()},_connectWith:function(){var b=this.options;return b.connectWith.constructor==String?[b.connectWith]:b.connectWith},_getItemsAsjQuery:function(b){var l=this;var g=[];var e=[];var h=this._connectWith();if(h&&b){for(var d=h.length-1;d>=0;d--){var k=a(h[d]);for(var c=k.length-1;c>=0;c--){var f=a.data(k[c],"sortable");if(f&&f!=this&&!f.options.disabled){e.push([a.isFunction(f.options.items)?f.options.items.call(f.element):a(f.options.items,f.element).not(".ui-sortable-helper"),f])}}}}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"),this]);for(var d=e.length-1;d>=0;d--){e[d][0].each(function(){g.push(this)})}return a(g)},_removeCurrentsFromItems:function(){var d=this.currentItem.find(":data(sortable-item)");for(var c=0;c<this.items.length;c++){for(var b=0;b<d.length;b++){if(d[b]==this.items[c].item[0]){this.items.splice(c,1)}}}},_refreshItems:function(b){this.items=[];this.containers=[this];var h=this.items;var p=this;var f=[[a.isFunction(this.options.items)?this.options.items.call(this.element[0],b,{item:this.currentItem}):a(this.options.items,this.element),this]];var l=this._connectWith();if(l){for(var e=l.length-1;e>=0;e--){var m=a(l[e]);for(var d=m.length-1;d>=0;d--){var g=a.data(m[d],"sortable");if(g&&g!=this&&!g.options.disabled){f.push([a.isFunction(g.options.items)?g.options.items.call(g.element[0],b,{item:this.currentItem}):a(g.options.items,g.element),g]);this.containers.push(g)}}}}for(var e=f.length-1;e>=0;e--){var k=f[e][1];var c=f[e][0];for(var d=0,n=c.length;d<n;d++){var o=a(c[d]);o.data("sortable-item",k);h.push({item:o,instance:k,width:0,height:0,left:0,top:0})}}},refreshPositions:function(b){if(this.offsetParent&&this.helper){this.offset.parent=this._getParentOffset()}for(var d=this.items.length-1;d>=0;d--){var e=this.items[d];if(e.instance!=this.currentContainer&&this.currentContainer&&e.item[0]!=this.currentItem[0]){continue}var c=this.options.toleranceElement?a(this.options.toleranceElement,e.item):e.item;if(!b){e.width=c.outerWidth();e.height=c.outerHeight()}var f=c.offset();e.left=f.left;e.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers){this.options.custom.refreshContainers.call(this)}else{for(var d=this.containers.length-1;d>=0;d--){var f=this.containers[d].element.offset();this.containers[d].containerCache.left=f.left;this.containers[d].containerCache.top=f.top;this.containers[d].containerCache.width=this.containers[d].element.outerWidth();this.containers[d].containerCache.height=this.containers[d].element.outerHeight()}}},_createPlaceholder:function(d){var b=d||this,e=b.options;if(!e.placeholder||e.placeholder.constructor==String){var c=e.placeholder;e.placeholder={element:function(){var f=a(document.createElement(b.currentItem[0].nodeName)).addClass(c||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!c){f.style.visibility="hidden"}return f},update:function(f,g){if(c&&!e.forcePlaceholderSize){return}if(!g.height()){g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10))}if(!g.width()){g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=a(e.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);e.placeholder.update(b,b.placeholder)},_contactContainers:function(d){for(var c=this.containers.length-1;c>=0;c--){if(this._intersectsWith(this.containers[c].containerCache)){if(!this.containers[c].containerCache.over){if(this.currentContainer!=this.containers[c]){var h=10000;var g=null;var e=this.positionAbs[this.containers[c].floating?"left":"top"];for(var b=this.items.length-1;b>=0;b--){if(!a.ui.contains(this.containers[c].element[0],this.items[b].item[0])){continue}var f=this.items[b][this.containers[c].floating?"left":"top"];if(Math.abs(f-e)<h){h=Math.abs(f-e);g=this.items[b]}}if(!g&&!this.options.dropOnEmpty){continue}this.currentContainer=this.containers[c];g?this._rearrange(d,g,null,true):this._rearrange(d,null,this.containers[c].element,true);this._trigger("change",d,this._uiHash());this.containers[c]._trigger("change",d,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder)}this.containers[c]._trigger("over",d,this._uiHash(this));this.containers[c].containerCache.over=1}}else{if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",d,this._uiHash(this));this.containers[c].containerCache.over=0}}}},_createHelper:function(c){var d=this.options;var b=a.isFunction(d.helper)?a(d.helper.apply(this.element[0],[c,this.currentItem])):(d.helper=="clone"?this.currentItem.clone():this.currentItem);if(!b.parents("body").length){a(d.appendTo!="parent"?d.appendTo:this.currentItem[0].parentNode)[0].appendChild(b[0])}if(b[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")}}if(b[0].style.width==""||d.forceHelperSize){b.width(this.currentItem.width())}if(b[0].style.height==""||d.forceHelperSize){b.height(this.currentItem.height())}return b},_adjustOffsetFromHelper:function(b){if(b.left!=undefined){this.offset.click.left=b.left+this.margins.left}if(b.right!=undefined){this.offset.click.left=this.helperProportions.width-b.right+this.margins.left}if(b.top!=undefined){this.offset.click.top=b.top+this.margins.top}if(b.bottom!=undefined){this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top}},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();if(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 b=this.currentItem.position();return{top:b.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else{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 e=this.options;if(e.containment=="parent"){e.containment=this.helper[0].parentNode}if(e.containment=="document"||e.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(e.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(e.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]}if(!(/^(document|window|parent)$/).test(e.containment)){var c=a(e.containment)[0];var d=a(e.containment).offset();var b=(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+(b?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+(b?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(f,h){if(!h){h=this.position}var c=f=="absolute"?1:-1;var e=this.options,b=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(b[0].tagName);return{top:(h.top+this.offset.relative.top*c+this.offset.parent.top*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(g?0:b.scrollTop()))*c)),left:(h.left+this.offset.relative.left*c+this.offset.parent.left*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:b.scrollLeft())*c))}},_generatePosition:function(e){var h=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,i=(/(html|body)/i).test(b[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0])){this.offset.relative=this._getRelativeOffset()}var d=e.pageX;var c=e.pageY;if(this.originalPosition){if(this.containment){if(e.pageX-this.offset.click.left<this.containment[0]){d=this.containment[0]+this.offset.click.left}if(e.pageY-this.offset.click.top<this.containment[1]){c=this.containment[1]+this.offset.click.top}if(e.pageX-this.offset.click.left>this.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:(!(g-this.offset.click.top<this.containment[1])?g-h.grid[1]:g+h.grid[1])):g;var f=this.originalPageX+Math.round((d-this.originalPageX)/h.grid[0])*h.grid[0];d=this.containment?(!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:(!(f-this.offset.click.left<this.containment[0])?f-h.grid[0]:f+h.grid[0])):f}}return{top:(c-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():(i?0:b.scrollTop())))),left:(d-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():i?0:b.scrollLeft())))}},_rearrange:function(g,f,c,e){c?c[0].appendChild(this.placeholder[0]):f.item[0].parentNode.insertBefore(this.placeholder[0],(this.direction=="down"?f.item[0]:f.item[0].nextSibling));this.counter=this.counter?++this.counter:1;var d=this,b=this.counter;window.setTimeout(function(){if(b==d.counter){d.refreshPositions(!e)}},0)},_clear:function(d,e){this.reverting=false;var f=[],b=this;if(!this._noFinalSort&&this.currentItem[0].parentNode){this.placeholder.before(this.currentItem)}this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var c in this._storedCSS){if(this._storedCSS[c]=="auto"||this._storedCSS[c]=="static"){this._storedCSS[c]=""}}this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}if(this.fromOutside&&!e){f.push(function(g){this._trigger("receive",g,this._uiHash(this.fromOutside))})}if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!e){f.push(function(g){this._trigger("update",g,this._uiHash())})}if(!a.ui.contains(this.element[0],this.currentItem[0])){if(!e){f.push(function(g){this._trigger("remove",g,this._uiHash())})}for(var c=this.containers.length-1;c>=0;c--){if(a.ui.contains(this.containers[c].element[0],this.currentItem[0])&&!e){f.push((function(g){return function(h){g._trigger("receive",h,this._uiHash(this))}}).call(this,this.containers[c]));f.push((function(g){return function(h){g._trigger("update",h,this._uiHash(this))}}).call(this,this.containers[c]))}}}for(var c=this.containers.length-1;c>=0;c--){if(!e){f.push((function(g){return function(h){g._trigger("deactivate",h,this._uiHash(this))}}).call(this,this.containers[c]))}if(this.containers[c].containerCache.over){f.push((function(g){return function(h){g._trigger("out",h,this._uiHash(this))}}).call(this,this.containers[c]));this.containers[c].containerCache.over=0}}if(this._storedCursor){a("body").css("cursor",this._storedCursor)}if(this._storedOpacity){this.helper.css("opacity",this._storedOpacity)}if(this._storedZIndex){this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex)}this.dragging=false;if(this.cancelHelperRemoval){if(!e){this._trigger("beforeStop",d,this._uiHash());for(var c=0;c<f.length;c++){f[c].call(this,d)}this._trigger("stop",d,this._uiHash())}return false}if(!e){this._trigger("beforeStop",d,this._uiHash())}this.placeholder[0].parentNode.removeChild(this.placeholder[0]);if(this.helper[0]!=this.currentItem[0]){this.helper.remove()}this.helper=null;if(!e){for(var c=0;c<f.length;c++){f[c].call(this,d)}this._trigger("stop",d,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){if(a.widget.prototype._trigger.apply(this,arguments)===false){this.cancel()}},_uiHash:function(c){var b=c||this;return{helper:b.helper,placeholder:b.placeholder||a([]),position:b.position,absolutePosition:b.positionAbs,offset:b.positionAbs,item:b.currentItem,sender:c?c.element:null}}}));a.extend(a.ui.sortable,{getter:"serialize toArray",version:"1.7",eventPrefix:"sort",defaults:{appendTo:"parent",axis:false,cancel:":input,option",connectWith:false,containment:false,cursor:"auto",cursorAt:false,delay:0,distance:1,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1000}})})(jQuery);;/*
 * jQuery UI Dialog 1.7
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Dialog
 *
 * Depends:
 *	ui.core.js
 *	ui.draggable.js
 *	ui.resizable.js
 */(function(c){var b={dragStart:"start.draggable",drag:"drag.draggable",dragStop:"stop.draggable",maxHeight:"maxHeight.resizable",minHeight:"minHeight.resizable",maxWidth:"maxWidth.resizable",minWidth:"minWidth.resizable",resizeStart:"start.resizable",resize:"drag.resizable",resizeStop:"stop.resizable"},a="ui-dialog ui-widget ui-widget-content ui-corner-all ";c.widget("ui.dialog",{_init:function(){this.originalTitle=this.element.attr("title");var l=this,m=this.options,j=m.title||this.originalTitle||"&nbsp;",e=c.ui.dialog.getTitleId(this.element),k=(this.uiDialog=c("<div/>")).appendTo(document.body).hide().addClass(a+m.dialogClass).css({position:"absolute",overflow:"hidden",zIndex:m.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(n){(m.closeOnEscape&&n.keyCode&&n.keyCode==c.ui.keyCode.ESCAPE&&l.close(n))}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(n){l.moveToTop(false,n)}),g=this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(k),f=(this.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(k),i=c('<a href="#"/>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){i.addClass("ui-state-hover")},function(){i.removeClass("ui-state-hover")}).focus(function(){i.addClass("ui-state-focus")}).blur(function(){i.removeClass("ui-state-focus")}).mousedown(function(n){n.stopPropagation()}).click(function(n){l.close(n);return false}).appendTo(f),h=(this.uiDialogTitlebarCloseText=c("<span/>")).addClass("ui-icon ui-icon-closethick").text(m.closeText).appendTo(i),d=c("<span/>").addClass("ui-dialog-title").attr("id",e).html(j).prependTo(f);f.find("*").add(f).disableSelection();(m.draggable&&c.fn.draggable&&this._makeDraggable());(m.resizable&&c.fn.resizable&&this._makeResizable());this._createButtons(m.buttons);this._isOpen=false;(m.bgiframe&&c.fn.bgiframe&&k.bgiframe());(m.autoOpen&&this.open())},destroy:function(){(this.overlay&&this.overlay.destroy());this.uiDialog.hide();this.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");this.uiDialog.remove();(this.originalTitle&&this.element.attr("title",this.originalTitle))},close:function(e){var d=this;if(false===d._trigger("beforeclose",e)){return}(d.overlay&&d.overlay.destroy());d.uiDialog.unbind("keypress.ui-dialog");(d.options.hide?d.uiDialog.hide(d.options.hide,function(){d._trigger("close",e)}):d.uiDialog.hide()&&d._trigger("close",e));c.ui.dialog.overlay.resize();d._isOpen=false},isOpen:function(){return this._isOpen},moveToTop:function(f,e){if((this.options.modal&&!f)||(!this.options.stack&&!this.options.modal)){return this._trigger("focus",e)}if(this.options.zIndex>c.ui.dialog.maxZ){c.ui.dialog.maxZ=this.options.zIndex}(this.overlay&&this.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=++c.ui.dialog.maxZ));var d={scrollTop:this.element.attr("scrollTop"),scrollLeft:this.element.attr("scrollLeft")};this.uiDialog.css("z-index",++c.ui.dialog.maxZ);this.element.attr(d);this._trigger("focus",e)},open:function(){if(this._isOpen){return}var e=this.options,d=this.uiDialog;this.overlay=e.modal?new c.ui.dialog.overlay(this):null;(d.next().length&&d.appendTo("body"));this._size();this._position(e.position);d.show(e.show);this.moveToTop(true);(e.modal&&d.bind("keypress.ui-dialog",function(h){if(h.keyCode!=c.ui.keyCode.TAB){return}var g=c(":tabbable",this),i=g.filter(":first")[0],f=g.filter(":last")[0];if(h.target==f&&!h.shiftKey){setTimeout(function(){i.focus()},1)}else{if(h.target==i&&h.shiftKey){setTimeout(function(){f.focus()},1)}}}));c([]).add(d.find(".ui-dialog-content :tabbable:first")).add(d.find(".ui-dialog-buttonpane :tabbable:first")).add(d).filter(":first").focus();this._trigger("open");this._isOpen=true},_createButtons:function(g){var f=this,d=false,e=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");this.uiDialog.find(".ui-dialog-buttonpane").remove();(typeof g=="object"&&g!==null&&c.each(g,function(){return !(d=true)}));if(d){c.each(g,function(h,i){c('<button type="button"></button>').addClass("ui-state-default ui-corner-all").text(h).click(function(){i.apply(f.element[0],arguments)}).hover(function(){c(this).addClass("ui-state-hover")},function(){c(this).removeClass("ui-state-hover")}).focus(function(){c(this).addClass("ui-state-focus")}).blur(function(){c(this).removeClass("ui-state-focus")}).appendTo(e)});e.appendTo(this.uiDialog)}},_makeDraggable:function(){var d=this,f=this.options,e;this.uiDialog.draggable({cancel:".ui-dialog-content",handle:".ui-dialog-titlebar",containment:"document",start:function(){e=f.height;c(this).height(c(this).height()).addClass("ui-dialog-dragging");(f.dragStart&&f.dragStart.apply(d.element[0],arguments))},drag:function(){(f.drag&&f.drag.apply(d.element[0],arguments))},stop:function(){c(this).removeClass("ui-dialog-dragging").height(e);(f.dragStop&&f.dragStop.apply(d.element[0],arguments));c.ui.dialog.overlay.resize()}})},_makeResizable:function(g){g=(g===undefined?this.options.resizable:g);var d=this,f=this.options,e=typeof g=="string"?g:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",alsoResize:this.element,maxWidth:f.maxWidth,maxHeight:f.maxHeight,minWidth:f.minWidth,minHeight:f.minHeight,start:function(){c(this).addClass("ui-dialog-resizing");(f.resizeStart&&f.resizeStart.apply(d.element[0],arguments))},resize:function(){(f.resize&&f.resize.apply(d.element[0],arguments))},handles:e,stop:function(){c(this).removeClass("ui-dialog-resizing");f.height=c(this).height();f.width=c(this).width();(f.resizeStop&&f.resizeStop.apply(d.element[0],arguments));c.ui.dialog.overlay.resize()}}).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_position:function(i){var e=c(window),f=c(document),g=f.scrollTop(),d=f.scrollLeft(),h=g;if(c.inArray(i,["center","top","right","bottom","left"])>=0){i=[i=="right"||i=="left"?i:"center",i=="top"||i=="bottom"?i:"middle"]}if(i.constructor!=Array){i=["center","middle"]}if(i[0].constructor==Number){d+=i[0]}else{switch(i[0]){case"left":d+=0;break;case"right":d+=e.width()-this.uiDialog.outerWidth();break;default:case"center":d+=(e.width()-this.uiDialog.outerWidth())/2}}if(i[1].constructor==Number){g+=i[1]}else{switch(i[1]){case"top":g+=0;break;case"bottom":g+=e.height()-this.uiDialog.outerHeight();break;default:case"middle":g+=(e.height()-this.uiDialog.outerHeight())/2}}g=Math.max(g,h);this.uiDialog.css({top:g,left:d})},_setData:function(e,f){(b[e]&&this.uiDialog.data(b[e],f));switch(e){case"buttons":this._createButtons(f);break;case"closeText":this.uiDialogTitlebarCloseText.text(f);break;case"dialogClass":this.uiDialog.removeClass(this.options.dialogClass).addClass(a+f);break;case"draggable":(f?this._makeDraggable():this.uiDialog.draggable("destroy"));break;case"height":this.uiDialog.height(f);break;case"position":this._position(f);break;case"resizable":var d=this.uiDialog,g=this.uiDialog.is(":data(resizable)");(g&&!f&&d.resizable("destroy"));(g&&typeof f=="string"&&d.resizable("option","handles",f));(g||this._makeResizable(f));break;case"title":c(".ui-dialog-title",this.uiDialogTitlebar).html(f||"&nbsp;");break;case"width":this.uiDialog.width(f);break}c.widget.prototype._setData.apply(this,arguments)},_size:function(){var e=this.options;this.element.css({height:0,minHeight:0,width:"auto"});var d=this.uiDialog.css({height:"auto",width:e.width}).height();this.element.css({minHeight:Math.max(e.minHeight-d,0),height:e.height=="auto"?"auto":Math.max(e.height-d,0)})}});c.extend(c.ui.dialog,{version:"1.7",defaults:{autoOpen:true,bgiframe:false,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:"center",resizable:true,show:null,stack:true,title:"",width:300,zIndex:1000},getter:"isOpen",uuid:0,maxZ:0,getTitleId:function(d){return"ui-dialog-title-"+(d.attr("id")||++this.uuid)},overlay:function(d){this.$el=c.ui.dialog.overlay.create(d)}});c.extend(c.ui.dialog.overlay,{instances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(d){return d+".dialog-overlay"}).join(" "),create:function(e){if(this.instances.length===0){setTimeout(function(){c(document).bind(c.ui.dialog.overlay.events,function(f){var g=c(f.target).parents(".ui-dialog").css("zIndex")||0;return(g>c.ui.dialog.overlay.maxZ)})},1);c(document).bind("keydown.dialog-overlay",function(f){(e.options.closeOnEscape&&f.keyCode&&f.keyCode==c.ui.keyCode.ESCAPE&&e.close(f))});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var d=c("<div></div>").appendTo(document.body).addClass("ui-widget-overlay").css({width:this.width(),height:this.height()});(e.options.bgiframe&&c.fn.bgiframe&&d.bgiframe());this.instances.push(d);return d},destroy:function(d){this.instances.splice(c.inArray(this.instances,d),1);if(this.instances.length===0){c([document,window]).unbind(".dialog-overlay")}d.remove()},height:function(){if(c.browser.msie&&c.browser.version<7){var e=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);var d=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);if(e<d){return c(window).height()+"px"}else{return e+"px"}}else{return c(document).height()+"px"}},width:function(){if(c.browser.msie&&c.browser.version<7){var d=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);var e=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);if(d<e){return c(window).width()+"px"}else{return d+"px"}}else{return c(document).width()+"px"}},resize:function(){var d=c([]);c.each(c.ui.dialog.overlay.instances,function(){d=d.add(this)});d.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);;/*
 * jQuery UI Effects 1.7
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Effects/
 */jQuery.effects||(function(d){d.effects={version:"1.7",save:function(g,h){for(var f=0;f<h.length;f++){if(h[f]!==null){g.data("ec.storage."+h[f],g[0].style[h[f]])}}},restore:function(g,h){for(var f=0;f<h.length;f++){if(h[f]!==null){g.css(h[f],g.data("ec.storage."+h[f]))}}},setMode:function(f,g){if(g=="toggle"){g=f.is(":hidden")?"show":"hide"}return g},getBaseline:function(g,h){var i,f;switch(g[0]){case"top":i=0;break;case"middle":i=0.5;break;case"bottom":i=1;break;default:i=g[0]/h.height}switch(g[1]){case"left":f=0;break;case"center":f=0.5;break;case"right":f=1;break;default:f=g[1]/h.width}return{x:f,y:i}},createWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent()}var g={width:f.outerWidth(true),height:f.outerHeight(true),"float":f.css("float")};f.wrap('<div class="ui-effects-wrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');var j=f.parent();if(f.css("position")=="static"){j.css({position:"relative"});f.css({position:"relative"})}else{var i=f.css("top");if(isNaN(parseInt(i,10))){i="auto"}var h=f.css("left");if(isNaN(parseInt(h,10))){h="auto"}j.css({position:f.css("position"),top:i,left:h,zIndex:f.css("z-index")}).show();f.css({position:"relative",top:0,left:0})}j.css(g);return j},removeWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent().replaceWith(f)}return f},setTransition:function(g,i,f,h){h=h||{};d.each(i,function(k,j){unit=g.cssUnit(j);if(unit[0]>0){h[j]=unit[0]*f+unit[1]}});return h},animateClass:function(h,i,k,j){var f=(typeof k=="function"?k:(j?j:null));var g=(typeof k=="string"?k:null);return this.each(function(){var q={};var o=d(this);var p=o.attr("style")||"";if(typeof p=="object"){p=p.cssText}if(h.toggle){o.hasClass(h.toggle)?h.remove=h.toggle:h.add=h.toggle}var l=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.addClass(h.add)}if(h.remove){o.removeClass(h.remove)}var m=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.removeClass(h.add)}if(h.remove){o.addClass(h.remove)}for(var r in m){if(typeof m[r]!="function"&&m[r]&&r.indexOf("Moz")==-1&&r.indexOf("length")==-1&&m[r]!=l[r]&&(r.match(/color/i)||(!r.match(/color/i)&&!isNaN(parseInt(m[r],10))))&&(l.position!="static"||(l.position=="static"&&!r.match(/left|top|bottom|right/)))){q[r]=m[r]}}o.animate(q,i,g,function(){if(typeof d(this).attr("style")=="object"){d(this).attr("style")["cssText"]="";d(this).attr("style")["cssText"]=p}else{d(this).attr("style",p)}if(h.add){d(this).addClass(h.add)}if(h.remove){d(this).removeClass(h.remove)}if(f){f.apply(this,arguments)}})})}};function c(g,f){var i=g[1]&&g[1].constructor==Object?g[1]:{};if(f){i.mode=f}var h=g[1]&&g[1].constructor!=Object?g[1]:(i.duration?i.duration:g[2]);h=d.fx.off?0:typeof h==="number"?h:d.fx.speeds[h]||d.fx.speeds._default;var j=i.callback||(d.isFunction(g[1])&&g[1])||(d.isFunction(g[2])&&g[2])||(d.isFunction(g[3])&&g[3]);return[g[0],i,h,j]}d.fn.extend({_show:d.fn.show,_hide:d.fn.hide,__toggle:d.fn.toggle,_addClass:d.fn.addClass,_removeClass:d.fn.removeClass,_toggleClass:d.fn.toggleClass,effect:function(g,f,h,i){return d.effects[g]?d.effects[g].call(this,{method:g,options:f||{},duration:h,callback:i}):null},show:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._show.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"show"))}},hide:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._hide.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"hide"))}},toggle:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))||(arguments[0].constructor==Function)){return this.__toggle.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"toggle"))}},addClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{add:g},f,i,h]):this._addClass(g)},removeClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{remove:g},f,i,h]):this._removeClass(g)},toggleClass:function(g,f,i,h){return((typeof f!=="boolean")&&f)?d.effects.animateClass.apply(this,[{toggle:g},f,i,h]):this._toggleClass(g,f)},morph:function(f,h,g,j,i){return d.effects.animateClass.apply(this,[{add:h,remove:f},g,j,i])},switchClass:function(){return this.morph.apply(this,arguments)},cssUnit:function(f){var g=this.css(f),h=[];d.each(["em","px","%","pt"],function(j,k){if(g.indexOf(k)>0){h=[parseFloat(g),k]}});return h}});d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(g,f){d.fx.step[f]=function(h){if(h.state==0){h.start=e(h.elem,f);h.end=b(h.end)}h.elem.style[f]="rgb("+[Math.max(Math.min(parseInt((h.pos*(h.end[0]-h.start[0]))+h.start[0],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[1]-h.start[1]))+h.start[1],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[2]-h.start[2]))+h.start[2],10),255),0)].join(",")+")"}});function b(g){var f;if(g&&g.constructor==Array&&g.length==3){return g}if(f=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(g)){return[parseInt(f[1],10),parseInt(f[2],10),parseInt(f[3],10)]}if(f=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(g)){return[parseFloat(f[1])*2.55,parseFloat(f[2])*2.55,parseFloat(f[3])*2.55]}if(f=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(g)){return[parseInt(f[1],16),parseInt(f[2],16),parseInt(f[3],16)]}if(f=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(g)){return[parseInt(f[1]+f[1],16),parseInt(f[2]+f[2],16),parseInt(f[3]+f[3],16)]}if(f=/rgba\(0, 0, 0, 0\)/.exec(g)){return a.transparent}return a[d.trim(g).toLowerCase()]}function e(h,f){var g;do{g=d.curCSS(h,f);if(g!=""&&g!="transparent"||d.nodeName(h,"body")){break}f="backgroundColor"}while(h=h.parentNode);return b(g)}var a={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]};d.easing.jswing=d.easing.swing;d.extend(d.easing,{def:"easeOutQuad",swing:function(g,h,f,j,i){return d.easing[d.easing.def](g,h,f,j,i)},easeInQuad:function(g,h,f,j,i){return j*(h/=i)*h+f},easeOutQuad:function(g,h,f,j,i){return -j*(h/=i)*(h-2)+f},easeInOutQuad:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h+f}return -j/2*((--h)*(h-2)-1)+f},easeInCubic:function(g,h,f,j,i){return j*(h/=i)*h*h+f},easeOutCubic:function(g,h,f,j,i){return j*((h=h/i-1)*h*h+1)+f},easeInOutCubic:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h+f}return j/2*((h-=2)*h*h+2)+f},easeInQuart:function(g,h,f,j,i){return j*(h/=i)*h*h*h+f},easeOutQuart:function(g,h,f,j,i){return -j*((h=h/i-1)*h*h*h-1)+f},easeInOutQuart:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h+f}return -j/2*((h-=2)*h*h*h-2)+f},easeInQuint:function(g,h,f,j,i){return j*(h/=i)*h*h*h*h+f},easeOutQuint:function(g,h,f,j,i){return j*((h=h/i-1)*h*h*h*h+1)+f},easeInOutQuint:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h*h+f}return j/2*((h-=2)*h*h*h*h+2)+f},easeInSine:function(g,h,f,j,i){return -j*Math.cos(h/i*(Math.PI/2))+j+f},easeOutSine:function(g,h,f,j,i){return j*Math.sin(h/i*(Math.PI/2))+f},easeInOutSine:function(g,h,f,j,i){return -j/2*(Math.cos(Math.PI*h/i)-1)+f},easeInExpo:function(g,h,f,j,i){return(h==0)?f:j*Math.pow(2,10*(h/i-1))+f},easeOutExpo:function(g,h,f,j,i){return(h==i)?f+j:j*(-Math.pow(2,-10*h/i)+1)+f},easeInOutExpo:function(g,h,f,j,i){if(h==0){return f}if(h==i){return f+j}if((h/=i/2)<1){return j/2*Math.pow(2,10*(h-1))+f}return j/2*(-Math.pow(2,-10*--h)+2)+f},easeInCirc:function(g,h,f,j,i){return -j*(Math.sqrt(1-(h/=i)*h)-1)+f},easeOutCirc:function(g,h,f,j,i){return j*Math.sqrt(1-(h=h/i-1)*h)+f},easeInOutCirc:function(g,h,f,j,i){if((h/=i/2)<1){return -j/2*(Math.sqrt(1-h*h)-1)+f}return j/2*(Math.sqrt(1-(h-=2)*h)+1)+f},easeInElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}return -(h*Math.pow(2,10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k))+f},easeOutElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}return h*Math.pow(2,-10*i)*Math.sin((i*l-j)*(2*Math.PI)/k)+m+f},easeInOutElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l/2)==2){return f+m}if(!k){k=l*(0.3*1.5)}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}if(i<1){return -0.5*(h*Math.pow(2,10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k))+f}return h*Math.pow(2,-10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k)*0.5+m+f},easeInBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}return k*(h/=j)*h*((i+1)*h-i)+f},easeOutBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}return k*((h=h/j-1)*h*((i+1)*h+i)+1)+f},easeInOutBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}if((h/=j/2)<1){return k/2*(h*h*(((i*=(1.525))+1)*h-i))+f}return k/2*((h-=2)*h*(((i*=(1.525))+1)*h+i)+2)+f},easeInBounce:function(g,h,f,j,i){return j-d.easing.easeOutBounce(g,i-h,0,j,i)+f},easeOutBounce:function(g,h,f,j,i){if((h/=i)<(1/2.75)){return j*(7.5625*h*h)+f}else{if(h<(2/2.75)){return j*(7.5625*(h-=(1.5/2.75))*h+0.75)+f}else{if(h<(2.5/2.75)){return j*(7.5625*(h-=(2.25/2.75))*h+0.9375)+f}else{return j*(7.5625*(h-=(2.625/2.75))*h+0.984375)+f}}}},easeInOutBounce:function(g,h,f,j,i){if(h<i/2){return d.easing.easeInBounce(g,h*2,0,j,i)*0.5+f}return d.easing.easeOutBounce(g,h*2-i,0,j,i)*0.5+j*0.5+f}})})(jQuery);;/*
 * jQuery UI Effects Blind 1.7
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Effects/Blind
 *
 * Depends:
 *	effects.core.js
 */(function(a){a.effects.blind=function(b){return this.queue(function(){var d=a(this),c=["position","top","left"];var h=a.effects.setMode(d,b.options.mode||"hide");var g=b.options.direction||"vertical";a.effects.save(d,c);d.show();var j=a.effects.createWrapper(d).css({overflow:"hidden"});var e=(g=="vertical")?"height":"width";var i=(g=="vertical")?j.height():j.width();if(h=="show"){j.css(e,0)}var f={};f[e]=h=="show"?i:0;j.animate(f,b.duration,b.options.easing,function(){if(h=="hide"){d.hide()}a.effects.restore(d,c);a.effects.removeWrapper(d);if(b.callback){b.callback.apply(d[0],arguments)}d.dequeue()})})}})(jQuery);;/*
 * jQuery UI Effects Slide 1.7
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Effects/Slide
 *
 * Depends:
 *	effects.core.js
 */(function(a){a.effects.slide=function(b){return this.queue(function(){var e=a(this),d=["position","top","left"];var i=a.effects.setMode(e,b.options.mode||"show");var h=b.options.direction||"left";a.effects.save(e,d);e.show();a.effects.createWrapper(e).css({overflow:"hidden"});var f=(h=="up"||h=="down")?"top":"left";var c=(h=="up"||h=="left")?"pos":"neg";var j=b.options.distance||(f=="top"?e.outerHeight({margin:true}):e.outerWidth({margin:true}));if(i=="show"){e.css(f,c=="pos"?-j:j)}var g={};g[f]=(i=="show"?(c=="pos"?"+=":"-="):(c=="pos"?"-=":"+="))+j;e.animate(g,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){e.hide()}a.effects.restore(e,d);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);;

/** File: javascript/jquery.cookie.js **/

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

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

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};

/** File: javascript/jquery.insertAtCursor.js **/

/**
 * insert text at carret location.
 */
jQuery.fn.insertAtCursor = function(string_to_insert) {
  return this.each(function() {
    var input_field = $(this);

    if ($.browser.msie) {
      input_field.focus();
      document.selection.createRange().text = string_to_insert;
      input_field.focus();
    } else {
      // find selection boundaries
      var selection_start = input_field[0].selectionStart;
      var selection_end = input_field[0].selectionEnd;   
      
      if (selection_start || selection_start == '0') {
        // make new string and insert it in input
        var new_string = input_field.val().substring(0, selection_start) + string_to_insert + input_field.val().substring(selection_end, input_field.val().length);
        input_field.val(new_string);
        input_field[0].selectionStart = input_field[0].selectionEnd = selection_start + string_to_insert.length;       
      } else {
        input_field.val(input_field.val() + string_to_insert);
      } // if
      input_field.focus();
    } // if
  });
};

/** File: javascript/jquery.tree_component.js **/

/*
 * jsTree 0.9.5
 * (jstree.com)
 *
 * Copyright (c) 2008 Ivan Bozhanov (vakata.com)
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Date: 2009-01-12
 *
 */

// jQuery plugin
jQuery.fn.tree = function (opts) {
	return this.each(function() {
		if(tree_component.inst && tree_component.inst[jQuery(this).attr('id')]) 
			tree_component.inst[jQuery(this).attr('id')].destroy();
		if(opts !== false) {
			var tmp = new tree_component();
			tmp.init(this, opts);
		}
	});
};

// core
function tree_component () {
	// instance manager
	if(typeof tree_component.inst == "undefined") {
		tree_component.cntr = 0;
		tree_component.inst = new Array();
		tree_component.drop = new Array();

		tree_component.focusInst = function () {
			return tree_component.inst[tree_component.focused];
		}
		tree_component.mousedown = function(event) {
			var _this = tree_component.focusInst();
			if(!_this) return;
			
			var tmp = jQuery(event.target);
			if(tree_component.drop.length && tmp.is("." + tree_component.drop.join(", .")) ) {
				_this.drag = jQuery("<li id='dragged' class='dragged foreign " + event.target.className + "'><a href='#'>" + tmp.text() + "</a></li>");
				_this._drag = _this.drag;
				_this.isdown	= true;
				_this.foreign	= tmp;
				tmp.blur();
				event.preventDefault(); 
				event.stopPropagation();
				return false;
			}
			event.stopPropagation();
			return true;
		};
		tree_component.mouseup = function(event) {
			var _this = tree_component.focusInst();
			if(!_this) return;

			// CLEAR TIMEOUT FOR OPENING HOVERED NODES WHILE DRAGGING
			if(tree_component.to)	clearTimeout(tree_component.to);
			if(tree_component.sto)	clearTimeout(tree_component.sto);
			if(_this.foreign === false && _this.drag && _this.drag.parentNode && _this.drag.parentNode == jQuery(_this.container).children("ul:eq(0)").get(0)) {
				jQuery(_this.drag).remove();
				// CALL FUNCTION FOR COMPLETING MOVE
				if(_this.moveType) {
					var tmp = tree_component.inst[jQuery(_this.moveRef).parents(".tree:eq(0)").attr("id")];
					if(tmp) { 
						tmp.moved(_this.container.find("li.dragged"), _this.moveRef, _this.moveType, false, (_this.settings.rules.drag_copy == "on" || (_this.settings.rules.drag_copy == "ctrl" && event.ctrlKey) ) );
					}
				}
				_this.moveType = false;
				_this.moveRef = false;
			}
			if(_this.drag && _this.foreign !== false) {
				jQuery(_this.drag).remove();
				if(_this.moveType) {
					var tmp = tree_component.inst[jQuery(_this.moveRef).parents(".tree:eq(0)").attr("id")];
					if(tmp) { 
						tmp.settings.callback.ondrop.call(null, _this.foreign.get(0), _this.get_node( _this.moveRef).get(0), _this.moveType, _this);
					}
				}
				_this.foreign = false;
				_this.moveType = false;
				_this.moveRef = false;
			}
			// RESET EVERYTHING
			jQuery("#marker").hide();
			_this._drag		= false;
			_this.drag		= false;
			_this.isdown	= false;
			_this.appended	= false;
			_this.container.find("li.dragged").removeClass("dragged");
			event.preventDefault(); 
			event.stopPropagation();
			return false;
		};
		tree_component.mousemove = function(event) {
			var _this = tree_component.focusInst();
			if(!_this) return;

			if(_this.locked) return _this.error("LOCKED");
			if(_this.isdown) {
				// CLEAR TIMEOUT FOR OPENING HOVERED NODES WHILE DRAGGING
				if(tree_component.to) clearTimeout(tree_component.to);
				if(!_this.appended) {
					_this.container.children("ul:eq(0)").append(_this.drag);
					var tmp = jQuery(_this.drag).offsetParent();
					if(tmp.is("html")) tmp = jQuery("body");
					_this.po = tmp.offset();
					_this.appended = true;
				}
				jQuery(_this.drag).css({ "left" : (event.pageX - _this.po.left - (_this.settings.ui.rtl ? jQuery(_this.drag).width() : -5 ) ), "top" : (event.pageY - _this.po.top  + (jQuery.browser.opera ? _this.container.scrollTop() : 0) + 15) });

				if(event.target.tagName == "IMG" && event.target.id == "marker") return false;

				var cnt = jQuery(event.target).parents(".tree:eq(0)");

				// if not moving over a tree
				if(cnt.size() == 0) {
					if(tree_component.sto) clearTimeout(tree_component.sto);
					if(jQuery(_this.drag).children("IMG").size() == 0) {
						jQuery(_this.drag).append("<img style='position:absolute; " + (_this.settings.ui.rtl ? "right" : "left" ) + ":4px; top:0px; background:white; padding:2px;' src='" + _this.settings.ui.theme_path + "default/remove.png' />");
					}
					_this.moveType = false;
					_this.moveRef  = false;
					jQuery("#marker").hide();
					return false;
				}

				tree_component.inst[cnt.attr("id")].off_height();

				// if moving over another tree and multitree is false
				if( _this.foreign === false && cnt.get(0) != _this.container.get(0) && (!_this.settings.rules.multitree || !tree_component.inst[cnt.attr("id")].settings.rules.multitree) ) {
					if(jQuery(_this.drag).children("IMG").size() == 0) {
						jQuery(_this.drag).append("<img style='position:absolute; " + (_this.settings.ui.rtl ? "right" : "left" ) + ":4px; top:0px; background:white; padding:2px;' src='" + _this.settings.ui.theme_path + "default/remove.png' />");
					}
					_this.moveType = false;
					_this.moveRef  = false;
					jQuery("#marker").hide();
					return false;
				}

				if(tree_component.sto) clearTimeout(tree_component.sto);
				tree_component.sto = setTimeout( function() { tree_component.inst[cnt.attr("id")].scrollCheck(event.pageX,event.pageY); }, 50);

				var mov = false;
				var st = cnt.scrollTop();

				if(event.target.tagName == "A" ) {
					// just in case if hover is over the draggable
					if(jQuery(event.target).is("#dragged")) return false;

					var goTo = { 
						x : (jQuery(event.target).offset().left - 1),
						y : (event.pageY - tree_component.inst[cnt.attr("id")].offset.top)
					}
					if(cnt.hasClass("rtl")) {
						goTo.x += jQuery(event.target).width() - 8;
					}
					if( (goTo.y + st)%_this.li_height < _this.li_height/3 + 1 ) {
						mov = "before";
						goTo.y = event.pageY - (goTo.y + st)%_this.li_height - 2 ;
					}
					else if((goTo.y + st)%_this.li_height > _this.li_height*2/3 - 1 ) {
						mov = "after";
						goTo.y = event.pageY - (goTo.y + st)%_this.li_height + _this.li_height - 2 ;
					}
					else {
						mov = "inside";
						goTo.x -= 2;
						if(cnt.hasClass("rtl")) {
							goTo.x += 36;
						}
						goTo.y = event.pageY - (goTo.y + st)%_this.li_height + Math.floor(_this.li_height/2) - 2 ;
						if(_this.get_node(event.target).hasClass("closed")) {
							tree_component.to = setTimeout( function () { _this.open_branch(_this.get_node(event.target)); }, 500);
						}
					}

					if(tree_component.inst[cnt.attr("id")].checkMove(_this.container.find("li.dragged"), jQuery(event.target), mov)) {
						if(mov == "inside")	jQuery("#marker").attr("src", _this.settings.ui.theme_path + "default/plus.gif").width(11);
						else {
							if(cnt.hasClass("rtl"))	{ jQuery("#marker").attr("src", _this.settings.ui.theme_path + "default/marker_rtl.gif").width(40); }
							else					{ jQuery("#marker").attr("src", _this.settings.ui.theme_path + "default/marker.gif").width(40); }
						}
						_this.moveType	= mov;
						_this.moveRef	= event.target;
						jQuery(_this.drag).children("IMG").remove();
						jQuery("#marker").css({ "left" : goTo.x , "top" : goTo.y }).show();
					}
					else {
						if(jQuery(_this.drag).children("IMG").size() == 0) {
							jQuery(_this.drag).append("<img style='position:absolute; " + (_this.settings.ui.rtl ? "right:0px;" : "left:4px;" ) + " top:0px; background:white; padding:2px;' src='" + _this.settings.ui.theme_path + "default/remove.png' />");
						}
						_this.moveType = false;
						_this.moveRef = false;
						jQuery("#marker").hide();
					}
				}
				else {
					if(jQuery(_this.drag).children("IMG").size() == 0) {
						jQuery(_this.drag).append("<img style='position:absolute; " + (_this.settings.ui.rtl ? "right:0px;" : "left:4px;" ) + " top:0px; background:white; padding:2px;' src='" + _this.settings.ui.theme_path + "default/remove.png' />");
					}
					_this.moveType = false;
					_this.moveRef = false;
					jQuery("#marker").hide();
				}
				event.preventDefault();
				event.stopPropagation();
				return false;
			}
			return true;
		};
	}
	return {
		cntr : tree_component.cntr ++,
		settings : {
			data	: {
				type	: "predefined",	// ENUM [json, xml_flat, xml_nested, predefined]
				method	: "GET",		// HOW TO REQUEST FILES
				async	: false,		// BOOL - async loading onopen
				async_data : function (NODE) { return { id : jQuery(NODE).attr("id") || 0 } }, // PARAMETERS PASSED TO SERVER
				url		: false,		// FALSE or STRING - url to document to be used (async or not)
				json	: false			// FALSE or OBJECT if type is JSON and async is false - the tree dump as json
			},
			selected	: false,		// FALSE or STRING or ARRAY
			opened		: [],			// ARRAY OF INITIALLY OPENED NODES
			languages	: [],			// ARRAY of string values (which will be used as CSS classes - si they must be valid)
			path		: false,		// FALSE or STRING (if false - will be autodetected)
			cookies		: false,		// FALSE or OBJECT (prefix, opts - from jqCookie - expires, path, domain, secure)
			ui		: {
				dots		: true,		// BOOL - dots or no dots
				rtl			: false,	// BOOL - is the tree right-to-left
				animation	: 0,		// INT - duration of open/close animations in miliseconds
				hover_mode	: true,		// SHOULD get_* functions chage focus or change hovered item
				scroll_spd	: 4,
				theme_path	: false,	// Path to themes
				theme_name	: "default",// Name of theme
				context		: [ 
					{
						id		: "create",
						label	: "Create", 
						icon	: "create.png",
						visible	: function (NODE, TREE_OBJ) { if(NODE.length != 1) return false; return TREE_OBJ.check("creatable", NODE); }, 
						action	: function (NODE, TREE_OBJ) { TREE_OBJ.create(false, NODE); } 
					},
					"separator",
					{ 
						id		: "rename",
						label	: "Rename", 
						icon	: "rename.png",
						visible	: function (NODE, TREE_OBJ) { if(NODE.length != 1) return false; return TREE_OBJ.check("renameable", NODE); }, 
						action	: function (NODE, TREE_OBJ) { TREE_OBJ.rename(); } 
					},
					{ 
						id		: "delete",
						label	: "Delete",
						icon	: "remove.png",
						visible	: function (NODE, TREE_OBJ) { return TREE_OBJ.check("deletable", NODE); }, 
						action	: function (NODE, TREE_OBJ) { NODE.each( function () { TREE_OBJ.remove(this); }); } 
					}
				]
			},
			rules	: {
				multiple	: false,	// FALSE | CTRL | ON - multiple selection off/ with or without holding Ctrl
				metadata	: false,	// FALSE or STRING - attribute name (use metadata plugin)
				type_attr	: "rel",	// STRING attribute name (where is the type stored if no metadata)
				multitree	: false,	// BOOL - is drag n drop between trees allowed
				createat	: "bottom",	// STRING (top or bottom) new nodes get inserted at top or bottom
				use_inline	: false,	// CHECK FOR INLINE RULES - REQUIRES METADATA
				clickable	: "all",	// which node types can the user select | default - all
				renameable	: "all",	// which node types can the user select | default - all
				deletable	: "all",	// which node types can the user delete | default - all
				creatable	: "all",	// which node types can the user create in | default - all
				draggable	: "none",	// which node types can the user move | default - none | "all"
				dragrules	: "all",	// what move operations between nodes are allowed | default - none | "all"
				drag_copy	: false,	// FALSE | CTRL | ON - drag to copy off/ with or without holding Ctrl
				droppable	: []
			},
			lang : {
				new_node	: "New folder",
				loading		: "Loading ..."
			},
			callback	: {				// various callbacks to attach custom logic to
				// before focus  - should return true | false
				beforechange: function(NODE,TREE_OBJ) { return true },
				// before move   - should return true | false
				beforemove  : function(NODE,REF_NODE,TYPE,TREE_OBJ) { return true }, 
				// before create - should return true | false
				beforecreate: function(NODE,REF_NODE,TYPE,TREE_OBJ) { return true }, 
				// before rename - should return true | false
				beforerename: function(NODE,LANG,TREE_OBJ) { return true }, 
				// before delete - should return true | false
				beforedelete: function(NODE,TREE_OBJ) { return true }, 

				onchange	: function(NODE,TREE_OBJ) { },					// focus changed
				onrename	: function(NODE,LANG,TREE_OBJ) { },				// node renamed ISNEW - TRUE|FALSE, current language
				onmove		: function(NODE,REF_NODE,TYPE,TREE_OBJ) { },	// move completed (TYPE is BELOW|ABOVE|INSIDE)
				oncopy		: function(NODE,REF_NODE,TYPE,TREE_OBJ) { },	// copy completed (TYPE is BELOW|ABOVE|INSIDE)
				oncreate	: function(NODE,REF_NODE,TYPE,TREE_OBJ) { },	// node created, parent node (TYPE is insertAt)
				ondelete	: function(NODE, TREE_OBJ) { },					// node deleted
				onopen		: function(NODE, TREE_OBJ) { },					// node opened
				onclose		: function(NODE, TREE_OBJ) { },					// node closed
				error		: function(TEXT, TREE_OBJ) { },					// error occured
				// double click on node - defaults to open/close & select
				ondblclk	: function(NODE, TREE_OBJ) { TREE_OBJ.toggle_branch.call(TREE_OBJ, NODE); TREE_OBJ.select_branch.call(TREE_OBJ, NODE); },
				// right click - to prevent use: EV.preventDefault(); EV.stopPropagation(); return false
				onrgtclk	: function(NODE, TREE_OBJ, EV) { },
				onload		: function(TREE_OBJ) { },
				onfocus		: function(TREE_OBJ) { },
				ondrop		: function(NODE,REF_NODE,TYPE,TREE_OBJ) {}
			}
		},
		// INITIALIZATION
		init : function(elem, opts) {
			var _this = this;
			this.container		= jQuery(elem);
			if(this.container.size == 0) { alert("Invalid container node!"); return }

			tree_component.inst[this.cntr] = this;
			if(!this.container.attr("id")) this.container.attr("id","jstree_" + this.cntr); 
			tree_component.inst[this.container.attr("id")] = tree_component.inst[this.cntr];
			tree_component.focused = this.cntr;

			// MERGE OPTIONS WITH DEFAULTS
			if(opts && opts.cookies) {
				this.settings.cookies = jQuery.extend({},this.settings.cookies,opts.cookies);
				delete opts.cookies;
				if(!this.settings.cookies.opts) this.settings.cookies.opts = {};
			}
			if(opts && opts.callback) {
				this.settings.callback = jQuery.extend({},this.settings.callback,opts.callback);
				delete opts.callback;
			}
			if(opts && opts.data) {
				this.settings.data = jQuery.extend({},this.settings.data,opts.data);
				delete opts.data;
			}
			if(opts && opts.ui) {
				this.settings.ui = jQuery.extend({},this.settings.ui,opts.ui);
				delete opts.ui;
			}
			if(opts && opts.rules) {
				this.settings.rules = jQuery.extend({},this.settings.rules,opts.rules);
				delete opts.rules;
			}
			if(opts && opts.lang) {
				this.settings.lang = jQuery.extend({},this.settings.lang,opts.lang);
				delete opts.lang;
			}
			this.settings		= jQuery.extend({},this.settings,opts);

			// PATH TO IMAGES AND XSL
			if(this.settings.path == false) {
				this.path = "";
				jQuery("script").each( function () { 
					if(this.src.toString().match(/tree_component.*?js$/)) {
						_this.path = this.src.toString().replace(/tree_component.*?js$/, "");
					}
				});
			}
			else this.path = this.settings.path;

			// DEAL WITH LANGUAGE VERSIONS
			this.current_lang	= this.settings.languages && this.settings.languages.length ? this.settings.languages[0] : false;
			if(this.settings.languages && this.settings.languages.length) {
				this.sn = get_sheet_num("tree_component.css");
				var st = false;
				var id = this.container.attr("id") ? "#" + this.container.attr("id") : ".tree";
				for(var ln = 0; ln < this.settings.languages.length; ln++) {
					st = add_css(id + " ." + this.settings.languages[ln], this.sn);
					if(st !== false) {
						if(this.settings.languages[ln] == this.current_lang)	st.style.display = "inline";
						else													st.style.display = "none";
					}
				}
			}

			// DROPPABLES 
			if(this.settings.rules.droppable.length) {
				for(i in this.settings.rules.droppable) {
					tree_component.drop.push(this.settings.rules.droppable[i]);
					tree_component.drop = jQuery.unique(tree_component.drop);
				}
			}

			// THEMES
			if(this.settings.ui.theme_path === false) this.settings.ui.theme_path = this.path + "themes/";
			this.theme = this.settings.ui.theme_path + _this.settings.ui.theme_name + "/";
			add_sheet(_this.settings.ui.theme_path + "default/style.css");
			if(this.settings.ui.theme_name != "default") add_sheet(_this.theme + "style.css");

			this.container.addClass("tree");
			if(this.settings.ui.rtl) this.container.addClass("rtl");
			if(this.settings.rules.multiple) this.selected_arr = [];
			this.offset = false;

			if(this.settings.ui.dots == false) this.container.addClass("no_dots");

			// CONTEXT MENU
			this.context = false;
			if(this.settings.ui.context != false) {
				var str = '<div class="context">';
				for(i in this.settings.ui.context) {
					if(this.settings.ui.context[i] == "separator") {
						str += "<span class='separator'>&nbsp;</span>";
						continue;
					}
					var icn = "";
					if(this.settings.ui.context[i].icon) icn = 'background-image:url(\'' + ( this.settings.ui.context[i].icon.indexOf("/") == -1 ? this.theme + this.settings.ui.context[i].icon : this.settings.ui.context[i].icon ) + '\');';
					str += '<a rel="' + this.settings.ui.context[i].id + '" href="#" style="' + icn + '">' + this.settings.ui.context[i].label + '</a>';
				}
				str += '</div>';
				this.context = jQuery(str);
				this.context.hide();
				this.context.append = false;
			}

			this.hovered = false;
			this.locked = false;

			// CREATE DUMMY FOR MOVING
			if(this.settings.rules.draggable != "none" && this.settings.rules.dragrules != "none") {
				var _this = this;
				jQuery("<img>")
					.attr({
						id		: "marker", 
						src	: _this.settings.ui.theme_path + "default/marker.gif"
					})
					.css({
						height		: "5px",
						width		: "40px",
						display		: "block",
						position	: "absolute",
						left		: "30px",
						top			: "30px",
						zIndex		: "1000"
					}).hide().appendTo("body");
			}
			this.refresh();
			this.attachEvents();
			this.focus();
		},
		off_height : function () {
			if(this.offset === false) {
				this.container.css({ position : "relative" });
				this.offset = this.container.offset();
				var tmp = 0;
				tmp = parseInt(jQuery.curCSS(this.container.get(0), "paddingTop", true),10);
				if(tmp) this.offset.top += tmp;
				tmp = parseInt(jQuery.curCSS(this.container.get(0), "borderTopWidth", true),10);
				if(tmp) this.offset.top += tmp;
				this.container.css({ position : "" });
			}
			if(!this.li_height) {
				var tmp = this.container.find("ul li:eq(0)");
				this.li_height = tmp.height();
				if(tmp.children("ul:eq(0)").size()) this.li_height -= tmp.children("ul:eq(0)").height();
				if(!this.li_height) this.li_height = 18;
			}
		},
		// REPAINT TREE
		refresh : function (obj) {
			if(this.locked) return this.error("LOCKED");
			var _this = this;

			// SAVE OPENED
			this.opened = Array();
			if(this.settings.cookies && jQuery.cookie(this.settings.cookies.prefix + '_open')) {
				var str = jQuery.cookie(this.settings.cookies.prefix + '_open');
				var tmp = str.split(",");
				jQuery.each(tmp, function () {
					_this.opened.push("#" + this.replace(/^#/,""));
				});
				this.settings.opened = false;
			}
			else if(this.settings.opened != false) {
				jQuery.each(this.settings.opened, function (i, item) {
					_this.opened.push("#" + this.replace(/^#/,""));
				});
				this.settings.opened = false;
			}
			else {
				this.container.find("li.open").each(function (i) { _this.opened.push("#" + this.id); });
			}

			// SAVE SELECTED
			if(this.selected) {
				this.settings.selected = Array();
				if(this.selected_arr) {
					jQuery.each(this.selected_arr, function () {
						_this.settings.selected.push("#" + this.attr("id"));
					});
				}
				else this.settings.selected.push("#" + this.selected.attr("id"));
			}
			else if(this.settings.cookies && jQuery.cookie(this.settings.cookies.prefix + '_selected')) {
				this.settings.selected = Array();
				var str = jQuery.cookie(this.settings.cookies.prefix + '_selected');
				var tmp = str.split(",");
				jQuery.each(tmp, function () {
					_this.settings.selected.push("#" + this.replace(/^#/,""));
				});
			}
			else if(this.settings.selected !== false) {
				var tmp = Array();
				if((typeof this.settings.selected).toLowerCase() == "object") {
					jQuery.each(this.settings.selected, function () {
						tmp.push("#" + this.replace(/^#/,""));
					});
				}
				else tmp.push("#" + this.settings.selected.replace(/^#/,""));
				this.settings.selected = tmp;
			}

			if(obj && this.settings.data.async) {
				this.opened = Array();
				obj = this.get_node(obj);
				obj.find("li.open").each(function (i) { _this.opened.push("#" + this.id); });
				this.close_branch(obj, true);
				obj.children("ul:eq(0)").html("");
				return this.open_branch(obj, true, function () { _this.reselect.apply(_this); });
			}

			var cls = "tree-default";
			if(this.settings.ui.theme_name != "default") cls += " tree-" + _this.settings.ui.theme_name;

			if(this.settings.data.type == "xml_flat" || this.settings.data.type == "xml_nested") {
				this.scrtop = this.container.get(0).scrollTop;
				var xsl = (this.settings.data.type == "xml_flat") ? "flat.xsl" : "nested.xsl";
				this.container.getTransform(this.path + xsl, this.settings.data.url, { params : { theme_name : cls, theme_path : _this.theme }, meth : _this.settings.data.method ,callback: function () { _this.reselect.apply(_this); } });
				return;
			}
			else if(this.settings.data.type == "json") {
				if(this.settings.data.json) {
					var str = "";
					if(this.settings.data.json.length) {
						for(var i = 0; i < this.settings.data.json.length; i++) {
							str += this.parseJSON(this.settings.data.json[i]);
						}
					} else str = this.parseJSON(this.settings.data.json);
					this.container.html("<ul class='" + cls + "'>" + str + "</ul>");
					this.container.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");
					this.container.find("li").not(".open").not(".closed").addClass("leaf");
					this.reselect();
				}
				else {
					var _this = this;
					jQuery.ajax({
						type		: this.settings.data.method,
						url			: this.settings.data.url, 
						data		: this.settings.data.async_data(false), 
						dataType	: "json",
						success		: function (data) {
							var str = "";
							if(data.length) {
								for(var i = 0; i < data.length; i++) {
									str += _this.parseJSON(data[i]);
								}
							} else str = _this.parseJSON(data);
							_this.container.html("<ul class='" + cls + "'>" + str + "</ul>");
							_this.container.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");
							_this.container.find("li").not(".open").not(".closed").addClass("leaf");
							_this.reselect.apply(_this);
						} 
					});
				}
			}
			else {
				this.container.children("ul:eq(0)").attr("class", cls);
				this.container.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");
				this.container.find("li").not(".open").not(".closed").addClass("leaf");
				this.reselect();
			}
		},
		// CONVERT JSON TO HTML
		parseJSON : function (data) {
			if(!data || !data.data) return "";
			var str = "";
			str += "<li ";
			var cls = false;
			if(data.attributes) {
				for(i in data.attributes) {
					if(i == "class") {
						str += " class='" + data.attributes[i] + " ";
						if(data.state == "closed" || data.state == "open") str += " " + data.state + " ";
						str += "' ";
						cls = true;
					}
					else str += " " + i + "='" + data.attributes[i] + "' ";
				}
			}
			if(!cls && (data.state == "closed" || data.state == "open")) str += " class='" + data.state + "' ";
			str += ">";
			if(this.settings.languages.length) {
				for(var i = 0; i < this.settings.languages.length; i++) {
					var attr = [];
					attr["href"] = "#";
					attr["style"] = "";
					attr["class"] = this.settings.languages[i];
					if(data.data[this.settings.languages[i]] && (typeof data.data[this.settings.languages[i]].attributes).toLowerCase() != "undefined") {
						for(j in data.data[this.settings.languages[i]].attributes) {
							if(j == "style" || j == "class")	attr[j] += " " + data.data[this.settings.languages[i]].attributes[j];
							else								attr[j]  = data.data[this.settings.languages[i]].attributes[j];
						}
					}
					if(data.data[this.settings.languages[i]] && data.data[this.settings.languages[i]].icon) {
						var icn = data.data[this.settings.languages[i]].icon.indexOf("/") == -1 ? this.theme + data.data[this.settings.languages[i]].icon : data.data[this.settings.languages[i]].icon;
						attr["style"] += " ; background-image:url('" + icn + "'); ";
					}
					str += "<a";
					for(j in attr) str += ' ' + j + '="' + attr[j] + '" ';
					str += ">" + ( (typeof data.data[this.settings.languages[i]].title).toLowerCase() != "undefined" ? data.data[this.settings.languages[i]].title : data.data[this.settings.languages[i]] ) + "</a>";
				}
			}
			else {
				var attr = [];
				attr["href"] = "#";
				attr["style"] = "";
				attr["class"] = "";
				if((typeof data.data.attributes).toLowerCase() != "undefined") {
					for(i in data.data.attributes) {
						if(i == "style" || i == "class")	attr[i] += " " + data.data.attributes[i];
						else								attr[i]  = data.data.attributes[i];
					}
				}
				if(data.data.icon) {
					var icn = data.data.icon.indexOf("/") == -1 ? this.theme + data.data.icon : data.data.icon;
					attr["style"] += " ; background-image:url('" + icn + "');";
				}
				str += "<a";
				for(i in attr) str += ' ' + i + '="' + attr[i] + '" ';
				str += ">" + ( (typeof data.data.title).toLowerCase() != "undefined" ? data.data.title : data.data ) + "</a>";
			}
			if(data.children && data.children.length) {
				str += '<ul>';
				for(var i = 0; i < data.children.length; i++) {
					str += this.parseJSON(data.children[i]);
				}
				str += '</ul>';
			}
			str += "</li>";
			return str;
		},
		// getJSON from HTML
		getJSON : function (nod, outer_attrib, inner_attrib, force) {
			var _this = this;
			if(!nod || jQuery(nod).size() == 0) {
				nod = this.container.children("ul").children("li");
			}
			else nod = jQuery(nod);

			if(nod.size() > 1) {
				var arr = [];
				nod.each(function () {
					arr.push(_this.getJSON(this, outer_attrib, inner_attrib));
				});
				return arr;
			}

			if(!outer_attrib) outer_attrib = [ "id", "rel", "class" ];
			if(!inner_attrib) inner_attrib = [ ];
			var obj = { attributes : {}, data : false };
			for(i in outer_attrib) {
				obj.attributes[outer_attrib[i]] = nod.attr(outer_attrib[i]);
			}
			if(this.settings.languages.length) {
				obj.data = {};
				for(i in this.settings.languages) {
					var a = nod.children("a." + this.settings.languages[i]);
					if(force || inner_attrib.length || a.get(0).style.backgroundImage.toString().length) {
						obj.data[this.settings.languages[i]] = {};
						obj.data[this.settings.languages[i]].title = a.text();
						if(a.get(0).style.backgroundImage.length) {
							obj.data[this.settings.languages[i]].icon = a.get(0).style.backgroundImage.replace("url(","").replace(")","");
						}
						if(inner_attrib.length) {
							obj.data[this.settings.languages[i]].attributes = {};
							for(j in inner_attrib) {
								obj.data[this.settings.languages[i]].attributes[inner_attrib[j]] = a.attr(inner_attrib[j]);
							}
						}
					}
					else {
						obj.data[this.settings.languages[i]] = a.text();
					}
				}
			}
			else {
				var a = nod.children("a");
				if(force || inner_attrib.length || a.get(0).style.backgroundImage.toString().length) {
					obj.data = {};
					obj.data.title = a.text();
					if(a.get(0).style.backgroundImage.length) {
						obj.data.icon = a.get(0).style.backgroundImage.replace("url(","").replace(")","");
					}
					if(inner_attrib.length) {
						obj.data.attributes = {};
						for(j in inner_attrib) {
							obj.data.attributes[inner_attrib[j]] = a.attr(inner_attrib[j]);
						}
					}
				}
				else {
					obj.data = a.text();
				}
			}

			if(nod.children("ul").size() > 0) {
				obj.children = [];
				nod.children("ul").children("li").each(function () {
					obj.children.push(_this.getJSON(this, outer_attrib, inner_attrib));
				});
			}
			return obj;
		},
		focus : function () {
			if(this.locked) return false;
			if(tree_component.focused != this.cntr) {
				tree_component.focused = this.cntr;
				this.settings.callback.onfocus.call(null, this);
			}
		},
		show_context : function (obj, x, y) {
			var tmp = this.context.show().offsetParent();
			if(tmp.is("html")) tmp = jQuery("body");
			tmp = tmp.offset();
			this.context.css({ "left" : (x - tmp.left - (this.settings.ui.rtl ? jQuery(this.context).width() : -5 ) ), "top" : (y - tmp.top  + (jQuery.browser.opera ? this.container.scrollTop() : 0) + 15) });
		},
		hide_context : function () {
			this.context.hide();
		},
		// ALL EVENTS
		attachEvents : function () {
			var _this = this;

			this.container
				.bind("mouseup", function (event) {
					setTimeout( function() { _this.focus.apply(_this); }, 5);
				})
				.bind("click", function (event) { 
					event.stopPropagation(); 
					return true;
				})
				.listen("click", "li", function(event) { // WHEN CLICK IS ON THE ARROW
					_this.toggle_branch.apply(_this, [event.target]);
					event.stopPropagation();
				})
				.listen("click", "a", function (event) { // WHEN CLICK IS ON THE TEXT OR ICON
					if(_this.locked) {
						event.preventDefault(); 
						event.target.blur();
						return _this.error("LOCKED");
					}
					_this.select_branch.apply(_this, [event.target, event.ctrlKey || _this.settings.rules.multiple == "on"]);
					if(_this.inp) { _this.inp.blur(); }
					event.preventDefault(); 
					event.target.blur();
					return false;
				})
				.listen("dblclick", "a", function (event) { // WHEN DOUBLECLICK ON TEXT OR ICON
					if(_this.locked) {
						event.preventDefault(); 
						event.stopPropagation();
						event.target.blur();
						return _this.error("LOCKED");
					}
					_this.settings.callback.ondblclk.call(null, _this.get_node(event.target).get(0), _this);
					event.preventDefault(); 
					event.stopPropagation();
					event.target.blur();
				})
				.listen("contextmenu", "a", function (event) {
					if(_this.locked) {
						event.target.blur();
						return _this.error("LOCKED");
					}
					var val = _this.settings.callback.onrgtclk.call(null, _this.get_node(event.target).get(0), _this, event);
					if(_this.context) {
						if(_this.context.append == false) {
							_this.container.find("ul:eq(0)").append(_this.context);
							_this.context.append = true;
							for(i in _this.settings.ui.context) {
								if(_this.settings.ui.context[i] == "separator") continue;
								(function () {
									var func = _this.settings.ui.context[i].action;
									_this.context.children("[rel=" + _this.settings.ui.context[i].id +"]")
										.bind("click", function (event) {
											if(!$(this).hasClass("disabled")) {
												func.call(null, _this.selected_arr || _this.selected, _this);
												_this.hide_context();
											}
											event.stopPropagation();
											event.preventDefault();
											return false;
										})
										.bind("mouseup", function (event) {
											this.blur();
											if($(this).hasClass("disabled")) {
												event.stopPropagation();
												event.preventDefault();
												return false;
											}
										});
								})();
							}
						}
						var obj = _this.get_node(event.target);
						if(_this.inp) { _this.inp.blur(); }
						if(obj) {
							if(!obj.children("a:eq(0)").hasClass("clicked")) {
								_this.select_branch.apply(_this, [event.target, event.ctrlKey || _this.settings.rules.multiple == "on"]);
								event.target.blur();
							}
							_this.context.children("a").removeClass("disabled").show();
							var go = false;
							for(i in _this.settings.ui.context) {
								if(_this.settings.ui.context[i] == "separator") continue;
								var state = _this.settings.ui.context[i].visible.call(null, _this.selected_arr || _this.selected, _this);
								if(state === false)	_this.context.children("[rel=" + _this.settings.ui.context[i].id +"]").addClass("disabled");
								if(state === -1)	_this.context.children("[rel=" + _this.settings.ui.context[i].id +"]").hide();
								else				go = true;
							}
							if(go == true) _this.show_context(obj, event.pageX, event.pageY);
							event.preventDefault(); 
							event.stopPropagation(); 
							return false;
						}
					}
					return val;
				})
				.listen("mouseover", "a", function (event) {
					if(_this.locked) {
						event.preventDefault();
						event.stopPropagation();
						return _this.error("LOCKED");
					}
					if(_this.settings.ui.hover_mode && _this.hovered !== false && event.target.tagName == "A") {
						_this.hovered.children("a").removeClass("hover");
						_this.hovered = false;
					}
				});

				// ATTACH DRAG & DROP ONLY IF NEEDED
				if(this.settings.rules.draggable != "none" && this.settings.rules.dragrules != "none") {
					this.container
						.listen("mousedown", "a", function (event) {
							_this.focus.apply(_this);
							if(_this.locked) return _this.error("LOCKED");
							// SELECT LIST ITEM NODE
							var obj = _this.get_node(event.target);
							// IF ITEM IS DRAGGABLE
							if(_this.settings.rules.multiple != false && _this.selected_arr.length > 1 && obj.children("a:eq(0)").hasClass("clicked")) {
								var counter = 0;
								for(i in _this.selected_arr) {
									if(_this.check("draggable", _this.selected_arr[i])) {
										_this.selected_arr[i].addClass("dragged");
										counter ++;
									}
								}
								if(counter > 0) {
									if(_this.check("draggable", obj))	_this._drag = obj;
									else								_this._drag = _this.container.find("li.dragged:eq(0)");
									_this.isdown	= true;
									_this.drag		= _this._drag.get(0).cloneNode(true);
									_this.drag.id	= "dragged";
									jQuery(_this.drag).children("a").html("Multiple selection").end().children("ul").remove();
								}
							}
							else {
								if(_this.check("draggable", obj)) {
									_this._drag		= obj;
									_this.drag		= obj.get(0).cloneNode(true);
									_this.drag.id	= "dragged";
									_this.isdown	= true;
									_this.foreign	= false;
									obj.addClass("dragged");
								}
							}
							obj.blur();
							event.preventDefault(); 
							event.stopPropagation();
							return false;
						});
					jQuery(document)
						.bind("mousedown",	tree_component.mousedown)
						.bind("mouseup",	tree_component.mouseup)
						.bind("mousemove",	tree_component.mousemove);
				} 
				// ENDIF OF DRAG & DROP FUNCTIONS
			if(_this.context) jQuery(document).bind("mouseup", function() { _this.hide_context(); });
		},
		checkMove : function (NODES, REF_NODE, TYPE) {
			if(this.locked) return this.error("LOCKED");
			var _this = this;
			// OVER SELF OR CHILDREN
			if(REF_NODE.parents("li.dragged").size() > 0 || REF_NODE.is(".dragged")) return this.error("MOVE: NODE OVER SELF");
			// CHECK AGAINST DRAG_RULES
			if(NODES.size() == 1) {
				var NODE = NODES.eq(0);
				if(NODE.hasClass("foreign")) {
					if(this.settings.rules.droppable.length == 0) return false;
					if(!NODE.is("." + this.settings.rules.droppable.join(", ."))) return false;
					var ok = false;
					for(i in this.settings.rules.droppable) {
						if(NODE.is("." + this.settings.rules.droppable[i])) {
							if(this.settings.rules.metadata) {
								jQuery.metadata.setType("attr", this.settings.rules.metadata);
								NODE.attr(this.settings.rules.metadata, "type: '" + this.settings.rules.droppable[i] + "'");
							}
							else {
								NODE.attr(this.settings.rules.type_attr, this.settings.rules.droppable[i]);
							}
							ok = true;
							break;
						}
					}
					if(!ok) return false;
				}
				if(!this.check("dragrules", [NODE, TYPE, REF_NODE.parents("li:eq(0)")])) return this.error("MOVE: AGAINST DRAG RULES");
			}
			else {
				var ok = true;
				NODES.each(function (i) {
					if(ok == false) return false;
					if(i > 0) {
						var ref = NODES.eq( (i - 1) );
						var mv = "after";
					}
					else {
						var ref = REF_NODE;
						var mv = TYPE;
					}
					if(!_this.check.apply(_this,["dragrules", [jQuery(this), mv, ref]])) ok = false;
				});
				if(ok == false) return this.error("MOVE: AGAINST DRAG RULES");
			}
			// CHECK AGAINST METADATA
			if(this.settings.rules.use_inline && this.settings.rules.metadata) {
				var nd = false;
				if(TYPE == "inside")	nd = REF_NODE.parents("li:eq(0)");
				else					nd = REF_NODE.parents("li:eq(1)");
				if(nd.size()) {
					// VALID CHILDREN CHECK
					if(typeof nd.metadata()["valid_children"] != "undefined") {
						var tmp = nd.metadata()["valid_children"];
						var ok = true;
						NODES.each(function (i) {
							if(ok == false) return false;
							if(jQuery.inArray(_this.get_type(this), tmp) == -1) ok = false;
						});
						if(ok == false) return this.error("MOVE: NOT A VALID CHILD");
					}
					// CHECK IF PARENT HAS FREE SLOTS FOR CHILDREN
					if(typeof nd.metadata()["max_children"] != "undefined") {
						if((nd.children("ul:eq(0)").children("li").not(".dragged").size() + NODES.size()) > nd.metadata().max_children) return this.error("MOVE: MAX CHILDREN REACHED");
					}
					// CHECK FOR MAXDEPTH UP THE CHAIN
					var incr = 0;
					NODES.each(function (i) {
						var i = 1;
						var t = jQuery(this);
						while(i < 100) {
							t = t.children("ul:eq(0)");
							if(t.size() == 0) break;
							i ++
						}
						incr = Math.max(i,incr);
					});
					var ok = true;
					nd.parents("li").each(function(i) {
						if(ok == false) return false;
						if(jQuery(this).metadata().max_depth) {
							if( (i + incr) >= jQuery(this).metadata().max_depth) ok = false;
						}
					});
					if(ok == false) return this.error("MOVE: MAX_DEPTH REACHED");
				}
			}
			return true;
		},
		// USED AFTER REFRESH
		reselect : function () {
			var _this = this;
			// REOPEN BRANCHES
			if(this.opened && this.opened.length) {
				var opn = false;
				for(var j = 0; j < this.opened.length; j++) {
					if(this.settings.data.async) {
						if(this.get_node(this.opened[j]).size() > 0) {
							opn = true;
							var tmp = this.opened[j];
							delete this.opened[j];
							this.open_branch(tmp, true, function () { _this.reselect.apply(_this); } )
						}
					}
					else this.open_branch(this.opened[j], true);
				}
				if(this.settings.data.async && opn) return;
				delete this.opened;
			}
			// REPOSITION SCROLL
			if(this.scrtop) {
				this.container.scrollTop(_this.scrtop);
				delete this.scrtop;
			}
			// RESELECT PREVIOUSLY SELECTED
			if(this.settings.selected !== false) {
				jQuery.each(this.settings.selected, function (i) {
					_this.select_branch(jQuery(_this.settings.selected[i]), (_this.settings.rules.multiple !== false && i > 0) );
				});
				this.settings.selected = false;
			}
			this.settings.callback.onload.call(null, _this);
		},
		// GET THE EXTENDED LI ELEMENT
		get_node : function (obj) {
			var obj = jQuery(obj);
			return obj.is("li") ? obj : obj.parents("li:eq(0)");
		},
		// GET THE TYPE OF THE NODE
		get_type : function (obj) {
			obj = !obj ? this.selected : this.get_node(obj);
			if(!obj) return;
			if(this.settings.rules.metadata) {
				jQuery.metadata.setType("attr", this.settings.rules.metadata);
				var tmp = obj.metadata().type;
				if(tmp) return tmp;
			} 
			return obj.attr(this.settings.rules.type_attr);
		},
		// SCROLL CONTAINER WHILE DRAGGING
		scrollCheck : function (x,y) { 
			var _this = this;
			var cnt = _this.container;
			var off = _this.offset;

			var st = cnt.scrollTop();
			var sl = cnt.scrollLeft();
			// DETECT HORIZONTAL SCROLL
			var h_cor = (cnt.get(0).scrollWidth > cnt.width()) ? 40 : 20;

			if(y - off.top < 20)						cnt.scrollTop(Math.max( (st - _this.settings.ui.scroll_spd) ,0));	// NEAR TOP
			if(cnt.height() - (y - off.top) < h_cor)	cnt.scrollTop(st + _this.settings.ui.scroll_spd);					// NEAR BOTTOM
			if(x - off.left < 20)						cnt.scrollLeft(Math.max( (sl - _this.settings.ui.scroll_spd),0));	// NEAR LEFT
			if(cnt.width() - (x - off.left) < 40)		cnt.scrollLeft(sl + _this.settings.ui.scroll_spd);					// NEAR RIGHT

			if(cnt.scrollLeft() != sl || cnt.scrollTop() != st) {
				_this.moveType = false;
				_this.moveRef = false;
				jQuery("#marker").hide();
			}
			tree_component.sto = setTimeout( function() { _this.scrollCheck(x,y); }, 50);
		},
		check : function (rule, nodes) {
			if(this.locked) return this.error("LOCKED");
			// CHECK LOCAL RULES IF METADATA
			if(rule != "dragrules" && this.settings.rules.use_inline && this.settings.rules.metadata) {
				jQuery.metadata.setType("attr", this.settings.rules.metadata);
				if(typeof this.get_node(nodes).metadata()[rule] != "undefined") return this.get_node(nodes).metadata()[rule];
			}
			if(!this.settings.rules[rule])			return false;
			if(this.settings.rules[rule] == "none")	return false;
			if(this.settings.rules[rule] == "all")	return true;
			if(rule == "dragrules") {
				var nds = new Array();
				nds[0] = this.get_type(nodes[0]);
				nds[1] = nodes[1];
				nds[2] = this.get_type(nodes[2]);
				for(var i = 0; i < this.settings.rules.dragrules.length; i++) {
					var r = this.settings.rules.dragrules[i];
					var n = (r.indexOf("!") === 0) ? false : true;
					if(!n) r = r.replace("!","");
					var tmp = r.split(" ");
					for(var j = 0; j < 3; j++) {
						if(tmp[j] == nds[j] || tmp[j] == "*") tmp[j] = true;
					}
					if(tmp[0] === true && tmp[1] === true && tmp[2] === true) return n;
				}
				return false;
			}
			else 
				return (jQuery.inArray(this.get_type(nodes),this.settings.rules[rule]) != -1) ? true : false;
		},
		hover_branch : function (obj) {
			if(this.locked) return this.error("LOCKED");
			if(this.settings.ui.hover_mode == false) return this.select_branch(obj);
			var _this = this;
			var obj = _this.get_node(obj);
			if(!obj.size()) return this.error("HOVER: NOT A VALID NODE");
			// CHECK AGAINST RULES FOR SELECTABLE NODES
			if(!_this.check("clickable", obj)) return this.error("SELECT: NODE NOT SELECTABLE");
			if(this.hovered) this.hovered.children("A").removeClass("hover");

			// SAVE NEWLY SELECTED
			this.hovered = obj;

			// FOCUS NEW NODE AND OPEN ALL PARENT NODES IF CLOSED
			this.hovered.children("a").removeClass("hover").addClass("hover");

			// SCROLL SELECTED NODE INTO VIEW
			var off_t = this.hovered.offset().top;
			var beg_t = this.container.offset().top;
			var end_t = beg_t + this.container.height();
			var h_cor = (this.container.get(0).scrollWidth > this.container.width()) ? 40 : 20;
			if(off_t + 5 < beg_t) this.container.scrollTop(this.container.scrollTop() - (beg_t - off_t + 5) );
			if(off_t + h_cor > end_t) this.container.scrollTop(this.container.scrollTop() + (off_t + h_cor - end_t) );
		},
		select_branch : function (obj, multiple) {
			if(this.locked) return this.error("LOCKED");
			if(!obj && this.hovered !== false) obj = this.hovered;
			var _this = this;
			obj = _this.get_node(obj);
			if(!obj.size()) return this.error("SELECT: NOT A VALID NODE");
			obj.children("a").removeClass("hover");
			// CHECK AGAINST RULES FOR SELECTABLE NODES
			if(!_this.check("clickable", obj)) return this.error("SELECT: NODE NOT SELECTABLE");
			if(_this.settings.callback.beforechange.call(null,obj.get(0),_this) === false) return this.error("SELECT: STOPPED BY USER");
			// IF multiple AND obj IS ALREADY SELECTED - DESELECT IT
			if(this.settings.rules.multiple != false && multiple && obj.children("a.clicked").size() > 0) {
				return this.deselect_branch(obj);
			}
			if(this.settings.rules.multiple != false && multiple) {
				this.selected_arr.push(obj);
			}
			if(this.settings.rules.multiple != false && !multiple) {
				for(i in this.selected_arr) {
					this.selected_arr[i].children("A").removeClass("clicked");
				}
				this.selected_arr = [];
				this.selected_arr.push(obj);
				if(this.selected) this.selected.children("A").removeClass("clicked");
			}
			if(!this.settings.rules.multiple) {
				if(this.selected) this.selected.children("A").removeClass("clicked");
			}
			// SAVE NEWLY SELECTED
			this.selected = obj;
			if(this.settings.ui.hover_mode && this.hovered !== false) {
				this.hovered.children("A").removeClass("hover");
				this.hovered = obj;
			}

			// FOCUS NEW NODE AND OPEN ALL PARENT NODES IF CLOSED
			this.selected.children("a").removeClass("clicked").addClass("clicked").end().parents("li.closed").each( function () { _this.open_branch(this, true); });

			// SCROLL SELECTED NODE INTO VIEW
			var off_t = this.selected.offset().top;
			var beg_t = this.container.offset().top;
			var end_t = beg_t + this.container.height();
			var h_cor = (this.container.get(0).scrollWidth > this.container.width()) ? 40 : 20;
			if(off_t + 5 < beg_t) this.container.scrollTop(this.container.scrollTop() - (beg_t - off_t + 5) );
			if(off_t + h_cor > end_t) this.container.scrollTop(this.container.scrollTop() + (off_t + h_cor - end_t) );

			this.set_cookie("selected");
			this.settings.callback.onchange.call(null, this.selected.get(0), _this);
		},
		deselect_branch : function (obj) {
			if(this.locked) return this.error("LOCKED");
			var _this = this;
			var obj = this.get_node(obj);
			obj.children("a").removeClass("clicked");
			if(this.settings.rules.multiple != false && this.selected_arr.length > 1) {
				this.selected_arr = [];
				this.container.find("a.clicked").filter(":first-child").parent().each(function () {
					_this.selected_arr.push(jQuery(this));
				});
				if(obj.get(0) == this.selected.get(0)) {
					this.selected = this.selected_arr[0];
					this.set_cookie("selected");
				}
			}
			else {
				if(this.settings.rules.multiple != false) this.selected_arr = [];
				this.selected = false;
				this.set_cookie("selected");
			}
			if(this.selected)	this.settings.callback.onchange.call(null, this.selected.get(0), _this);
			else				this.settings.callback.onchange.call(null, false, _this);
		},
		toggle_branch : function (obj) {
			if(this.locked) return this.error("LOCKED");
			var obj = this.get_node(obj);
			if(obj.hasClass("closed"))	return this.open_branch(obj);
			if(obj.hasClass("open"))	return this.close_branch(obj); 
		},
		open_branch : function (obj, disable_animation, callback) {
			if(this.locked) return this.error("LOCKED");
			var obj = this.get_node(obj);
			if(!obj.size()) return this.error("OPEN: NO SUCH NODE");
			if(obj.hasClass("leaf")) return this.error("OPEN: OPENING LEAF NODE");

			if(this.settings.data.async && obj.find("li").size() == 0) {
				var _this = this;
				obj.children("ul:eq(0)").remove().end().append("<ul><li class='last'><a class='loading' href='#'>" + (_this.settings.lang.loading || "Loading ...") + "</a></li></ul>");
				obj.removeClass("closed").addClass("open");
				if(this.settings.data.type == "xml_flat" || this.settings.data.type == "xml_nested") {
					var xsl = (this.settings.data.type == "xml_flat") ? "flat.xsl" : "nested.xsl";
					var str = (this.settings.data.url.indexOf("?") == -1) ? "?id=" + encodeURIComponent(obj.attr("id")) : "&id=" + encodeURIComponent(obj.attr("id"));
					obj.children("ul:eq(0)").getTransform(this.path + xsl, this.settings.data.url + str, { params : { theme_path : _this.theme }, meth : this.settings.data.method, repl : true, callback: function (str, json) { 
							if(str.length < 15) {
								obj.removeClass("closed").removeClass("open").addClass("leaf").children("ul").remove();
								if(callback) callback.call();
								return;
							}
							_this.open_branch.apply(_this, [obj]); 
							if(callback) callback.call();
						} 
					});
				}
				else {
					jQuery.ajax({
						type		: this.settings.data.method,
						url			: this.settings.data.url, 
						data		: this.settings.data.async_data(obj), 
						dataType	: "json",
						success		: function (data, textStatus) {
							if(!data || data.length == 0) {
								obj.removeClass("closed").removeClass("open").addClass("leaf").children("ul").remove();
								if(callback) callback.call();
								return;
							}
							var str = "";
							if(data.length) {
								for(var i = 0; i < data.length; i++) {
									str += _this.parseJSON(data[i]);
								}
							}
							else str = _this.parseJSON(data);
							if(str.length > 0) {
								obj.children("ul:eq(0)").replaceWith("<ul>" + str + "</ul>");
								obj.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");
								obj.find("li").not(".open").not(".closed").addClass("leaf");
								_this.open_branch.apply(_this, [obj]);
							}
							else obj.removeClass("closed").removeClass("open").addClass("leaf").children("ul").remove();
							if(callback) callback.call();
						}
					});
				}
				return true;
			}
			else {
				if(parseInt(this.settings.ui.animation) > 0 && !disable_animation && !(jQuery.browser.msie && jQuery.browser.version < 7) ) {
					obj.children("ul:eq(0)").css("display","none");
					obj.removeClass("closed").addClass("open");
					obj.children("ul:eq(0)").slideDown(parseInt(this.settings.ui.animation), function() {
						jQuery(this).css("display","");
						if(callback) callback.call();
					});
				} else {
					obj.removeClass("closed").addClass("open");
					if(callback) callback.call();
				}
				this.set_cookie("open");
				this.settings.callback.onopen.call(null, obj.get(0), this);
				return true;
			}
		},
		close_branch : function (obj, disable_animation) {
			if(this.locked) return this.error("LOCKED");
			var _this = this;
			var obj = this.get_node(obj);
			if(parseInt(this.settings.ui.animation) > 0 && !disable_animation && !(jQuery.browser.msie && jQuery.browser.version < 7) && obj.children("ul:eq(0)").size() == 1) {
				obj.children("ul:eq(0)").slideUp(parseInt(this.settings.ui.animation), function() {
					obj.removeClass("open").addClass("closed");
					_this.set_cookie("open");
					jQuery(this).css("display","");
				});
			} 
			else {
				obj.removeClass("open").addClass("closed");
				this.set_cookie("open");
			}
			if(this.selected && obj.children("ul:eq(0)").find("a.clicked").size() > 0) {
				obj.find("li:has(a.clicked)").each(function() {
					_this.deselect_branch(this);
				});
				if(obj.children("a.clicked").size() == 0) this.select_branch(obj, (this.settings.rules.multiple != false && this.selected_arr.length > 0) );
			}
			this.settings.callback.onclose.call(null, obj.get(0), this);
		},
		open_all : function (obj) {
			if(this.locked) return this.error("LOCKED");
			var _this = this;
			obj = obj ? jQuery(obj) : this.container;
			obj.find("li.closed").each( function () { var __this = this; _this.open_branch.apply(_this, [this, true, function() { _this.open_all.apply(_this, [__this]); } ]); });
		},
		close_all : function () {
			if(this.locked) return this.error("LOCKED");
			var _this = this;
			jQuery(this.container).find("li.open").each( function () { _this.close_branch(this, true); });
		},
		show_lang : function (i) { 
			if(this.locked) return this.error("LOCKED");
			if(this.settings.languages[i] == this.current_lang) return true;
			var st = false;
			var id = this.container.attr("id") ? "#" + this.container.attr("id") : ".tree";
			st = get_css(id + " ." + this.current_lang, this.sn);
			if(st !== false) st.style.display = "none";
			st = get_css(id + " ." + this.settings.languages[i], this.sn);
			if(st !== false) st.style.display = "block";
			this.current_lang = this.settings.languages[i];
			return true;
		},
		cycle_lang : function() {
			if(this.locked) return this.error("LOCKED");
			var i = jQuery.inArray(this.current_lang, this.settings.languages);
			i ++;
			if(i > this.settings.languages.length - 1) i = 0;
			this.show_lang(i);
		},
		create : function (type, obj, data, icon, id ) {
			if(this.locked) return this.error("LOCKED");
			// NOTHING SELECTED
			obj = obj ? this.get_node(obj) : this.selected;
			if(!obj || !obj.size()) return this.error("CREATE: NO NODE SELECTED");
			if(!this.check("creatable", obj)) return this.error("CREATE: CANNOT CREATE IN NODE");

			var t = type || this.get_type(obj) || "";
			if(this.settings.rules.use_inline && this.settings.rules.metadata) {
				jQuery.metadata.setType("attr", this.settings.rules.metadata);
				if(typeof obj.metadata()["valid_children"] != "undefined") {
					if(jQuery.inArray(t, obj.metadata()["valid_children"]) == -1) return this.error("CREATE: NODE NOT A VALID CHILD");
				}
				if(typeof obj.metadata()["max_children"] != "undefined") {
					if( (obj.children("ul:eq(0)").children("li").size() + 1) > obj.metadata().max_children) return this.error("CREATE: MAX_CHILDREN REACHED");
				}
				var ok = true;
				obj.parents("li").each(function(i) {
					if(jQuery(this).metadata().max_depth) {
						if( (i + 1) >= jQuery(this).metadata().max_depth) {
							ok = false;
						}
					}
				});
				if(!ok) return this.error("CREATE: MAX_DEPTH REACHED");
			}
			if(obj.hasClass("closed")) {
				var _this = this;
				return this.open_branch(obj, true, function () { _this.create.apply(_this, [type, obj, data, icon, id]); } );
			}

			if(id)	$li = jQuery("<li id='" + id + "' />");
			else	$li = jQuery("<li />");
			// NEW NODE IS OF PASSED TYPE OR PARENT'S TYPE
			if(this.settings.rules.metadata) {
				jQuery.metadata.setType("attr", this.settings.rules.metadata);
				$li.attr(this.settings.rules.metadata, "type: '" + t + "'");
			}
			else {
				$li.attr(this.settings.rules.type_attr, t)
			}

			var icn = "";
			if((typeof icon).toLowerCase() == "string") {
				icn = icon;
				icn = icn.indexOf("/") == -1 ? this.theme + icn : icn;
			}
			if(this.settings.languages.length) {
				for(i = 0; i < this.settings.languages.length; i++) {
					if((typeof data).toLowerCase() == "string") val = data;
					else if(data && data[i]) {
						val = data[i];
					}
					else if(this.settings.lang.new_node) {
						if((typeof this.settings.lang.new_node).toLowerCase() != "string" && this.settings.lang.new_node[i]) 
							val = this.settings.lang.new_node[i];
						else 
							val = this.settings.lang.new_node;
					}
					else {
						val = "New folder";
					}
					if((typeof icon).toLowerCase() != "string" && icon && icon[i]) {
						icn = icon[i];
						icn = icn.indexOf("/") == -1 ? this.theme + icn : icn;
					}
					$li.append("<a href='#'" + ( icn.length ? " style='background-image:url(\"" + icn + "\");' " : " ") + "class='" + this.settings.languages[i] + "'>" + val + "</a>");
				}
			}
			else { $li.append("<a href='#'" + ( icn.length ? " style='background-image:url(\"" + icn + "\");' " : " ") + ">" + (data || this.settings.lang.new_node || "New folder") + "</a>"); }
			$li.addClass("leaf");
			if(this.settings.rules.createat == "top" || obj.children("ul").size() == 0) {
				this.moved($li,obj.children("a:eq(0)"),"inside", true);
			}
			else {
				this.moved($li,obj.children("ul:eq(0)").children("li:last").children("a:eq(0)"),"after",true);
			}
			this.select_branch($li.children("a:eq(0)"));
			if(!data) this.rename();
			return $li;
		},
		rename : function () {
			if(this.locked) return this.error("LOCKED");
			if(this.selected) {
				var _this = this;
				if(!this.check("renameable", this.selected)) return this.error("RENAME: NODE NOT RENAMABLE");
				if(!this.settings.callback.beforerename.call(null,this.selected.get(0), _this.current_lang, _this)) return this.error("RENAME: STOPPED BY USER");
				var obj = this.selected;
				if(this.current_lang)	obj = obj.find("a." + this.current_lang).get(0);
				else					obj = obj.find("a:first").get(0);
				last_value = obj.innerHTML;
				_this.inp = jQuery("<input type='text' />");
				_this.inp
					.val(last_value)
					.bind("mousedown",		function (event) { event.stopPropagation(); })
					.bind("mouseup",		function (event) { event.stopPropagation(); })
					.bind("click",			function (event) { event.stopPropagation(); })
					.bind("keyup",			function (event) { 
							var key = event.keyCode || event.which;
							if(key == 27) { this.value = last_value; this.blur(); return }
							if(key == 13) { this.blur(); return }
						});
				_this.inp.blur(function(event) {
						if(this.value == "") this.value == last_value; 
						jQuery(obj).html( jQuery(obj).parent().find("input").eq(0).attr("value") ).get(0).style.display = ""; 
						jQuery(obj).prevAll("span").remove(); 
						if(this.value != last_value) _this.settings.callback.onrename.call(null, _this.get_node(obj).get(0), _this.current_lang, _this);
						_this.inp = false;
					});
				var spn = jQuery("<span />").addClass(obj.className).append(_this.inp);
				spn.attr("style", jQuery(obj).attr("style"));
				obj.style.display = "none";
				jQuery(obj).parent().prepend(spn);
				_this.inp.get(0).focus();
				_this.inp.get(0).select();
			}
			else return this.error("RENAME: NO NODE SELECTED");
		},
		// REMOVE NODES
		remove : function(obj) {
			if(this.locked) return this.error("LOCKED");
			if(obj) {
				obj = this.get_node(obj);
				if(obj.size()) {
					if(!this.check("deletable", obj)) return this.error("DELETE: NODE NOT DELETABLE");
					if(!this.settings.callback.beforedelete.call(null,obj.get(0), _this)) return this.error("DELETE: STOPPED BY USER");
					$parent = obj.parent();
					obj = obj.remove();
					$parent.children("li:last").addClass("last");
					if($parent.children("li").size() == 0) {
						$li = $parent.parents("li:eq(0)");
						$li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove();
						this.set_cookie("open");
					}
					this.settings.callback.ondelete.call(null, obj, this);
				}
			}
			else if(this.selected) {
				if(!this.check("deletable", this.selected)) return this.error("DELETE: NODE NOT DELETABLE");
				if(!this.settings.callback.beforedelete.call(null,this.selected.get(0), _this)) return this.error("DELETE: STOPPED BY USER");
				$parent = this.selected.parent();
				var obj = this.selected;
				if(this.settings.rules.multiple == false || this.selected_arr.length == 1) {
					var stop = true;
					var tmp = (this.selected.prev("li:eq(0)").size()) ? this.selected.prev("li:eq(0)") : this.selected.parents("li:eq(0)");
					// this.get_prev(true);
				}
				obj = obj.remove();
				$parent.children("li:last").addClass("last");
				if($parent.children("li").size() == 0) {
					$li = $parent.parents("li:eq(0)");
					$li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove();
					this.set_cookie("open");
				}
				//this.selected = false;
				this.settings.callback.ondelete.call(null, obj, this);
				if(stop && tmp) this.select_branch(tmp);
				if(this.settings.rules.multiple != false && !stop) {
					var _this = this;
					this.selected_arr = [];
					this.container.find("a.clicked").filter(":first-child").parent().each(function () {
						_this.selected_arr.push(jQuery(this));
					});
					if(this.selected_arr.length > 0) {
						this.selected = this.selected_arr[0];
						this.remove();
					}
				}
			}
			else return this.error("DELETE: NO NODE SELECTED");
		},
		// FOR EXPLORER-LIKE KEYBOARD SHORTCUTS
		get_next : function(force) {
			var obj = this.hovered || this.selected;
			if(obj) {
				if(obj.hasClass("open"))						return force ? this.select_branch(obj.find("li:eq(0)")) : this.hover_branch(obj.find("li:eq(0)"));
				else if(jQuery(obj).nextAll("li").size() > 0)	return force ? this.select_branch(obj.nextAll("li:eq(0)")) : this.hover_branch(obj.nextAll("li:eq(0)"));
				else											return force ? this.select_branch(obj.parents("li").next("li").eq(0)) : this.hover_branch(obj.parents("li").next("li").eq(0));
			}
		},
		get_prev : function(force) {
			var obj = this.hovered || this.selected;
			if(obj) {
				if(obj.prev("li").size()) {
					var obj = obj.prev("li").eq(0);
					while(obj.hasClass("open")) obj = obj.children("ul:eq(0)").children("li:last");
					return force ? this.select_branch(obj) : this.hover_branch(obj);
				}
				else { return force ? this.select_branch(obj.parents("li:eq(0)")) : this.hover_branch(obj.parents("li:eq(0)")); }
			}
		},
		get_left : function(force, rtl) {
			if(this.settings.ui.rtl && !rtl) return this.get_right(force, true);
			var obj = this.hovered || this.selected;
			if(obj) {
				if(obj.hasClass("open"))	this.close_branch(obj);
				else {
					return force ? this.select_branch(obj.parents("li:eq(0)")) : this.hover_branch(obj.parents("li:eq(0)"));
				}
			}
		},
		get_right : function(force, rtl) {
			if(this.settings.ui.rtl && !rtl) return this.get_left(force, true);
			var obj = this.hovered || this.selected;
			if(obj) {
				if(obj.hasClass("closed"))	this.open_branch(obj);
				else {
					return force ? this.select_branch(obj.find("li:eq(0)")) : this.hover_branch(obj.find("li:eq(0)"));
				}
			}
		},
		toggleDots : function () {
			this.container.toggleClass("no_dots");
		},
		set_cookie : function (type) {
			if(this.settings.cookies === false) return false;
			switch(type) {
				case "selected":
					if(this.settings.rules.multiple != false && this.selected_arr.length > 1) {
						var val = Array();
						jQuery.each(this.selected_arr, function () {
							val.push(this.attr("id"));
						});
						val = val.join(",");
					}
					else var val = this.selected ? this.selected.attr("id") : false;
					jQuery.cookie(this.settings.cookies.prefix + '_selected',val,this.settings.cookies.opts);
					break;
				case "open":
					var str = "";
					this.container.find("li.open").each(function (i) { str += this.id + ","; });
					jQuery.cookie(this.settings.cookies.prefix + '_open',str.replace(/,$/ig,""),this.settings.cookies.opts);
					break;
			}
		},
		moved : function (what, where, how, is_new, is_copy) {
			var what	= jQuery(what);
			var $parent	= jQuery(what).parents("ul:eq(0)");
			var $where	= jQuery(where);
			// IF MULTIPLE
			if(what.size() > 1) {
				var _this = this;
				var tmp = this.moved(what.eq(0),where,how, false, is_copy);
				what.each(function (i) {
					if(i == 0) return;
					tmp = _this.moved(this, tmp.children("a:eq(0)"), "after", false, is_copy);
				})
				return;
			}
			if(is_copy) {
				what = what.clone();
				what.each(function (i) {
					this.id = this.id + "_copy";
					jQuery(this).find("li").each(function () {
						this.id = this.id + "_copy";
					})
					jQuery(this).find("a.clicked").removeClass("clicked");
				});
			}
			if(is_new) {
				if(!this.settings.callback.beforecreate.call(null,this.get_node(what).get(0), this.get_node(where).get(0),how,this)) return;
			}
			else {
				if(!this.settings.callback.beforemove.call(null,this.get_node(what).get(0), this.get_node(where).get(0),how,this)) return;
			}
			
			if(!is_new) {
				var tmp = jQuery(what).parents(".tree:eq(0)");
				// if different trees
				if(tmp.get(0) != this.container.get(0)) {
					tmp = tree_component.inst[tmp.attr("id")];
					// if there are languages - otherwise - no cleanup needed
					if(tmp.settings.languages.length) {
						var res = [];
						// if new tree has no languages - use current visible
						if(this.settings.languages.length == 0) res.push("." + tmp.current_lang);
						else {
							for(i in this.settings.languages) {
								for(j in tmp.settings.languages) {
									if(this.settings.languages[i] == tmp.settings.languages[j]) res.push("." + this.settings.languages[i]);
								}
							}
						}
						if(res.length == 0) return this.error("MOVE: NO COMMON LANGUAGES");
						what.find("a").removeClass("clicked").not(res.join(",")).remove();
					}
				}
			}

			// ADD NODE TO NEW PLACE
			switch(how) {
				case "before":
					$where.parents("ul:eq(0)").children("li.last").removeClass("last");
					$where.parent().before(what.removeClass("last"));
					$where.parents("ul:eq(0)").children("li:last").addClass("last");
					break;
				case "after":
					$where.parents("ul:eq(0)").children("li.last").removeClass("last");
					$where.parent().after(what.removeClass("last"));
					$where.parents("ul:eq(0)").children("li:last").addClass("last");
					break;
				case "inside":
					if(this.settings.data.async) {
						var obj = this.get_node($where);
						if(obj.hasClass("closed")) {
							var _this = this;
							return this.open_branch(obj, true, function () { _this.moved.apply(_this, [what, where, how, is_new, is_copy]); })
						}
					}
					if($where.parent().children("ul:first").size()) {
						if(this.settings.rules.createat == "top")	$where.parent().children("ul:first").prepend(what.removeClass("last")).children("li:last").addClass("last");
						else										$where.parent().children("ul:first").children(".last").removeClass("last").end().append(what.removeClass("last")).children("li:last").addClass("last");
					}
					else {
						what.addClass("last");
						$where.parent().append("<ul/>").removeClass("leaf").addClass("closed");
						$where.parent().children("ul:first").prepend(what);
					}
					if(!this.settings.data.async) {
						this.open_branch($where);
					}
					break;
				default:
					break;
			}
			// CLEANUP OLD PARENT
			if($parent.find("li").size() == 0) {
				var $li = $parent.parent();
				$li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove();
				$li.parents("ul:eq(0)").children("li.last").removeClass("last").end().children("li:last").addClass("last");
				this.set_cookie("open");
			}
			else {
				$parent.children("li.last").removeClass("last");
				$parent.children("li:last").addClass("last");
			}
			if(is_new && how != "inside") where = this.get_node(where).parents("li:eq(0)");
			if(is_copy)		this.settings.callback.oncopy.call(null, this.get_node(what).get(0), this.get_node(where).get(0), how, this)
			else if(is_new)	this.settings.callback.oncreate.call(null, this.get_node(what).get(0), this.get_node(where).get(0), this.settings.insertAt, this);
			else			this.settings.callback.onmove.call(null, this.get_node(what).get(0), this.get_node(where).get(0), how, this);
			return what;
		},
		error : function (code) {
			this.settings.callback.error.call(null,code,this);
			return false;
		},
		lock : function (state) {
			this.locked = state;
			if(this.locked)	this.container.addClass("locked");
			else			this.container.removeClass("locked");
		},
		cut : function () {
			if(this.locked) return this.error("LOCKED");
			if(!this.selected) return this.error("CUT: NO NODE SELECTED");
			this.copy_nodes = false;
			this.cut_nodes = this.container.find("a.clicked").filter(":first-child").parent();
		},
		copy : function () {
			if(this.locked) return this.error("LOCKED");
			if(!this.selected) return this.error("COPY: NO NODE SELECTED");
			this.copy_nodes = this.container.find("a.clicked").filter(":first-child").parent();
			this.cut_nodes = false;
		},
		paste : function () {
			if(this.locked) return this.error("LOCKED");
			if(!this.selected) return this.error("PASTE: NO NODE SELECTED");
			if(!this.copy_nodes && !this.cut_nodes) return this.error("PASTE: NOTHING TO DO");
			if(this.copy_nodes && this.copy_nodes.size()) {
				if(!this.checkMove(this.copy_nodes, this.selected.children("a:eq(0)"), "inside")) return false;
				this.moved(this.copy_nodes, this.selected.children("a:eq(0)"), "inside", false, true);
				this.copy_nodes = false;
			}
			if(this.cut_nodes && this.cut_nodes.size()) {
				if(!this.checkMove(this.cut_nodes, this.selected.children("a:eq(0)"), "inside")) return false;
				this.moved(this.cut_nodes, this.selected.children("a:eq(0)"), "inside");
				this.cut_nodes = false;
			}
		},
		search : function(str) {
			var _this = this;
			if(!str || (this.srch && str != this.srch) ) {
				this.srch = "";
				this.srch_opn = false;
				this.container.find("a.search").removeClass("search");
			}
			this.srch = str;
			if(!str) return;
			if(this.settings.data.async) {
				if(!this.srch_opn) {
					var dd = jQuery.extend( { "search" : str } , this.settings.data.async_data(false) );
					jQuery.ajax({
						type		: this.settings.data.method,
						url			: this.settings.data.url, 
						data		: dd, 
						dataType	: "text",
						success		: function (data) {
							_this.srch_opn = jQuery.unique(data.split(","));
							_this.search.apply(_this,[str]);
						} 
					});
				}
				else if(this.srch_opn.length) {
					if(this.srch_opn && this.srch_opn.length) {
						var opn = false;
						for(var j = 0; j < this.srch_opn.length; j++) {
							if(this.get_node("#" + this.srch_opn[j]).size() > 0) {
								opn = true;
								var tmp = "#" + this.srch_opn[j];
								delete this.srch_opn[j];
								this.open_branch(tmp, true, function () { _this.search.apply(_this,[str]); } );
							}
						}
						if(!opn) {
							this.srch_opn = [];
							 _this.search.apply(_this,[str]);
						}
					}
				}
				else {
					var selector = "a";
					// IF LANGUAGE VERSIONS
					if(this.settings.languages.length) selector += "." + this.current_lang;
					this.container.find(selector + ":contains('" + str + "')").addClass("search");
					this.srch_opn = false;
				}
			}
			else {
				var selector = "a";
				// IF LANGUAGE VERSIONS
				if(this.settings.languages.length) selector += "." + this.current_lang;
				this.container.find(selector + ":contains('" + str + "')").addClass("search").parents("li.closed").each( function () { _this.open_branch(this, true); });
			}
		},

		destroy : function() {
			try {
				var evts = ["click","dblclick","contextmenu","mouseover","mousedown"];
				for(i in evts) {
					var idxer = this.container.indexer(evts[i]);
					idxer.stop();
					jQuery.removeData( idxer.listener, idxer.event + '.indexer' );
				}
			} catch(err) { }
			this.container.unbind();

			this.container.removeClass("tree").children("ul").removeClass("tree-" + this.settings.ui.theme_name).find("li").removeClass("leaf").removeClass("open").removeClass("closed").removeClass("last").children("a").removeClass("clicked");

			if(this.cntr == tree_component.focused) {
				for(i in tree_component.inst) {
					if(i != this.cntr && i != this.container.attr("id")) {
						tree_component.inst[i].focus();
						break;
					}
				}
			}
			delete tree_component.inst[this.cntr];
			delete tree_component.inst[this.container.attr("id")];
			tree_component.cntr --;
		}
	}
};

/** File: javascript/jquery.tree_component_css.js **/

function get_css(rule_name, stylesheet, delete_flag) {
	if (!document.styleSheets) return false;
	rule_name = rule_name.toLowerCase(); stylesheet = stylesheet || 0;
	for (var i = stylesheet; i < document.styleSheets.length; i++) { 
		var styleSheet = document.styleSheets[i]; css_rules = document.styleSheets[i].cssRules || document.styleSheets[i].rules;
		if(!css_rules) continue;
		var j = 0;
		do {
			if(css_rules[j].selectorText.toLowerCase() == rule_name) {
				if(delete_flag == true) {
					if(document.styleSheets[i].removeRule) document.styleSheets[i].removeRule(j);
					if(document.styleSheets[i].deleteRule) document.styleSheets[i].deleteRule(j);
					return true;
				}
				else return css_rules[j];
			}
		}
		while (css_rules[++j]);
	}
	return false;
}
function add_css(rule_name, stylesheet) {
	rule_name = rule_name.toLowerCase(); stylesheet = stylesheet || 0;
	if (!document.styleSheets || get_css(rule_name, stylesheet)) return false;
	(document.styleSheets[stylesheet].addRule) ? document.styleSheets[stylesheet].addRule(rule_name, null, 0) : document.styleSheets[stylesheet].insertRule(rule_name+' { }', 0);
	return get_css(rule_name);
}
function get_sheet_num (href_name) {
	if (!document.styleSheets) return false;
	for (var i = 0; i < document.styleSheets.length; i++) { if(document.styleSheets[i].href && document.styleSheets[i].href.toString().match(href_name)) return i; } 
	return false;
}
function remove_css(rule_name, stylesheet) { return get_css(rule_name, stylesheet, true); }

function add_sheet(url, media) {
	if(document.createStyleSheet) {
		document.createStyleSheet(url);
	}
	else {
		var newSS	= document.createElement('link');
		newSS.rel	= 'stylesheet';
		newSS.type	= 'text/css';
		newSS.media	= media || "all";

		newSS.href	= url;
		// var styles	= "@import url(' " + url + " ');";
		// newSS.href	='data:text/css,'+escape(styles);
		document.getElementsByTagName("head")[0].appendChild(newSS);
	}
}

/** File: javascript/jquery.listen.js **/

/**
 * jQuery.Listen - Light and fast event handling, using event delegation.
 * Copyright (c) 2007-2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under MIT and GPL.
 * Date: 3/7/2008
 * http://flesler.blogspot.com/2007/10/jquerylisten.html
 * @version 1.0.3
 */
;(function($){var a='indexer',h=$.event,j=h.special,k=$.listen=function(c,d,e,f){if(typeof d!='object'){f=e;e=d;d=document}o(c.split(/\s+/),function(a){a=k.fixes[a]||a;var b=m(d,a)||m(d,a,new n(a,d));b.append(e,f);b.start()})},m=function(b,c,d){return $.data(b,c+'.'+a,d)};$.fn[a]=function(a){return this[0]&&m(this[0],a)||null};$[a]=function(a){return m(document,a)};$.extend(k,{regex:/^((?:\w*?|\*))(?:([#.])([\w-]+))?$/,fixes:{focus:'focusin',blur:'focusout'},cache:function(a){this.caching=a}});$.each(k.fixes,function(a,b){j[b]={setup:function(){if($.browser.msie)return!1;this.addEventListener(a,j[b].handler,!0)},teardown:function(){if($.browser.msie)return!1;this.removeEventListener(a,j[b].handler,!0)},handler:function(e){arguments[0]=e=h.fix(e);e.type=b;return h.handle.apply(this,arguments)}}});$.fn.listen=function(a,b,c){return this.each(function(){k(a,this,b,c)})};function n(a,b){$.extend(this,{ids:{},tags:{},listener:b,event:a});this.id=n.instances.push(this)};n.instances=[];n.prototype={constructor:n,handle:function(e){var a=e.stopPropagation;e.stopPropagation=function(){e.stopped=1;a.apply(this,arguments)};m(this,e.type).parse(e);e.stopPropagation=a;a=e.data=null},on:0,bubbles:0,start:function(){var a=this;if(!a.on){h.add(a.listener,a.event,a.handle);a.on=1}},stop:function(){var a=this;if(a.on){h.remove(a.listener,a.event,a.handle);a.on=0}},cache:function(a,b){return $.data(a,'listenCache_'+this.id,b)},parse:function(e){var z=this,c=e.data||e.target,d=arguments,f;if(!k.caching||!(f=z.cache(c))){f=[];if(c.id&&z.ids[c.id])p(f,z.ids[c.id]);o([c.nodeName,'*'],function(a){var b=z.tags[a];if(b)o((c.className+' *').split(' '),function(a){if(a&&b[a])p(f,b[a])})});if(k.caching)z.cache(c,f)}if(f[0]){o(f,function(a){if(a.apply(c,d)===!1){e.preventDefault();e.stopPropagation()}})}if(!e.stopped&&(c=c.parentNode)&&(c.nodeName=='A'||z.bubbles&&c!=z.listener)){e.data=c;z.parse(e)}f=d=c=null},append:function(f,g){var z=this;o(f.split(/\s*,\s*/),function(a){var b=k.regex.exec(a);if(!b)throw'$.listen > "'+a+'" is not a supported selector.';var c=b[2]=='#'&&b[3],d=b[1].toUpperCase()||'*',e=b[3]||'*';if(c)(z.ids[c]||(z.ids[c]=[])).push(g);else if(d){d=z.tags[d]=z.tags[d]||{};(d[e]||(d[e]=[])).push(g)}})}};function o(a,b,c){for(var i=0,l=a.length;i<l;i++)b.call(c,a[i],i)};function p(a,b){a.push.apply(a,b);return a};$(window).unload(function(){if(typeof n=='function')o(n.instances,function(b){b.stop();$.removeData(b.listener,b.event+'.'+a);b.ids=b.names=b.listener=null})})})(jQuery);

/** File: javascript/app-base.js **/

var App = window.App || {};

/** We will put all of our variables and resources (URL-s, listings etc) **/
App.data = {};

// All widgets should be defined here
App.widgets = {};

/**
 * Send post request to specific link
 *
 * @param string the_link
 */
App.postLink = function(the_link) {
  var form = $(document.createElement('form'));
  form.attr({
    'action' : the_link,
    'method' : 'post'
  });
  
  var submitted_field = $(document.createElement('input'));
  submitted_field.attr({
    'type'  : 'hidden',
    'name'  : 'submitted',
    'value' : 'submitted'
  });
  
  form.append(submitted_field);
  
  $('body').append(form);
  
  form.submit();
  return false;
};

/**
 * Convert & -> &amp; < -> &lt; and > -> &gt;
 *
 * @param str
 * @return string
 */
App.clean = function(str) {
  if(typeof(str) == 'string') {
    str = str.replace(/&/g, '&amp;');
    str = str.replace(/\>/g, '&gt;');
    str = str.replace(/\</g, '&lt;');
  }
  
  return str;
};

/**
 * JS version of lang function / helper
 *
 * @param string content
 * @param object params
 */
App.lang = function(content, params) {
  var translation = content;
  
  if(typeof(App.langs) == 'object') {
    if(App.langs[content]) {
      translation = App.langs[content];
    }
  }
  
  if(typeof params == 'object') {
    for(key in params) {
      translation = translation.replace(':' + key, App.clean(params[key]));
    } // if
  } // if
  return translation;
};

/**
 * JavaScript implementation of isset() function
 *
 * Usage example:
 *
 * if(isset(undefined, true) || isset('Something')) {
 *   // Do stuff
 * }
 *
 * @param value
 * @return boolean
 */
App.isset = function(value) {
  return !(typeof(value) == 'undefined' || value === null);
};

/**
 * Add async variables to async link
 *
 * @param string link
 * @return string
 */
App.makeAsyncUrl = function(link) {
  if (link) {
    if (link.indexOf('?') < 0) {
      link += '?async=1&skip_layout=1'
    } else {
      link += '&async=1&skip_layout=1'
    } // if
    return link;
  } else {
    return false;
  }
};

/**
 * Convert MySQL formatted datetime string to Date() object
 *
 * @params String timestamp
 * @return Date
 */
App.mysqlToDate = function(timestamp) {
  var regex=/^([0-9]{2,4})-([0-1][0-9])-([0-3][0-9]) (?:([0-2][0-9]):([0-5][0-9]):([0-5][0-9]))?$/;
  var parts=timestamp.replace(regex, "$1 $2 $3 $4 $5 $6").split(' ');
  return new Date(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5]);
};

/**
 * Attach more parameters to URL
 *
 * @param string url
 * @param object extend_with
 */
App.extendUrl = function(url, extend_with) {
  if(!url || !extend_with) {
    return url;
  } // if
  
  var extended_url = url;
  var parameters = [];
  
  extended_url += extended_url.indexOf('?') < 0 ? '?' : '&';
  
  for(var i in extend_with) {
    if(typeof(extend_with[i]) == 'object') {
      for(var j in extend_with[i]) {
        parameters.push(i + '[' + j + ']' + '=' + extend_with[i][j]);
      } // for
    } else {
      parameters.push(i + '=' + extend_with[i]);
    } // if
  } // for
  
  return extended_url + parameters.join('&');
};

/**
 * Parse numeric value and return integer or float
 *
 * @param String value
 * @return mixed
 */
App.parseNumeric = function(value) {
  if(typeof(value) == 'number') {
    return value;
  } else if(typeof(value) == 'string') {
    if(value.indexOf('.') > -1) {
      var separator = '.';
    } else if(value.indexOf(',') > -1) {
      var separator = ',';
    } else {
      return value == '' ? 0 : parseInt(value);
    } // if
       
    var separator_pos = value.indexOf(separator);
    var whole_number = parseInt(value.substring(0, separator_pos));
    var decimal = parseFloat('0.' + value.substring(separator_pos + 1));    

    return value.indexOf('-', 0) ? whole_number + decimal : whole_number - decimal;
  } else {
    return NaN;
  }
};

/**
 * Parse string and return version object
 *
 * @param String str
 * @return Object
 */
App.parseVersionString = function (str) {
    if (typeof(str) != 'string') { return false; }
    var x = str.split('.');
    // parse from string or default to 0 if can't parse
    var maj = parseInt(x[0]) || 0;
    var min = parseInt(x[1]) || 0;
    var pat = parseInt(x[2]) || 0;
    return {
        major: maj,
        minor: min,
        patch: pat
    }
}; // parseVersionString

/**
 * compare versions, if they are same returns 0, if first is lower returns -1, and
 * if second is lower returns 1
 *
 * @var string version1
 * @var string version2
 * @return int
 */
App.compareVersions = function (version1, version2) {
  version1 = App.parseVersionString(version1);
  version2 = App.parseVersionString(version2);
    
  if (version1.major < version2.major) {
    return -1;
  } else if (version1.major > version2.major) {
    return 1;
  } else {
    if (version1.minor < version2.minor) {
      return -1;
    } else if (version1.minor > version2.minor) {
      return 1;
    } else {
      if (version1.patch < version2.patch) {
        return -1;
      } if (version1.patch > version2.patch) {
        return 1;
      } else {
        return 0;
      } // if
    } // if
  } // if
} // compareVersions

jQuery.fn.highlightFade = function() {
  return this.effect("highlight", {}, 1000)
};

function ucfirst( str ) {
  str += '';
  var f = str.charAt(0).toUpperCase();
  return f + str.substr(1);
}

/** File: javascript/app.js **/

// Do stuff that we need to do on every page...
$(document).ready(function() {
  App.layout.init();
  App.RefreshSession.init();
  App.PrintPreview.init();
  App.widgets.SendReminder.init();
});

/** Layout **/
App.layout = function() {
  
  // Result
  return {
  
    /**
     * Initialize layout
     */
    init : function() {
      // Preload indicator...
      var indicator = new Image();
      indicator.src = App.data.indicator_url;
      
      // Jump to project button
      var project_menu_item = $('#menu_item_projects');
      project_menu_item.append('<span class="additional"><a href="' + App.data.jump_to_project_url + '"><span>' + App.lang('Jump to Project') + '</span></a></span>');
      project_menu_item.find('span.additional a').click(function() {
        App.ModalDialog.show('jump_to_project', App.lang('Jump to Project'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(App.data.jump_to_project_url), {});
        return false;
      });
      
      // Search button
      var search_menu_item = $('#menu_item_search a').click(function() {
        var quick_search_url = App.extendUrl($(this).attr('href'), { 
          skip_layout : 1, 
          async : 1 
        });
        App.ModalDialog.show('quick_search', App.lang('Quick Search'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(quick_search_url), {
          buttons : false
        });
        return false;
      });
      
      $('#page_actions .with_subitems>a').click(function() {
        return false;
      });
      
      // Quick add button
      $('#menu_item_quick_add a').click(function() {
        var url = App.extendUrl(App.data.quick_add_url, { skip_layout : 1});
        
        App.ModalDialog.show('quick_add', App.lang('Quick Add'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(url), {
          buttons : false,
          width: 560
        });
        return false;
      });
      
      // Flash
      $('#success, #error').click(function() {
        $(this).hide('fast');
      });
      
      // Hoverable
      $('.hoverable').hover(function() {
        $(this).addClass('hover');
      }, function() {
        $(this).removeClass('hover');
      });
      
      // Card
      $('.card div.options').each(function() {
        wrapper = $(this);
        var first_list_item = wrapper.find('li.first');
        wrapper.find('a').hover(function() {
          first_list_item.text($(this).attr('title'));
        }, function() {
          first_list_item.html('&nbsp;');
        });
      });
      
      // Scale big images in object description blocks
      $('div.body.content').scaleBigImages();
      
      $('.button_dropdown').each(function () {
        var dropdown_button = $(this);
        var dropdown_menu = dropdown_button.find('.dropdown_container');
        dropdown_button.hover(function () {
          
        }, function () {
          dropdown_menu.fadeOut(100);
        }).click(function () {
          if (dropdown_menu.is(':visible')) {
            dropdown_menu.fadeOut(100);  
          } else {
            dropdown_menu.fadeIn(100);
          } // if
        });
      });
    },
    
    /**
     * Init star unstar link
     *
     * @param string id
     * @return null
     */
    init_star_unstar_link : function(id) {
      $('#' + id).click(function() {
        var link = $(this);
        var parent = link.parent();
      
        // Block additional clicks
        if(link[0].block_clicks) {
          return false;
        } else {
          link[0].block_clicks = true;
        } // if
        
        var img = link.find('img');
        var old_src = img.attr('src');
        
        img.attr('src', App.data.indicator_url);
        
        $.ajax({
          url     : App.extendUrl(link.attr('href'), { async : 1 }),
          type    : 'POST',
          data    : {'submitted' : 'submitted'},
          success : function(response) {
            parent.empty();
            parent.append(response);
          },
          error   : function() {
            img.attr('src', old_src);
          }
        });
        
        return false;
      });
    },
    
    /**
     * Complete / reopen task
     *
     * @param string id
     */
    init_complete_open_link : function(id) {
      $('#' + id).click(function() {
        var link = $(this);
        var parent = link.parent();
      
        // Block additional clicks
        if(link[0].block_clicks) {
          return false;
        } else {
          link[0].block_clicks = true;
        } // if
        
        var img = link.find('img');
        var old_src = img.attr('src');
        
        img.attr('src', App.data.indicator_url);
        
        $.ajax({
          url     : App.extendUrl(link.attr('href'), { async : 1 }),
          type    : 'POST',
          data    : {'submitted' : 'submitted'},
          success : function(response) {
            parent.empty();
            parent.append(response);
          },
          error   : function() {
            img.attr('src', old_src);
          }
        });
        
        return false;
      });
    },
    
    /**
     * Initialize subscribe / unsubscribe link
     *
     * @param string wrapper_id
     * @return null
     */
    init_subscribe_unsubscribe_link : function(wrapper_id) {
      $('#' + wrapper_id + ' a').click(function(e) {
        var link = $(this);
        var parent = link.parent();
      
        // Block additional clicks
        if(link[0].block_clicks) {
          return false;
        } else {
          link[0].block_clicks = true;
        } // if
        
        var img = link.find('img');
        var old_src = img.attr('src');
        
        img.attr('src', App.data.indicator_url);
        
        $.ajax({
          url     : App.extendUrl(link.attr('href'), { async : 1 }),
          type    : 'POST',
          data    : {'submitted' : 'submitted'},
          success : function(response) {
            parent.empty();
            parent.append(response);
          },
          error   : function() {
            img.attr('src', old_src);
          }
        });
        
        return false;
      });
    },
    
    /**
     * Reindex opened tasks table, change colors of rows, and display hidden row if necessarry
     *
     * @param string table
     * @return null
     */
    reindex_task_table: function (table) {
      table = $(table);
      var counter = 0;
      table.find('li:not(.empty_row):not(.ui-sortable-helper):not(.sort_placeholder)').each(function() {
        row = $(this);
        if ((counter % 2) == 1) {
          row.removeClass('odd');
          row.addClass('even');
        } else {
          row.removeClass('even');
          row.addClass('odd');
        } // if
        counter++;
      });     
      
      if (counter<1) {
        table.find('.empty_row').show();
      } else {
        table.find('.empty_row').hide();
      } // if
    },
    
    /**
     * Init row in tasks table
     *
     * @param object row
     * @param object wrapper
     */
    init_object_task: function (row, wrapper) {
      if (wrapper.drag_enabled==true) {
        row.find('.drag_handle').show();
      } else {
        row.find('.drag_handle').hide();
      }
      
      // complete task
      row.find('a.complete_task').click(function() {
        var link = $(this);
        var complete_tasks_table = link.parents('.object_tasks').find('.completed_tasks_table');
        
        // Block additional clicks
        if(link[0].block_clicks) {
          return false;
        } else {
          link[0].block_clicks = true;
        } // if
        
        var img = link.find('img');
        var old_src = img.attr('src');
        
        img.attr('src', App.data.indicator_url);
        
        $.ajax({
          url     : link.attr('href'),
          type    : 'POST',
          data    : {'submitted' : 'submitted'},
          success : function(response) {
            var response_obj = $(response);
            var open_tasks_table = link.parents('.object_tasks').find('.tasks_table');
            complete_tasks_table.prepend(response_obj);
            row.remove();
            App.layout.init_object_task(response_obj,wrapper);
            App.layout.reindex_task_table(open_tasks_table);
          },
          error   : function() {
            img.attr('src', old_src);
          }
        });
        
        return false;
      });
      
      // open task
      row.find('a.open_task').click(function() {
        var link = $(this);
        var open_tasks_table = link.parents('.object_tasks').find('.open_tasks_table');
        
        // Block additional clicks
        if(link[0].block_clicks) {
          return false;
        } else {
          link[0].block_clicks = true;
        } // if
        
        var img = link.find('img');
        var old_src = img.attr('src');
        
        img.attr('src', App.data.indicator_url);
        
        $.ajax({
          url     : link.attr('href'),
          type    : 'POST',
          data    : {'submitted' : 'submitted'},
          success : function(response) {
            var response_obj = $(response);
            open_tasks_table.append(response_obj);
            row.remove();
            App.layout.init_object_task(response_obj,wrapper);
            App.layout.reindex_task_table(open_tasks_table);
          },
          error   : function() {
            img.attr('src', old_src);
          }
        });
        
        return false;
      });
      
      // Remove buttons
      row.find('a.remove_task').click(function() {
        var link = $(this);
        
        // Block additional clicks
        if(link[0].block_clicks) {
          return false;
        } else {
          link[0].block_clicks = true;
        } // if
        
        var img = link.find('img');
        var old_src = img.attr('src');
        
        img.attr('src', App.data.indicator_url);
        
        $.ajax({
          url     : App.extendUrl(link.attr('href'), {'async' : 1}),
          type    : 'POST',
          data    : {'submitted' : 'submitted'},
          success : function() {
            row.remove();
          },
          error   : function() {
            img.attr('src', old_src);
          }
        });
        
        return false;
      });
    },
    
    /**
     * Initialize tasks table
     *
     * @param string wrapper_id ID of wrapper div
     */
    init_object_tasks : function(wrapper_id, enable_reordering) {
        var wrapper = $('#' + wrapper_id);
        var form_wrapper = wrapper.find('div.add_task_form');
        var show_form = wrapper.find('a.add_task_link');
        var hide_form = wrapper.find('a.cancel_button');
        var active_tasks_table = wrapper.find('.tasks_table.open_tasks_table');
        
        form_wrapper.find('.show_due_date_and_priority a').click(function () {
          $(this).parent().hide();
          form_wrapper.find('.due_date_and_priority').slideDown();
          return false;
        });
        form_wrapper.find('.due_date_and_priority').hide();
                
        // Submit add task form
        form_wrapper.find('form').submit(function() {
          var form = $(this);
          if(UniForm.is_valid(form)) {       
            var old_form_action = form.attr('action');
            
            form.attr('action', App.extendUrl(old_form_action, { async : 1 }));
            
            var loading_row = '<li><img src="' + App.data.indicator_url + '" alt="loading" /> <strong>' + App.lang('Working') + '</strong></li>';
            active_tasks_table.append(loading_row);
            var temp_row = active_tasks_table.find('li:last');
          
            // submit form via ajax
            form.ajaxSubmit({
              success : function(response) {
                var response_obj = $(response);
                // insert real row in table
                response_obj.insertAfter(temp_row);
                // remove fake row
                temp_row.remove();
                App.layout.init_object_task(response_obj, wrapper);
                App.layout.reindex_task_table(active_tasks_table);
              },
              error : function (response) {
                // remove fake row
                temp_row.remove();
              }
            });
            
            // empty task message
            form.attr('action', old_form_action).find('input:first').val('').focus();
          } // if
          
          return false;
        });
        
        // Show task form
        show_form.click(function() {
          show_form.hide();
          $('.main_object .resource.object_tasks').show();
          form_wrapper.show().focusFirstField();
          return false;
        });
        
        $('#object_quick_option_new_task a').click(function () {
          show_form.hide();
          $('.main_object .resource.object_tasks').show();
          form_wrapper.show().focusFirstField();
          return false;
        });
        
        // Hide task form
        hide_form.click(function() {
          show_form.show();
          form_wrapper.clearErrorMessages().hide();
          form_wrapper.find('input:eq(0)').val('');
          return false;
        });
        
        form_wrapper.find('input').keypress(function(e) {
          if (e.keyCode == 27) {
            hide_form.click();
          } // if
        });
        
        if (enable_reordering > 0) {
          // init sortable behvaiour
          wrapper.find('.open_tasks_table').sortable({
            axis : 'y',      
            cursor: 'move',
            items: 'li.sort',
            delay: 3,
            revert: false,
            connectWith: ['.open_tasks_table'],
            tolerance : 'pointer',
            placeholder: 'sort_placeholder',
            forcePlaceholderSize : false,
            update: function (e, ui) {
              var sort_form = $(this).parents('form.sort_form');
              ui.item.parent().attr('style','');
              sort_form.ajaxSubmit({
                method : 'POST'
              });
              App.layout.reindex_task_table($(this));
            },
            over: function (table_object,ui) {
              $(this).addClass('dragging');
            },
            out: function (table_object,ui) {
              $(this).removeClass('dragging');
            },
            receive : function (event, ui) {
              App.layout.reindex_task_table($(this));
            },
            remove : function (event, ui) {
              App.layout.reindex_task_table($(this));
            }
          });
        } // if
               
        // init every row in table
        wrapper.find('.tasks_table li, .completed_tasks_table li').each(function () {
          App.layout.init_object_task($(this), wrapper);
        });
        
        // 'view all completed' behaviour
        wrapper.find('.completed_tasks_table li.list_all_completed a').click(function () {
          var anchor = $(this);
          var completed_tasks_table = anchor.parents('ul.completed_tasks_table:first');
          anchor.after('<span class="loading"><img src="' + App.data.indicator_url + '" alt="" />' + App.lang('Loading...') + '</a>');
          var loading_block = anchor.parent().find('.loading:first');
          anchor.hide();
          
          $.ajax({
            url : App.extendUrl(anchor.attr('href'), {async : 1, skip_layout : 1}),
            success : function (response) {
              completed_tasks_table.html(response);
              completed_tasks_table.find('li').each(function () {
                App.layout.init_object_task($(this), wrapper);
              });
            },
            error : function () {
              loading_block.remove();
              anchor.show();   
            }
          });
          return false;
        });
    }
  
  } // init
  
}();

/**
 * Modal dialog module
 */
App.ModalDialog = function() {
  
  /**
   * Current dialog reference
   *
   * @var jQuery
   */
  var dialog_object;
  
  // Let's return public interface object
  return {
    
    /**
     * Show modal dialog
     *
     *
     * @param String name
     * @param String title
     * @param mixed body
     * @param mixed settings
     */
    show : function(name, title, body, settings) {
      // dialog options
      var options = {
        modal     : true,
        draggable : false,
        resizable : true,
        title     : title,
        id        : name,
        position  : 'top',
        bgiframe  : true,
        close     : function (type,data) {
          if (settings.close) {
            settings.close();
          } // if
          dialog_object.dialog('destroy').remove();
        },
        resizeStart : function (type,data) {

        }
      };

      if (settings) {
        // width and height settings
        options.width = settings.width ? settings.width : 410;
        options.height = settings.height ? settings.height : 'auto';        
        // additional buttons
        options.buttons = {};
        if (settings && settings.buttons) {
          for (var x = 0; x < settings.buttons.length; x++) {
            if (settings.buttons[x].callback) {
              options.buttons[settings.buttons[x].label] = settings.buttons[x].callback;
            } else {
              options.buttons[settings.buttons[x].label] = function () {
                dialog_object.dialog('close');
              } // function
            } // if
          } // if
        } // if
      } // if

      options.maxWidth = options.width;
      options.minWidth = options.width;
      
      dialog_object = $(body).dialog(options);
     
      var counter = 0;
      dialog_object.parent().parent().find('.ui-dialog-buttonpane button').each(function () {
        var button = $(this);
        button.removeClass('ui-state-default').removeClass('ui-corner-all');

        var label = button.html();
        button.html('<span><span>' + label + '</span></span>');
        if (counter != 0) {
          button.addClass('alternative');
        } // if
        counter++;
      });
    },
    
    /**
     * Close the dialog
     */
    close : function() {
      dialog_object.dialog('destroy').remove();
    },
    
    /**
     * sets width of dialog
     */
    setWidth : function (width_px) {     
      var dom_dialog = $('.ui-dialog');
      var position = dom_dialog.position();
      var new_left_offset = position.left - ((width_px - dom_dialog.width())/2);
      dom_dialog.css('width' , width_px+'px').css('left', new_left_offset+'px');
    },
    
    /**
     * Sets dialog title
     */
    setTitle : function (title) {
     var dom_dialog = $('.ui-dialog .ui-dialog-titlebar span.ui-dialog-title').html(title);
    },
    
    /**
     * Checks if dialog is open
     */
    isOpen : function () {
      if ($('.ui-dialog').length > 0) {
        return true;
      } else {
        return false;
      }
    }
  };
  
}();


/**
 * Print preview module
 */
App.PrintPreview = function() {
  /**
   * Dom element of main css
   *
   * @var jQuery
   */
  var css_main;
  /**
   * Dom element of theme css
   *
   * @var jQuery
   */
  var css_theme;
  /**
   * Dom element of css preview
   *
   * @var jQuery
   */
  var css_print_preview;
  
  // Return value
  return {
    
    /**
     * Initialize print preview behavior
     *
     * @param void
     * @return null
     */
    init : function() {
      $('#print_button').click(function(e) {
        App.PrintPreview.open();
        e.stopPropagation();
        return false;
      });
      
      $('#print_preview_header #print_preview_close').click(function() {
        App.PrintPreview.close();
        return false;
      });
      
      $('#print_preview_header #print_preview_print').click(function() {
        window.print();
        return false;
      });
      
      css_main = $('#style_main_css');
      css_theme = $('#style_theme_css');
      css_print_preview = $('#print_preview_css');
    },
    
    /**
     * Show print preview view
     *
     * @param void
     * @return null
     */
    open : function() {
        css_main.attr('disabled', true);
        css_theme.attr('disabled', true);
        
        if ($.browser.msie == true) {
          $('#print_preview_css').each(function () {
            // please don't ask me why i did this stupendity
            this.disabled = false;
            this.disabled = true;
            this.disabled = false;
          });
        } else {
          $('#print_preview_css').attr('rel','stylesheet').each(function () {
            this.disabled = false;
          });
        } // if
    },

    /**
     * Close print preview view
     *
     * @param void
     * @return null
     */
    close : function() {
        css_main.attr('disabled', false);
        css_theme.attr('disabled', false);
        if ($.browser.msie == true) {
          css_print_preview.each(function () {
            // please don't ask me why i did this stupendity
            this.disabled = true;
            this.disabled = false;
            this.disabled = true;
          });
        } else {
          css_print_preview.attr('rel','stylesheet').each(function () {
            this.disabled = true;
          });
        } // if
    }
    
  };
  
}();

/**
 * Comment options behavior
 */
App.CommentOptions = function() {
  
  /**
   * Result
   */
  return {
    
    /**
     * Initialize
     *
     * @param string wrapper_id ID of warpper div
     * @return void
     */
    init : function(wrapper_id) {
      $('#' + wrapper_id).each(function() {
        var wrapper = $(this);
        var first_element = wrapper.find('li.comment_options_first');
        
        wrapper.find('a, span').hover(function() {
          first_element.html($(this).attr('title'));
        }, function() {
          first_element.html('&nbsp;');
        });
      });
    } // init
    
  }
  
}();

App.EmailObject = function() {
  return {
    init : function (object_id) {
      var email_object = $('#'+object_id);
      var blockquotes = email_object.find('>blockquote');
      blockquotes.each(function () {
        var blockquote = $(this);
        if (!blockquote.parent().is('div.content')) {
          blockquote = blockquote.parent();
        } // if
        blockquote.before('<a href="#" class="hidden_history">' + App.lang('Hidden Email History') + '</a>');
        blockquote.hide();
        var blockquote_anchor = blockquote.prev();
        
        blockquote_anchor.click(function () {
          blockquote.slideDown();
          $(this).remove();
          return false;
        });
      });
    }
  }
}();

// Refresh session requests
App.RefreshSession = function() {
  
  /**
   * Interval object used to call refresh function
   */
  var refresh_interval = null;
  
  // Return value
  return {
    
    /**
     * Initialize refresh interval
     *
     * @params void
     * @return void
     */
    init : function() {
      if(App.data.keep_alive_interval > 0) {
        refresh_interval = setInterval('App.RefreshSession.refresh()', App.data.keep_alive_interval);
      } // if
    },
    
    /**
     * Function used to refresh session
     *
     * @param void
     * @return null
     */
    refresh : function() {
      $.ajax({
        url : App.data.refresh_session_url
      });
    }
  }
  
}();

/**
 * Quick search module
 */
App.QuickSearch = function() {
  
  // Public interface
  return {
    
    /**
     * Initialize quick search form
     *
     * @param void
     * @return undefined
     */
    init : function() {
      $('#quick_search_form').submit(function() {
        $('#quick_search_button').hide();
        $('#quick_search_indicator').show();
        
        var form = $(this);
        var results = $('#quick_search_results');
        
        results.empty();
        
        $.ajax({
          type : 'POST',
          url : App.extendUrl(form.attr('action'), { async : 1}),
          data : {
            submitted : 'submitted',
            search_for : $('#quick_search_input').val(),
            search_type : $('#quick_search_type').val()
          },
          success : function(response) {
            results.append(response);
            
            $('#quick_search_button').show();
            $('#quick_search_indicator').hide();
          }
        });
        return false;
      });
      
      $('#quick_search_form ul li').click(function() {
        var list_element = $(this);
        
        $('#quick_search_form ul li').removeClass('selected');
        list_element.addClass('selected');
        
        $('#quick_search_type').val(list_element.attr('id').substr(7));
      });
      
      $('#quick_search_form #quick_search_input')[0].focus();
    }
  };
  
}();

/**
 * Functions for main menu
 */
App.MainMenu = function() {
  var menu
  
  // Public interface
  return {
    
    /**
     * Initialize main menu
     *
     * @param void
     * @return undefined
     */
    init : function(menu_id) {
      menu = $('#'+menu_id);
    },
    
    /**
     * add item to menu
     *
     *  @param object item
     *  @param string group_id
     *  @return null
     */
    addToGroup: function (item, group_id) {
      var button_class = 'last';
      
      var group = $('#menu_group_'+group_id, menu);
      if (group.length > 0) {
        var button_text = "<li id='menu_item_" + item.id + "' class='item " + button_class + "'>";
        button_text +=    "<a class='main' href='" + item.href + "'><span class='outer'>";
        button_text +=    "<span style='background-image: url(" + item.icon + ");' class='inner'>";
        if (item.badge_value > 0) {
          button_text +=    "<span class='badge'>" + item.badge_value + "</span>"
        } // if
        button_text +=    item.label;
        button_text +=    "</span>";
        button_text +=    "</span></a>";
        button_text +=    "</li>";
        $('li.item:last', group).removeClass('last').removeClass('single').addClass('middle');
        group.append(button_text);
      } // if
    },
    
    /**
     * Check if item with id item exists in group with group_id
     *
     *  @param string item
     *  @param string group_id
     *  @return bolean
     */
    itemExists: function (item_id, group_id) {
      var group = $('#menu_group_'+group_id, menu);
      if (group.length > 0) {
        var menu_item = $('#menu_item_' + item_id, group);
        if (menu_item.length > 0) {
          return true;
        } // if
      };
      return false;
    },
    
    /**
     * Remove item if exists
     *
     *  @param string item
     *  @param string group_id
     *  @return bolean
     */
    removeButton: function (item_id, group_id) {
      var group = $('#menu_group_'+group_id, menu);
      if (group.length > 0) {
        var previous_class = 'last'
        if ($('li', group).length <= 2) {
          previous_class = 'single';
        } // if
        $('#menu_item_' + item_id, group).remove();
        $('li:last', group).removeClass('middle').addClass(previous_class);
      };
    },
    
    /**
     * Set badge value for item
     *
     *  @param string item
     *  @param string group_id
     *  @param string badge_value
     *  @return bolean
     */
    setItemBadgeValue: function (item_id, group_id, badge_value) {
      var group = $('#menu_group_'+group_id, menu);
      if (group.length > 0) {
        var menu_item = $('#menu_item_' + item_id, group);
        if (menu_item.length) {
          if (badge_value > 0) {
            var badge = $('span.badge', menu_item);
            if (badge.length > 0) {
              badge.text(badge_value);
            } else {
              $('a>span>span', menu_item).prepend('<span class="badge">' + badge_value + '</span>');
            } // if
            return true;
          } else {
            $('span.badge', menu_item).remove();
            return true;
          } // if
        } // if
      } // if
      return false;
    }
  };
}();

/*
App.Menu = function() {
  
  return {
    set_badge_value : function(item_id, value) {     
      if(value > 0) {
        var parent = $('#' + item_id + '>a>span>span');
        var badge = parent.find('span.badge');
        if(badge.length > 0) {
          badge.text(value);
        } else {
          parent.prepend('<span class="badge">' + value + '</span>');
        } // if
      } else {
        $('#' + item_id + ' span.badge').remove();
      }
    }
    
  };
  
}();
*/

/** File: modules/system/javascript/main.js **/

App.system = {
  controllers : {},
  models      : {}
};

/**
 * People controller client side behavior
 */
App.system.controllers.dashboard = {
  
  /**
   * Prepare dashboard index page
   */
  index : function() {
    $(document).ready(function() {
      
      // Active reminders
      $('#active_reminders').each(function() {
        var wrapper = $(this);
        
        wrapper.find('table tr.with_comment').each(function() {
          var row = $(this);
          row.find('td.name').prepend('<span class="show_hide_reminder_comment"><a href="#">' + App.lang('Show Comment') + '</a></span>');
          row.find('td.name span.show_hide_reminder_comment a').click(function() {
            var note = row.find('td.name span.reminder_comment');
            var link = $(this);
            
            if(note.length) {
              if(note.css('display') == 'none') {
                note.show('fast');
                link.text(App.lang('Hide Comment'));
              } else {
                note.hide('fast');
                link.text(App.lang('Show Comment'));
              } // if
            } // if
            return false;
          });
        });
        
        var reindex_odd_even_rows = function() {
          var counter = 1;
          wrapper.find('tr').each(function() {
            var row = $(this);
            row.removeClass('even').removeClass('odd');
            if(counter % 2 == 1) {
              row.addClass('odd');
            } else {
              row.addClass('even');
            } // if
            counter++;
          });
        };
        
        wrapper.find('table a.dismiss_reminder').click(function() {
          var link = $(this);
        
          // Block additional clicks
          if(link[0].block_clicks) {
            return false;
          } else {
            link[0].block_clicks = true;
          } // if
          
          var img = link.find('img');
          var old_src = img.attr('src');
          
          img.attr('src', App.data.indicator_url);
          
          $.ajax({
            url     : link.attr('href'),
            type    : 'POST',
            data    : {'submitted' : 'submitted'},
            success : function() {
              link.parent().parent().remove();
              reindex_odd_even_rows();
              if(wrapper.find('table tr').length < 1) {
                wrapper.find('div.section_container').append('<p class="details center">' + App.lang('All reminders dismissed') + '</p>');
              } // if
            },
            error   : function() {
              img.attr('src', old_src);
            }
          });
          
          return false;
        });
      })
      
      $('#active_projects .pinned a').click(function() {
				var link = $(this);
				var wrapper = link.parents('.pinned');
				var row = wrapper.parent();
				var container = row.parents('.section_container');
				
				/**
		     * Reindex table rows
		     */
		    var reindex_odd_even_rows = function() {
		      var counter = 1;
		      container.find('tr').each(function() {
		        var rows = $(this);
		        rows.removeClass('even').removeClass('odd');
		        if(counter % 2 == 1) {
		          rows.addClass('even');
		        } else {
		          rows.addClass('odd');
		        } // if
		        counter++;
		      });
		    } // reindex_table_rows
				
				link.hide();
				wrapper.prepend('<img src="' + App.data.indicator_url  + '" class="indicator" alt="" />');
				
				$.ajax({
					url     : App.extendUrl(link.attr('href'), { async : 1 }),
					type    : 'POST',
					data    : {'submitted' : 'submitted'},
					success : function(response) {
						
					if (link.is('.pin_to_top')){
						row.prependTo(container.find('#pinned_active_projects tbody'));
						row.highlightFade();
						row.find('img.indicator').remove();
						link.attr({
							'href'  : response,
							'title' : App.lang('Unpin')
						}).show().find('img').attr({
							'src'   : App.data.pin_icon_url,
							'title' : App.lang('Unpin')
						});
						link.removeClass('pin_to_top').addClass('unpin');
					} else if(link.is('.unpin')) {
						row.appendTo(container.find('#other_active_projects tbody'));
						row.highlightFade();
						row.find('img.indicator').remove();
						link.attr({
							'href'  : response,
							'title' : App.lang('Pin to top')
						}).show().find('img').attr({
							'src'   : App.data.unpin_icon_url,
							'title' : App.lang('Pin to top')
						});
						link.removeClass('unpin').addClass('pin_to_top');
					}
						reindex_odd_even_rows();
					},
					error   : function() {
						link.show();
					}
				});
				
				return false;
			});
      
    });
  },
  
  /**
   * Search page behavior
   */
  search : function() {
    $(document).ready(function() {
      $('#search_form').submit(function() {
        var form = $(this);
        
        var search_for = jQuery.trim($("#search_for_input").val());
        if(search_for == '') {
          return false;
        } // if
        
        form.block(App.lang('Working...'));
        
        location.href = App.extendUrl(form.attr('action'), {
          q : search_for,
          type : $('#search_for_type').val()
        });
        
        return false;
      });
    });
  },
  
  /**
   * Trash page behavior
   */
  trash : function() {
    $(document).ready(function() {
      $('#trashed_objects_form').submit(function() {
        var form = $(this);
        var selected_action = form.find('option:selected').val();
        
        if(selected_action == 'delete') {
          return confirm(App.lang('Are you sure that you wish to permanently delete selected item(s)?'));
        } // if
      });
    });
  }
  
};

/**
 * Handlers for settings section
 */
App.system.controllers.settings = {
  
  /**
   * General options
   */
  general : function() {
    $(document).ready(function() {
      
      /**
       * Show/Hide on_logout_url option
       */
      var show_hide_logout_url_field = function() {
        var checked_option = $('input[name=use_on_logout_url]:checked').val();
        var use_logout_url = $('#on_logout_url_container');
        if (checked_option == 0) {
          use_logout_url.hide('fast');
        }
        else {
          use_logout_url.show('fast', function() {
            use_logout_url.find('input')[0].focus();
          });
        }
      }
      
      $('input[name=use_on_logout_url]').click(show_hide_logout_url_field);
      show_hide_logout_url_field();
    });
  },
  
  
  /**
   * Mailing settings
   */
  mailing : function() {
    $(document).ready(function() {
      
      /**
       * Enable or disable SMTP settings block
       */
      var enable_disable_smtp_settings = function() {
        if($('#mailingType').val() == 'smtp') {
          $('#smtp_mailer_settings').show();
          $('#smtp_mailer_settings input').attr('disabled', '');
          $('#mailingSecurity').attr('disabled', '');
          
          $('#native_mailer_settings').hide();
        } else {
          $('#smtp_mailer_settings').hide();
          $('#smtp_mailer_settings input').attr('disabled', 'disabled');
          $('#mailingSecurity').attr('disabled', 'disabled');
          
          $('#native_mailer_settings').show();
        } // if
      };
      
      var enable_disable_smpt_authentication = function() {
        if($('#mailingAuthenticateRadioWrapper input:checked').val() == '0') {
          $('#mailingAuthenticateWrapper')
            .find('input').val('').end()
            .find('select').val('off').end();
          $('#mailingAuthenticateWrapper').hide('fast');
        } else {
          $('#mailingAuthenticateWrapper').show('fast');
        } // if
      };
      
      $('#mailingType').change(enable_disable_smtp_settings);
      enable_disable_smtp_settings();
      
      $('#mailingAuthenticateRadioWrapper input[type=radio]').click(enable_disable_smpt_authentication);
      enable_disable_smpt_authentication();

      
      
      var mailbox_form = $('#mailing_settings_admin');
      var result_container = $('#test_connection .test_connection_results', mailbox_form);
      var result_image = $('img:eq(0)', result_container);
      var result_output = $('span:eq(0)', result_container);
      
      $('#test_connection button').click(function () {
        result_output.text('');
        result_image.attr('src', App.data.indicator_url);

        mailbox_form.ajaxSubmit({
          dataType : 'json',
          success:    function(response) {
            result_output.text(response.message);
            if (response.isSuccess) {
              result_image.attr('src', App.data.ok_indicator_url);
              result_container.removeClass('connection_error');
              result_container.addClass('connection_ok');              
            } else {
              result_image.attr('src', App.data.error_indicator_url);
              result_container.removeClass('connection_ok');
              result_container.addClass('connection_error');
            } // if
          },
          error:      function(response) {
            result_output.text(App.lang('Could not connect to server with given parameters'));
            result_image.attr('src', App.data.error_indicator_url);
            result_container.removeClass('connection_ok');
            result_container.addClass('connection_error');
          },
          url: App.data.test_smtp_connection_url
        });
      });
      
    });
  }
};

/**
 * Handlers for roles administration controller
 */
App.system.controllers.roles_admin = {
  
  /**
   * Roles admin behavior
   */
  index : function() {
    $(document).ready(function() {
      $('#system_roles td.checkbox input').click(function() {
        var checkbox = $(this);
        var cell = checkbox.parent();
        
        // Status is not changed to checked (status is set before callback)
        if(this.checked) {
          this.checked = false;
        } else {
          return false;
        } // if
        
        if(confirm(App.lang('Are you sure that you want to set this role as a default role? Please check description in "About Roles" section to learn what is default role and why is it important'))) {
          checkbox.hide();
          cell.append('<img src="' + App.data.indicator_url + '" />');
          
          $.ajax({
            url  : App.extendUrl(checkbox.attr('set_as_default_url'), { async : 1 }),
            type : 'POST',
            data : {
              submitted : 'submitted'
            },
            success : function() {
              $('#system_roles td.checkbox input').each(function() {
                this.checked = false;
              });
              
              checkbox[0].checked = true;
              
              cell.find('img').remove();
              checkbox.show();
              return true;
            },
            error : function() {
              cell.find('img').remove();
              checkbox.show();
              
              alert(App.lang('Failed to set this role as default role'));
              
              return false;
            }
          });
        } // if
        
        return false;
      });
    });
  }
  
};

/**
 * Languages controller behavior
 */
App.system.controllers.languages_admin = {
  
  /**
   * Language administration index page behavior
   */
  index : function() {
    $(document).ready(function() {
      $('#languages td.checkbox input').click(function() {
        var checkbox = $(this);
        var cell = checkbox.parent();
        
        // Status is not changed to checked (status is set before callback)
        if(this.checked) {
          this.checked = false;
        } else {
          return false;
        } // if
        
        if(confirm(App.lang('Are you sure that you want to set this language as a default?'))) {
          checkbox.hide();
          cell.append('<img src="' + App.data.indicator_url + '" />');
          
          $.ajax({
            url  : App.extendUrl(checkbox.attr('set_as_default_url'), { async : 1 }),
            type : 'POST',
            data : {
              submitted : 'submitted'
            },
            success : function() {
              $('#languages td.checkbox input').each(function() {
                this.checked = false;
              });
              
              checkbox[0].checked = true;
              
              cell.find('img').remove();
              checkbox.show();
              return true;
            },
            error : function() {
              cell.find('img').remove();
              checkbox.show();
              
              alert(App.lang('Failed to set this language as default'));
              
              return false;
            }
          });
        } // if
        
        return false;
      });
    });
  },
  
  /**
   * Edit translation page
   */
  edit_translation_file : function() {
    $(document).ready(function() {
      $('.common_table.lang_table tr td input').focus(function() {
        $(this).parent().parent().addClass('focused');
        $(this).parent().removeClass('new');
      });
      
      $('.common_table.lang_table tr td input').blur(function() {
        $(this).parent().parent().removeClass('focused');
        if ($(this).val()) {
          $(this).parent().removeClass('new');
        } else {
          $(this).parent().addClass('new');
        }
      });
      
      $('.common_table.lang_table .copy_arrow img').click(function() {
        var string = $(this).parent().siblings('.dictionary').text();
        $(this).parent().siblings('.input').children('input').each(function() {
          $(this).val(string);
          $(this).parent().removeClass('new');
        })
      });
    });
  } // edit_translation_file
  
};

/**
 * Project controller actions behavior
 */
App.system.controllers.project = {
  
  /**
   * Add project form behavior
   */
  add : function() {
    $(document).ready(function() {
      $('#projectTemplate').change(function() {
        if($(this).val() == '') {
          $('#users_from_template').hide();
          $('#users_from_auto_assignment').show();
        } else {
          $('#users_from_auto_assignment').hide();
          $('#users_from_template').show();
        } // if
      });
    });
  },
  
  /**
   * User tasks page
   */
  user_tasks : function() {
    $(document).ready(function() {
      $('#assignments a.complete_assignment, #assignments a.remove_assignment').click(function() {
        var link = $(this);
        
        // Block additional clicks
        if(link[0].block_clicks) {
          return false;
        } else {
          link[0].block_clicks = true;
        } // if
        
        var img = link.find('img');
        var old_src = img.attr('src');
        
        img.attr('src', App.data.indicator_url);
        
        $.ajax({
          url     : link.attr('href'),
          type    : 'POST',
          data    : {'submitted' : 'submitted'},
          success : function(response) {
            link.parent().parent().remove();
            
            var counter = 1;
            $('#assignments tr.assignment_row').each(function() {
              var new_class = counter % 2 == 1 ? 'odd' : 'even';
              $(this).removeClass('even').removeClass('odd').addClass(new_class);
              counter++;
            });
          },
          error   : function() {
            img.attr('src', old_src);
            link[0].block_clicks = false;
          }
        });
        
        return false;
      });
    });
  }
  
}

/**
 * Projects section
 */
App.system.controllers.projects = {
  
  /**
   * Projects administration index page
   */
  index: function() { 
    $(document).ready(function() {
      $('#projects').checkboxes();
    });
  },
  
  /**
   * Projects administration archive page
   */
  archive: function() { 
    $(document).ready(function() {
      $('#projects').checkboxes();
    });
  }
  
};

/**
 * Project groups administration behavior
 */
App.system.controllers.project_groups = {
  
  /**
   * View projects group
   */
  view : function() { 
    $(document).ready(function() {
      $('#projectGroup').checkboxes();
    });
  }
  
};

/**
 * User profile controller behavior
 */
App.system.controllers.users = {
  
  /**
   * View user profile behavior
   */
  view : function() {
    $(document).ready(function() {
      $('#send_welcome_message_page_action a').click(function() {
        var send_welcome_message_url = App.extendUrl($(this).attr('href'), { async : 1 });
        
        App.ModalDialog.show('send_welcome_message_popup', App.lang('Send Welcome Message'), $('<p><img src="' + App.data.indicator_url + '" alt="" /> ' + App.lang('Loading...') + '</p>').load(send_welcome_message_url), {
          width: 500
        });
        
        return false;
      });
    });
  },
  
  /**
   * Create user page behavior
   */
  add : function() {
    $(document).ready(function() {
      $('#new_user div.additional_step').each(function() {
        var wrapper = $(this);
        var body = wrapper.find('div.body');
        
        wrapper.find('div.head input[type=checkbox]').each(function() {
          if(this.checked) {
            body.show('fast');
          } else {
            body.hide();
          } // if
          
          $(this).click(function() {
            if(this.checked) {
              body.show('fast');
            } else {
              body.hide();
            } // if
          });
        });
      });
    });
  },
  
  /**
   * Edit user settings page behavior
   */
  edit_settings : function() {
    $(document).ready(function() {
      $('#userAutoAssignYesInput').click(function() {
        $('#auto_assign_role_and_permissions').show();
      });
      
      $('#userAutoAssignNoInput').click(function() {
        $('#auto_assign_role_and_permissions').hide();
      });
    });
  }
  
};

/**
 * Dashboard sections behavior implementation
 */
App.widgets.DashboardSections = function() {
  
  /**
   * Wrapper instance
   *
   * @var jQuery
   */
  var wrapper;
  
  /**
   * Content block wrapper
   *
   * @var jQuery
   */
  var section_content_wrapper;
  
  // Public interface
  return {
    
    /**
     * Initialize dashboard sections
     *
     * @param String wrapper_id
     */
    init : function(wrapper_id) {
      wrapper = $('#' + wrapper_id);
      section_content_wrapper = wrapper.find('div.top_tabs_object_list .dashboard_wide_sidebar_inner_2');
      
      wrapper.find('ul.dashboard_tabs a').click(function(e) {
        var link = $(this);
        var list_item = link.parent();
        
        if(list_item.is('li.selected')) {
          return false;
        } // if
        
        var section_content_id = list_item.attr('id') + '_content';
        
        // Hide all visible content blocks
        section_content_wrapper.find('div.dashboard_section_content').hide();
        
        // Find or load section content
        var section_content = section_content_wrapper.find('#' + section_content_id);
        if(section_content.length == 0) {
          section_content = $('<div id="' + section_content_id + '" class="dashboard_section_content"><p class="dashboard_sections_loading"><img src="' + App.data.big_indicator_url + '" alt="" /></p></div>').appendTo(section_content_wrapper);
          section_content.load(App.extendUrl(link.attr('href'), {
            'async' : 1,
            'for_dashboard_section' : 1
          }));
        } // if
        
        section_content.show();
        
        // Mark tab as selected
        wrapper.find('ul.dashboard_tabs li').removeClass('selected');
        list_item.addClass('selected');
        
        return false;
      });
      
      // Select first section automatically
      wrapper.find('ul.dashboard_tabs li:first a').click(); 
    }
    
  }
  
}();

/**
 * Dashboard favorite projects behavior implementation
 */
App.widgets.DashboardFavoriteProjects = function() {
  
  /**
   * Wrapper instance
   *
   * @var jQuery
   */
  var wrapper;
  
  /**
   * initialize favorite row
   
   */
  var init_favorite_row = function (favorite_row) {
    
      favorite_row.find('a.unpin').click(function () {
        var anchor = $(this);
        var anchor_container = anchor.parents('li.pinned_project:first');
        var anchor_list = anchor.parents('ul:first');
        anchor_container.block();
        $.ajax({
          data    : '&submitted=submitted',
          url     : App.extendUrl(anchor.attr('href'), {async : 1, skip_layout : 1}),
          type    : 'POST',
          success : function () {
            anchor_container.remove();
            check_favorite_list(anchor_list);
          },
          error   : function () {
            anchor_container.unblock();
          }
        });
        
        return false;
      });
      
      favorite_row.hover(function () {
        $(this).find('a.unpin').show();
      }, function () {
        $(this).find('a.unpin').hide();
      });
      
      return favorite_row;
  };
  
  var check_favorite_list = function (favorite_list) {
    if (favorite_list.find('li').length==1) {
      favorite_list.find('li.drop_here').show();
    } else {
      favorite_list.find('li.drop_here').hide();
    } // if
  } 
  
  // Public interface
  return {
    
    /**
     * Initialize dashboard sections
     *
     * @param String wrapper_id
     */
    init : function(wrapper_id) {
      wrapper = $('#' + wrapper_id);
      check_favorite_list(wrapper.find('ul:first'));
      
      wrapper.find('li.pinned_project').each(function () {
        init_favorite_row($(this));
      });
      
      wrapper.find('ul').droppable({
        accept      : '.active_project',
        hoverClass  : 'droppable_active',
        tolerance   : 'pointer',
        drop        : function(event, ui) {
          var project_id = ui.helper.attr('id');
          var favorite_list = $(this);
          var existing_favorite = favorite_list.find('li[id='+project_id+']');
          if (existing_favorite.length == 0) {
            var new_entry = '<li class="with_icon pinned_project" id="'+project_id+'">' +
              '<a href="' + ui.helper.attr('unpin_url') + '" class="unpin"><img src="' + App.data.assets_url + '/images/dismiss.gif" alt="" /></a>' +
              ui.helper.find('td.icon').html() +
              '<span class="name">' + ui.helper.find('td.name').html() + '</span>' +
            '</li>';
            
            var new_favorite_row = favorite_list.find('.drop_here').before(new_entry).prev();
            init_favorite_row(new_favorite_row);
            
            $.ajax({
              data    : '&submitted=submitted',
              url     : App.extendUrl(ui.helper.attr('pin_url'), {async : 1, skip_layout : 1}),
              type    : 'POST',
              success : function () {
              },
              error   : function () {
                new_favorite_row.remove();
                check_favorite_list(favorite_list);
              }
            })
            check_favorite_list(favorite_list);
            
            ui.helper.remove();
          } else {
            existing_favorite.highlightFade();
          }
        }
      });
    }
    
  }
}();

/**
 * Dashboard active projects behavior implementation
 */
App.widgets.ActiveProjects = function() {
  
  /**
   * Wrapper instance
   *
   * @var jQuery
   */
  var wrapper;
  
 
  // Public interface
  return {
    
    /**
     * Initialize dashboard sections
     *
     * @param String wrapper_id
     */
    init : function(wrapper_id) {
      wrapper = $('#' + wrapper_id);
      
      wrapper.find('.active_project').draggable({
        helper: 'clone',
        scroll: true,
        distance: 3,
        revert: true
      });
    }
    
  }
}();

/**
 * Dashboard important items behavior implementation
 */
App.widgets.DashboardImportantItems = function() {
  
  /**
   * Wrapper instance
   *
   * @var jQuery
   */
  var wrapper;
  
 
  // Public interface
  return {
    
    /**
     * Initialize dashboard important items
     *
     * @param String wrapper_id
     */
    init : function(wrapper_id) {
      wrapper = $('#' + wrapper_id);
      
      
      // Show and initialize reminders      
      wrapper.find('li.reminders a').click(function () {
        var anchor = $(this);
        var popup_url = App.extendUrl(anchor.attr('href'), {async : 1, skip_layout : 1});
        App.ModalDialog.show('reminders_popup', App.lang('Active Reminders'), $('<p><img src="' + App.data.indicator_url + '" alt="" /> ' + App.lang('Loading...') + '</p>').load(popup_url), { 
          buttons : [
            { label: App.lang('Close'), callback: null }
          ],
          width: 700
        });
        return false;
      });
            
    },
    
    /**
     * Remove item from list
     */
    removeItem : function(classname) {
      wrapper.find('li.'+classname).remove();
      if (wrapper.find('li').length == 0) {
        wrapper.hide();
      } // if
    } // removeItem
    
  }
}();

/**
 * Create new object from select box behavior
 */
jQuery.fn.new_object_from_select = function() {
  return this.each(function() {
    var select = $(this);
    
    var new_object_option = select.find('option.new_object_option');
    if(new_object_option.length > 0) {
      select.change(function() {
        var settings = {
          add_object_url     : App.extendUrl(select.attr('add_object_url'), { async : 1 }),
          object_name        : select.attr('object_name'),
          add_object_message : select.attr('add_object_message')
        };
      
        var selected_option = select.find('option:selected');
        if(selected_option.attr('class') == 'new_object_option') {
          var object_name = jQuery.trim(prompt(settings.add_object_message, ''));
          if(object_name) {
            var name_used = false;
            select.find('option.object_option').each(function() {
              if($(this).text().toLowerCase() == object_name.toLowerCase()) {
                name_used = $(this).attr('value');
              } // if
            });
            
            if(name_used) {
              select.val(name_used);
              return;
            } // if
            
            select.attr('disabled', true);
            
            var post_data = { 'submitted' : 'submitted' };
            post_data[settings.object_name + '[name]'] = object_name;
            
            $.ajax({
              url : settings.add_object_url,
              type : 'POST',
              data : post_data,
              success : function(response) {
                select.attr('disabled', false);
                
                var new_object_option = $('<option></option>').addClass('object_option').attr('value', response).text(object_name);
                select.find('option.object_option:last').after(new_object_option);
                select.val(response);
              },
              error : function() {
                select.attr('disabled', false);
                
                alert(App.lang('Failed to create new :name based on data you provided. Please try again later', { name : settings.object_name }));
              }
            });
          } // if
        } // if
      });
    } // if
  });
};

/**
 * Select multiple users dialog that can be attached to any control
 *
 * Settings:
 *
 * - exclude_ids  - Array of user ID-s that need to be excluded
 * - selected_ids - Array of user ID-s that are already selected. In some 
 *                  situations we do not know who the selected people are on 
 *                  time of initialization so this parameter can also be a 
 *                  callback function
 * - company_id   - Show only users that belong to this company
 * - project_id   - Show only users that have access to this project
 * - widget_id    - ID of the widget
 * - on_ok        - Callback function called when user hits OK button. Array of 
 *                  selected users is provided as parameter
 */
jQuery.fn.select_multiple_users = function(settings) {
  settings = jQuery.extend({
    exclude_ids  : null,
    selected_ids : null,
    widget_id    : null,
    company_id   : null,
    project_id   : null,
    on_ok        : null
  }, settings);
  
  $(this).click(function() {
    widget_popup = null;
    select_users_table = null;
    
    var select_users_url_data = {
      'widget_id' : settings.widget_id
    };
    
    // We need selected user ID-s
    if(settings.selected_ids) {
      
      // Do we have an array or a callback?
      if(typeof(settings.selected_ids) == 'function') {
        var selected_ids = settings.selected_ids();
      } else {
        var selected_ids = settings.selected_ids;
      } // if
      
      // If we have selected users add them to the list of request parameters
      if(selected_ids.length > 0) {
        select_users_url_data['selected_user_ids'] = [];
        for(var i = 0; i < selected_ids.length; i++) {
          if(selected_ids[i]) {
            select_users_url_data['selected_user_ids'].push(selected_ids[i]);
          } // if
        } // for
        select_users_url_data['selected_user_ids'] = select_users_url_data['selected_user_ids'].join(',');
      } // if
    } // if
    
    // Exclude ID-s
    if(settings.exclude_ids && (settings.exclude_ids.length > 0)) {
      select_users_url_data['exclude_user_ids'] = [];
      for(var i = 0; i < settings.exclude_ids.length; i++) {
        if(settings.exclude_ids[i]) {
          select_users_url_data['exclude_user_ids'].push(settings.exclude_ids[i]);
        } // if
      } // for
      select_users_url_data['exclude_user_ids'] = select_users_url_data['exclude_user_ids'].join(',');
    } // if
    
    if(settings.company_id) {
      select_users_url_data['company_id'] = settings.company_id;
    } // if
    
    if(settings.project_id) {
      select_users_url_data['project_id'] = settings.project_id;
    } // if
    
    var select_users_url = App.data.path_info_through_query_string ? 
      App.extendUrl(App.data.url_base, { 'path_info' : 'select-users' }) : 
      App.data.url_base + '/select-users';
      
    select_users_url = App.extendUrl(select_users_url, select_users_url_data);
    
    App.ModalDialog.show(
      'select_users_popup', // name
      App.lang('Select Users'),  // caption
      $('<p><img src="' + App.data.indicator_url + '" alt="" /> ' + App.lang('Loading...') + '</p>').load(select_users_url, function() {
        
        // We'll need these references later on
        widget_popup = $('#' + settings.widget_id + '_popup');
        selected_users_table = widget_popup.find('td.selected_users div.selected_users_list table');
        
        // These are just use locally
        var available_users = widget_popup.find('select');
        var selected_users_table_wrapper = widget_popup.find('td.selected_users div.selected_users_list');
        
        /**
         * Reindex even / odd classes in selected users table
         *
         * @param void
         * @return null
         */
        var reindex_odd_even_rows = function() {
          var counter = 1;
          selected_users_table.find('td').attr('style', ''); // clear style attributes left by higlightFade
          selected_users_table.find('tr').each(function() {
            $(this).removeClass('even').removeClass('odd').addClass(
              ((counter % 2) == 0) ? 'even' : 'odd'
            );
            counter++;
          });
        };
        
        /**
         * Move selected items from availale list to selected list
         *
         * @param void
         * @return null
         */
        var available_users_to_selected_users = function() {
          var users = available_users.val();
          
          if(users && users.length > 0) {
            for(var i = 0; i < users.length; i++) {
              var option = available_users.find('option[value=' + users[i] + ']');
              var row_id = settings.widget_id + '_user_' + users[i];
              var row = selected_users_table.find('#' + row_id);
              
              if(row.length == 0) {
                var row_class = (selected_users_table.find('tr').length % 2) == 0 ? 'odd' : 'even';
                
                selected_users_table.append('<tr id="' + row_id + '" class="' + row_class + '"><td class="display_name">' +
                App.lang('<span>:username</span> of :company', {
                  'username' : option.text(),
                  'company'  : option.parent().attr('label')
                }) + '</td><td class="remove"><img src="' + App.data.assets_url + '/images/gray-delete.gif" alt="" title="' + App.lang('Remove from the list') + '" /></td></tr>');
                
                row = selected_users_table.find('#' + row_id);
                row.find('td.remove img').click(remove_selected_user_row);
                
                if(selected_users_table_wrapper.css('display') == 'none') {
                  selected_users_table_wrapper.css('display', 'block');
                  widget_popup.find('td.selected_users p.no_users_selected').css('display', 'none');
                } // if
              } // if
              
              row.find('td').highlightFade();
            } // for
          } // if
        };
        
        /**
         * Remove user row from the list when clicked on the image
         *
         * @param void
         * @return null
         */
        var remove_selected_user_row = function(event) {
          $(this).parent().parent().remove();
          
          if(selected_users_table.find('tr').length == 0) {
            selected_users_table_wrapper.css('display', 'none');
            widget_popup.find('td.selected_users p.no_users_selected').css('display', 'block');
          } else {
            reindex_odd_even_rows();
          } // if
          
          event.stopPropagation();
        };
        
        // If we already have a list of selected users
        selected_users_table.find('td.remove img').click(remove_selected_user_row);
        
        // User manipulation
        widget_popup.find('td.divider img').click(available_users_to_selected_users);
        available_users.dblclick(available_users_to_selected_users);
      }), // body
      { 
        buttons : [
          {
            label: App.lang('Ok'),
            callback: function() {
              if(settings.on_ok) {
                var selected_users = [];
                widget_popup.find('td.selected_users div.selected_users_list table tr').each(function() {
                  var row = $(this);
                  selected_users.push({
                    'id'   : parseInt(row.attr('id').substr(settings.widget_id.length + 6)),
                    'name' : row.find('span').text()
                  });
                });
                settings.on_ok(selected_users);
              } // if
              App.ModalDialog.close();
            } // callback            
          },
          {
            label: App.lang('Cancel'),
            callback: null
          }
        ], // buttons
        width: 630
      } // options
    );
    
    return false;
  });
};

/**
 * Select users widget
 */
App.widgets.SelectUsers = function() {
  
  // Public interface
  return {
    
    /**
     * Initialize select users widget
     *
     * @param string widget_id
     * @param string control_name
     * @param string company_id
     * @param string project_id
     * @param Array exclude_ids
     * @return void
     */
    init : function(widget_id, control_name, company_id, project_id, exclude_ids) {
      var widget = $('#' + widget_id);
      
      widget.find('.assignees_button').select_multiple_users({
        'widget_id'    : widget_id,
        'company_id'   : company_id,
        'project_id'   : project_id,
        'selected_ids' : function() {
          var selected_ids = [];
          $('#' + widget_id + ' div.select_users_widget_users input[type=hidden]').each(function() {
            selected_ids.push($(this).attr('value'));
          });
          return selected_ids;
        },
        'exclude_ids'  : exclude_ids,
        'on_ok'        : function(selected_users) {
          widget.find('div.select_users_widget_users').empty();
          
          if(selected_users.length > 0) {
            for(var i = 0; i < selected_users.length; i++) {
              App.widgets.SelectUsers.add_user(widget_id, control_name, selected_users[i]['id'], selected_users[i]['name']);
            } // for
          } else {
            widget.find('div.select_users_widget_users').append('<p class="details">' + App.lang('No users selected') + '</p>');
          } // if
        }
      });
      
      return false;
    },
    
    /**
     * Add new user to the list
     *
     * @param integer widget_id
     * @param string control_name
     * @param integer user_id
     * @param string display_name
     * @return void
     */
    add_user : function(widget_id, control_name, user_id, display_name) {
      var widget = $('#' + widget_id);
      var users_list = widget.find('div.select_users_widget_users ul.users_list');
      
      if(users_list.length == 0) {
        widget.find('div.select_users_widget_users').empty();
        users_list = $('<ul class="users_list"</ul>');
        widget.find('div.select_users_widget_users').append(users_list);
      } // if
      
      users_list.append('<li>' + App.clean(display_name) + '</li>');
      users_list.after('<input type="hidden" name="' + control_name + '[]" value="' + user_id + '" />');
    }
    
  };
  
}();

/**
 * Select projects widget behavior
 */
App.widgets.SelectProjects = function() {
  
  // Public interface
  return {
    
    /**
     * Initialize widget
     *
     * @param String widget_id
     * @param String control_name
     * @param Boolean active_only
     * @param Boolean show_all
     * @param Array exclude_ids
     */
    init : function(widget_id, control_name, active_only, show_all, exclude_ids) {
      var widget = $('#' + widget_id);
      
      widget.find('a.projects_button').click(function() {
        // Prepare popup URL
        var popup_url = App.data.path_info_through_query_string ? 
          App.extendUrl(App.data.url_base, { 'path_info' : 'select-projects' }) : 
          App.data.url_base + '/select-projects';
          
        var popup_data = {
          'widget_id' : widget_id,
          'active_only' : active_only ? 1 : 0,
          'show_all' : show_all ? 1 : 0
        };
        
        var counter = 0;
        $('#' + widget_id + ' div.select_projects_widget_projects input[type=hidden]').each(function() {
          popup_data['selected_ids[' + counter +']'] = $(this).attr('value');
          counter++;
        });
        
        if(exclude_ids && exclude_ids.length > 0) {
          for(var i = 0; i < exclude_ids.length; i++) {
             popup_data['exclude_ids[' + i +']'] = exclude_ids[i];
          } // for
        } // if
        
        popup_url = App.extendUrl(popup_url, popup_data);
        
        var widget_popup = false;
        
        // Show and initialize popup
        App.ModalDialog.show('select_projects_popup', App.lang('Select Projects'), $('<p><img src="' + App.data.indicator_url + '" alt="" /> ' + App.lang('Loading...') + '</p>').load(popup_url, function() {
          widget_popup = $('#' + widget_id + '_popup');
        }), { 
          buttons : [
            {
              label: App.lang('Ok'),
              callback: function() {
                if(widget_popup) {
                  widget.find('div.select_users_widget_users').empty();
                  
                  var checkboxes = widget_popup.find('input:checked');
                  
                  if(checkboxes.length > 0) {
                    widget.find('div.select_projects_widget_projects').empty();
                    
                    checkboxes.each(function() {
                      var checkbox = $(this);
                      var row = checkbox.parent().parent();
                      
                      App.widgets.SelectProjects.add_project(widget_id, control_name, checkbox.attr('value'), row.find('td.name').text());
                    });
                  } else {
                    widget.find('div.select_projects_widget_projects').empty().append('<p class="details">' + App.lang('No projects selected') + '</p>');
                  } // if
                } // if
                App.ModalDialog.close();
              } // callback            
            }, {
              label: App.lang('Cancel'),
              callback: null
            }
          ]
        });
        
        return false;
      });
    },
    
    /**
     * Add project to the list
     *
     * @param String wrapper_id
     * @param String control_name
     * @param Integer project_id
     * @param String project_name
     */
    add_project : function(widget_id, control_name, project_id, project_name) {
      var widget = $('#' + widget_id);
      var projects_list = widget.find('div.select_projects_widget_projects ul.projects_list');
      
      if(projects_list.length == 0) {
        widget.find('div.select_projects_widget_projects').empty();
        projects_list = $('<ul class="projects_list"</ul>');
        widget.find('div.select_projects_widget_projects').append(projects_list);
      } // if
      
      var item_class = 'selected_project_' + project_id;
      if(projects_list.find('li.' + item_class).length == 0) {
        projects_list.append('<li class="' + item_class + '">' + App.clean(project_name) + '</li>');
        projects_list.after('<input type="hidden" name="' + control_name + '[]" value="' + project_id + '" />');
      } // if
    }
    
  };
  
}();

/**
 * Select project permissions widget behavior
 */
App.widgets.SelectProjectPermissions = function() {
  
  // Public interface
  return {
    
    /**
     * Initialize select project permissions widget
     *
     * @param string wrapper_id
     */
    init : function(wrapper_id) {
      // removed obsolete code
      // saving this for future use
    }
    
  };
  
}();

/**
 * Select user project permissions widget behavior
 */
App.widgets.SelectUserProjectPermissions = function() {
  
  // Public interface
  return {
    
    /**
     * Initialize select user project permissions widget
     *
     * @param string wrapper_id
     */
    init : function(wrapper_id) {
      var wrapper = $('#' + wrapper_id);
      wrapper.find('td.radio input').click(function() {
        if($(this).attr('value') == '0') {
          wrapper.find('td div.custom_permissions').show('fast');
        } else {
          wrapper.find('td div.custom_permissions').hide('fast');
        } // if
      });
    }
    
  };
  
}();

/**
 * Object visibility widget
 */
App.widgets.ObjectVisibility = function() {
  
  // Public interface
  return {
    
    /**
     * Initialize object visibility link
     *
     * @param String link_id
     */
    init : function(link_id) {
      var link = $('#' + link_id);
      link.click(function() {
        var dialog_link = App.extendUrl(link.attr('href'), { async : 1 });
        App.ModalDialog.show('object_visibility', link.attr('title'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(dialog_link), {
          buttons : false
        });
        return false
      });
    }
    
  };
  
}();

/**
 * Manage project group behavior
 */
App.system.ManageProjectGroups = function() {
  
  /**
   * Manage project groups tab used to initialize the popup
   *
   * This value is present only on pages where we have project groups tabs
   *
   * @var jQuery
   */
  var manage_project_groups_tab = false;
  
  /**
   * Initialize single project group table row
   *
   * @var jQuery
   */
  var init_row = function(row) {
    var table = row.parent().parent();
    
    // Rename project group
    row.find('td.options a.rename_project_group').click(function() {
      var link = $(this);
      
      // Block additional clicks
      if(link[0].block_clicks) {
        return false;
      } // if
      
      var row = link.parent().parent().addClass('renaming');
      var name_cell = row.find('td.name');
      var name_link = name_cell.find('a');
      
      // Remember start name and start URL
      var start_name = name_link.text();
      var start_url = name_link.attr('href');
      
      link[0].block_clicks = true;
      
      name_cell.empty();
      
      var input = $('<input type="text" />').val(start_name).appendTo(name_cell);
      var save_button = $('<button class="simple">' + App.lang('Save') + '</button>').appendTo(name_cell);
      
      input[0].focus();
      
      // Submission indicator
      var submitting_changes = false;
      
      /**
       * Do submit changes we made
       */
      var submit_changes = function() {
        if(submitting_changes) {
          return;
        } // if
        
        var new_project_group_name = jQuery.trim(input.val());
        if(new_project_group_name == '') {
          input[0].focus();
        } // if
        
        // Check if new project group name is already in use
        var name_used = false;
        table.find('td.name').each(function() {
          var current_row = $(this);
          if(current_row.attr('class').indexOf('renaming') == -1 && current_row.text() == new_project_group_name) {
            name_used = true;
            current_row.highlightFade();
          } // if
        });
        
        if(name_used) {
          return;
        } // if
        
        // And submit the request
        save_button.text(App.lang('Saving ...'));
        input.attr('disabled', 'disabled');
        submitting_changes = true;
        
        $.ajax({
          type : 'POST',
          url : App.extendUrl(link.attr('href'), { async : 1 }),
          data : {
            'submitted' : 'submitted',
            'project_group[name]' : new_project_group_name
          },
          success : function(response) {
            if(manage_project_groups_tab) {
              var project_group_id = row.attr('project_group_id');
              manage_project_groups_tab.parent().find('li').each(function() {
                if($(this).attr('project_group_id') == project_group_id) {
                  $(this).find('a span').text(response);
                } // if
              });
            } // if
            
            name_cell.empty().append($('<a></a>').attr('href', start_url).text(response));
            row.find('td').highlightFade();
            submitting_changes = false;
          },
          error : function() {
            name_cell.empty().append($('<a></a>').attr('href', start_url).text(start_name));
            submitting_changes = false;
            
            alert(App.lang('Failed to rename selected project group'));
          }
        });
        
        link[0].block_clicks = false;
      };
      
      /**
       * Cancel changes
       */
      var cancel_changes = function() {
        name_cell.empty().append($('<a></a>').attr('href', start_url).text(start_name));
        link[0].block_clicks = false;
      };
      
      // Input key handling
      input.keydown(function(e) {
        //e.stopPropagation(); // Don't close dialog!
      }).keypress(function(e) {
        switch(e.keyCode) {
          case 13:
            submit_changes();
            break;
          case 27:
            cancel_changes();
            break;
          default:
            return true;
        } // if
        
        e.stopPropagation();
        return false;
      });
      
      // Button click 
      save_button.click(function() {
        submit_changes();
      });
      
      return false;
    });
    
    // Delete project group
    row.find('td.options a.delete_project_group').click(function() {
      var link = $(this);
      
      // Block additional clicks
      if(link[0].block_clicks) {
        return false;
      } // if
      
      if(confirm(App.lang('Are you sure that you want to delete this project group? There is no undo for this operation!'))) {
        link[0].block_clicks = true;
        
        var row = link.parent().parent();
        var img = link.find('img');
        var old_src = img.attr('src');
        
        img.attr('src', App.data.indicator_url);
        
        $.ajax({
          url     : App.extendUrl(link.attr('href'), { async : 1 }),
          type    : 'POST',
          data    : {'submitted' : 'submitted'},
          success : function(response) {
            if(manage_project_groups_tab) {
              var project_group_id = row.attr('project_group_id');
              manage_project_groups_tab.parent().find('li').each(function() {
                if($(this).attr('project_group_id') == project_group_id) {
                  $(this).remove();
                } // if
              });
            } // if
            
            row.remove();
            if(table.find('tr').length > 0) {
              reindex_even_odd_rows(table);
            } else {
              table.hide();
              $('#manage_project_groups_empty_list').show();
            } // if
          },
          error   : function() {
            img.attr('src', old_src);
          }
        });
      } // if
      
      return false;
    });
  };
  
  /**
   * Reindex table even odd rows
   *
   * @param jQuery wrapper
   */
  var reindex_even_odd_rows = function(table) {
    var counter = 1;
    table.find('tr').each(function() {
      var new_class = counter % 2 ? 'odd' : 'even';
      $(this).removeClass('odd').removeClass('even').addClass(new_class);
      counter++;
    });
  }
  
  // Public interface
  return {
    
    /**
     * Initialize manage project group popup
     *
     * @param String list_item_id
     */
    init : function(list_item_id) {
      manage_project_groups_tab = $('#' + list_item_id); // Remember manage project group tab!
      
      var link = manage_project_groups_tab.find('a');
      
      link.click(function() {
        var open_url = App.extendUrl(link.attr('href'), {
          skip_layout : 1,
          async : 1
        });
        
        App.ModalDialog.show('manage_project_groups_popup', App.lang('Manage Project Groups'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(open_url), {});
        return false;
      });
    },
    
    /**
     * Initialize project groups list behavior
     *
     * @param String wrapper_id
     */
    init_page : function(wrapper_id) {
      var wrapper = $('#' + wrapper_id);
      
      // New project group implementation
      var form = wrapper.find('form');
      var new_project_group_input = form.find('input');
      var new_project_group_icon = form.find('img');
      
      var default_text = App.lang('New Project Group...');
      new_project_group_input.focus(function() {
        if(new_project_group_input.val() == default_text) {
          new_project_group_input.val('');
        } // if
      }).blur(function() {
        if(new_project_group_input.val() == '') {
          new_project_group_input.val(default_text);
        } // if
      }).val(default_text);
      
      // Submitting form indicator
      var submitting_new_project_group = false;
      
      // Click on + image
      new_project_group_icon.click(function() {
        if(!submitting_new_project_group) {
          form.submit();
        } // if
      });
      
      // Create new project group...
      form.submit(function() {
        if(submitting_new_project_group) {
          return false;
        } // if
        
        var new_project_group_name = jQuery.trim(new_project_group_input.val());
        if(new_project_group_name == '') {
          new_project_group_input[0].focus();
        } // if
        
        // Check if new project group name is already in use
        var name_used = false;
        wrapper.find('td.name').each(function() {
          var current_row = $(this);
          if(current_row.text() == new_project_group_name) {
            name_used = true;
            current_row.highlightFade();
          } // if
        });
        
        if(name_used) {
          return false;
        } // if
        
        var old_icon_url = new_project_group_icon.attr('src');
        
        submitting_new_project_group = true;
        new_project_group_input.attr('disabled', 'disabled');
        new_project_group_icon.attr('src', App.data.indicator_url);
        
        $.ajax({
          type : 'POST',
          url : App.extendUrl(form.attr('action'), { async : 1}),
          data : {
            'submitted' : 'submitted',
            'project_group[name]' : new_project_group_name
          },
          success : function(response) {
            $('#manage_project_groups_empty_list').hide();
            
            var new_row = $(response);
            var table = wrapper.find('table');
            
            table.append(new_row).show();
            init_row(new_row);
            reindex_even_odd_rows(table);
            
            new_row.find('td').highlightFade();
            
            new_project_group_input.attr('disabled', '').val('')[0].focus();
            submitting_new_project_group = false;
            new_project_group_icon.attr('src', old_icon_url);
            
            // Add to list of project group tabs
            if(manage_project_groups_tab) {
              var new_tab = $('<li><a><span></span></a></li>');
              
              new_tab.attr('project_group_id', new_row.attr('project_group_id'));
              
              var new_project_group_link = new_row.find('td.name a');
              new_tab.find('a').attr('href', new_project_group_link.attr('href'));
              new_tab.find('span').text(new_project_group_link.text());
              
              manage_project_groups_tab.before(new_tab);
            } // if
          },
          error : function() {
            submitting_new_project_group = false;
            new_project_group_input.attr('disabled', '');
            new_project_group_icon.attr('src', old_icon_url);
            
            alert(App.lang('Failed to create new project group ":name"', { 'name' :  new_project_group_name}));
          }
        });
        
        return false;
      });
      
      wrapper.find('table tr').each(function() {
        init_row($(this));
      }); 
    }
    
  };
  
}();

/**
 * Quick add module
 */
App.system.QuickAdd = function() {
  
  /**
   * wrapper
   */
  var wrapper;
  
  /**
   * Wizzard step 1
   *
   * var jQuery
   */
  var step_1;
  
  /**
   * Wizzard step 2
   *
   * var jQuery
   */
  var step_2;
  
  /**
   * Variable that contains preloader string
   *
   * var String
   */
  var preloader_string;
  
  /**
   * Current object type
   *
   * var String
   */
  var current_object_type;
  
  /**
   * Current project id
   *
   * var integer
   */
  var current_project_id;
  
  /**
   * Tells if step 1 was already initialied
   *
   * var boolean
   */
  var step_1_initialized;

  
  // Public interface
  return {
    
    /**
     * initial initialize
     *
     * @param void
     * @return null
     */
    init : function () {
      wrapper = $('#quick_add');
      step_1 = wrapper.find('#quick_add_step_1');
      step_2 = wrapper.find('#quick_add_step_2');
      step_3 = wrapper.find('#quick_add_step_3');
      preloader_string = '<p class="quick_add_loading"><img src="' + App.data.big_indicator_url + '" alt="" /></p>';
      step_1_initialized = false;
      App.system.QuickAdd.init_step_1();
    },
    
    /**
     * Initialize Step 1 - project chooser
     *
     * @param boolean skip_initial
     * @return null
     */
    init_step_1 : function(skip_initial) {
      step_1.show();
      step_2.hide();
            
      if (App.ModalDialog.isOpen) {
        App.ModalDialog.setWidth(560);
        App.ModalDialog.setTitle(App.lang('Quick Add'));
      } // if
      
      if (!step_1_initialized) {
        if (App.ModalDialog.isOpen) {
          step_1.find('.wizzard_back').click(function () {
            App.ModalDialog.close();
            return false;
          });
        } else {
          step_1.find('.wizzard_back').hide();
        } // if
              
        step_1.find('.continue').click(function () {
          App.system.QuickAdd.init_step_2(
            project_chooser.find('input[checked=true]').val(), // project id
            object_chooser.find('input[checked=true]').val(), // object type
            object_chooser.find('input[checked=true]').attr('quick_add_url'), // quick_add url
            project_chooser.find('input[checked=true]').parent().text(), // project name
            object_chooser.find('input[checked=true]').parent().text() // translated object type
          );
          return false;
        });
        
        var project_chooser = step_1.find('#project_id:first');
        var object_chooser = step_1.find('#object_chooser:first');
        
        project_chooser.find('label').hover(function () {
          $(this).addClass('hover');
        }, function () {
          $(this).removeClass('hover');
        });
               
        project_chooser.find('input').click(function () {
          var previous_object_type = object_chooser.find('input[checked=true]:first');
          if (previous_object_type.length > 0) {
            var previous_object_type = previous_object_type.attr('value');
          } else {
            var cookie_previous_object_type = $.cookie('quick_add_object_type');
            if (cookie_previous_object_type) {
              previous_object_type = cookie_previous_object_type;
            } else {
              previous_object_type = previous_object_type;
            } // if
          } // if
          
          var radio_button = $(this);
          if(radio_button.attr('checked') == true) {
            project_chooser.find('label').removeClass('selected');
            radio_button.parent().addClass('selected');
          } // if
          
          var project_objects = App.data.quick_add_map[radio_button.val()]['permissions'];
          
          object_chooser.find('label').remove();
          for (var counter = 0; counter < project_objects.length; counter++) {
            var type_name =  project_objects[counter]['name'];
            var type_title =  project_objects[counter]['title'];
            
            var label = $('<label></label>').attr('for', 'type_' + type_name);
            var radio = $('<input type="radio" name="object_type" class="input_radio" />').attr({
              'name'          : 'object_type',
              'class'         : 'input_radio',
              'id'            : 'type_' + type_name,
              'value'         : type_name,
              'quick_add_url' : App.data.quick_add_urls[type_name]
            }).appendTo(label);
            
            label.append(ucfirst(type_title)).appendTo(object_chooser);
          } // for
          
          object_chooser.find('label').hover(function () {
            $(this).addClass('hover');
          }, function () {
            $(this).removeClass('hover');
          });
          
          object_chooser.find('input').click(function () {
            var radio_button = $(this);
            if (radio_button.attr('checked') == true) {
              object_chooser.find('label').removeClass('selected');
              radio_button.parent().addClass('selected');
            } // if       
          }).keydown(function(event) {
            if ((event.keyCode == 13) || (event.keyCode == 32)) {
              App.system.QuickAdd.init_step_2(
                project_chooser.find('input[checked=true]').val(), // project id
                object_chooser.find('input[checked=true]').val(), // object type
                object_chooser.find('input[checked=true]').attr('quick_add_url'), // quick_add url
                project_chooser.find('input[checked=true]').parent().text(), // project name
                object_chooser.find('input[checked=true]').parent().text() // translated object type
              );
            } // if
            if (event.keyCode == 9) {
              step_1.find('.wizzard_continue').focus();
            } // if
          });
          
          if (previous_object_type) {
            previous_object_type = object_chooser.find('input[value='+previous_object_type+']:first');
            if (previous_object_type.length > 0) {
              previous_object_type.attr('checked', 'checked').click();
            } else {
              object_chooser.find('input:first').attr('checked', 'checked').click();
            } // if
          } else {
            object_chooser.find('input:first').attr('checked', 'checked').click();
          } // if
          
        }).keydown(function(event) {
          if ((event.keyCode == 13) || (event.keyCode == 32)) {
            object_chooser.find('input[checked=true]').focus();
          } // if
        });
        
        if (!skip_initial) {
          var initial_project;
          if (App.data.active_project_id && (App.data.active_project_id > 0)) {
            initial_project = project_chooser.find('#quickadd_project_'+App.data.active_project_id);
          } else {
            initial_project = project_chooser.find('input:first');
          } // if
          initial_project.attr('checked', 'checked').focus().click();
        } // if
        step_1_initialized = true;
      } // if
    },
    
    /**
     * Initialize Step 2 - quick add form
     *
     * @param integer project_id
     * @param string object_type
     * @return null
     */
    init_step_2 : function (project_id, object_type, object_add_url, project_name, object_translated_type) {
      step_1.hide();
      step_2.show();
      
      current_project_id = project_id;
      current_object_type = object_type;
      
      if (!object_translated_type) {
        object_translated_type = object_type
      } // if
      
      $.cookie('quick_add_object_type', object_type);
      
      object_add_url = object_add_url.replace(/\-PROJECT\-ID\-/, project_id);
           
      step_2.html(preloader_string);
      var preloader = step_2.find('p.quick_add_loading');
      
      $.ajax({
        url : object_add_url,
        success : function (response) {
          step_2.html(response);
          if (App.ModalDialog.isOpen) {
            App.ModalDialog.setTitle(App.lang('Quick Add :object_type in :project_name', {'object_type' : ucfirst(object_translated_type), 'project_name' : project_name}));
          } // if
          App.system.QuickAdd.init_object_form();
        },
        error : function (response) {
          App.system.QuickAdd.init_step_1(true);
        }
      });
    },
    
    init_object_form : function () {
      var object_form = step_2.find('form');
      object_form.find('input:first').focus();
      
      // flush behaviour
      step_2.find('.flash').click(function () {
        $(this).hide('fast');
      });
      
      // back button
      step_2.find('.wizzard_back').click(function () {
        App.system.QuickAdd.init_step_1(true);
        return false;
      });
      
      object_form.submit(function () {
        step_2.find('.flash').hide();
        step_2.prepend(preloader_string);
        var preloader = wrapper.find('.quick_add_loading');
        object_form.hide();

        object_form.ajaxSubmit({
          success : function (response) {
            step_2.html(response);
            App.system.QuickAdd.init_object_form();
          },
          error : function (response) {
            object_form.show();
            preloader.remove();
            alert(response.responseText);
          }
        });

        return false;
      });
    }
  };
  
}();

/**
 * String list behavior
 */
App.system.StringList = function() {
  
  /**
   * Init specific row
   *
   * @param jQuery row
   * @return void
   */
  var init_row = function(row) {
    var wrapper = row.parent().parent();
    
    row.find('td.remove a').click(function() {
      row.remove();
      reindex_row_data(wrapper);
    });
  };
  
  /**
   * Reindex row numbers
   *
   * @param jQuery wrapper
   * @return void
   */
  var reindex_row_data = function(wrapper) {
    var counter = 1;
    wrapper.find('tr.item').each(function() {
      var row = $(this);
      row.removeClass('even').removeClass('odd');
      if((counter % 2) > 0) {
        row.addClass('odd');
      } else {
        row.addClass('even');
      } // if
      row.find('td.num').text('#' + counter);
      
      counter++;
    });
  };
  
  /**
   * Create a new list item
   *
   * @param jQuery wrapper
   * @param string item_title
   * @param string input_name
   * @return void
   */
  var add_item_to_the_list = function(wrapper, item_title, input_name) {
    if(item_title == '') {
      return false;
    } else if(jQuery.trim(item_title).length < 3) {
      alert(App.lang('Project group name should be at least 3 characters long'));
      return false;
    } // if
    
    var exists = false;
    
    // Check if value already exists
    wrapper.find('tr.item').each(function() {
      var row = $(this);
      
      if(row.find('input[type=hidden]').val().toLowerCase() == item_title.toLowerCase()) {
        exists = true;
        row.find('td.value').highlightFade();
      }
    });
    
    // Add an item
    if(exists) {
      return false;
    } else {
      var row = $('<tr class="item">' +
        '<td class="num">#</td>' +
        '<td class="value"><span></span> <sup>' + App.lang('Unsaved') + '</sup> <input type="hidden" /></td>' +
        '<td class="remove"><a href="javascript: return false;"><img src="' + App.data.assets_url + '/images/gray-delete.gif" alt="" /></a></td>' +
      '</tr>');
      
      row.find('td.value span').text(item_title);
      row.find('input[type=hidden]').val(item_title).attr('name', input_name + '[]');
      
      wrapper.find('table').append(row);
      
      init_row(row);
      reindex_row_data(wrapper);
      
      row.find('td').highlightFade();
      
      return true;
    } // if
  };
  
  // Public interface
  return {
    
    /**
     * Initialize string list
     *
     * @param string wrapper_id
     * @return void
     */
    init : function(wrapper_id, name) {
      var wrapper = $('#' + wrapper_id);
      
      var add_item_input = wrapper.find('input.add_list_item_name');
      
      var default_add_item_input_text = add_item_input.val();
      
      var handle_submission = function() {
        add_item_to_the_list(wrapper, add_item_input.val(), name);
        add_item_input.val('');
        return false;
      };
      
      wrapper.find('input.add_list_item_button').click(function(e) {
        if(add_item_input.val() == default_add_item_input_text) {
          add_item_input[0].focus();
        } else {
          handle_submission();
        } // if
        e.preventDefault();
      });
      
      add_item_input.keypress(function(e) {
        if(e.which == 13) {
          handle_submission();
          e.preventDefault();
        } // if
      });
      
      // Focus / blur behavior
      add_item_input.focus(function() {
        if(add_item_input.val() == default_add_item_input_text) {
          add_item_input.val('');
        }
      }).blur(function() {
        if(add_item_input.val() == '') {
          add_item_input.val(default_add_item_input_text);
        }
      });
      
      // Init rows
      wrapper.find('tr.item').each(function() {
        init_row($(this));
      });
    }
    
  };
  
}();

/**
 * Dashboard sections behavior implementation
 */
App.widgets.IconPicker = function() {
  
  /**
   * icon_container
   *
   * @var jQuery
   */
  var icon_container;
  
  /**
   * icon_container
   *
   * @var jQuery
   */
  var picker_url;
  
  // Public interface
  return {
    
    /**
     * Initialize icon picker button
     *
     */
    init : function (icon_picker, icon_to_update, icon_title) {
      icon_container = $('#' + icon_to_update);
      picker_url = App.extendUrl(icon_container.attr('href'), {async : 1, skip_layout : 1});
            
      icon_container.click(function () {
        App.ModalDialog.show('icon_picker', icon_title, $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(picker_url, function () {
          App.widgets.IconPicker.upload_form(icon_picker, icon_to_update);
        }), {
          buttons : false
        });
        return false;
      });
    },
    
    /**
     *  initialize upload icon form
     *
     */
    upload_form : function (container_id, icon_to_update) {
      var upload_container = $('#'+container_id);
      var upload_container_form = upload_container.find('form');
      
      if (icon_to_update) {
        $('#'+icon_to_update+' img').attr('src', upload_container.find('#updated_icon img').attr('src'));
      } // if
      
      // submit upload form assync
      upload_container_form.submit(function () {
        upload_container.block();
        upload_container_form.ajaxSubmit({
          url : App.extendUrl(upload_container_form.attr('action'), {async : 1, skip_layout : 1}),
          type : 'post',
          success : function(response) {
            $('#'+icon_to_update+' img').attr('src', $(response).find('#updated_icon img').attr('src'));
            App.ModalDialog.close();
          },
          error : function (response) {
            upload_container.unblock();
            alert(response.statusText);
          }
        })
        return false;
      });
          
      // delete icon
      upload_container_form.find('.details a.delete_current:eq(0)').click(function () {
        var delete_url = App.extendUrl($(this).attr('href'), {async : 1, skip_layout : 1});
        upload_container.block();
        $.ajax({
          url: delete_url,
          type: 'post',
          data: 'submitted=submitted',
          success : function (response) {
            eval ('response = ' + response);
            if (typeof response == 'object') {
              $('#'+icon_to_update+' img').attr('src', response.icon);
              App.ModalDialog.close();
            } // if
          }
        });
        return false;
      });
    }
    
  }
}();

/**
 * Mark all new objects as read
 */
App.system.MarkAllAsRead = function() {
  
  // Public interface
  return {
    
    /**
     * Mark all new object as read
     *
     * @param String wrapper_id
     */
    init : function(wrapper_id) {
      var wrapper = $('#' + wrapper_id);
      
      wrapper.find('#mark_all_read_link').click(function () {
        var anchor = $(this);
        
        wrapper.hide();
        wrapper.before('<p class="dashboard_sections_loading" id="new_since_last_visit_preloader"><img src="' + App.data.big_indicator_url + '" alt="" /></p>')
        
        $.ajax({
          type: 'post',
          data: { 
            'submitted' : 'submitted' 
          },
          url: App.extendUrl(anchor.attr('href'), {
            async : 1
          }),
          success : function () {
            $('#dashboard_section_recent_activities a:first').click();
            $('#dashboard_section_new_updated').remove();
            wrapper.remove();
          },
          error : function () {
            $('#new_since_last_visit_preloader').remove();
            wrapper.show();
          }
        })
        return false;
      });
    }
  }
  
}();

/**
 * Send welcome message behavior
 */
App.system.SendWelcomeMessage = function() {
  
  // Public interface
  return {
    
    /**
     * Initialize welcome message form
     *
     * @param String wrapper_id
     */
    init : function(wrapper_id) {
      var wrapper = $('#send_welcome_message');
      var form = wrapper.find('form');
      
      form.submit(function() {
        form.block('Sending...');
      
        $.ajax({
          url : App.extendUrl(form.attr('action'), { async : 1 }),
          type : 'post',
          data : {
            'submitted' : 'submitted',
            'welcome_message[message]' : form.find('textarea').val()
          },
          success : function(response) {
            form.unblock();
            wrapper.empty().append($('<p></p>').text(response));
          },
          error : function(response) {
            form.unblock();
            wrapper.empty().append($('<p></p>').text(App.lang('Failed to send welcome message. Please try again later')));
          }
        });
        
        return false;
      });
    }
    
  };
  
}();

/**
 * Role permission value behavior
 */
App.system.RolePermissionValue = function() {
  
  // Public interface
  return {
    
    /**
     * Initialize role permission value behavior for a single checkbox
     *
     * @param String checkbox_id
     */
    init : function(checkbox_id) {
      var checkbox = $('#' + checkbox_id);
      var cell = checkbox.parent();
      
      checkbox.click(function() {
        checkbox.hide();
        cell.append('<img src="' + App.data.indicator_url + '" />');
        
        $.ajax({
          url  : App.extendUrl(checkbox.attr('set_permission_value_url'), { async : 1 }),
          type : 'POST',
          data : {
            submitted : 'submitted',
            value : this.checked ? 1 : 0
          },
          success : function() {
            cell.find('img').remove();
            checkbox.show();
            return true;
          },
          error : function() {
            cell.find('img').remove();
            checkbox.show();
            
            alert(App.lang('Failed to set value of this role'));
            
            return false;
          }
        });
      });
    }
    
  };
  
}();

/** File: modules/resources/javascript/main.js **/

App.resources = {
  controllers : {},
  models      : {}
};

/**
 * Assignments controller behavior
 */
App.resources.controllers.assignments = {
  
  /**
   * Assignments index page
   */
  index : function() {
    $(document).ready(function() {
      $('#assignments_filter_select select').change(function() {
        var filter_url = $(this).val();
        if(filter_url != location.href) {
          $(this).after(' ' + App.lang('Loading ...')).attr('disabled', 'disabled');
          location.href = filter_url;
        } // if
      });
      
      $('#assignments_filter_options a').hover(function() {
        $('#assignments_filter_options span.tooltip').text($(this).attr('title'));
      }, function() {
        $('#assignments_filter_options span.tooltip').text('');
      }); 
      
      $('#toggle_filter_details').click(function() {
        $('#assignments_filter_details').toggle('fast');
        return false;
      });
      
      // Complete / Move to trash tasks
      $('#assignments a.complete_assignment, #assignments a.remove_assignment').click(function() {
        var link = $(this);
        
        // Block additional clicks
        if(link[0].block_clicks) {
          return false;
        } else {
          link[0].block_clicks = true;
        } // if
        
        var img = link.find('img');
        var old_src = img.attr('src');
        
        img.attr('src', App.data.indicator_url);
        
        $.ajax({
          url     : link.attr('href'),
          type    : 'POST',
          data    : {'submitted' : 'submitted'},
          success : function(response) {
            link.parent().parent().remove();
            
            var counter = 1;
            $('#assignments tr.assignment_row').each(function() {
              var new_class = counter % 2 == 1 ? 'odd' : 'even';
              $(this).removeClass('even').removeClass('odd').addClass(new_class);
              counter++;
            });
          },
          error   : function() {
            img.attr('src', old_src);
            link[0].block_clicks = false;
          }
        });
        
        return false;
      });
    });
  }
  
}

/**
 * Select assignees widget
 */
App.widgets.SelectAssignees = function() {
  
  /**
   * Update value of hidden owner_id field based on selected user
   *
   * @param string widget_id
   * @param string control_name
   * @return undefined
   */
  var update_responsible_user = function(widget_id, control_name) {
    var widget = $('#' + widget_id);
    var users_list = widget.find('div.select_assignees_widget_users ul.users_list');
    
    if(users_list.length == 0) {
      widget.find('input.responsible_assignee_id').remove();
    } else {
      var responsible_user = users_list.find('li.responsible');
      var responsible_user_id = 0;
      
      if(responsible_user.length == 0) {
        var responsible_user = users_list.find('li:first');
        responsible_user.addClass('responsible');
        responsible_user_id = responsible_user.attr('user_id');
      } else {
        var responsible_user_id = responsible_user.attr('user_id');
      } // if
      
      var hidden_field = widget.find('input.responsible_assignee_id');
      if(hidden_field.length > 0) {
        hidden_field.attr('value', responsible_user_id);
      } else {
        hidden_field = users_list.after('<input type="hidden" name="' + control_name + '[1]" value="' + responsible_user_id + '" class="responsible_assignee_id" />');
      } // if
    } // if
  };
  
  /**
   * Initialize behavior of user list item in an user list
   *
   * @param string widget_id
   * @param string control_name
   * @return undefined
   */
  var init_user_list_items = function(widget_id, control_name) {
    var users_list = $('#' + widget_id + ' div.select_assignees_widget_users ul.users_list');
    var list_items = users_list.find('li');
    
    list_items.hover(function() {
      $(this).attr('title', App.lang('Set as responsible')).addClass('hovered');
    }, function() {
      $(this).attr('title', '').removeClass('hovered');
    }).click(function() {
      list_items.removeClass('responsible');
      $(this).addClass('responsible');
      update_responsible_user(widget_id, control_name);
    });
  };
  
  // Public interface
  return {
    
    /**
     * Initialize select users widget
     *
     * @param string widget_id
     * @param string control_name
     * @param string company_id
     * @param string project_id
     * @param Array exclude_ids
     * @return void
     */
    init : function(widget_id, control_name, company_id, project_id, exclude_ids) {
      var widget = $('#' + widget_id);
      
      widget.find('.assignees_button').select_multiple_users({
        'widget_id'    : widget_id,
        'company_id'   : company_id,
        'project_id'   : project_id,
        'selected_ids' : function() {
          var selected_ids = [];
          $('#' + widget_id + ' div.select_assignees_widget_users input[type=hidden]').each(function() {
            selected_ids.push($(this).attr('value'));
          });
          return selected_ids;
        },
        'exclude_ids'  : exclude_ids,
        'on_ok'        : function(selected_users) {
          var responsible_user_id = widget.find('input.responsible_assignee_id').val();
          
          widget.find('div.select_assignees_widget_users').empty();
          
          if(selected_users.length > 0) {
            for(var i = 0; i < selected_users.length; i++) {
              App.widgets.SelectAssignees.add_user(widget_id, control_name, selected_users[i]['id'], selected_users[i]['name'], responsible_user_id == selected_users[i]['id']);
            } // for
            
            // Done adding users
            update_responsible_user(widget_id, control_name);
            init_user_list_items(widget_id, control_name);
          } else {
            widget.find('div.select_assignees_widget_users').append('<p class="details">' + App.lang('No users selected') + '</p>');
          } // if
        } // function
      });
      
      return false;
    },
    
    /**
     * Add new user to the list
     *
     * @param integer widget_id
     * @param string control_name
     * @param integer user_id
     * @param string display_name
     * @param boolean is_owner
     * @return void
     */
    add_user : function(widget_id, control_name, user_id, display_name, is_owner) {
      var widget = $('#' + widget_id);
      var users_list = widget.find('div.select_assignees_widget_users ul.users_list');
      
      if(users_list.length == 0) {
        widget.find('div.select_assignees_widget_users').empty();
        users_list = $('<ul class="users_list"</ul>');
        widget.find('div.select_assignees_widget_users').append(users_list);
      } // if
      
      var list_item_class = is_owner ? 'responsible' : 'not_responsible'; 
      
      users_list.append('<li class="' + list_item_class + '" user_id="' + user_id + '">' + App.clean(display_name) + '</li>');
      users_list.after('<input type="hidden" name="' + control_name + '[0][]" value="' + user_id + '" />');
    },
    
    /**
     * When we are done adding users we should call this method to initialize 
     * widget behaviro
     *
     * @param string widget_id
     * @param string control_name
     * @return undefined
     */
    done_adding_users : function(widget_id, control_name) {
      update_responsible_user(widget_id, control_name);
      init_user_list_items(widget_id, control_name);
    }
    
  };
  
}();

/**
 * Select assignees widget
 */
App.widgets.SelectAsigneesInlineWidget = function () {
  /**
   * Wrapper that containts this widget
   *
   * @var jQuery
   */
  var wrapper;
  
  /**
   * Hidden field that contains value of responsible person
   *
   * @var jQuery
   */
  var responsible_field;
  
  /**
   * Block that contains information about currently responsible person
   *
   * @var jQuery
   */
  var responsible_information_block;
  
  /**
   * Enable responsible person
   *
   * @var boolean
   */
  var enable_responsible;
  
  /**
   * Sets current checkbox to be responsible one
   * 
   * @param jQuery checkbox
   * @return null
   */
  var set_as_responsible = function (checkbox) {
    var responsible_span = checkbox.next();
    if (!checkbox.attr('checked')) {
      checkbox.attr('checked','checked');
      checkbox.change();
    } //if
    wrapper.find('span.responsible_setter.responsible').removeClass('responsible');
    responsible_span.addClass('responsible');
    responsible_field.val(checkbox.val());
    responsible_information_block.html(App.lang('<strong>:user</strong> is responsible', {
      'user' : responsible_span.html()
    }));
    responsible_information_block.find('strong').highlightFade();
  };
  
  /**
   * Sets current checkbox as not responsible
   * 
   * @param jQuery checkbox
   * @return null
   */
  var set_as_not_responsible = function (checkbox) {
    var responsible_span = checkbox.next();
    responsible_span.removeClass('responsible');
    
    var first_checked = wrapper.find('.company_user input:checked:first');
    if (first_checked.length < 1) {
      responsible_field.val('');
      responsible_information_block.html(App.lang('No one is responsible'));
    } else {
      set_as_responsible(first_checked);
    } // if
  };
  
  return {
    /**
     * Function that handles all widget behaviour
     *
     * @param string wrapper_id
     * @param boolean wrapper_id
     */
    init  : function (wrapper_obj, wrapper_id, choose_responsible, responsible_id) {
      wrapper = wrapper_obj;
      enable_responsible = choose_responsible;
      if (enable_responsible) {
        responsible_field = wrapper.find('#'+wrapper_id+'_responsible');
        responsible_information_block = wrapper.find('.select_asignees_inline_widget_responsible_block .placeholder');
      } // if
           
      // handle company checkboxes behaviour
      wrapper.find('.company_name input').click(function () {
        var company_checkbox = $(this);
        var company_group = company_checkbox.parents('.user_group:first');
        
        // set all user checkbox states to current company checkbox state
        company_group.find('.company_user input').attr('checked', company_checkbox.attr('checked'));
        
        if (enable_responsible) {
          if (!company_checkbox.attr('checked')) {
            // checks if there is responsible in group and if yes make it not responsible
            var group_responsible = company_group.find('.company_user input').next('.responsible');
            if (group_responsible.length > 0) {
              set_as_not_responsible(group_responsible.prev());
            } // if
          } else {
            // check if there is a responsible person and if not, it uses first in the group as responsible
            if (wrapper.find('.company_user input').next('.responsible').length == 0) {
              set_as_responsible(company_group.find('.company_user input:first'));
            } // if
          } // if
          
        } // if
        
        company_checkbox.blur();
      });
      
      // handle user checkboxes behaviour
      wrapper.find('.company_user input').change(function () {
        var company_user = $(this);
        var responsible_span = company_user.next();
        
        var company_checkbox = company_user.parents('.user_group:first').find('.company_name input:first');
        
        var total_group_checkboxes_count = company_user.parents('.user_group:first').find('.company_user input').length;
        var checked_group_checkboxes_count = company_user.parents('.user_group:first').find('.company_user input:checked').length;
        
        // if all checkboxes in group are checked, we need to check company checkbox, otherwise we need to uncheck it
        if (total_group_checkboxes_count == checked_group_checkboxes_count) {
          company_checkbox.attr('checked', 'checked');
        } else {
          company_checkbox.attr('checked', '');
        } // if
        
        if (enable_responsible) {
          // if uncheck responsible person it becomes not responsible
          if (!company_user.attr('checked') && responsible_span.is('.responsible')) {
            set_as_not_responsible(company_user);
          } // if
          
          // if you check assignee and, he is only assignee it automatically becomes responsible one
          if (company_user.attr('checked') && (wrapper.find('.company_user input:checked').length == 1)) {
            set_as_responsible(company_user);
          } // if
        } // if
        
        company_user.blur();
      });
      
      if (enable_responsible) {
        // if enable_responsible is true we need to setup responsible person chooser
        wrapper.find('.responsible_setter').hover(function () {
          $(this).css('text-decoration', 'underline');
        }, function () {
          $(this).css('text-decoration', 'none');
        }).click(function () {
          var this_span = $(this);
          var this_checkbox = this_span.prev();
          set_as_responsible(this_checkbox);
        });
      } else {
        // otherwise we need to simulate label clicking
        wrapper.find('.responsible_setter').click(function () {
          var this_span = $(this);
          var this_checkbox = this_span.prev();
          if (this_checkbox.attr('checked')==false) {
            this_checkbox.attr('checked','checked');
          } else {
            this_checkbox.attr('checked','');
          } // if
          this_checkbox.change();
        });
      } // if
      
      // initial setup
      wrapper.find('.user_group').each(function () {
        $(this).find('.company_user input:first').change();
      });
      
      if (enable_responsible && responsible_id) {
        var init_responsible = wrapper.find('#' + wrapper_id + '_user_' + responsible_id + ':first');
        if (init_responsible.length > 0) {
          set_as_responsible(init_responsible);
        } // if
      } // if
      //$_select_assignees_responsible
    }
  }
}();

/**
 * Send reminder behavior
 */
App.widgets.SendReminder = function() {
  
  /**
   * Public interface
   */
  return {
    
    /**
     * Initialize send reminder link if present
     */
    init : function() {
      $('li.send_reminder a').click(function() {
        var link = $(this);
        
        var reminder_url = App.extendUrl(link.attr('href'), { 
          skip_layout : 1 
        });
        
        App.ModalDialog.show(
          'send_reminder_users', // name
          App.lang('Remind'),  // caption
          $('<p><img src="' + App.data.indicator_url + '" alt="" /> ' + App.lang('Loading...') + '</p>').load(reminder_url, function() {
            var form = $('#send_reminder_users_form');
            form.submit(function() {
              form.attr('action', form.attr('action') + '&skip_layout=1');
              form.block(App.lang('Working...'));
              form.ajaxSubmit({
                success : function(response) {
                  form.after(response);
                  form.remove();
                }
              });
              return false;
            });
          }), // body
          {
            buttons : false,
            width: 500
          }
        );
        return false;
      });
    },
    
    /**
     * Initialize form behavior
     */
    init_form : function() {
      var form = $('#send_reminder_users_form');
            
      /**
       * Change details in who radio group
       */
      var change_who = function() {
        form.find('div.content_wrapper').hide();
        form.find('div.label_wrapper input:checked').each(function() {
          $(this).parent().parent().find('div.content_wrapper').show();
        });
      };
      
      form.find('div.label_wrapper input').click(change_who);
      change_who();
    }
    
  };
  
}();

/**
 * Add / Edit assignments filter form behavior
 */
App.resources.AssignmentFilterForm = function() {
  
  /**
   * Form instance
   *
   * @var jQuery
   */
  var form;
  
  // Public interface
  return {
    
    /**
     * Initialize assignment filter form
     *
     * @param string form_id
     * @param string partial_generator_url
     * @return void
     */
    init : function(form_id, partial_generator_url) {
      form = $('#' + form_id);
      
      form.find('select.filter_async_select').change(function() {
        var select = $(this);
        var row = select.parent().parent();
        var cell_additional = row.find('td.filter_select_additional');
        var option = select.find('option[value=' + select.val() + ']');
        
        if(option.attr('class') == 'filter_async_option') {
          cell_additional.each(function() {
            cell_additional.empty().append('<img src="' +  App.data.indicator_url + '" alt="" />');
            $.ajax({
              url     : partial_generator_url,
              type    : 'GET',
              data    : {
                'select_box'   : select.attr('name'),
                'option_value' : option.val()
              },
              success : function(response) {
                cell_additional.empty();
                cell_additional.append(response);
              },
              error   : function() {
                cell_additional.empty();
              }
            });
          })
        } else {
          cell_additional.empty();
        }
      })
    }
    
  };
  
}();

/**
 * Object assignments form behavior
 */
App.resources.ObjectAttachments = function() {
  
  // Public interface
  return {
    
    /**
     * Initialize behavior
     *
     * @param string wrapper_id
     */
    init : function(wrapper_id) {
      var wrapper = $('#' + wrapper_id);
      
      /**
       * File details
       */
      wrapper.find('a.show_file_details').click(function() {
        var brief = wrapper.find('div.brief_files_view');
        var full = wrapper.find('div.full_files_view')
        
        if(brief.css('display') == 'none') {
          full.css('display', 'none');
          brief.css('display', 'block');
          
          $(this).text(App.lang('Show Details'));
        } else {
          brief.css('display', 'none');
          full.css('display', 'block');
          
          $(this).text(App.lang('Hide Details'));
        }
        
        return false;
      });
      
      /**
       * Reindex table rows
       */
      var reindex_odd_even_rows = function() {
        var counter = 1;
        wrapper.find('tr').each(function() {
          var row = $(this);
          row.removeClass('even').removeClass('odd');
          if(counter % 2 == 1) {
            row.addClass('odd');
          } else {
            row.addClass('even');
          } // if
          counter++;
        });
      };
      
      /**
       * Prepare details row
       */
      var prepare_details_row = function(row) {
        row.find('td.options a').click(function() {
          var link = $(this);
          
          if (!confirm(App.lang('Are you sure that you want to permanently remove this attachment? There is no Undo!'))) {
            return false;
          } // if
          
          // Block additional clicks
          if(link[0].block_clicks) {
            return false;
          } else {
            link[0].block_clicks = true;
          } // if
          
          var img = link.find('img');
          var old_src = img.attr('src');
          
          img.attr('src', App.data.indicator_url);
          
          $.ajax({
            url     : App.extendUrl(link.attr('href'), {async: 1}),
            type    : 'POST',
            data    : {'submitted' : 'submitted'},
            success : function() {
              var row = link.parent().parent();
              wrapper.find('li.attachment_' + row.attr('attachment_id')).remove(); // remove from brief view
              row.remove(); // remove from detail
              
              reindex_odd_even_rows();
              if(wrapper.find('table tr').length < 1) {
                wrapper.find('div.body').append('<p class="details center files_moved_to_trash">' + App.lang('All files moved to Trash') + '</p>');
              } // if
            },
            error   : function() {
              img.attr('src', old_src);
            }
          });
          
          return false;
        });
      };
      
      // Initialize rows
      wrapper.find('div.full_files_view table tr').each(function() {
        prepare_details_row($(this));
      });
      
      // Prepare form behavior
      var form_wrapper = wrapper.find('div.attach_another_file');
      var form = form_wrapper.find('form');
      
      form.submit(function() {
        var initial_action = form.attr('action');
        
        // Alter form action
        form.attr('action', App.extendUrl(initial_action, { async : 1 }));
        
        var list = wrapper.find('div.brief_files_view ul');
        var details = wrapper.find('div.full_files_view table tbody');
        
        if(UniForm.is_valid(form)) {
          form_wrapper.block(App.lang('Working...'));
          form.ajaxSubmit({
            success : function(response) {
              // Lets get rid of the notification if we already removed all 
              // attachments
              wrapper.find('p.files_moved_to_trash').remove();
              
              // jQuery acts a bit weird here. Insted of providing response as 
              // a string it tries to append it to the BODY so some markup 
              // (tr, td) gets discarded. That is why we need to use temp 
              // table in order to get properly marked-up row
              var tmp_table = $(response);
              var row = tmp_table.find('tr');
              
              details.append(row);
              tmp_table.remove();
              
              var row_class = details.find('tr').length % 2  == 1 ? 'odd' : 'even';
              
              row.addClass(row_class);
              prepare_details_row(row);
              row.find('td').highlightFade({
                complete : function() {
                  $(this).attr('style', '');
                }
              });
              
              // Now, lets create brief list entry (extract data from row)
              var brief = $('<li class="attachment_' + row.attr('attachment_id') + '"></li>');
              
              row.find('a.filename').clone().appendTo(brief);
              brief.append(' <span class="details">(' + row.find('span.filesize').text() + ')</span>');
              list.append(brief);
              brief.highlightFade();
              
              // Unblock and reset
              form_wrapper.unblock();
              form[0].reset();
            },
            error : function() {
              form_wrapper.unblock();
              form[0].reset();
            }
          });
        } // if
        
        // Revert back to initial action
        form.attr('action', initial_action);
        return false;
      });
      
      /**
       * Attach another file
       */
      wrapper.find('a.attach_another_file').click(function() {
        var link = $(this);
        
        // Toggle section options
        if(form_wrapper.css('display') == 'block') {
          form_wrapper.css('display', 'none');
          link.text(App.lang('Attach Another File'));
        } else {
          form_wrapper.css('display', 'block');
          link.text(App.lang('Done Adding Files'));
        } // if
        
        return false;
      });
    }
  };
}();

/**
 * Attach files widget behavior
 */
App.resources.AttachFiles = function() {
  
  // Public interface
  return {
    
    /**
     * Initialize widget behavior
     *
     * @param String wrapper_id
     */
    init : function(wrapper_id) {
      var wrapper = $('#' + wrapper_id);
      var name_counter = 1;
      
      var inputs_wrapper = $('<div class="attach_files_inputs"></div>').prependTo(wrapper);
      var max_files = parseInt(wrapper.attr('max_files'));
      
      if(max_files > 1) {
        var attach_another_wrapper = $('<p class="attach_files_add_another"></p>');
        inputs_wrapper.after(attach_another_wrapper);
        $('<div class="clear"></div>').insertAfter(attach_another_wrapper);
        
        var attach_another = $('<a href="#" class="button_add">' + App.lang('Attach Another File') + '</a>').appendTo(attach_another_wrapper).click(function() {
          add_input();
          show_hide_attach_another();
          return false;
        });
      } // if
      
      /**
       * Add single file input to the list of inputs
       */
      var add_input = function() {
        var input_wrapper = $('<div class="attach_files_input"></div>');
        var input = $('<input type="file" name="attach_from_files_file_' + name_counter +'" />').appendTo(input_wrapper);
        name_counter++;
        if(max_files > 1) {
          var remove_link = $('<a href="#"><img src="' + App.data.assets_url + '/images/dismiss.gif" /></a>').appendTo(input_wrapper).click(function() {
            if(inputs_wrapper.find('div.attach_files_input').length > 1) {
              input_wrapper.remove();
              show_hide_attach_another();
            } // if
            return false;
          });
        } // if
        
        inputs_wrapper.append(input_wrapper); // and add...
      };
      
      var show_hide_attach_another = function() {
        if(inputs_wrapper.find('div.attach_files_input').length >= max_files) {
          attach_another_wrapper.hide();
        } else {
          attach_another_wrapper.show();
        } // if
      };
      
      add_input(); // add input
    }
    
  };
  
}();

/**
 * Manage categories behavior
 */
App.resources.ManageCategories = function() {
  
  /**
   * Manage categories tab used to initialize the popup
   *
   * This value is present only on pages where we have categories tabs
   *
   * @var jQuery
   */
  var manage_categories_tab = false;
  
  /**
   * Initialize single categories table row
   *
   * @var jQuery
   */
  var init_row = function(row) {
    var table = row.parent().parent();
    
    // Rename category
    row.find('td.options a.rename_category').click(function() {
      var link = $(this);
      
      // Block additional clicks
      if(link[0].block_clicks) {
        return false;
      } // if
      
      var row = link.parent().parent().addClass('renaming');
      var name_cell = row.find('td.name');
      var name_link = name_cell.find('a');
      
      // Remember start name and start URL
      var start_name = name_link.text();
      var start_url = name_link.attr('href');
      
      link[0].block_clicks = true;
      
      name_cell.empty();
      
      var input = $('<input type="text" />').val(start_name).appendTo(name_cell);
      var save_button = $('<button class="simple">' + App.lang('Save') + '</button>').appendTo(name_cell);
      
      input[0].focus();
      
      // Submission indicator
      var submitting_changes = false;
      
      /**
       * Do submit changes we made
       */
      var submit_changes = function() {
        if(submitting_changes) {
          return;
        } // if
        
        var new_category_name = jQuery.trim(input.val());
        if(new_category_name == '') {
          input[0].focus();
        } // if
        
        // Check if new category name is already in use
        var name_used = false;
        table.find('td.name').each(function() {
          var current_row = $(this);
          if(current_row.attr('class').indexOf('renaming') == -1 && current_row.text() == new_category_name) {
            name_used = true;
            current_row.highlightFade();
          } // if
        });
        
        if(name_used) {
          return;
        } // if
        
        // And submit the request
        save_button.text(App.lang('Saving ...'));
        input.attr('disabled', 'disabled');
        submitting_changes = true;
        
        $.ajax({
          type : 'POST',
          url : App.extendUrl(link.attr('href'), { async : 1 }),
          data : {
            'submitted' : 'submitted',
            'category[name]' : new_category_name
          },
          success : function(response) {
            if(manage_categories_tab) {
              var category_id = row.attr('category_id');
              manage_categories_tab.parent().find('li').each(function() {
                if($(this).attr('category_id') == category_id) {
                  $(this).find('a span').text(response);
                } // if
              });
            } // if
            
            name_cell.empty().append($('<a></a>').attr('href', start_url).text(response));
            row.find('td').highlightFade();
            submitting_changes = false;
          },
          error : function() {
            name_cell.empty().append($('<a></a>').attr('href', start_url).text(start_name));
            submitting_changes = false;
            
            alert(App.lang('Failed to rename selected category'));
          }
        });
        
        link[0].block_clicks = false;
      };
      
      /**
       * Cancel changes
       */
      var cancel_changes = function() {
        name_cell.empty().append($('<a></a>').attr('href', start_url).text(start_name));
        link[0].block_clicks = false;
      };
      
      // Input key handling
      input.keydown(function(e) {
        //e.stopPropagation(); // Don't close dialog!
      }).keypress(function(e) {
        switch(e.keyCode) {
          case 13:
            submit_changes();
            break;
          case 27:
            cancel_changes();
            break;
          default:
            return true;
        } // if
        
        e.stopPropagation();
        return false;
      });
      
      // Button click 
      save_button.click(function() {
        submit_changes();
      });
      
      return false;
    });
    
    // Delete category implementation
    row.find('td.options a.move_category_to_trash').click(function() {
      var link = $(this);
      
      // Block additional clicks
      if(link[0].block_clicks) {
        return false;
      } // if
      
      if(confirm(App.lang('Are you sure that you want to delete this category? Objects that are currently within it will be marked as uncategorized, but will not be deleted. There is no Undo!'))) {
        link[0].block_clicks = true;
        
        var row = link.parent().parent();
        var img = link.find('img');
        var old_src = img.attr('src');
        
        img.attr('src', App.data.indicator_url);
        
        $.ajax({
          url     : App.extendUrl(link.attr('href'), { async : 1 }),
          type    : 'POST',
          data    : {'submitted' : 'submitted'},
          success : function(response) {
            if(manage_categories_tab) {
              var category_id = row.attr('category_id');
              manage_categories_tab.parent().find('li').each(function() {
                if($(this).attr('category_id') == category_id) {
                  $(this).remove();
                } // if
              });
            } // if
            
            row.remove();
            if(table.find('tr').length > 0) {
              reindex_even_odd_rows(table);
            } else {
              table.hide();
              $('#manage_categories_empty_list').show();
            } // if
          },
          error   : function() {
            img.attr('src', old_src);
          }
        });
      } // if
      
      return false;
    });
  };
  
  /**
   * Reindex table even odd rows
   *
   * @param jQuery wrapper
   */
  var reindex_even_odd_rows = function(table) {
    var counter = 1;
    table.find('tr').each(function() {
      var new_class = counter % 2 ? 'odd' : 'even';
      $(this).removeClass('odd').removeClass('even').addClass(new_class);
      counter++;
    });
  }
  
  // Public interface
  return {
    
    /**
     * Initialize manage categories popup
     *
     * @param String list_item_id
     */
    init : function(list_item_id) {
      manage_categories_tab = $('#' + list_item_id); // Remember manage categories tab!
      
      var link = manage_categories_tab.find('a');
      
      link.click(function() {
        var open_url = App.extendUrl(link.attr('href'), {
          skip_layout : 1,
          async : 1
        });
        
        App.ModalDialog.show('manage_categories_popup', App.lang('Manage Categories'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(open_url), {});
        return false;
      });
    },
    
    /**
     * Initialize categories list behavior
     *
     * @param String wrapper_id
     */
    init_page : function(wrapper_id) {
      var wrapper = $('#' + wrapper_id);
      
      // New category implementation
      var form = wrapper.find('form');
      var new_category_input = form.find('input');
      var new_category_icon = form.find('img');
      
      var default_text = App.lang('New Category...');
      new_category_input.focus(function() {
        if(new_category_input.val() == default_text) {
          new_category_input.val('');
        } // if
      }).blur(function() {
        if(new_category_input.val() == '') {
          new_category_input.val(default_text);
        } // if
      }).val(default_text);
      
      // Submitting form indicator
      var submitting_new_category = false;
      
      // Click on + image
      new_category_icon.click(function() {
        if(!submitting_new_category) {
          form.submit();
        } // if
      });
      
      // Create new category...
      form.submit(function() {
        if(submitting_new_category) {
          return false;
        } // if
        
        var new_category_name = jQuery.trim(new_category_input.val());
        if(new_category_name == '') {
          new_category_input[0].focus();
        } // if
        
        // Check if new category name is already in use
        var name_used = false;
        wrapper.find('td.name').each(function() {
          var current_row = $(this);
          if(current_row.text() == new_category_name) {
            name_used = true;
            current_row.highlightFade();
          } // if
        });
        
        if(name_used) {
          return false;
        } // if
        
        var old_icon_url = new_category_icon.attr('src');
        
        submitting_new_category = true;
        new_category_input.attr('disabled', 'disabled');
        new_category_icon.attr('src', App.data.indicator_url);
        
        $.ajax({
          type : 'POST',
          url : App.extendUrl(form.attr('action'), { async : 1}),
          data : {
            'submitted' : 'submitted',
            'category[name]' : new_category_name
          },
          success : function(response) {
            $('#manage_categories_empty_list').hide();
            
            var new_row = $(response);
            var table = wrapper.find('table');
            
            table.append(new_row).show();
            init_row(new_row);
            reindex_even_odd_rows(table);
            
            new_row.find('td').highlightFade();
            
            new_category_input.attr('disabled', '').val('')[0].focus();
            submitting_new_category = false;
            new_category_icon.attr('src', old_icon_url);
            
            // Add to list of category tabs
            if(manage_categories_tab) {
              var new_tab = $('<li><a><span></span></a></li>');
              
              new_tab.attr('category_id', new_row.attr('category_id'));
              
              var new_category_link = new_row.find('td.name a');
              new_tab.find('a').attr('href', new_category_link.attr('href'));
              new_tab.find('span').text(new_category_link.text());
              
              manage_categories_tab.before(new_tab);
            } // if
          },
          error : function() {
            submitting_new_category = false;
            new_category_input.attr('disabled', '');
            new_category_icon.attr('src', old_icon_url);
            
            alert(App.lang('Failed to create new category ":name"', { 'name' :  new_category_name}));
          }
        });
        
        return false;
      });
      
      wrapper.find('table tr').each(function() {
        init_row($(this));
      }); 
    }
    
  };
  
}();

/**
 * Manage subscriptions popup and section behavior
 */
App.resources.ManageSubscriptions = function() {
  
  /**
   * Wrapper block
   *
   * @var jQuery
   */
  var wrapper;
  
  // Public interface
  return {
    
    /**
     * Initialize block behavior
     *
     * @param String wrapper_id
     * @param String object_type
     */
    init : function(wrapper_id, object_type) {
      wrapper = $('#' + wrapper_id);
      
      $('#manage_subscriptions_page_action a, #' + wrapper_id+ ' a.open_manage_subscriptions').click(function() {
        if(wrapper.css('display') != 'block') {
          wrapper.show();
        } // if
        
        var popup_url = wrapper.attr('popup_url');
        
        App.ModalDialog.show('manage_object_subscriptions_popup', App.lang('Manage Subscriptions'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(popup_url, function() {
          $('#object_subscriptions table td.subscription input[type=checkbox]').click(function() {
            var checkbox = $(this);
            var cell = checkbox.parent();
            
            checkbox.hide();
            cell.append('<img src="' + App.data.indicator_url + '" alt="" />');
            
            if(this.checked) {
              var url = checkbox.attr('subscribe_url');
            } else {
              var url = checkbox.attr('unsubscribe_url');
            } // if
            
            $.ajax({
              url  : App.extendUrl(url, { async : 1 }),
              type : 'POST',
              data : {
                submitted : 'submitted'
              },
              success : function() {
                cell.find('img').remove();
                checkbox.show();
                
                // Lets update list of users
                var subscribed_users = [];
                $('#object_subscriptions table td.subscription input:checked').each(function() {
                  subscribed_users.push($(this).parent().parent().find('td.name a').clone());
                });
                
                var subscribed_users_list_wrapper = wrapper.find('div.object_subscriptions_list_wrapper').empty();
                var subscribed_users_length = subscribed_users.length;
                
                if(subscribed_users_length == 0) {
                  subscribed_users_list_wrapper.append(App.lang('There are no users subscribed to this :type', { type : object_type }));
                } else if(subscribed_users_length == 1) {
                  subscribed_users_list_wrapper.append(subscribed_users[0]).append(' ' + App.lang('is subscribed to this :type', { type : object_type }));
                } else {
                  if (subscribed_users_length <= App.data.max_subscribers_count) {
                    for(var i = 0; i < subscribed_users_length; i++) {
                      subscribed_users_list_wrapper.append(subscribed_users[i]);
                      
                      if(i < (subscribed_users_length - 2)) {
                        subscribed_users_list_wrapper.append(', ');
                      } else if(i == (subscribed_users_length - 2)) {
                        subscribed_users_list_wrapper.append(App.lang(' and '));
                      } // if
                    } // for
                    
                    subscribed_users_list_wrapper.append(' ' + App.lang('are subscribed to this :type', { type : object_type }));
                  } else {
                    subscribed_users_list_wrapper.append(' ' + App.lang(':subscribers_count people subscribed to this :type', { subscribers_count: subscribed_users_length,  type : object_type }));
                  } // if
                } // if
              },
              error : function() {
                cell.find('img').remove();
                checkbox[0].checked = !checkbox[0].checked;
                checkbox.show();
              }
            });
          });
        }), {
          height: 400,
          buttons : [{
            label : App.lang('Close')
          }]          
        });
        
        return false;
      });
    }
    
  };
  
}();

/**
 * Insert image editor widget
 */
App.widgets.EditorImagePicker = function() {
  /**
   * Editor instance
   */
  var editor_instance = null;
  
  /**
   * element in which editor is contained
   */
  var editor_container = null;
  
  /**
   * variable name for hidden fields
   */
  var hidden_input_variable_name = null;
  
  /**
   * disable image upload
   */
  var disable_image_upload = false;
  
  /**
   * Dialog container
   */
  var dialog_container;
  
  /**
   * cursor position
   */
  var cursor_position = null;
  
  // public interface
  return {
    /**
     * Display dialog
     */
    show : function (editor_instance_object, variable_name) {
      editor_instance = editor_instance_object;
      editor_container = $(editor_instance_object.contentAreaContainer).parents('table:first').parent().parent();
      cursor_position = editor_instance.selection.getBookmark();
      
      hidden_input_variable_name = variable_name;
      
      var picker_url;
      if (App.widgets.EditorImagePicker.disable_image_upload) {
        picker_url = App.extendUrl(App.data.image_picker_url, {async:1, skip_layout:1, disable_upload : true});
      } else {
        picker_url = App.extendUrl(App.data.image_picker_url, {async:1, skip_layout:1});
      } // if
      
      App.ModalDialog.show('image_picker_dialog', App.lang('Choose or Upload Image'), $('<p><img src="' + App.data.indicator_url + '" alt="" /> ' + App.lang('Loading...') + '</p>').load(picker_url), {
        width: 500
      });
    },
    
    /**
     * Initialize dialog
     */
    init : function (container_id) {      
      dialog_container = $(container_id +':first');
      
      dialog_container.find('.top_tabs a').click(function () {
        var anchor = $(this);
        anchor.parent().parent().find('li').removeClass('selected');
        anchor.parent().addClass('selected');
        dialog_container.find('.top_tabs_object_list>div').hide();
        dialog_container.find('.top_tabs_object_list #container_'+anchor.attr('id')).show();
        return false;
      });
      dialog_container.find('.top_tabs a:first').click();
      
      
      // upload image behaviour
      $('#upload_image_form').resetForm();
      $('#upload_image_form').submit(function () {
                      
        $('#upload_image_form').ajaxSubmit({
          url               : App.data.image_picker_url,
          type              : 'post',
          success           : function (response) {
            var jquery_response = $(response);
            if (jquery_response.is('img')) {
              App.widgets.EditorImagePicker.update_editor(jquery_response.attr('src'), jquery_response.attr('attachment_id'));
            } else {
              alert(response);
            } // if
          },
          error : function (response) {
            alert(response.statusText);
          }
        });
        return false;
      });
      
      $('#link_image_form').submit(function () {
        var image_url = $('#link_image_form').find('input[type=text]').val();
        if (image_url) {
          App.widgets.EditorImagePicker.update_editor(image_url);
        } // if
        return false;
      });
    },
    
    update_editor : function (image_url, attachment_id) {
      if (editor_instance) {
      editor_instance.focus();
      editor_instance.selection.moveToBookmark(cursor_position);
      
        editor_instance.execCommand('mceInsertContent', false, "<img src='"+image_url+"' />");
        if (attachment_id) {
          if (editor_container.find('input[name='+hidden_input_variable_name+'][value='+attachment_id+']').length == 0) {
            editor_container.prepend('<input type="hidden" name="'+hidden_input_variable_name+'" value="'+attachment_id+'" />');
          } // if
        } // if
        App.ModalDialog.close();
      } // if
    }
  }
}();

/**
 * Select assignees widget
 */
App.widgets.EditorLinkPicker = function() {
  /**
   * Editor instance
   */
  var editor_instance = null;
  
  /**
   * element in which editor is contained
   */
  var editor_container = null;
  
  /**
   * cursor position
   */
  var cursor_position = null;
  
  /**
   * Dialog container
   */
  var dialog_container;
  
  // public interface
  return {
    /**
     * Display dialog
     */
    show : function (editor_instance_object) {
      editor_instance = editor_instance_object;
      editor_container = $(editor_instance_object.contentAreaContainer).parents('table:first').parent().parent();
      cursor_position = editor_instance.selection.getBookmark();
      
      var initial_text = editor_instance.selection.getContent();

      var dialog_body = 
      '<div id="editor_link_container">'+
        '<form method="GET" action="#" class="uniForm showErrors">'+
        '<div class="blockLabels">'+
          '<div class="ctrlHolder">'+
            '<label for="url">'+App.lang('Link URL')+'<em>*</em></label>'+
            '<input type="text" class="title required" id="url" name="link_url" value="http://" />'+
          '</div>';
      if (!initial_text || initial_text.length < 1) {
        dialog_body = dialog_body +
          '<div class="ctrlHolder">'+
            '<label for="link_text">'+App.lang('Link Text')+'</label>'+
            '<input type="text" class="title required" id="link_text" name="link_text" value="'+initial_text+'"/>'+
          '</div>';
      } // if
        dialog_body = dialog_body +
          '<div class="buttonHolder">'+
            '<button accesskey="s" type="submit"><span><span>'+App.lang('Insert link')+'</span></span></button>'+
          '</div>'+
        '</div>'+
        '</form>'+
      '</div>';
      
      App.ModalDialog.show('editor_link_picker', App.lang('Insert Link'), dialog_body, {
        width: 500
      });
      
      $('#editor_link_container').find('form input[name=link_url]:first').focus();
      
      $('#editor_link_container').find('.buttonHolder button:first').click(function () {
        var link_url = $('#editor_link_container').find('form input[name=link_url]:first').val();
        if (!initial_text) {
          var link_text = $('#editor_link_container').find('form input[name=link_text]:first').val();
        } else {
          link_text = initial_text;
        } // if
        if (link_url) {
          App.widgets.EditorLinkPicker.insert(link_text, link_url);
        } // if
        return false;
      });
    },
    /**
     * insert link into body
     */
    insert : function (link_text, link_url) {
      if (!link_text) {
        link_text = link_url;
      } // if
      editor_instance.focus();
      editor_instance.selection.moveToBookmark(cursor_position);
      editor_instance.execCommand('mceInsertContent', false, '<a href="'+link_url+'">'+link_text+'</a>');  
      App.ModalDialog.close();
    }
  }
}();

App.widgets.EditorCleanTextDialog = function () {
  /**
   * Editor instance
   */
  var editor_instance = null;
  
  /**
   * Cursor position
   */
  var cursor_position = null;
  
  /**
   * Clean word HTML
   */
  var cleanWordHtml = function (content) { 
		if (!content || content.length < 1) {
		  return '';
		} // if
		
		var bull = String.fromCharCode(8226);
		var middot = String.fromCharCode(183);     
		
		var rl = '\u2122,<sup>TM</sup>,\u2026,...,\x93|\x94|\u201c|\u201d,",\x60|\x91|\x92|\u2018|\u2019,\',\u2013|\u2014|\u2015|\u2212,-'.split(',');
		for (var i=0; i < rl.length; i+=2)
			content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]);

    // convert headers to strong
		content = content.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>', 'gi'), '<p><b>$1</b></p>');
		content = content.replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--");
		content = content.replace(new RegExp(bull + "(.*?)<BR>", "gi"), "<p>" + middot + "$1</p>");
		content = content.replace(new RegExp('<SPAN style="mso-list: Ignore">', 'gi'), "<span>" + bull); // Covert to bull list
		content = content.replace(/<o:p><\/o:p>/gi, "");
		content = content.replace(new RegExp('<br style="page-break-before: always;.*>', 'gi'), '-- page break --'); // Replace pagebreaks
		content = content.replace(/<!--([\s\S]*?)-->|<style>[\s\S]*?<\/style>/g, "");  // Word comments
		content = content.replace(/<(meta|link)[^>]+>/g, ""); // Header elements

		// remove spans
		content = content.replace(/<\/?span[^>]*>/gi, "");
    // remove styles
		content = content.replace(new RegExp('<(\\w[^>]*) style=\'(.*?)\'([^>]*)', 'gi'), "<$1$3");
		content = content.replace(new RegExp('<(\\w[^>]*) style="(.*?)"([^>]*)', 'gi'), "<$1$3");
    // remove fonts
		content = content.replace(/<\/?font[^>]*>/gi, "");
    // remove class atributes
    content = content.replace(/<(\w[^>]*) class="(.*?)"([^>]*)/gi, "<$1$3");
    content = content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3");

		content = content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3");
		content = content.replace(/<\\?\?xml[^>]*>/gi, "");
		content = content.replace(/<\/?\w+:[^>]*>/gi, "");
		content = content.replace(/-- page break --\s*<p>&nbsp;<\/p>/gi, ""); // Remove pagebreaks
		content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks
		content = content.replace(/--list--/gi, ""); // Remove --list--
		
		// remove empty paragraphs
    content = content.replace(/<p>&nbsp;<\/p>/gi, '');
    content = content.replace(/<p><\/p>/gi, '');
    // remove empty lines
    content = content.replace(/\/?&nbsp;*/gi, "");
    // remove div's
		content = content.replace(/<\/?div[^>]*>/gi, "");

		// Convert all middlot lists to UL lists
		// var div = ed.dom.create("div", null, content);
		// var className = this.editor.getParam("paste_unindented_list_class", "unIndentedList");
		// while (this._convertMiddots(div, "--list--")) ; // bull
		// while (this._convertMiddots(div, middot, className)) ; // Middot
		// while (this._convertMiddots(div, bull)) ; // bull
		// content = div.innerHTML;

    // Replace all headers with strong and fix some other issues
		//content = content.replace(/<h[1-6]>&nbsp;<\/h[1-6]>/gi, '<p>&nbsp;&nbsp;</p>');
		//content = content.replace(/<h[1-6]>/gi, '<p><b>');
		//content = content.replace(/<\/h[1-6]>/gi, '</b></p>');
		//content = content.replace(/<b>&nbsp;<\/b>/gi, '<b>&nbsp;&nbsp;</b>');
		//content = content.replace(/^(&nbsp;)*/gi, '');
    return content;
	};
  
  return {
    show : function (editor_instance_object) {
      editor_instance = editor_instance_object;
      cursor_position = editor_instance.selection.getBookmark();
      
      var dialog_body = 
      '<div id="editor_clean_text_dialog_container">' +
        '<form method="post" action="#" class="uniForm">' +
          '<div class="blockLabels">' +
            '<div class="ctrlHolder">'+
              '<label for="pasted_text">'+App.lang('Use CTRL+V on your keyboard to paste the text into the window')+'</label>'+
              '<textarea id="pasted_text" name="pasted_text"></textarea>'+
            '</div>' +
            '<div class="buttonHolder">'+
              '<button accesskey="s" type="submit"><span><span>'+App.lang('Insert Cleaned Text')+'</span></span></button>'+
            '</div>'+
          '</div>' +
        '</form>' +
      '</div>';
      
      App.ModalDialog.show('editor_clean_text_dialog', App.lang('Clean Text'), dialog_body, {
        width: 500
      });
      
      $('#editor_clean_text_dialog_container').find('.buttonHolder button:first').click(function () {
        var content = $('#editor_clean_text_dialog_container textarea:first').val();
        content = content.replace(/(\r\n|[\r\n])/g, "<br />");
        App.widgets.EditorCleanTextDialog.insert(content);
        return false;
      });
    },
    
    /**
     * insert cleaned text into body
     */
    insert : function (cleaned_text) {
      editor_instance.focus();
      editor_instance.selection.moveToBookmark(cursor_position);
      editor_instance.execCommand('mceInsertContent', false, cleaned_text);
      App.ModalDialog.close();
    }
  }
}();

/**
 * initialize Active Reminders
 */
App.widgets.ActiveReminders = function() {
  
  /**
   * Wrapper instance
   *
   * @var jQuery
   */
  var wrapper;
  
 
  // Public interface
  return {
    
    /**
     * Initialize Active Reminders
     *
     * @param String wrapper_id
     */
    init : function(wrapper_id) {
      wrapper = $('#' + wrapper_id);
      
      wrapper.find('td.options a').click(function () {
        var anchor = $(this);
        var ajax_url = App.extendUrl(anchor.attr('href'), { async: 1, skip_layout : 1 });
        var delete_image_element = anchor.find('img');
        var delete_icon = delete_image_element.attr('src');
        
        delete_image_element.attr('src', App.data.indicator_url);
        $.ajax({
          url     : ajax_url,
          type    : 'post',
          data    : '&submitted=submitted',
          success : function () {
            anchor.parents('tr:first').remove();
            if (wrapper.find('tr').length == 1) {
              wrapper.parent().find('.empty_page').show();
              wrapper.parent().find('#active_reminders').hide();
              if (App.widgets.DashboardImportantItems) {
                App.widgets.DashboardImportantItems.removeItem('reminders');
              } // if
            } // if
          },
          error   : function () {
            delete_image_element.attr('src', delete_icon);
          }
        });       

        return false;
      });
            
    }
    
  }
}();



/**
 * Resource module behavior initialized on every page
 */
$(document).ready(function() {
  
  // Starred
  $('#menu_item_starred_folder a').click(function() {
    var link = $(this);
    
    App.ModalDialog.show('starred_objects_popup', App.lang('Starred'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(App.extendUrl(link.attr('href'), { async : 1 })), {
      width: '500px'
    });
    
    return false;
  });
   
  if (!App.data.copyright_removed && $('#footer #powered_by a[href=http://www.activecollab.com/]').length == 0) {
    if ($('#footer').length == 0) {
      $('body').append('<div id="footer"></div>');
    } // if
    $('#footer').prepend('<p id="powered_by"><a href="http://www.activecollab.com/" target="_blank"><img src="' + App.data.assets_url + '/images/acpowered.gif" alt="powered by activeCollab" /></a></p>').css('display', 'block').css('visibility','visible').css('position', 'static');
    $('#powered_by').css('display', 'block').css('visibility','visible').css('position', 'static');
  } // if
});

/** File: modules/documents/javascript/main.js **/

App.documents = {
	controllers : {},
	models      : {}
};

/**
 * Main files JS file
 */
App.documents.controllers.documents = {
	
	/**
   * Documents list page behavior
   */
	index : function() {
		
		$(document).ready(function() {
			$('.documents_table span.delete a').click(function() {
				var link = $(this);
				var wrapper = link.parent();
				var row = wrapper.parent().parent();
				var container = row.parent();
				
				/**
		     * Reindex table rows
		     */
		    var reindex_odd_even_rows = function() {
		      var counter = 1;
		      container.find('tr').each(function() {
		        var rows = $(this);
		        rows.removeClass('even').removeClass('odd');
		        if(counter % 2 == 1) {
		          rows.addClass('odd');
		        } else {
		          rows.addClass('even');
		        } // if
		        counter++;
		      });
		    } // reidex_table_rows
				
		    if(confirm(App.lang('Are you sure that you want to permanently delete this document?'))) {
					link.hide();
					wrapper.prepend('<img src="' + App.data.indicator_url  + '" alt="" />');
					
					$.ajax({
						url     : link.attr('href'),
						type    : 'POST',
						data    : {'submitted' : 'submitted'},
						success : function(response) {
							row.remove();
							reindex_odd_even_rows();
							
							if($('.documents_table tr').length < 1) {
								$('.documents_table').after('<p class="empty_page">' + App.lang('There are no documents to show.') + '</p>');
							} // if
						},
						error   : function() {
							link.show();
						}
					});
					
					return false;
				} // if
				
				return false;
			})
			
		$('.documents_table .pin a').click(function() {
				var link = $(this);
				var wrapper = link.parent();
				var row = wrapper.parent();
				var container = row.parent();
				
				/**
		     * Reindex table rows
		     */
		    var reindex_odd_even_rows = function() {
		      var counter = 1;
		      container.find('tr').each(function() {
		        var rows = $(this);
		        rows.removeClass('even').removeClass('odd');
		        if(counter % 2 == 1) {
		          rows.addClass('odd');
		        } else {
		          rows.addClass('even');
		        } // if
		        counter++;
		      });
		    } // reindex_table_rows
				
				link.hide();
				wrapper.prepend('<img src="' + App.data.indicator_url  + '" class="indicator" alt="" />');
				
				$.ajax({
					url     : App.extendUrl(link.attr('href'), { async : 1 }),
					type    : 'POST',
					data    : {'submitted' : 'submitted'},
					success : function(response) {
					if (link.is('.not_pinned')){
						container.prepend(row);
						row.highlightFade();
						row.find('img.indicator').remove();
						link.attr({
							'href'  : response
						}).show().find('img').attr({
							'src'   : App.data.pin_icon_url,
							'title' : App.lang('Unpin'),
							'alt'   : App.lang('Unpin')
						});
						link.removeClass('not_pinned').addClass('pinned')
					} else {
						container.append(row);
						row.highlightFade();
						row.find('img.indicator').remove();
						link.attr({
							'href'  : response
						}).show().find('img').attr({
							'src'   : App.data.unpin_icon_url,
							'title' : App.lang('Pin to top'),
							'alt'   : App.lang('Pin to top')
						});
						link.removeClass('pinned').addClass('not_pinned')
					}
						reindex_odd_even_rows();
					},
					error   : function() {
						link.show();
					}
				});
				
				return false;
			});
		});
	}
	
}

/**
 * Main files JS file
 */
App.documents.controllers.document_categories = {
	
	/**
   * Manage categories page behavior
   */
	index : function() {
		$(document).ready(function() {
			$('.common_table span.delete a').click(function() {
				var link = $(this);
				var wrapper = link.parent();
				var row = wrapper.parent().parent();
				var container = row.parent();
				
				/**
         * Reindex table rows
         */
        var reindex_odd_even_rows = function() {
          var counter = 1;
          container.find('tr').each(function() {
            var rows = $(this);
            rows.removeClass('even').removeClass('odd');
            if(counter % 2 == 1) {
              rows.addClass('odd');
            } else {
              rows.addClass('even');
            } // if
            counter++;
          });
        };
				
				if(confirm(App.lang('Are you sure that you want to delete this document category? You will also delete all documents belongs to category!'))) {
	        link.hide();
					wrapper.prepend('<img src="' + App.data.indicator_url  + '" alt="" />');
					
					$.ajax({
						url     : link.attr('href'),
						type    : 'POST',
						data    : {'submitted' : 'submitted'},
						success : function(response) {
							row.remove();
							reindex_odd_even_rows();
							
							if($('.documents_table tr').length < 1) {
								$('.documents_table').after('<p class="empty_page">' + App.lang('All document categories are deleted.') + '</p>');
							} // if
						},
						error   : function() {
							link.show();
						}
					});
				} // if
				
				return false;
			});
		});
	}, // index
	
	/**
   * Documents list inside category page behavior
   */
	view : function() {
		$(document).ready(function() {
			$('.documents_table span.delete a').click(function() {
				var link = $(this);
				var wrapper = link.parent();
				var row = wrapper.parent().parent();
				var container = row.parent();
				
				/**
         * Reindex table rows
         */
        var reindex_odd_even_rows = function() {
          var counter = 1;
          container.find('tr').each(function() {
            var rows = $(this);
            rows.removeClass('even').removeClass('odd');
            if(counter % 2 == 1) {
              rows.addClass('odd');
            } else {
              rows.addClass('even');
            } // if
            counter++;
          });
        };
				
        if(confirm(App.lang('Are you sure that you want to permanently delete this document?'))) {
					link.hide();
					wrapper.prepend('<img src="' + App.data.indicator_url  + '" alt="" />');
					
					$.ajax({
						url     : link.attr('href'),
						type    : 'POST',
						data    : {'submitted' : 'submitted'},
						success : function(response) {
							row.remove();
							reindex_odd_even_rows();
							
							if($('.documents_table tr').length < 1) {
								$('.documents_table').after('<p class="empty_page">' + App.lang('All files from this page are deleted.') + '</p>');
							} // if
						},
						error   : function() {
							link.show();
						}
					});
					
					return false;
        } // if
				
				return false;
			})
			
			$('.documents_table .pin a').click(function() {
				var link = $(this);
				var wrapper = link.parent();
				var row = wrapper.parent();
				var container = row.parent();
				
				/**
		     * Reindex table rows
		     */
		    var reindex_odd_even_rows = function() {
		      var counter = 1;
		      container.find('tr').each(function() {
		        var rows = $(this);
		        rows.removeClass('even').removeClass('odd');
		        if(counter % 2 == 1) {
		          rows.addClass('odd');
		        } else {
		          rows.addClass('even');
		        } // if
		        counter++;
		      });
		    } // reindex_table_rows
				
				link.hide();
				wrapper.prepend('<img src="' + App.data.indicator_url  + '" class="indicator" alt="" />');
				
				$.ajax({
					url     : App.extendUrl(link.attr('href'), { async : 1 }),
					type    : 'POST',
					data    : {'submitted' : 'submitted'},
					success : function(response) {
					if (link.is('.not_pinned')){
						container.prepend(row);
						row.find('img.indicator').remove();
						link.attr({
							'href'  : response
						}).show().find('img').attr({
							'src'   : App.data.pin_icon_url,
							'title' : App.lang('Unpin'),
							'alt'   : App.lang('Unpin')
						});
						link.removeClass('not_pinned').addClass('pinned')
					} else {
						container.append(row);
						row.find('img.indicator').remove();
						link.attr({
							'href'  : response
						}).show().find('img').attr({
							'src'   : App.data.unpin_icon_url,
							'title' : App.lang('Pin to top'),
							'alt'   : App.lang('Pin to top')
						});
						link.removeClass('pinned').addClass('not_pinned')
					}
						reindex_odd_even_rows();
					},
					error   : function() {
						link.show();
					}
				});
				
				return false;
			});
		});
	}
	
};

/**
 * Manage document categories behavior
 */
App.system.ManageDocumentCategories = function() {
  
  /**
   * Manage document categories tab used to initialize the popup
   *
   * This value is present only on pages where we have document categories tabs
   *
   * @var jQuery
   */
  var manage_document_categories_tab = false;
  
  /**
   * Initialize single document category table row
   *
   * @var jQuery
   */
  var init_row = function(row) {
    var table = row.parent().parent();
    
    // Rename document category
    row.find('td.options a.rename_document_category').click(function() {
      var link = $(this);
      
      // Block additional clicks
      if(link[0].block_clicks) {
        return false;
      } // if
      
      var row = link.parent().parent().addClass('renaming');
      var name_cell = row.find('td.name');
      var name_link = name_cell.find('a');
      
      // Remember start name and start URL
      var start_name = name_link.text();
      var start_url = name_link.attr('href');
      
      link[0].block_clicks = true;
      
      name_cell.empty();
      
      var input = $('<input type="text" />').val(start_name).appendTo(name_cell);
      var save_button = $('<button class="simple">' + App.lang('Save') + '</button>').appendTo(name_cell);
      
      input[0].focus();
      
      // Submission indicator
      var submitting_changes = false;
      
      /**
       * Do submit changes we made
       */
      var submit_changes = function() {
        if(submitting_changes) {
          return;
        } // if
        
        var new_document_category_name = jQuery.trim(input.val());
        if(new_document_category_name == '') {
          input[0].focus();
        } // if
        
        // Check if new document category name is already in use
        var name_used = false;
        table.find('td.name').each(function() {
          var current_row = $(this);
          if(current_row.attr('class').indexOf('renaming') == -1 && current_row.text() == new_document_category_name) {
            name_used = true;
            current_row.highlightFade();
          } // if
        });
        
        if(name_used) {
          return;
        } // if
        
        // And submit the request
        save_button.text(App.lang('Saving ...'));
        input.attr('disabled', 'disabled');
        submitting_changes = true;
        
        $.ajax({
          type : 'POST',
          url : App.extendUrl(link.attr('href'), { async : 1 }),
          data : {
            'submitted' : 'submitted',
            'category[name]' : new_document_category_name
          },
          success : function(response) {
            if(manage_document_categories_tab) {
              var document_category_id = row.attr('document_category_id');
              manage_document_categories_tab.parent().find('li').each(function() {
                if($(this).attr('document_category_id') == document_category_id) {
                  $(this).find('a span').text(response);
                } // if
              });
            } // if
            
            name_cell.empty().append($('<a></a>').attr('href', start_url).text(response));
            row.find('td').highlightFade();
            submitting_changes = false;
          },
          error : function() {
            name_cell.empty().append($('<a></a>').attr('href', start_url).text(start_name));
            submitting_changes = false;
            
            alert(App.lang('Failed to rename selected document category'));
          }
        });
        
        link[0].block_clicks = false;
      };
      
      /**
       * Cancel changes
       */
      var cancel_changes = function() {
        name_cell.empty().append($('<a></a>').attr('href', start_url).text(start_name));
        link[0].block_clicks = false;
      };
      
      // Input key handling
      input.keydown(function(e) {
        //e.stopPropagation(); // Don't close dialog!
      }).keypress(function(e) {
        switch(e.keyCode) {
          case 13:
            submit_changes();
            break;
          case 27:
            cancel_changes();
            break;
          default:
            return true;
        } // if
        
        e.stopPropagation();
        return false;
      });
      
      // Button click 
      save_button.click(function() {
        submit_changes();
      });
      
      return false;
    });
    
    // Delete document category
    row.find('td.options a.delete_document_category').click(function() {
      var link = $(this);
      
      // Block additional clicks
      if(link[0].block_clicks) {
        return false;
      } // if
      
      if(confirm(App.lang('Are you sure that you want to delete this document category? There is no undo for this operation!'))) {
        link[0].block_clicks = true;
        
        var row = link.parent().parent();
        var img = link.find('img');
        var old_src = img.attr('src');
        
        img.attr('src', App.data.indicator_url);
        
        $.ajax({
          url     : App.extendUrl(link.attr('href'), { async : 1 }),
          type    : 'POST',
          data    : {'submitted' : 'submitted'},
          success : function(response) {
            if(manage_document_categories_tab) {
              var document_category_id = row.attr('document_category_id');
              manage_document_categories_tab.parent().find('li').each(function() {
                if($(this).attr('document_category_id') == document_category_id) {
                  $(this).remove();
                } // if
              });
            } // if
            
            row.remove();
            if(table.find('tr').length > 0) {
              reindex_even_odd_rows(table);
            } else {
              table.hide();
              $('#manage_document_categories_empty_list').show();
            } // if
          },
          error   : function() {
            img.attr('src', old_src);
          }
        });
      } // if
      
      return false;
    });
  };
  
  /**
   * Reindex table even odd rows
   *
   * @param jQuery wrapper
   */
  var reindex_even_odd_rows = function(table) {
    var counter = 1;
    table.find('tr').each(function() {
      var new_class = counter % 2 ? 'odd' : 'even';
      $(this).removeClass('odd').removeClass('even').addClass(new_class);
      counter++;
    });
  }
  
  // Public interface
  return {
    
    /**
     * Initialize manage document category popup
     *
     * @param String list_item_id
     */
    init : function(list_item_id) {
      manage_document_categories_tab = $('#' + list_item_id); // Remember manage document category tab!
      
      var link = manage_document_categories_tab.find('a');
      
      link.click(function() {
        var open_url = App.extendUrl(link.attr('href'), {
          skip_layout : 1,
          async : 1
        });
        
        App.ModalDialog.show('manage_document_categories_popup', App.lang('Manage Document Categories'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(open_url), {});
        return false;
      });
    },
    
    /**
     * Initialize document categoriess list behavior
     *
     * @param String wrapper_id
     */
    init_page : function(wrapper_id) {
      var wrapper = $('#' + wrapper_id);
      
      // New document categories implementation
      var form = wrapper.find('form');
      var new_document_category_input = form.find('input');
      var new_document_category_icon = form.find('img');
      
      var default_text = App.lang('New Document Category...');
      new_document_category_input.focus(function() {
        if(new_document_category_input.val() == default_text) {
          new_document_category_input.val('');
        } // if
      }).blur(function() {
        if(new_document_category_input.val() == '') {
          new_document_category_input.val(default_text);
        } // if
      }).val(default_text);
      
      // Submitting form indicator
      var submitting_new_document_category = false;
      
      // Click on + image
      new_document_category_icon.click(function() {
        if(!submitting_new_document_category) {
          form.submit();
        } // if
      });
      
      // Create new document category...
      form.submit(function() {
        if(submitting_new_document_category) {
          return false;
        } // if
        
        var new_document_category_name = jQuery.trim(new_document_category_input.val());
        if(new_document_category_name == '') {
          new_document_category_input[0].focus();
        } // if
        
        // Check if new document category name is already in use
        var name_used = false;
        wrapper.find('td.name').each(function() {
          var current_row = $(this);
          if(current_row.text() == new_document_category_name) {
            name_used = true;
            current_row.highlightFade();
          } // if
        });
        
        if(name_used) {
          return false;
        } // if
        
        var old_icon_url = new_document_category_icon.attr('src');
        
        submitting_new_document_category = true;
        new_document_category_input.attr('disabled', 'disabled');
        new_document_category_icon.attr('src', App.data.indicator_url);
        
        $.ajax({
          type : 'POST',
          url : App.extendUrl(form.attr('action'), { async : 1}),
          data : {
            'submitted' : 'submitted',
            'category[name]' : new_document_category_name
          },
          success : function(response) {
            $('#manage_document_categories_empty_list').hide();
            
            var new_row = $(response);
            var table = wrapper.find('table');
            
            table.append(new_row).show();
            init_row(new_row);
            reindex_even_odd_rows(table);
            
            new_row.find('td').highlightFade();
            
            new_document_category_input.attr('disabled', '').val('')[0].focus();
            submitting_new_document_category = false;
            new_document_category_icon.attr('src', old_icon_url);
            
            // Add to list of document category tabs
            if(manage_document_categories_tab) {
              var new_tab = $('<li><a><span></span></a></li>');
              
              new_tab.attr('document_category_id', new_row.attr('document_category_id'));
              
              var new_document_category_link = new_row.find('td.name a');
              new_tab.find('a').attr('href', new_document_category_link.attr('href'));
              new_tab.find('span').text(new_document_category_link.text());
              
              manage_document_categories_tab.before(new_tab);
            } // if
          },
          error : function() {
            submitting_new_document_category = false;
            new_document_category_input.attr('disabled', '');
            new_document_category_icon.attr('src', old_icon_url);
            
            alert(App.lang('Failed to create new document category ":name"', { 'name' :  new_document_category_name}));
          }
        });
        
        return false;
      });
      
      wrapper.find('table tr').each(function() {
        init_row($(this));
      }); 
    }
    
  };
  
}();

/** File: modules/calendar/javascript/main.js **/

/**
 * Remember focused calendar cell ID
 */
jQuery.fn.calendarCurrentCellId = null;

/**
 * Focus single calendar cell
 */
jQuery.fn.calendarFocusCell = function() {
  var cell = $(this);
  var link = cell.find('div.day_num a');
  var details = cell.find('div.day_details');
  
  cell.addClass('zoomed');
          
  cell.find('div.day_brief').hide();
  
  if(details.children().length) {
    details.show();
  } else {
    details.show();
    details.append('<img src="' + App.data.assets_url + '/images/indicator.gif" class="indicator" alt="Working..." />');
    details.load(App.extendUrl(link.attr('href'), { skip_layout : 1 }), function() {
      details.find('a').click(function(e) {
        e.stopPropagation();
        return true;
      });
    });
  } // if
};

/**
 * Unfocus calendar cell
 */
jQuery.fn.calendarUnfocusCell = function() {
  var cell = $(this);
  
  cell.removeClass('collapsed').removeClass('zoomed');
  
  cell.find('div.day_brief').show();
  cell.find('div.day_details').hide();
};

/**
 * Attach calendar behavior to DOM
 */
$(document).ready(function() {
  $('#calendar td.day_cell').click(function() {
    var cell = $(this);
    var table = cell.parent().parent().parent();
    
    if(jQuery.fn.calendarCurrentCellId) {
      if(cell.attr('id') == jQuery.fn.calendarCurrentCellId) {
        table.find('td.day_cell').removeClass('collapsed').removeClass('zoomed');
        cell.calendarUnfocusCell();
        
        jQuery.fn.calendarCurrentCellId = null;
      } else {
        $('#' + jQuery.fn.calendarCurrentCellId).calendarUnfocusCell();
        table.find('td.day_cell').addClass('collapsed').removeClass('zoomed');
        cell.calendarFocusCell();
        
        jQuery.fn.calendarCurrentCellId = cell.attr('id');
      }
    } else {
      table.find('td.day_cell').addClass('collapsed').removeClass('zoomed');
      cell.calendarFocusCell();
      
      jQuery.fn.calendarCurrentCellId = cell.attr('id');
    } // if
    
    return false;
  });
  
  $('#calendar td.day_cell a').click(function(e) {
    e.stopPropagation();
    location.href = $(this).attr('href');
  });
});

/** File: modules/timetracking/javascript/main.js **/

App.timetracking = {
  controllers : {},
  models      : {}
};

/**
 * Timetracking behavior
 */
App.timetracking.controllers.timetracking = {
  
  /**
   * Timetracking index action
   */
  index : function() {
    $(document).ready(function() {
      // Mass edit functionality
      var mass_edit = $('#mass_edit');
      
      var mass_edit_change = function () {
        if($('.time_record input:checked').length > 0) {
          mass_edit.find('select').attr('disabled', '');
          if(mass_edit.find('select').val() != '') {
            mass_edit.find('button').attr('disabled', '').removeClass('button_disabled');
          } else {
            mass_edit.find('button').attr('disabled', 'disabled').addClass('button_disabled');
          } // if
        } else {
          mass_edit.find('select').attr('disabled', 'disabled');
          mass_edit.find('button').attr('disabled', 'disabled').addClass('button_disabled');
        } // if
      } // mass_edit_change
      
      $('.time_record input').click(mass_edit_change);
      mass_edit.change(mass_edit_change).click(mass_edit_change);
      
      var form = $('#add_time_record_form');
      
      // Add time record form
      form.submit(function() {
        var add_form = $(this);
        var add_form_url = App.extendUrl(add_form.attr('action'), {async : 1});
       
        if(UniForm.validate(add_form, true)) {
          $('#new_record td.actions').prepend('<img src="' + App.data.indicator_url + '" alt="" />').find('button').hide();
          
          $(this).ajaxSubmit({
            url    : add_form_url,
            success: function(responseText) {
              $('#no_records').hide();
              $('#mass_edit').show();
              
              $('#timerecords table tbody tr:eq(0)').after(responseText);
              
              $('#new_record td.actions').find('img').remove();
              $('#new_record td.actions').find('button').show();
              
              $('#time_summary').val('');
              $('#time_hours').val('')[0].focus();
              
              var new_row = $('#timerecords table tbody tr:eq(1)');
              App.timetracking.records.init_mark_as_billed_link(new_row);
              App.timetracking.records.init_time_record_row(new_row, mass_edit);
              new_row.find('td').highlightFade();
              
              App.timetracking.records.rebuild_even_odd_classes();
            },
            error : function() {
              $('#new_record td.actions').find('img').remove();
              $('#new_record td.actions').find('button').show();
              
              $('#time_summary').val('');
              $('#time_hours').val('')[0].focus();
            }
          });
        } // if
        
        return false;
      });
      
      App.timetracking.records.init_mark_as_billed_link($('#timerecords table.timerecords'));
      App.timetracking.records.recalculate_total();
      
      // initialize time records table
      form.find('.time_record').each(function () {
        App.timetracking.records.init_time_record_row($(this), mass_edit);
      });      
      
      $('#records_submit').click(function () {
        hidden_form = $('<form method=post action="'+App.data.mass_update_url+'" style="display:none" id="hidden_mass_update"><input type="hidden" name="submitted" value="submitted" /><input type="hidden" value="'+mass_edit.find('select').val()+'" name="action" /></form>');
        hidden_form.prepend(form.find('.time_record input:checked').clone().attr('checked','checked'));
        $('body').append(hidden_form)
        $('#hidden_mass_update').submit();
      });
      
    });
  },
  
  /**
   * Prepare behavior for reports page
   *
   * @param void
   * @return null
   */
  reports : function() { 
    $(document).ready(function() {
      if($('#report_type').val() == 'custom') {
        $('#generate_report .select_date').show();
        $('#generate_report .date_separator').show();
        
      } else {
        $('#generate_report .select_date').hide();
        $('#generate_report .date_separator').hide();
      } // if
      
      $('#report_type').change( function() {
        if($(this).val() == 'custom') {
          $('#generate_report .select_date').show();
          $('#generate_report .date_separator').show();
        } else {
          $('#generate_report .select_date').hide();
          $('#generate_report .date_separator').hide();
        } // if
      });
      
      $('#generate_report').submit(function() {
        if($('#report_type').val() != 'custom') {
          $(this).find('.select_date').remove();
        } // if
        return true;
      });
      
      App.timetracking.records.init_mark_as_billed_link($('#records table'));
      App.timetracking.records.recalculate_total();
    });
  }
  
};

/**
 * Records management module
 */
App.timetracking.records = function() {
  
  /**
   * Public interface
   */
  return {
    
    /**
     * Make sure that even - odd classes are rebuilt when we add / remove 
     * records
     *
     * @param void
     * @return void
     */
    rebuild_even_odd_classes : function() {
      var counter = 0;
      $('table.timerecords tr.time_record').each(function() {
        var row = $(this);
        
        if(row.attr('id') != 'records_summary') {
          counter++;
        
          row.removeClass('even').removeClass('odd');
          if((counter % 2) > 0) {
            row.addClass('odd');
          } else {
            row.addClass('even');
          } // if
        } // if
      });
    }, // rebuild_even_odd_classes
    
    /**
     * Recalculate total time
     *
     * @param void
     * @return void
     */
    recalculate_total : function() {
      $('table.timerecords').each(function() {
        var wrapper = $(this);
        
        var reports_cell = wrapper.find('td.total');
        if(reports_cell.length > 0) {
          var total = 0;
          wrapper.find('td.hours').each(function() {
            total += parseFloat($(this).text());
          });
          
          reports_cell.text(App.lang('Total ') + total);
        } // if
      });
    }, // recalculate_total
    
    /**
     * Init mark as (not) billed link
     *
     * @param jQuery wrapper
     * @return void
     */
    init_mark_as_billed_link : function(wrapper) {
      wrapper.find('a.mark_time_record_as_billed').click(function() {
        var link = $(this);
        var parent_cell = link.parent();
        
        // Block additional clicks
        if(link[0].block_clicks) {
          return false;
        } else {
          link[0].block_clicks = true;
        } // if
        
        var img = link.find('img');
        var old_src = img.attr('src');
        
        img.attr('src', App.data.indicator_url);
        
        $.ajax({
          url     : App.extendUrl(link.attr('href'), {'async' : 1}),
          type    : 'POST',
          data    : {'submitted' : 'submitted'},
          success : function(response) {
            link.remove();
            parent_cell.prepend(response);
            App.timetracking.records.init_mark_as_billed_link(parent_cell);
            
            var link_href = link.attr('href');
            if(link_href.substr(link_href.indexOf('to=') + 3) == '1') {
              parent_cell.parent().addClass('billed');
            } else {
              parent_cell.parent().removeClass('billed');
            } // if
          },
          error   : function() {
            img.attr('src', old_src);
          }
        });
        
        return false;
      });
    }, // init_mark_as_billed_link
    
    /**
     * Initialize time record row
     */
    init_time_record_row : function (time_record_row, mass_edit) {
      var checkbox = time_record_row.find('input');
      checkbox.click(function () {
        if ($('table.timerecords').find('.time_record input:checked').length > 0) {
          mass_edit.enable();
        } else {
          mass_edit.disable();
        } // if
      });
    } // init_time_record_row
    
  };
  
}();

/**
 * Time popup behaviro
 */
App.TimePopup = function() {
  
  // Public interface
  return {
    
    /**
     * Initialize timetracking widget
     *
     * @param string wrapper_id
     * @return void
     */
    init : function(wrapper_id) {
      var object_id = parseInt(wrapper_id.substr(19));
      
      $('#' + wrapper_id + ' a').click(function(e) {
        var link = $(this);
        var current_openner = link.parent();
        
        var indicator_image_src =  App.data.assets_url + '/images/indicator.gif';
        var time_popup_url = App.extendUrl(link.attr('href'), { 
          for_popup_dialog : 1 
        });
        
        App.ModalDialog.show('object_time', App.lang('Time'), $('<div><img src="' + indicator_image_src + '" alt="" /> ' + App.lang('Loading...') + '</div>').load(time_popup_url, function() {
          
          /**
           * Initialize popup behavior
           *
           * @param String popup_wrapper_id
           */
          var init_popup = function(popup_wrapper_id) {
            var wrapper = $('#' + popup_wrapper_id);
          
            wrapper.find('p.object_time_add_link a').click(function() {
              $(this).parent().hide();
              wrapper.find('div.object_time_add').show('fast', function() {
                wrapper.find('div.time_popup_hours_wrapper input')[0].focus();
              });
              
              return false;
            });
            
            wrapper.find('button.object_time_cancel_button').click(function() {
              wrapper.find('p.object_time_add_link').show();
              wrapper.find('div.object_time_add').hide();
              
              return false;
            });
            
            wrapper.find('form').submit(function() {
              var form = $(this);
              var popup_wrapper = form.parent().parent();
              
              form.block(App.lang('Working...'));
              
              form.ajaxSubmit({
                success : function(response) {
                  popup_wrapper.empty();
                  popup_wrapper.append(response);
                  popup_wrapper.find('div.object_time_popup_details dl span.time').highlightFade();
                  
                  if(current_openner.attr('class').indexOf('with_text') && popup_wrapper.find('div.object_time_popup_details dl dd.object_time').length > 0 && popup_wrapper.find('div.object_time_popup_details dl dd.tasks_time').length > 0) {
                    var object_time = App.parseNumeric(popup_wrapper.find('div.object_time_popup_details dl dd.object_time span.time').text());
                    var tasks_time = App.parseNumeric(popup_wrapper.find('div.object_time_popup_details dl dd.tasks_time span.time').text());
                    
                    if(object_time > 0 && tasks_time > 0) {
                      var total_time = object_time + tasks_time;
                      
                      ':total hours logged - :object_time for the ticket and :tasks_time for tasks'
                      current_openner.find('span.time_widget_text').text(App.lang(':total hours logged - :object_time for the ticket and :tasks_time for tasks', {
                        'total'       : parseFloat(total_time.toFixed(2)),
                        'object_time' : parseFloat(object_time.toFixed(2)),
                        'tasks_time'  : parseFloat(tasks_time.toFixed(2))
                      }));
                    } else {
                      current_openner.find('span.time_widget_text').text(App.lang(':total hours logged', {
                        'total' : parseFloat(object_time.toFixed(2))
                      }));
                    } // if
                  } // if
                  
                  current_openner.find('img').attr('src', App.data.assets_url + '/images/clock-small.gif');
                  
                  init_popup('object_time_popup_' + object_id);
                }
              });
              
              return false;
            });
          };
          
          init_popup('object_time_popup_' + object_id);
        }), {
          buttons : false,
          width: 450
        });
        return false;
      });
    }
    
  };
  
}();

App.timetracking.TimeReport = function() {
  
  // Public interface
  return {
    
    /**
     * Initialize report page
     */
    init : function() {
      $('#time_report_select select').change(function() {
        var report_url = $(this).val();
        if(report_url != location.href) {
          $(this).after(' ' + App.lang('Loading ...')).attr('disabled', 'disabled');
          location.href = report_url;
        } // if
      });
      
      $('#time_report_options a').hover(function() {
        $('#time_report_options span.tooltip').text($(this).attr('title'));
      }, function() {
        $('#time_report_options span.tooltip').text('');
      }); 
      
      $('#toggle_report_details').click(function() {
        $('#time_report_details').toggle('fast');
        return false;
      });
    }
    
  };
  
}();

/**
 * Add / Edit time report form behavior
 */
App.timetracking.TimeReportForm = function() {
  
  /**
   * Form instance
   *
   * @var jQuery
   */
  var form;
  
  // Public interface
  return {
    
    /**
     * Initialize time report form
     *
     * @param string form_id
     * @param string partial_generator_url
     * @return void
     */
    init : function(form_id, partial_generator_url) {
      form = $('#' + form_id);
      
      form.find('select.report_async_select').change(function() {
        var select = $(this);
        var row = select.parent().parent();
        var cell_additional = row.find('td.report_select_additional');
        var option = select.find('option[value=' + select.val() + ']');
        
        if(option.attr('class') == 'report_async_option') {
          cell_additional.each(function() {
            cell_additional.empty().append('<img src="' +  App.data.indicator_url + '" alt="" />');
            $.ajax({
              url     : partial_generator_url,
              type    : 'GET',
              data    : {
                'select_box'   : select.attr('name'),
                'option_value' : option.val()
              },
              success : function(response) {
                cell_additional.empty();
                cell_additional.append(response);
              },
              error   : function() {
                cell_additional.empty();
              }
            });
          })
        } else {
          cell_additional.empty();
        }
      })
    }
    
  };
  
}();

/** File: modules/pages/javascript/main.js **/

App.pages = {
  controllers : {},
  models      : {}
};

/**
 * Revisions table behavior module
 */
App.pages.revisions_table = function() {
  
  // Public interface
  return {
    rebuild_even_odd_classes : function() {
      var counter = 0
      $('table.revisions_table tr').each(function() {
        counter++;
        
        var row = $(this);
        row.removeClass('even').removeClass('odd');
        if((counter % 2) > 0) {
          row.addClass('odd');
        } else {
          row.addClass('even');
        } // if
      });
    }
  };
  
}();

/**
 * reorder page behavior module
 */
App.pages.reorder_page = function() {
  
  // Public interface
  return {
    init  : function () {
      reorder_tree = new tree_component();
      reorder_tree.init($("#pages_reorder"),{
        ui    : {
          context     : false,
          theme_path  : App.data.assets_url + '/images/tree_component/',
          theme_name  : 'default'
        },
        rules : {
          draggable : 'all',
          dragrules : 'all',
          clickable   : "none",
          renameable  : "none",
          deletable   : "none",
          creatable   : "none"
        }
      });
      
      // force expand all pages
      $("#pages_reorder").find('li').each(function () {
        reorder_tree.open_branch($(this),true);
      });
      
      $('#reorder_form button:first').click(function () {
        var inputs = '';
        $('#pages_reorder ul li').each(function () {
          var li_element = $(this);
          var page_id = li_element.find('input:first').attr('value');
          var parent_li = li_element.parent().parent();
          if (parent_li.is('li')) {
            var parent_page_id = parent_li.find('input:first').attr('value');
          } else {
            var parent_page_id = 0;
          } // if
          inputs+= '<input type="hidden" name="ordered_pages['+page_id+']" value="'+parent_page_id+'" />';
        });
        
        inputs+= '<input type="hidden" name="submitted" value="submitted" />';
        var submit_url = $('#reorder_form').attr('action');
        
        if (!App.data.is_assync_call) {
          var hidden_form = $("<form method='post' action='"+submit_url+"' style='display:none' id='hidden_form'>"+inputs+"</form>");
          $('body').append(hidden_form);
          $('#hidden_form').submit();
          return false;
        } else {
          $('#reorder_form').before('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').hide();
          inputs = $(inputs);
          $('#page_content').block();
          App.ModalDialog.close()
          $.ajax({
            data    : inputs,
            url     : App.extendUrl(submit_url, {async : 1, skip_layout : 1}),
            type  : 'post',
            success : function (response) {
              $('#page_content').html(response);
            }
          });
          return false;
        } // if
      }) // click      
    }  
  };
  
}();

/**
 * Pages controller behavior
 */
App.pages.controllers.pages = {
  /**
   * Index page behaviour
   *
   * @param void
   * @return void
   */
  index : function () {
    $(document).ready(function () {
      $('#reorder_pages_button').click(function () {
        App.data.is_assync_call = true;
        var assync_url = App.extendUrl($(this).attr('href'), { async: 1 });
  
        App.ModalDialog.show('reorder_pages_dialog', App.lang('Reorder Pages'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(assync_url), {
          buttons : null 
        });
        return false;
      });
    });
  },
  
  /**
   * Prepare view page behavior
   *
   * @param void
   * @return void
   */
  view : function() {
    $(document).ready(function() {
      $('table.revisions_table a.remove_revision').click(function() {
        var link = $(this);
      
        // Block additional clicks
        if(link[0].block_clicks) {
          return false;
        } else {
          link[0].block_clicks = true;
        } // if
        
        if(confirm(App.lang('Are you sure that you want to delete this page version? There is no undo!'))) {
          var img = link.find('img');
          var old_src = img.attr('src');
          
          img.attr('src', App.data.indicator_url);
          
          $.ajax({
            url     : App.extendUrl(link.attr('href'), {'async' : 1}),
            type    : 'POST',
            data    : {'submitted' : 'submitted'},
            success : function() {
              link.parent().parent().remove();
              App.pages.revisions_table.rebuild_even_odd_classes();
            },
            error   : function() {
              img.attr('src', old_src);
            }
          });
        } // if
        
        return false;
      });
    });
    
  },
  
  /**
   * Compare page behavior
   */
  compare_versions : function() {
    $(document).ready(function() {
      var loading = false;
      
      $('#page_compare form').submit(function() {
        if(loading) {
          return false; // let the last operation be completed...
        } // if
        
        var form = $(this);
        
        var new_version = $('#new_version_select').val();
        var old_version = $('#old_version_select').val();
        
        if(new_version == old_version) {
          alert(App.lang('Please select different versions!'));
          return false;
        } // if
        
        loading = true;
        
        var compared_versions_wrapper = $('#compared_versions');
        compared_versions_wrapper.block(App.lang('Loading...'));
        form.find('select').attr('disabled', 'disabled');
        
        $.ajax({
          type : 'GET',
          url : App.extendUrl(App.data.compare_pages_url, {
            'new'   : new_version,
            'old'   : old_version,
            'async' : 1
          }),
          success : function(response) {
            compared_versions_wrapper.find('table').remove();
            compared_versions_wrapper.append(response);
            compared_versions_wrapper.unblock();
            form.find('select').attr('disabled', '');
            compared_versions_wrapper.highlightFade();
            
            loading = false;
          },
          error : function() {
            compared_versions_wrapper.unblock();
            
            loading = false;
          }
        });
        
        return false;
      });
    });
  }
  
};

/** File: modules/project_exporter/javascript/main.js **/

App.project_exporter = {
  controllers : {},
  models      : {}
};

/**
 * Project Exporter client side behaviour
 */
App.project_exporter.controllers.project_exporter = {
  
  /**
   * Index page bahaviour
   *
   */ 
  index : function () {
    $(document).ready(function() {
      var global_container = $('#project_exporter_container');
      var additional_controls = global_container.find('#additional_controls');
      var button_holder = global_container.find('.buttonHolder');
      var main_table = global_container.find('#main_table');
      
      button_holder.find('button:first').click(function () {
        additional_controls.hide();
        button_holder.hide();
 
        main_table.find('input:not(:checked)').each(function () {
          $(this).parents('tr:first').hide();
        });
 
        var modules = new Array();
        var loop = 0;
        main_table.find('input:checked').each(function () {
          var current_checkbox = $(this);
          var current_row = current_checkbox.parents('tr:first');
 
          if ((loop % 2) == 1) {
          current_row.removeClass('odd');
          current_row.addClass('even');
          } else {
          current_row.removeClass('even');
          current_row.addClass('odd');            
          } // if
 
          modules.push({
            module : current_row.attr('module'),
            url : current_row.attr('export_url')
          });
 
          current_checkbox.before('<img src="' + App.data.pending_indicator_url + '" alt="." />');
          current_checkbox.remove();
 
          loop++;
        });
 
        export_project(modules, additional_controls.find('#visibility input:checked').val(), additional_controls.find('#compress_container input:checked').length);
        return false;
      });
      
      /**
       * Start exporting project
       *
       * @param array modules
       * @param integer visibility
       * @param boolean compress_output
       * @return null
       */
      var export_project = function (modules, visibility, compress_output) {
      var response_obj;
      var imploded_modules = new Array();
      for (var counter=0; counter < modules.length; counter++) {
        var current_module = modules[counter].module;
        if (current_module != 'finalize') {
        imploded_modules.push(current_module);
        } // if
      } // for
      imploded_modules = imploded_modules.join(',');
      modules = modules.reverse();
 
      /**
       * Check if there is warning
       *
       * @param object execution_log
       * @return null
       */
      var warning_exists = function (execution_log) {
        if (execution_log == undefined) return true;
        for (x=0; x<execution_log.length; x++) {
        if (execution_log[x].status == 1) {
          return true
        } // if
        } // for
        return false;
      } // warning_exists
 
      /**
       * Export single module and ping next one
       *
       * @param object module
       * @return null
       */
      var export_module = function (module, visibility, compress_output) {
        if (typeof module != 'object') {
        if (compress_output && !warning_exists(response_obj.log)) {
          var message_block = 
          '<div id="download_link_block" style="display:block">' +
          App.lang('Download project archive using following link') + 
          ':<br /><div id="download_link">' + '<a href="'+App.data.download_url+'">'+App.data.download_url+'</a></div>' +
          '</div>';
        } else {
          var message_block = 
          '<div id="download_link_block" style="display:block">' +
          App.lang('Exported project is located') + 
          ':<br /><div id="download_link"><strong>' + App.data.download_ftp_url + '</strong></a></div>' +
          '</div>';              
        }
        main_table.after(message_block);
        return false;
        } // if
 
        row_status_indicator = main_table.find('#module_'+module.module+' .status_indicator img');
        row_log_field = main_table.find('#module_'+module.module+' .module_log');
 
        // indicate progress
        row_status_indicator.attr('src', App.data.indicator_url);
 
        var ping_url = App.extendUrl(module.url, {visibility : visibility, modules : imploded_modules, compress : compress_output})
 
        // do the magic
        $.ajax({
        url: ping_url,
        type: "GET",
        success: function (response) {
          eval('response_obj = '+response);
          if (response_obj.error_count > 0) {
          row_status_indicator.attr('src', App.data.error_indicator_url);
          } else if ((response_obj.log.length > 0) && (warning_exists(response_obj.log))) {
          row_status_indicator.attr('src', App.data.warning_indicator_url);
          } else {
          row_status_indicator.attr('src', App.data.ok_indicator_url);
          } // if
 
          if (response_obj.log.length > 0) {
          status_message = new Array();
          for (x=0; x<response_obj.log.length; x++) {
            message = response_obj.log[x].message;
            message_status = response_obj.log[x].status;
            if (message_status == 1) {
            message = '<span class="status_warning">'+message+'</span>';
            } else if (message_status == 2) {
            message = '<span class="status_ok">'+message+'</span>';
            } else {
            message = '<span class="status_error">'+message+'</span>';
            }
            status_message.push(message);
          }
          row_log_field.html(status_message.join("<br />"));
          } // if
          export_module(modules.pop(), visibility, compress_output);         
        }
        })
 
      } // if
 
      export_module(modules.pop(), visibility, compress_output);
      } // if
    }) // document ready
  }
};

/** File: modules/source/javascript/main.js **/

App.source = {
  controllers : {},
  models      : {}
};

App.source.controllers.repository = {

  /**
  * Add repository
  */
  add : function() {
    $(document).ready(function() {
      App.source.AddEditForm.init();
    });
  },


  /**
  * Edit repository
  */
  edit : function() {
    $(document).ready(function() {
      App.source.AddEditForm.init();
    });
  },


  /**
  * History page behaviour
  */
  history : function() {
    $(document).ready(function() {

      $('tr.commit div.commit_files').hide(); // hide all paths on page load
      $('#toggle_all_paths span').text(App.lang('Show all paths')); // set initial text

      // show/hide one
      $('tr.commit').each(function() {
        var wrapper = $(this);

        wrapper.find('a.toggle_files').click(function() {
          wrapper.find('div.commit_files').toggle();
          return false;
        });
      }); // show/hide one


      $('#repository_delete_page_action').click(function() {
        return confirm(App.lang('Are you sure that you wish to delete this repository from activeCollab?'));
      });
      
      // show/hide all
      var toggle_new_class = null;
      var link_text = null;

      $('#toggle_all_paths').click(function() {
        var toggle_button = $(this);

        if (toggle_button.is('.hide')) {
          $('tr.commit div.commit_files').hide();
          link_text = App.lang('Show all paths');
          toggle_button.removeClass('hide');
          toggle_button.addClass('show');
        }
        else {
          $('tr.commit div.commit_files').show();
          link_text = App.lang('Hide all paths');
          toggle_button.removeClass('show');
          toggle_button.addClass('hide');
        }
        $('span', toggle_button).text(link_text);

        return false;
      }); //show/hide all


      // Update repository
      /*
      $('#repository_ajax_update, a.repository_ajax_update').click(function() {
        var delimiter = App.data.path_info_through_query_string ? '&' : '?';
        App.ModalDialog.show('repository_update', App.lang('Repository update'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Checking for updates...') + '</p>').load($(this).attr('href')+ delimiter + 'skip_layout=1&async=1'), {
          buttons : false,
          width: 400
        });
        return false;
      });
      */


    });

  }, // history

  update : function() {
    progress_div = $('#repository_update_progress');
    
    var delimiter = App.data.path_info_through_query_string ? '&' : '?';
    
    var notify_subscribers = function(total_commits) {
      $('#progress_content').append('<p class="subscribers"><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Sending subscriptions...') + ' </p>');

      $.ajax({
        url: App.data.repository_update_url + delimiter + 'async=1&notify=' + total_commits,
        type: 'GET',
        success : function(response) {
          $('#progress_content p.subscribers img').attr({
          'src' : App.data.assets_url + '/images/ok_indicator.gif'
          });

          $('#progress_content p.subscribers').append(App.lang('Done!'));
        }
      });
    }

    var get_logs = function() {
      progress_content = $('#progress_content');

      progress_content.html('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Importing commits</p>'));
      $.ajax( {
        url: App.data.repository_update_url + delimiter + '&async=1',
        type: 'GET',
        success : function(response) {
          // if starts with 'success', update step went ok
          if (response == 'success') {
            get_logs();
          }
          
          // update finished
          else if (response == 'finished') {
            progress_content.html('<p><img src="' + App.data.assets_url + '/images/ok_indicator.gif" alt="" /> '+ App.lang('Repository successfully updated') + '</p>');
            notify_subscribers(total_commits);
          }
          
          // update error
          else {
            progress_content.html(response); // if not success, reponse is a svn error message
          } // if
        }
      });
    }


    if (App.data.repository_uptodate == 1) {
      progress_div.html('<p><img src="' + App.data.assets_url + '/images/ok_indicator.gif" alt="" /> '+ App.lang('Repository is already up-to-date') + '</p>');
    }
    else {
      total_commits = App.data.repository_head_revision - App.data.repository_last_revision;

      if (total_commits > 0) {
        progress_div.prepend('<p>There are new commits, please wait until the repository gets updated to revision #'+App.data.repository_head_revision+'</p>');
        get_logs();
      }
      else {
        progress_div.prepend('<p>' + App.lang('Error getting new commits') + ':</p>');
      }
    }


  }, // update
  
  browse : function() {
    $(document).ready(function () {
      
      App.widgets.SourceFilePages.init();
      
      $('a.source_item_info').each(function() {
        var link_obj = $(this);
        link_obj.click(function() {         
          App.ModalDialog.show('item_info', App.lang('Item info'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Fetching data...') + '</p>').load(link_obj.attr('href')), {
            buttons : false,
            width: 700
          });
          return false;
        });
      }); // show/hide one      
    })
  }, // browse
  
  
  repository_users : function() {
    $(document).ready(function () {
      
      var select_box = $('#repository_user');
      
      $('table.mapped_users').find('a.remove_source_user').click(function() {
        if (confirm(App.lang('Are you sure that you wish to delete remove this mapping?'))) {
          var link = $(this);
  
          var img = link.find('img');
          var old_src = img.attr('src');
  
          img.attr('src', App.data.indicator_url);
  
          $.ajax({
            url     : App.extendUrl(link.attr('href'), {'async' : 1}),
            type    : 'POST',
            data    : {'submitted' : 'submitted', 'repository_user' : link.attr('name')},
            success : function(response) {
              if (response == 'true') {
                link.parent().parent().remove();
                select_box.append('<option value="'+link.attr('name')+'">'+link.attr('name')+'</option>');
                
                $('#all_mapped').hide();
                $('#no_users').hide();
                $('#new_record').show();
                
                if ($('#records tbody').children().length == 0) {
                  $('#records').hide();
                }
                
              } else {
                img.attr('src', old_src);
              }
            }
          });

        }
        
        return false;
      });
      
      
      
      var form = $('form.map_user_form');
      form.attr('action', App.extendUrl(form.attr('action'), { async : 1 }));

      form.submit(function() {
        if ($('#user_id').find('option:selected').val() == '') {
          alert(App.lang('Please select activeCollab user'));
          return false;
        }
        
        var form = $(this);
        
        $('#new_record td.actions').prepend('<img src="' + App.data.indicator_url + '" alt="" />').find('button').hide();
        
        $(this).ajaxSubmit({
            success: function(responseText) {
              $('#records tbody').prepend(responseText);
              $('#records').show();
              
              $('#new_record td.actions').find('img').remove();
              $('#new_record td.actions').find('button').show();
              
              var new_row = $('#records tbody tr:first');
              new_row.find('td').highlightFade();
              
              select_box.find('option:selected').remove();
              
              if (select_box.children().length == 0) {
                $('#new_record').hide();
                $('#all_mapped').show();
              }
            },
            error : function() {
              $('#new_record td.actions').find('img').remove();
              $('#new_record td.actions').find('button').show();
            }
        });
          
        return false;
      });
      
      
    });
  }
  
};

/**
* Javascript for source administration
*/
App.source.controllers.source_admin = {

  index : function () {
    $(document).ready(function () {
      var test_results_div = $(this).find('.test_results');
      var test_div = test_results_div.parent();
      test_results_div.prepend('<img class="source_results_img" src="" alt=""/>');
      $('.source_results_img').hide();
      
      $('#check_svn_path button:eq(0)').click(function () {
        $('.source_results_img').show();
        var svn_path = $('#svn_path').val();
        var indicator_img = $('.source_results_img');
        var result_span = test_div.find('.test_results span:eq(0)');
        indicator_img.attr('src', App.data.indicator_url);
        result_span.html('');
        $.ajax({
          type: "GET",
          data: "svn_path=" + svn_path,
          url: App.data.test_svn_url,
          success: function(msg){
            if (msg=='true') {
              indicator_img.attr('src', App.data.ok_indicator_url);
              result_span.html(App.lang('Subversion executable found'));
            } else {
              indicator_img.attr('src', App.data.error_indicator_url);
              result_span.html(App.lang('Error accessing SVN executable') + ': ' + msg);
            } // if
          }
        });

      });
    });
  }

};

/**
* Init JS functions for source file pages
*/
App.widgets.SourceFilePages = function () {
  return {
    init : function () {
      var delimiter = '&';
      
      $('#object_quick_option_compare a').click(function () {
        var compared_revision = parseInt(prompt(App.lang('Enter revision number'), ""));
        
        if (isNaN(compared_revision)) {
          alert(App.lang('Please insert a revision number'));
        } else {
          window.location = App.data.compare_url + delimiter + 'compare_to=' + compared_revision + 'peg=' + App.data.active_revision;
        } // if

        return false;
      });
      
      $('#change_revision').click(function () {
        var new_revision = parseInt(prompt(App.lang('Enter new revision number'), ""));

        if (isNaN(new_revision)) {
          alert(App.lang('Please insert a revision number'));
        } else {
          window.location = App.data.browse_url + delimiter + 'r=' + new_revision + delimiter + 'peg=' + App.data.active_revision;
        } // if

        return false;
      });
    }
  }
} ();


/**
* Test repository connection
*/
App.source.AddEditForm = function() {
  return {
    init : function () {
      var result_container = $('#test_connection .test_connection_results');
      var result_image = $('img:eq(0)', result_container);
      var result_output = $('span:eq(0)', result_container);

      $('#test_connection button').click(function () {
        result_output.html(App.lang('Checking...'));
        result_image.attr('src', App.data.indicator_url);

        if ($('#repositoryUrl').attr('value') == undefined) {
          result_image.attr('src', App.data.error_indicator_url);
          result_output.html(App.lang('You need to enter repository URL first'));
        }
        else {
          var delimiter = App.data.path_info_through_query_string ? '&' : '?';
          $.ajax( {
            url: App.data.repository_test_connection_url + delimiter + 'url=' + $('#repositoryUrl').attr('value') + '&user=' + $('#repositoryUsername').attr('value') + '&pass=' + $('#repositoryPassword').attr('value') + '&engine=' + $('#repositoryType option:selected').attr('value'),
            type: 'GET',
            success : function(response) {
              if (response == 'ok') {
                result_image.attr('src', App.data.ok_indicator_url);
                result_output.html(App.lang('Connection parameters are valid'));
              }
              else {
                result_image.attr('src', App.data.error_indicator_url);
                result_output.html(App.lang('Could not connect to repository:') + ' ' + response); // if not success, reponse is a svn error message
              }
            }
          });
        }
      });
    }
  };
} ();

/** File: modules/incoming_mail/javascript/main.js **/

App.incoming_mail = {
  controllers : {},
  models      : {}
};

/**
 * Incoming mail client side behaviour
 */
App.incoming_mail.controllers.incoming_mail_admin = { 
  /**
   * Archive page bahaviour
   *
   */
  index       : function () {
    $(document).ready(function() {
      $('#only_active_toggler').change(function() {
        var toggle_form = $(this).parents('form');
        var url = toggle_form.attr('action');
        var checkbox = toggle_form.find('.input_checkbox:checked');
        
        url = App.extendUrl(url, {only_problematic : checkbox.length})
        window.location = url;
      });
    });
  },
  
  add_mailbox : function () {    
    $(document).ready(function() {
      App.incoming_mail.AddEditForm.init('mailbox_form');
    });
  },
  
  edit_mailbox : function () {    
    $(document).ready(function() {
      App.incoming_mail.AddEditForm.init('mailbox_form');
    });
  },
  
  view_mailbox : function () {
    $(document).ready(function() {
      $('#only_active_toggler').change(function() {
        var toggle_form = $(this).parents('form');
        var url = toggle_form.attr('action');
        var checkbox = toggle_form.find('.input_checkbox:checked');
        
        url = App.extendUrl(url, {only_problematic : checkbox.length})
        window.location = url;
      });
    });
  }
};

/**
* Incoming mail frontend
*/
App.incoming_mail.controllers.incoming_mail_frontend = {
  index: function () {    
    $(document).ready(function() {
      
       $('.incoming_mails_table').checkboxes();
      
        $('.incoming_mails_table .import_button').click(function() {
          return true;
          var anchor = $(this);
          var init_import_form = function() {
            $('#import_form .submit_button').click(function () {
              $('#import_form').ajaxSubmit({
                success : function(response) {
                  $('#import_mail.dialog div.body > p').html(response);
                  anchor.parent().parent().addClass('imported_sucessfully');
                },
                error : function(response) {
                  if (response.status == 409) {
                    $('#import_mail.dialog div.body > p').html(response.responseText);
                  } // if
                  init_import_form();
                }
              });
              $('#import_mail.dialog div.body > p').html('<img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...'));
              return false;
            });
          };
          
          var dialog_url = App.extendUrl(anchor.attr('href'), { 
            skip_layout : 1, 
            async : 1 
          });
          
          App.ModalDialog.show('import_mail', App.lang('Import Email'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(dialog_url, function() {
            init_import_form();
          }), {
            buttons : false,
            width : 978,
            height: 350
          });
          return false;
        });
    });
  }
};

App.incoming_mail.importPendingEmailForm = function() {
  var form;
  return {
    init : function(form_id) {
      form = $('#'+form_id);
      
      // set project select box behaviour
      $('#project_id', form).change(function () {
        // var ajax_request_url = App.data.additional_fields_url + $(this).val() + '&user_id=' + $('#user_id', form).val() + '&object_type=' + $('#object_type', form).val();

        var ajax_request_url = App.extendUrl(App.data.additional_fields_url, {
          'skip_layout' : 1,
          'async' : 1,
          'project_id' : $(this).val(),
          'user_id' : $('#user_id', form).val(),
          'object_type' : $('#object_type', form).val()
        });
        
        $('#additional_fields_loader', form).text(App.lang('Loading')).load(ajax_request_url, null, function () {
          // set object type selector behaviour
          $('#object_type', form).change(function () {
            if ($(this).val() == 'comment') {
              $('#parent_id_block', form).show()
            } else {
              $('#parent_id_block', form).hide()
            } // if
          });
          
          if ($('#object_type', form).val() != 'comment') {
            $('#parent_id_block', form).hide()
          } // if
        });
      });
      
      // set object type selector behaviour
      $('#object_type', form).change(function () {
        if ($(this).val() == 'comment') {
          $('#parent_id_block', form).show()
        } else {
          $('#parent_id_block', form).hide()
        } // if
      });
      
      if ($('#object_type', form).val() != 'comment') {
        $('#parent_id_block', form).hide()
      } // if
    }
  };
}();

App.incoming_mail.AddEditForm = function() {
  return {
    init : function(wrapper_id) {
      var mailbox_form = $('#' + wrapper_id);
      var result_container = $('#test_connection .test_connection_results', mailbox_form);
      var result_image = $('img:eq(0)', result_container);
      var result_output = $('span:eq(0)', result_container);
      
      $('#test_connection button').click(function () {
        result_output.text('');
        result_image.attr('src', App.data.indicator_url);
        
        mailbox_form.ajaxSubmit({ 
          success:    function(response) {
            result_output.text(response);
            result_image.attr('src', App.data.ok_indicator_url);
            result_container.removeClass('connection_error');
            result_container.addClass('connection_ok');
          },
          error:      function(response) {
            result_output.text(response.responseText);
            result_image.attr('src', App.data.error_indicator_url);
            result_container.removeClass('connection_ok');
            result_container.addClass('connection_error');
          },
          url: App.data.test_mailbox_connection_url
        });
      });
      
      // Change port value when type is change and port value is empty or 
      // uses default value of other type
      var type_change_handler = function() {
        var port_field = $('#mailboxPort');
        
        if($(this).val() == 'POP3') {
          if(port_field.val() == '' || port_field.val() == '143') {
            port_field.val('110').parent().highlightFade();
          } // if
        } else {
          if(port_field.val() == '' || port_field.val() == '110') {
            port_field.val('143').parent().highlightFade();
          } // if
        } // if
      };
      
      $('#mailboxType').click(type_change_handler).change(type_change_handler);
    }
    
  };
  
}();

$(document).ready(function() {  
  // check if there are problematic incoming mails
  var update_incoming_mail_menu_badge_item = function () {
    var count_url = App.data.path_info_through_query_string ? 
      App.extendUrl(App.data.url_base, { path_info : 'incoming-mail/count-pending' }) :
      App.data.url_base + '/incoming-mail/count-pending';
      
    var inbox_url = App.data.path_info_through_query_string ? 
      App.extendUrl(App.data.url_base, { path_info : 'incoming-mail' }) :
      App.data.url_base + '/incoming-mail';
      
    var group_id = 'main';
    var menu_item_id = 'incoming_mail';
    
    $.ajax({
      type: "GET",
      url: count_url,
      success : function (response) {
        if (response > 0) {
         if (!App.MainMenu.itemExists(menu_item_id, group_id)) {
      	   App.MainMenu.addToGroup({
      	     label       : App.lang('Inbox'),
      	     href        : inbox_url,
      	     icon        : App.data.assets_url + '/modules/incoming_mail/images/icon_menu.gif',
      	     id          : menu_item_id,
      	     badge_value : response
      	   }, group_id);
         } else {
           App.MainMenu.setItemBadgeValue(menu_item_id, group_id, response);
         }
        } else {
          App.MainMenu.removeButton(menu_item_id, group_id);
        } // if
      } // if
    })
  } // update_incoming_mail_menu_badge_item
  
  setInterval(update_incoming_mail_menu_badge_item, 60000 * 3); 
});

/** File: modules/milestones/javascript/main.js **/

App.milestones = {
  controllers : {},
  models      : {}
};

/**
 * Main milestones JS file
 */
App.milestones.controllers.milestones = {
  
  /**
   * Prepare stuff on reschedule form
   *
   * @param void
   * @return null
   */
  reschedule : function() {
    $(document).ready(function() {
      
      // Lets hide successive milestone. There must be a better way to do this 
      // but we'll leave it at this for now :)
      $('div.with_successive_milestones input[type=radio]').each(function() {
        if(this.checked && $(this).val() != 'move_selected') {
          $('div.with_successive_milestones div.successive_milestones').hide();
        }
      })
      
      // Click handler for action selectors
      $('div.with_successive_milestones input[type=radio]').click(function() {
        if($(this).val() == 'move_selected') {
          $('div.with_successive_milestones div.successive_milestones').show('fast');
        } else {
          $('div.with_successive_milestones div.successive_milestones').hide('fast');
        }
      });
    });
  }
  
}

/** File: modules/tickets/javascript/main.js **/

App.tickets = {
  controllers : {},
  models      : {}
};

/**
 * Tickets behavior
 */
App.tickets.controllers.tickets = {
  /**
   * Ticket index page behavior
   */
  index : function() {    
    $(document).ready(function () {
      reindex_tickets_table = function (table) {
        var counter = 0;
        table.find('li').each(function () {
          var row = $(this);
          if (row.html() && !row.is('.empty_row') && !row.is('.ui-sortable-helper')) {
            if ((counter % 2) == 0) {
              row.removeClass('even');
              row.addClass('odd');
            } else {
              row.removeClass('odd');
              row.addClass('even');
            } // if
            counter ++;
          } // if
        });
        if (counter<1) {
          table.find('.empty_row').show();
        } else {
          table.find('.empty_row').hide();
        } // if
      } // reindex_tickets_table

      if (App.data.can_manage_tickets) {
        $('.tickets_list').sortable({
          axis : 'y',      
          cursor: 'move',
          delay: 3,
          placeholder: 'drag_placeholder',
          forcePlaceholderSize : true,
          revert: false,
          connectWith: ['.tickets_list'],
          items: 'li.sort',
          update : function (e, ui) {
            var sortable_list = ui.item.parent();
            reindex_tickets_table(sortable_list);
            var reorder_data = sortable_list.find('input').serialize();
            if (reorder_data) {
              reorder_data+='&submitted=submitted';
              $.ajax({
                type: "POST",
                url: sortable_list.attr('reorder_url'),
                data: reorder_data
              });
            } // if
          },
          over: function (table_object,ui) {
            $(this).addClass('dragging');
          },
          out: function (table_object,ui) {
            $(this).removeClass('dragging');
          }
        });
      } // if
    });
  },
  
  /**
   * View ticket behavior
   */
  view : function() {
    $(document).ready(function() {
      $('#show_all_ticket_changes a').click(function() {
        var link = $(this);
        if(link.attr('loading') == 'loading') {
          return false;
        } else {
          link.attr('loading', 'loading');
        } // if
        
        var wrapper = $('#ticket_changes_wrapper');
        
        wrapper.block(App.lang('Loading...'));
        
        $.ajax({
          url : App.extendUrl(link.attr('href'), { async : 1}),
          success : function(response) {
            wrapper.empty().append(response).unblock().highlightFade();
            $('#show_all_ticket_changes').remove();
          },
          error : function() {
            wrapper.unblock();
            alert(App.lang('Failed to load all ticket changes'));
          }
        });
        
        return false;
      });
    });
  }
  
};

/** File: modules/status/javascript/main.js **/

App.status = {
  controllers : {},
  models      : {}
};

/**
 * Status update client side behaviour
 */
App.status.controllers.status = { 
  
  /**
   * Index page bahaviour
   */   
  index : function () {
    $(document).ready(function() {
      $('#select_user').change(function() {
        $("#status_update_archive_work_indicator").show();
        window.location = $(this).val();
      });
    });
  },
  
  /**
   * View status message page behavior
   */
  view : function() {
    $(document).ready(function() {
      var initial_status_message_reply = App.lang('Type your reply and hit Enter to post it');
      $('#status_update_details tr.status_update_reply').each(function() {
        var row = $(this);
        
        row.find('td.message textarea').each(function() {
          var status_message_reply = $(this).val(initial_status_message_reply);
          
          // Form
          status_message_reply.focus(function() {
            if(status_message_reply.attr('class').indexOf('focused') == -1) {
              status_message_reply.addClass('focused');
            } // if
            if(status_message_reply.val() == initial_status_message_reply) {
              status_message_reply.addClass('focused').val('');
            } // if
          }).blur(function() {
            if(status_message_reply.val() == '') {
              status_message_reply.removeClass('focused').val(initial_status_message_reply);
            } // if
          }).keydown(function(e) {
            if(e.keyCode == 13) {
              var status_message_reply_value = jQuery.trim(status_message_reply.val());
              if(status_message_reply_value) {
                row.find('#status_update_reply').block();
              
                $.ajax({
                  'url' : App.extendUrl(row.attr('reply_url'), { async : 1}),
                  type : 'POST',
                  data : {
                    'submitted' : 'submitted',
                    'reply[message]' : status_message_reply_value
                  },
                  success : function(response) {
                    row.find('#status_update_reply').unblock();
                    row.before(response);
                    status_message_reply.val('')[0].focus();
                  },
                  error : function(response) {
                    row.find('#status_update_reply').unblock();
                    
                    status_message_reply.val(status_message_reply_value)[0].focus();
                    alert(App.lang('We are sorry, but system failed to save your status message. Please try again later.'));
                  }
                });
              } // if
            } // if
          });
        });
      })
    });
  }
  
};

/**
 * Update dialog behavior
 */
App.widgets.StatusUpdateDialog = function() {
  
  /**
   * Submit status update URL
   *
   * @param String
   */
  var submit_status_update_url;
  
  /**
   * Status messages table
   *
   * @var jQuery
   */
  var status_update_table;
  
  /**
   * Status updates table wrapper
   *
   * @var jQuery
   */
  var status_update_table_wrapper;
  
  /**
   * Empty new message textarea value
   *
   * @param jQuery
   */
  var initial_status_message = App.lang('Type your message and hit Enter to post it');
  
  /**
   * New status message textarea
   *
   * @var jQuery
   */
  var status_message;
  
  /**
   * Initialize single status update row
   *
   * @param jQuery row
   */
  var initialize_row = function(row) {
    row.find('td.message a.status_message_reply').click(function() {
      var textarea_row = row.find('td.message tr.status_update_reply_textarea');
      var link_row = row.find('td.message tr.status_update_reply_link');
      
      var reply_textarea = textarea_row.find('textarea').keydown(function(e) {
        if(e.keyCode == 13) {
          var value = jQuery.trim(reply_textarea.val());
          
          if(value) {
            reply_textarea.block();
            submit_status_update(value, row.attr('status_update_id'));
            
            return false;
          } // if
        } // if
      });
      
      link_row.hide();
      textarea_row.show().find('textarea').focus();
      
      return false;
    });
  };
  
  /**
   * Submit status update
   *
   * @param String submit_url
   * @param String text
   * @param Function on_success
   * @param Function on_error
   */
  var submit_status_update = function(text, reply_to_id, on_success, on_error) {
    $.ajax({
      url  : App.extendUrl(submit_status_update_url, { async : 1 }),
      type : 'POST',
      data : {
        'submitted' : 'submitted',
        'status[message]' : text, 
        'status[parent_id]' : reply_to_id
      },
      'success' : function(response) {
        var row = $(response);
        initialize_row(row);
        
        var status_update_id = row.attr('status_update_id');
        
        status_update_table.find('tr[status_update_id=' + status_update_id + ']').remove();
        
        status_update_table_wrapper.show().scrollTo(0);
        status_update_table.prepend(row);
        
        var counter = 1;
        status_update_table.find('tr.status_update').each(function() {
          var new_class = counter % 2 ? 'odd' : 'even';
          $(this).removeClass('odd').removeClass('even').addClass(new_class);
          counter++;
        });
        
        status_update_table.find('tr:first td').highlightFade();
        
        if(typeof(on_success) == 'function') {
          on_success();
        } // if
      },
      'error' : function(response) {
        if(typeof(on_error) == 'function') {
          on_error();
        } // if
        
        alert(App.lang('We are sorry, but system failed to save your status message. Please try again later.'));
      }
    });
  };
  
  // Public interface
  return {
    
    /**
     * Initalize status updates dialog
     *
     * @param String add_message_url
     */
    init : function(add_message_url) {
      submit_status_update_url = add_message_url;
      status_update_table = $("#status_updates_table tbody.first_level");
      status_update_table_wrapper = $("#status_updates_dialog div.table_wrapper");
      status_message = $('#status_updates_dialog #add_status_message textarea').val(initial_status_message);
      
      // Top links
      $('.status_update_top_links li a').hover(function () {
        $('li:eq(0)', $(this).parent().parent()).text($(this).attr('title'));
      }, function () {
        $('li:eq(0)', $(this).parent().parent()).text('');
      });
      
      status_update_table.find('tr.status_update').each(function() {
        initialize_row($(this));
      });
      
      // Form
      status_message.focus(function() {
        if(status_message.attr('class').indexOf('focused') == -1) {
          status_message.addClass('focused');
        } // if
        if(status_message.val() == initial_status_message) {
          status_message.addClass('focused').val('');
        } // if
      }).blur(function() {
        if(status_message.val() == '') {
          status_message.removeClass('focused').val(initial_status_message);
        } // if
      }).keydown(function(e) {
        if(e.keyCode == 13) {
          var status_message_value = jQuery.trim(status_message.val());
          if(status_message_value) {
            $('#status_updates_dialog #add_status_message').block();
            
            submit_status_update(status_message_value, null, function() {
              $('#status_updates_dialog #add_status_message').unblock();
              status_message.val('').focus();
            }, function() {
              $('#status_updates_dialog #add_status_message').unblock();
              status_message.val(status_message_value).focus();
            });
          } // if
          
          return false;
        } // if
      });
    }
  };
  
}();

$(document).ready(function() {
  
  // check if there are new messages
  var update_status_menu_badge_item = function () {
    var count_url = App.data.path_info_through_query_string ? 
      App.extendUrl(App.data.url_base, { path_info : 'status/count-new-messages' }) :
      App.data.url_base + '/status/count-new-messages';
    
    $.ajax({
      type: "GET",
      url: count_url,
      success : function (response) {
        App.MainMenu.setItemBadgeValue('status', 'main', response);
      }
    })
  } // update_status_menu_badge_item
  setInterval(update_status_menu_badge_item, 60000 * 3); 
  
  // init menu item button
  $('#menu_item_status a').click(function() {
    var status_update_url = App.extendUrl($(this).attr('href'), { 
      async : 1 
    });
    
    App.ModalDialog.show('status_updates', App.lang('Status Updates'), $('<p><img src="' + App.data.assets_url + '/images/indicator.gif" alt="" /> ' + App.lang('Loading...') + '</p>').load(status_update_url), {
      buttons : false,
      height : 400,
      width: 600
    });
    App.MainMenu.setItemBadgeValue('status', 'main', 0);
    return false;
  });
})


/** File: modules/checklists/javascript/main.js **/

App.checklists = {
  controllers : {},
  models      : {}
};

/**
 * Project Exporter client side behaviour
 */
App.checklists.controllers.checklists = { 
  /**
   * Archive page bahaviour
   *
   */   
  index : function () {   
    $(document).ready(function() {
      $('td.expander a').click(function () {
        var anchor = $(this);
        var anchor_row = anchor.parents('tr:first');
        var anchor_image = anchor.find('img');
        var ajax_url = App.extendUrl(anchor.attr('href'), {show_only_tasks : 'true', async : 1})
        var checklist_tasks_row = anchor.parents('div.checklist').find('.tasks_container:first');
        
        if (anchor.is('.collapsed')) {
          anchor.removeClass('collapsed');
          anchor_row.removeClass('collapsed');
          anchor_image.attr('src', App.data.indicator_url);
          if (!checklist_tasks_row.html()) {
            $.ajax({
              url : ajax_url,
              success : function (response) {
                anchor.addClass('expanded');
                anchor_row.addClass('expanded');
                anchor_row.removeClass('collapsed');
                anchor_image.attr('src', App.data.expander_expanded);
                checklist_tasks_row.hide();
                checklist_tasks_row.html(response);
                checklist_tasks_row.slideDown();
              },
              error : function(response) {
                anchor_image.attr('src', App.data.expander_collapsed);
              }
            });
          } else {
            anchor.addClass('expanded');
            anchor_row.addClass('expanded');
            anchor_row.removeClass('collapsed');
            anchor_image.attr('src', App.data.expander_expanded);
            checklist_tasks_row.slideDown();
          } // if
        } else if (anchor.is('.expanded')) {
          anchor.addClass('collapsed');
          anchor_row.addClass('collapsed');
          anchor_row.removeClass('expanded');
          anchor_image.attr('src', App.data.expander_collapsed);
          checklist_tasks_row.slideUp();
        } // if
        return false;
      });
      
      if(App.data.can_manage_checklists) {
        $('#checklists .checklists_container').sortable({
          items: 'div.checklist',
          axis: 'y',
          distance: '3',
          handle: 'table:first',
          update: function (event, ui) {
            var ajax_data = {
              'submitted' : 'submitted'
            };
            
            var counter = 0;
            $('#checklists div.checklists_container div.checklist:not(.ui-sortable-placeholder)').each(function () {
              ajax_data['checklists[' + counter + ']'] = $(this).attr('checklist_id');
              counter++;
            });
            $.ajax({
              type : 'post',
              data : ajax_data,
              url : App.extendUrl(App.data.reorder_checklists_url, { async : 1 })
            })
          }
        });
        $('#checklists .checklists_container .checklist:not(.ui-sortable-placeholder) table').css('cursor', 'move');
      } // if
    });
  }
};

App.widgets.reorder_checklists = function() {
  var reorder_list;
  var reorder_form;

  return {
    init : function(list_id) {
      reorder_list = $('#' + list_id);
      reorder_form = reorder_list.parents('form');
      
      var list_container = $('#checklists .checklists_container:first');
      var list_prefix = 'checklist_';
      
      reorder_list.sortable({
        axis        : 'y'
      });
      
      reorder_form.find('.buttonHolder button').click(function () {
        reorder_form.block();
        reorder_form.ajaxSubmit({
          method  : 'post',
          url  : App.makeAsyncUrl(reorder_form.attr('action')),
          success : function (response) {
            reorder_form.find('input').each(function () {
              list_container.append($('#'+list_prefix+$(this).val()));
            });
            App.ModalDialog.close();
          },
          error : function (response) {
            reorder_form.unblock();
          }
        });
      });
    }
  }
}();



/** File: modules/invoicing/javascript/main.js **/

App.invoicing = {
  controllers : {},
  models      : {}
};

/**
 * Invoicing controller
 */
App.invoicing.controllers.invoices = {
  /**
   * Behavior for send page
   */
  issue : function() {
    $(document).ready(function() {
      if ($('#select_invoice_recipients').length > 0) {
        if($('#issue_invoice table input[type=radio]:checked').length < 1) {
          $('#issue_invoice table input[type=radio]:first')[0].checked = true; // Select first user if nobody is selected
        } // if
        
        $('#select_invoice_recipients table tr').click(function() {
          $(this).find('input[type=radio]')[0].checked = true;
        });
        
        $('#issue_invoice p input[type=radio]').click(function() {
          if($('#issueFormSendEmailsYes')[0].checked) {
            $('#select_invoice_recipients').show('fast');
          } else {
            $('#select_invoice_recipients').hide('fast');
          } // if
        });
        
        if($('#issueFormSendEmailsYes')[0].checked) {
          $('#select_invoice_recipients').show();
        } // if
      } // if
    });
  },
  
  notify : function() {
    $(document).ready(function() {
      if($('#issue_invoice table input[type=radio]:checked').length < 1) {
        $('#issue_invoice table input[type=radio]:first')[0].checked = true; // Select first user if nobody is selected
      } // if
      
      $('#select_invoice_recipients table tr').click(function() {
        $(this).find('input[type=radio]')[0].checked = true;
      });
      
      $('#issue_invoice p input[type=radio]').click(function() {
        if($('#issueFormSendEmailsYes')[0].checked) {
          $('#select_invoice_recipients').show('fast');
        } else {
          $('#select_invoice_recipients').hide('fast');
        } // if
      });
      
      if($('#issueFormSendEmailsYes')[0].checked) {
        $('#select_invoice_recipients').show();
      } // if
    });
  }
};

/**
 * Invoice payments controller
 */
App.invoicing.controllers.invoice_payments = {
  add : function () {
    $(document).ready(function () {      
      var payment_value_input = $('#invoicePaymentAmount');
      var skip_email_notification = $('#notifyCompanyBlock');
      
      var payment_value_changed = function () {
        var max_value = parseFloat(App.data.max_invoice_payment);
        var current_value = parseFloat(payment_value_input.val());
        if (current_value >= max_value) {
          skip_email_notification.show();
        } else {
          skip_email_notification.hide();
        } // if
      } // payment_value_changed
      payment_value_changed();
            
      payment_value_input.change(payment_value_changed).keyup(payment_value_changed);
    });
  }
}

/**
 * Currencies administration
 */
App.invoicing.controllers.currencies_admin = {
  
  /**
   * Currencies administration index behavior
   */
  index : function() {
    $(document).ready(function() {
      $('#currencies td.checkbox input').click(function() {
        var checkbox = $(this);
        var cell = checkbox.parent();
        
        // Status is not changed to checked (status is set before callback)
        if(this.checked) {
          this.checked = false;
        } else {
          return false;
        } // if
        
        if(confirm(App.lang('Are you sure that you want to set this currency as a default?'))) {
          checkbox.hide();
          cell.append('<img src="' + App.data.indicator_url + '" />');
          
          $.ajax({
            url  : App.extendUrl(checkbox.attr('set_as_default_url'), { async : 1 }),
            type : 'POST',
            data : {
              submitted : 'submitted'
            },
            success : function() {
              $('#currencies td.checkbox input').each(function() {
                this.checked = false;
              });
              
              checkbox[0].checked = true;
              
              cell.find('img').remove();
              checkbox.show();
              return true;
            },
            error : function() {
              cell.find('img').remove();
              checkbox.show();
              
              alert(App.lang('Failed to set this currencies as default'));
              
              return false;
            }
          });
        } // if
        
        return false;
      });
    });
  }
  
};

/**
 * PDF settings
 */
App.invoicing.controllers.pdf_settings_admin = {
  /**
   * Behavior for send page
   */
  index : function() {
    $(document).ready(function() {      
      $('.color_selector').each(function () {
        var picker = $(this);
        var input_control = $('input:eq(0)', picker.parent())
        var initial_color = '#' + input_control.val();
        
    		$('div', picker).css('backgroundColor', initial_color);
        picker.ColorPicker({
        	color: initial_color,
        	onShow: function (colpkr) {
        		$(colpkr).fadeIn(500);
        		return false;
        	},
        	onHide: function (colpkr) {
        		$(colpkr).fadeOut(500);
        		return false;
        	},
        	onSubmit: function (hsb, hex, rgb) {
        		$('div', picker).css('backgroundColor', '#' + hex);
        		input_control.val(hex);
        	}
        });
        
        input_control.change(function() {
      		$('div', picker).css('backgroundColor', '#' + $(this).val());
      		picker.ColorPickerSetColor($(this).val());
        });
      });
    });
  }
  
};

/**
 * Invoice form behavior
 */
App.invoicing.InvoiceForm = function() {
  
  /**
   * Instances reused in the code below
   *
   * @var jQuery
   */
  var form, items_table;
  
  /**
   * Registered tax rates
   *
   * @var Object
   */
  var tax_rates = {};
  
  /**
   * Reindex items rows
   */
  var reindex_items_rows = function() {
    var counter = 1;
    items_table.find('tr.item').each(function() {
      var row = $(this);
      row.removeClass('odd').removeClass('even').addClass((counter % 2 ? 'odd' : 'even')).find('td.num span').text('#' + counter).show();
      row.find('.move_handle').hide();
      counter++;
    });
    
    items_table.find('tr.item td.num').each(function () {
      var cell = $(this);
      var move_handle = cell.find('.move_handle');
      var num_span = cell.find('span');
     
      cell.hover(function () {
        move_handle.show();
        num_span.hide();
      }, function () {
        var row = $(this);
        move_handle.hide();
        num_span.show();        
      });
    });
    
    $('#invoice_items table').sortable('destroy');
    $('#invoice_items table').sortable({
      axis : 'y',
      items : 'tr.item',
      handle : '.move_handle',
      start : function () {
        $('#invoice_items table tr.item').removeClass('even').removeClass('odd');
      },
      stop : function () {
        reindex_items_rows();
      }
    });
  }; // reindex_items_rows 
  
  /**
   * Initialize item row
   *
   * @param jQuery row
   */
  var initialize_item_row = function(row) {
    row.find('td.tax_rate input[type=hidden]').each(function() {
      var input = $(this);
      var cell = input.parent();
      
      var select = $('<select><option value="0" rate="0">' + App.lang('No Tax') + '</option></select>').attr('name', input.attr('name'));
      for(var i in tax_rates) {
        var option = $('<option></option>').text(tax_rates[i]['name']).attr({
          'value'    : i,
          'rate'     : tax_rates[i]['rate']
        }).appendTo(select);
      } // for
      
      var tax_value = input.val();
      if(tax_value) {
        select.val(tax_value);
      } // if
      
      input.remove();
      cell.append(select);
    });
    
    /**
     * function that handles changes of item fields
     *
     * @param void
     * @return null
     */
    var handle_keyup = function() {
      var input_element = $(this);
      var input_element_cell = input_element.parents('td:first');     
      
      if (input_element_cell.is('.total')) {
        input_element.parents('tr').addClass('recalculate_unit_cost');
      } else {
        input_element.parents('tr').addClass('recalculate_total');
      } // if
      recalculate_total();
    } // handle_keyup
    
    /**
     * filter keypresses that are not allowed
     *
     * @param mixed e
     * @return boolean
     */
    var handle_keypress = function (e) {
      if (handle_special_keypress(e, this) == false) {
        return false;
      } // if
      if ((e.which >= 48) && (e.which <= 57) || (e.which == 46) || (e.which = 43) || (e.altKey || e.metaKey || e.ctrlKey || (e.keyCode > 0))) {
        // check if dot is already present
        if (e.which == 46) {
          var value = $(this).val();
          if (value.indexOf('.') > 0) {
            return false;
          } // if
        } // if
        return true;
      } // if
      return false;
    } // handle_keypress
    
    /**
     * filter enter keypress
     *
     * @param mixed e
     * @return boolean
     */
    var handle_special_keypress = function (e, input_element) {
      if (e.which == 13) {
        //if key is enter add new row
        if (input_element) {
          var next_row = $(input_element).parents('tr.item').next();
        } else {
          var next_row = $(this).parents('tr.item').next();
        } // if
        if (next_row.is('.item')) {
          next_row.find('td.description input').focus();
        } else {
          App.invoicing.InvoiceForm.add_row(true);  
        } // if
        return false;
      } else if (e.keyCode == 27 && e.charCode == 0) {
        if (input_element) {
          var this_row = $(input_element).parents('tr.item');
        } else {
          var this_row = $(this).parents('tr.item');
        } // if
        
        var delete_button = this_row.find('td.options .button_remove');
        var next_row_input = this_row.next().find('td.description input');
        var previous_row_input = this_row.prev().find('td.description input');
        
        delete_button.click();
        
        if (previous_row_input.length > 0) {
          previous_row_input.focus();
        } else if (next_row_input.length > 0) {
          next_row_input.focus();
        } // if
        return false;        
      } // if
      return true;
    } // handle_special_keypress
    
    /**
     * handle blur events
     *
     * @param mixed e
     * @return boolean
     */
    var handle_blur = function (e) {
      var input_element = $(this);
      input_element.val(App.parseNumeric(input_element.val()).toFixed(App.data.invoicing_precision));
    } // handle_blur
    
    row.find('td.quantity input').keyup(handle_keyup);
    row.find('td.unit_cost input').keyup(handle_keyup);
    row.find('td.total input').keyup(handle_keyup); 
    row.find('td.tax_rate select').change(handle_keyup);
    
    row.find('td.quantity input').keypress(handle_keypress);
    row.find('td.unit_cost input').keypress(handle_keypress);
    row.find('td.total input').keypress(handle_keypress);
    
    row.find('td.quantity input').blur(handle_blur);
    row.find('td.unit_cost input').blur(handle_blur);
    row.find('td.total input').blur(handle_blur);
    
    row.find('td.description input').keypress(handle_special_keypress);
    
    row.find('td.options img.button_remove').click(function() {
      if(items_table.find('tr.item').length > 1) {
        row.remove();
        recalculate_total();
        reindex_items_rows();
      } // if
    });
    
    row.find('input, select').focus(function() {
      UniForm.focus_field(form, $(this));
    });
  }; // initialize_item_row
    
  /**
   * Recalculate only total of totals
   */
  var recalculate_total = function() {
    var total_subtotal = 0;
    var total_of_totals = 0;
    
    // recalculate rows which are modified
    items_table.find('tr.item.recalculate_total, tr.item.recalculate_unit_cost').each(function() {
      var row = $(this);
      if (row.is('.recalculate_total')) {
        // recalculate total
        var quantity = App.parseNumeric(row.find('td.quantity input').val());
        var unit_cost = App.parseNumeric(row.find('td.unit_cost input').val());
        var tax_rate = App.parseNumeric(row.find('td.tax_rate select option:selected').attr('rate'));
        var total = 0;
        var subtotal = 0;
        
        if(isNaN(quantity) || isNaN(unit_cost) || isNaN(tax_rate)) {
          row.find('td.subtotal input').val(subtotal.toFixed(App.data.invoicing_precision));
          row.find('td.total input').val(total.toFixed(App.data.invoicing_precision));
        } else {
          var subtotal = quantity * unit_cost;
          var total = subtotal * (1 + tax_rate / 100);
          
          row.find('td.subtotal input').val(subtotal.toFixed(App.data.invoicing_precision));
          row.find('td.total input').val(total.toFixed(App.data.invoicing_precision));
        } // if
        row.removeClass('recalculate_total');
      } else {
        // recalculate unit cost
        var quantity = App.parseNumeric(row.find('td.quantity input').val());
        var unit_cost = 0;
        var tax_rate = App.parseNumeric(row.find('td.tax_rate select option:selected').attr('rate'));
        var total = App.parseNumeric(row.find('td.total input').val());
        var subtotal = 0;
        if(isNaN(quantity) || isNaN(total) || isNaN(tax_rate)) {
          row.find('td.subtotal input').val(subtotal.toFixed(App.data.invoicing_precision));
          row.find('td.unit_cost input').val(unit_cost.toFixed(App.data.invoicing_precision));
        } else {
          var unit_cost = total / (quantity * (1 + tax_rate / 100));
          var subtotal = quantity * unit_cost;
          
          row.find('td.subtotal input').val(subtotal.toFixed(App.data.invoicing_precision));
          row.find('td.unit_cost input').val(unit_cost.toFixed(App.data.invoicing_precision));
        } // if
        row.removeClass('recalculate_unit_cost');  
      } // if
    });
    
    // recalculate total subtotal
    items_table.find('tr.item td.subtotal input').each(function() {
      total_subtotal += App.parseNumeric($(this).val());
    });
    
    // recalculate total of totals
    items_table.find('tr.item td.total input').each(function() {
      var value = $(this).val();
      total_of_totals += App.parseNumeric($(this).val());
    });
    
    var currency_code = form.find('#currencyId option:selected').attr('code');
    var invoice_total_text = '<div>'+App.lang('Subtotal: :total :currency', {
      'total' : total_subtotal.toFixed(App.data.invoicing_precision),
      'currency' : currency_code
    })+ '</div>';
    invoice_total_text+= '<div><strong>'+App.lang('Total Due: :total :currency', {
      'total' : total_of_totals.toFixed(App.data.invoicing_precision),
      'currency' : currency_code
    })+ '</strong></div>';
    
    $('#invoice_sub_total').val(total_subtotal.toFixed(App.data.invoicing_precision));
    $('#invoice_total').val(total_of_totals.toFixed(App.data.invoicing_precision));
    items_table.find('tr.invoice_totals td.total').html(invoice_total_text);
  }; // recalculate_total
  
  /**
   * Validate invoice items
   *
   * @param jQuery field
   * @param String caption
   */
  window.validate_invoice_items = function(field, caption) {
    var error_message = false;
    var error_messages = new Array();
    
    var item_count = items_table.find('tr.item').length;
    
    items_table.find('tr.item').each(function() {
      var row = $(this);
      var description = jQuery.trim(row.find('td.description input').val());
      var quantity = App.parseNumeric(row.find('td.quantity input').val());
      var unit_cost = App.parseNumeric(row.find('td.unit_cost input').val());
      var total = App.parseNumeric(row.find('td.total input').val());
      
      if (!description && !total && !unit_cost) {
        // check if there are empty rows
        if (item_count > 1) {
          row.remove();
        } // if
      } else if (!description && (total && unit_cost)) {
        // check if there are missing descriptions
        error_messages[0] = App.lang('All descriptions are required.');
      } // if
    });
    
    var invoice_total = App.parseNumeric(items_table.find('#invoice_total').val());
    if (invoice_total <= 0) {
      error_messages[1] = App.lang('Invoce total is invalid. Invoice total must be greater than zero');
    } // if    
    
    if (error_messages.length > 0) {
      error_message = error_messages.join('<br />');
    } // if
    return error_message ? error_message : true;
  };
  
  // Public interface
  return {
    
    /**
     * Initialize invoice form
     *
     * @param String form_id
     */
    init : function(form_id, mode) {
      form = $('#' + form_id);
      
      var ID_autogenerate = $('#autogenerateID');
      var ID_manually = $('#manuallyID');
      
      ID_autogenerate.find('a').click(function () {
        ID_autogenerate.hide();
        ID_manually.show();
        return false;
      });
      
      ID_manually.find('a').click(function () {
        ID_autogenerate.show();
        ID_manually.hide();
        ID_manually.find('input').val('');
        return false;
      });
      
      // currency handler
      form.find('#currencyId').change(function() {
        recalculate_total();
      });

      var company_id = $('#companyId');
      var company_address = $('#companyAddress');
      
      var ajax_request;
      company_id.change(function () {
        var ajax_url = App.extendUrl(App.data.company_details_url, {
          company_id  : company_id.val(),
          async       : 1,
          skip_layout : 1
        });
        
        // abort request if already exists and it's active
        if ((ajax_request) && (ajax_request.readyState !=4)) {
          ajax_request.abort();
        } // if
        
        if (!company_address.is('loading')) {
          company_address.addClass('loading');
        } // if
        
        company_address.attr("disabled","disabled");
        company_id.attr("disabled","disabled");
        
        ajax_request = $.ajax({
          url         : ajax_url,
          success     : function (response) {
            company_address.val(response);
            company_address.removeClass('loading');
            company_address.removeAttr("disabled","disabled");
            company_id.removeAttr("disabled","disabled");
          }
        });
      });
      if (mode == 'add') {
        company_id.change();
      } // if
      
      items_table = form.find('#invoice_items table');
      items_table.find('a.button_add#add_new').click(function() {
        App.invoicing.InvoiceForm.add_row(true);
        return false;
      });
      
      items_table.find('span.button_dropdown#add_from_template a').click(function() {
        var link = $(this);
        link.parents('.dropdown_container').fadeOut(100);
        App.invoicing.InvoiceForm.add_from_template(link.attr('href'));
        return false;
      });
            
      // initialze preloaded rows     
      var item_rows = items_table.find('tr.item');
      if(item_rows.length < 1) {
        App.invoicing.InvoiceForm.add_row(false);
      } else {
        item_rows.each(function() {
          var row = $(this);
          initialize_item_row(row);
        });
      } // if
                 
      // predefined notes
      form.find('#show_invoice_note_link').click(function() {
        $(this).parent().remove();
        form.find('#invoice_note_wrapper').show('fast', function() {
          $(this).find('textarea')[0].focus();
        });
        return false;
      });
      
      var select_predefined = $('#predefined_notes');
      var note_field = $('#invoice_note');
      select_predefined.change(function () {
        var selected_id = select_predefined.attr('value');
        if (App.data.invoice_notes[selected_id] !== undefined) {
          note_field.val(App.data.invoice_notes[selected_id]);
          note_field.show();
        } else if (selected_id == 'empty') {
          note_field.val('');
          note_field.hide();
        } else if (selected_id == 'original') {
          note_field.val(App.data.original_note);
          note_field.show();
        } else if (selected_id == 'custom') {
          note_field.val('');
          note_field.show();
        } // if
      });
      
      select_predefined.change();
      
      recalculate_total();
      reindex_items_rows();
    },
    
    /**
     * Create a new row
     *
     * @param boolea auto_focus
     */
    add_row : function(auto_focus) {
      var row_number = 0;
      items_table.find('tr.item').each(function () {
        var loop_row = $(this);
        var loop_row_id = loop_row.attr('id');
        if (loop_row_id) {
          loop_row_id = parseInt(loop_row_id.substr(10));
          if (loop_row_id > row_number) {
            row_number = loop_row_id;
          } // if
        } // if
      });
      row_number++;
      var next_row_name = 'invoice[items][' + row_number + ']';
      var zero = 0;
      
      var row = $('<tr class="item" id="items_row_' + row_number + '">' +
        '<td class="num"><span></span><img src="' + App.data.move_icon_url + '" class="move_handle" /></td>' + 
        '<td class="description"><input type="text" name="' + next_row_name + '[description]" value="" /></td>' + 
        '<td class="unit_cost"><input type="text" name="' + next_row_name + '[unit_cost]" class="short" value="'+zero.toFixed(App.data.invoicing_precision)+'" /></td>' + 
        '<td class="quantity"><input type="text" name="' + next_row_name + '[quantity]" class="short" value="1" /></td>' + 
        '<td class="tax_rate"><input type="hidden" name="' + next_row_name + '[tax_rate_id]" value="" /></td>' + 
        '<td class="subtotal" style="display: none"><input type="hidden" name="' + next_row_name + '[subtotal]" value="" /></td>' +
        '<td class="total"><input type="text" name="invoice' + next_row_name + '[total]" value="'+zero.toFixed(App.data.invoicing_precision)+'"/></td>' + 
        '<td class="options"><img src="' + App.data.assets_url + '/images/gray-delete.gif" class="button_remove" /></td>' + 
      '</tr>');
      
      var last_item_row = items_table.find('tr.item:last');
      if(last_item_row.length > 0) {
        last_item_row.after(row);
      } else {
        items_table.find('tr.header').after(row);
      } // if
      reindex_items_rows();
      initialize_item_row(row);
      recalculate_total();
      
      if(auto_focus) {
        row.find('td.description input')[0].focus();
      } // if
    },
    
    /**
     * Create a new row
     *
     * @param boolea auto_focus
     */
    add_from_template : function(template_id, auto_focus) {
      var row_number = 0;
      items_table.find('tr.item').each(function () {
        var loop_row = $(this);
        var loop_row_id = loop_row.attr('id');
        if (loop_row_id) {
          loop_row_id = parseInt(loop_row_id.substr(10));
          if (loop_row_id > row_number) {
            row_number = loop_row_id;
          } // if
        } // if
      });
      row_number++;
      
      last_row = items_table.find('tr.item:last');
      last_row_description = last_row.find('td.description input:[type=text]:first').val();
      last_row_unit_cost = last_row.find('td.unit_cost input:[type=text]:first').val();
      last_row_unit_total = last_row.find('td.total input:[type=text]:first').val();
      
      if (!last_row_description && !parseInt(last_row_unit_cost) && !parseInt(last_row_unit_total)) {
        row_number--
        last_row.remove();
      } // if
            
      var next_row_name = 'invoice[items][' + row_number + ']';
      var zero = 0;
      
      var row = $('<tr class="item recalculate_total" id="items_row_' + row_number + '">' +
        '<td class="num"><span></span><img src="' + App.data.move_icon_url + '" class="move_handle" /></td>' + 
        '<td class="description"><input type="text" name="' + next_row_name + '[description]" value="'+App.data.invoice_item_templates[template_id].description+'" /></td>' + 
        '<td class="unit_cost"><input type="text" name="' + next_row_name + '[unit_cost]" class="short" value="'+App.data.invoice_item_templates[template_id].unit_cost+'" /></td>' + 
        '<td class="quantity"><input type="text" name="' + next_row_name + '[quantity]" class="short" value="'+App.data.invoice_item_templates[template_id].quantity+'" /></td>' + 
        '<td class="tax_rate"><input type="hidden" name="' + next_row_name + '[tax_rate_id]" value="'+App.data.invoice_item_templates[template_id].tax_rate_id+'" /></td>' + 
        '<td class="subtotal" style="display: none"><input type="hidden" name="' + next_row_name + '[subtotal]" value="" /></td>' +
        '<td class="total"><input type="text" name="invoice' + next_row_name + '[total]" value="'+zero.toFixed(App.data.invoicing_precision)+'"/></td>' + 
        '<td class="options"><img src="' + App.data.assets_url + '/images/gray-delete.gif" class="button_remove" /></td>' + 
      '</tr>');
      
      var last_item_row = items_table.find('tr.item:last');
      if(last_item_row.length > 0) {
        last_item_row.after(row);
      } else {
        items_table.find('tr.header').after(row);
      } // if
      reindex_items_rows();
      initialize_item_row(row);
      recalculate_total();
      
      if(auto_focus) {
        row.find('td.description input')[0].focus();
      } // if
    },
    
    /**
     * Register a new tax rate
     *
     * @param String name
     * @param float rate
     */
    register_tax_rate : function(id, name, rate) {
      tax_rates[id] = {
        'name' : name,
        'rate' : rate
      };
    }
    
  };
  
}();

/**
 * Invoice item templates
 */
App.invoicing.controllers.invoice_item_templates_admin = {
  /**
   * Behavior for send page
   */
  index : function() {
    $(document).ready(function() {      
      $('#invoice_item_templates_list table').sortable({
        axis : 'y',
        items : 'tr.template',
        handle : '.move_handle img',
        forcePlaceholderSize : true,
        start : function () {
          $('#invoice_item_templates_list table tr').each(function () {
            var row = $(this);
            row.removeClass('even').removeClass('odd');
          });
        },
        stop : function () {
          var counter = 0;
          $('#invoice_item_templates_list table tr').each(function () {
            var row = $(this);
            row.removeClass('even').removeClass('odd');
            if (counter % 2 == 0) {
              row.addClass('even');
            } else {
              row.addClass('odd');
            } // if
            counter++;
          });
        },
        update : function () {
          $('#invoice_item_templates_list form').ajaxSubmit({
            type : 'post'
          })
        }
      });
    });
  }
};

/**
 * Invoice note templates
 */
App.invoicing.controllers.invoice_note_templates_admin = {
  /**
   * Behavior for send page
   */
  index : function() {
    $(document).ready(function() {      
      $('#invoice_item_templates_list table').sortable({
        axis : 'y',
        items : 'tr.template',
        handle : '.move_handle img',
        forcePlaceholderSize : true,
        start : function () {
          $('#invoice_item_templates_list table tr').each(function () {
            var row = $(this);
            row.removeClass('even').removeClass('odd');
          });
        },
        stop : function () {
          var counter = 0;
          $('#invoice_item_templates_list table tr').each(function () {
            var row = $(this);
            row.removeClass('even').removeClass('odd');
            if (counter % 2 == 0) {
              row.addClass('even');
            } else {
              row.addClass('odd');
            } // if
            counter++;
          });
        },
        update : function () {
          $('#invoice_item_templates_list form').ajaxSubmit({
            type : 'post'
          })
        }
      });
    });
  }
};

/**
 * Invoice number generator
 */
App.invoicing.controllers.invoice_number_generator_admin = {
  /**
   * Behavior for send page
   */
  index : function() {
    $(document).ready(function() {
      var pattern_input = $('.invoice_generator_pattern_input:first');
      var preview_input = $('.invoice_generator_preview_input:first');
      $('.generator_patterns_and_counters .invoice_generator_variables a').click(function () {
        pattern_input.insertAtCursor($(this).text()).change();
      });
      
      var do_the_preview = function () {
        var preview_string = $(this).val();
        $.each(App.data.pattern_variables, function (key, value) {
          var regexp = new RegExp(key, "g");
          preview_string = preview_string.replace(regexp, value);
        });
        preview_input.val(preview_string);
      } // do_the_preview
      
      pattern_input.change(do_the_preview).keyup(do_the_preview);
      pattern_input.change();
    });
  }
};



/** File: modules/files/javascript/main.js **/

App.files = {
  controllers : {},
  models      : {}
};

/**
 * Main files JS file
 */
App.files.controllers.files = {
  
  /**
   * Index page behavior
   */
  index : function() {
    $(document).ready(function() {
      $('#file_list').checkboxes();
    });
  },
  
  /**
   * Initial file details page behavior
   */
  view : function() {
    $(document).ready(function() {
      $('div.file_revisions').each(function() {
        var wrapper = $(this);
        
        /**
         * Reindex table rows
         */
        var reindex_odd_even_rows = function() {
          var counter = 1;
          wrapper.find('tr').each(function() {
            var row = $(this);
            row.removeClass('even').removeClass('odd');
            if(counter % 2 == 1) {
              row.addClass('odd');
            } else {
              row.addClass('even');
            } // if
            counter++;
          });
        };
        
        wrapper.find('td.options a').click(function() {
          var link = $(this);
            
          // Block additional clicks
          if(link[0].block_clicks) {
            return false;
          } else {
            link[0].block_clicks = true;
          } // if
          
          var img = link.find('img');
          var old_src = img.attr('src');
          
          img.attr('src', App.data.indicator_url);
          
          $.ajax({
            url     : link.attr('href'),
            type    : 'POST',
            data    : {'submitted' : 'submitted'},
            success : function() {
              link.parent().parent().remove();
              reindex_odd_even_rows();
              if(wrapper.find('table tr').length < 1) {
                wrapper.find('div.body').append('<p class="details center files_moved_to_trash">' + App.lang('All revision moved to Trash') + '</p>');
              } // if
            },
            error   : function() {
              img.attr('src', old_src);
            }
          });
          
          return false;
        });
      });
    });
  },
  
  /**
   * Upload files behavior
   */
  upload : function() {
    var rows_for_upload = new Array();
    
    var current_row_id = 0;
    var current_row;
    
    var main_form;
    var upload_form;
    var upload_table;
    
    var summary_table;
    
    var uploads_ok = 0;
    var uploads_failed = 0;
    
    /**
     * function to call to submit multiupload form
     */
    var submit_multiupload_form = function () {
      file_id = 0;
      start_upload();
    };
    
    /**
     * Reindex table rows (set odd,even classes and add row #)
     */
    var reindex_table_rows = function () {
      var counter = 0;
      $('tr', upload_table).each(function () {
        row = $(this);
        if ((counter % 2) == 0 ) {
          row.attr('class', 'odd');
        } else {
          row.attr('class', 'even');
        } // if
        $('.number', row).text('#'+counter);
        counter++;
      });
    } // reindex_table_rows
    
    /**
    * Init row in upload table (add remove button functionality)
    */
    var init_multiupload_row = function (row) {
      if (row) {
        $('.button_remove', row).click(function () {
          if ($('tr', upload_table).length > 2) {
            $(this).parent().parent().remove();
            reindex_table_rows();
          } // if
        });
        $('td.description input:eq(0)' ,row).keydown(function(e) {
          if (e.keyCode == 13) {
            submit_multiupload_form();
            return false;
          } // if
        });
      } // if
    } // init_multiupload_row
    
    /**
     * set up hidden form for upload (based on curently selected row from upload table)
     * and do the upload
     */
    var upload_single_file = function () {
      var current_row = rows_for_upload[current_row_id];
      
      // if no more uploads are left, then do some stuff like showing upload statistics
      if (!current_row) {
        var params = {
          files_uploaded : uploads_ok,
          files_failed : uploads_failed
        }
        
        // form result message dependable of number failed and number of succeeded uploads
        if (uploads_ok && uploads_failed) {
          var upload_message = App.lang("Done, :files_uploaded files uploaded and :files_failed uploads failed<br />", params);
        } else if (uploads_ok) {
          var upload_message = App.lang("Done, :files_uploaded files uploaded<br />", params);
        } else {
          var upload_message = App.lang("Done, :files_failed uploads failed<br />", params);
        } // if
        
        // generates links for view files and for multiupload files
        var category_id = $("#multiupload_parent_id").val();
        var upload_more_files_url = main_form.attr('action');
        if (category_id) {
          var files_section_url = App.extendUrl(App.data.files_section_url, { 
            'category_id' :  category_id
          });
          upload_more_files_url = App.extendUrl(upload_more_files_url, { 
            'category_id' :  category_id
          });
        } else {
          var files_section_url = App.data.files_section_url;
        } // if

        upload_message += App.lang('Upload <a href=":upload_url">more files</a> or go back to <a href=":files_url">Files</a> section', {
          files_url : files_section_url,
          upload_url : upload_more_files_url
        });
  
        $('#page_content').append("<div class='important_block'>" + upload_message + "</div>");
        return true;
      } // if
      
      // remove input field from hidden form
      var previous_input = $("input[name=attachment]", upload_form);
      if (previous_input) {
        previous_input.remove();
      } // if
      
      // select current input
      var this_file_file = $("input:eq(0)", current_row);
      var this_file_body = $("input:eq(1)", current_row);
      
      // set progress indicator
      $("tr:eq(" + (current_row_id + 1) + ") img:eq(0)", summary_table).attr('src', App.data.indicator_url);
      
      // move file input from old form to new form (we cannot use clone() function because of jquery explorer bug)
      this_file_file.prependTo(upload_form);
      $('#multiupload_body').val(this_file_body.val());
            
      // submit current form
      upload_form.submit();
      current_row_id++;
      
      return false;
    } // upload_single_file
    
    /**
     * Start upload (copy selected common parameters from main form to hidden
     * upload form, and call upload function for first row from upload table
     */
    var start_upload = function () {
      main_form.hide();
      
      // create upload summary table      
      $('#page_content').append('<table id="upload_table_result" class="common_table"><tr><th></th><th colspan="2">' + App.lang('Uploading files') + '</th></tr></table>');
      summary_table = $('#upload_table_result');
      $('tr', upload_table).each(function () {
        var row = $(this);
        if ($('input',row).val()) {
          rows_for_upload.push(row);
          summary_table.append(
            '<tr>' +
              '<td class="indicator"><img alt="status" src="' + App.data.pending_indicator_url + '"</td>' +
              '<td class="filename">' + $('input',row).val() + '</td>' +
              '<td class="log"></div>' +
            '</tr>'
          );
        } // if
      });
      
      // set category and other stuff      
      $("#multiupload_parent_id").val($("#main_form #fileParent").val());
      $("#multiupload_milestone_id").val($("#main_form #fileMilestone").val());
      $("#multiupload_tags").val($("#main_form #fileTags").val());
      
      $("#multiupload_visibility").val(1);
      
      var visiblity_field_1 = $("#main_form #fileVisibility_1");
      
      // Checkbox?
      if(visiblity_field_1.attr('type') == 'radio') {
        if (visiblity_field_1[0].checked) {
          $("#multiupload_visibility").val(1);
        } else {
          $("#multiupload_visibility").val(0);
        } // if
        
      // Nope. Hidden
      } else {
        $("#multiupload_visibility").val(visiblity_field_1.val());
      } // if
      
      $('.people', upload_form).remove();
      
      $("#main_form .select_asignees_inline_widget .company_user input:checked").each(function () {
        upload_form.append("<input type='hidden' name='notify_users[]' class='people' value='" + $(this).val() + "' />");
      });
      upload_single_file();
    } // start_upload
    
    /**
     * set up basic stuff when page finishes loading
     */
    $(document).ready(function() {
      main_form = $('#main_form');
      upload_form = $('#multiupload_form');
      upload_table = $('.multiupload_table');
      
      // init table rows
      $('tr', upload_table).each(function () {
        init_multiupload_row($(this));
      });
      
      // add "new file" button handler
      $('.button_add', main_form).click(function () {
        image_src = $('tr:eq(1) .button_column img:eq(0)', upload_table).attr('src');
        upload_table.append(''+
        '<tr>' +
          '<td class="number"></td>' +
          '<td class="input"><input type="file" value="" name="attachment"/></td>' +
          '<td class="description"><input type="text" name="file[body]" /></td>' +
          '<td class="button_column"><img src="' + image_src + '" class="button_remove" /></td>' +
        '</tr>');
        init_multiupload_row(row.next());
        reindex_table_rows();
        return false;
      });
      
      // reindex table rows
      reindex_table_rows();
      
      // define upload_form behaviour
      upload_form.ajaxForm({ 
        success:    function(response) {
          /*
            because of wodoo magic with ajaxForm and file uploads, we can't use 
            error and success callbacks as we used to use them. In this special case
            error callback is called only when request is failed, not when server
            returns some of error headers, so we need to set up our serverside script
            to return strings 'error' when there is some http error, and string
            'success' if return is http ok.
          */
          if (response!=='success') {
            $("tr:eq(" + (current_row_id) + ") img:eq(0)", summary_table).attr('src', App.data.error_indicator_url);
            uploads_failed++;
          } else {
            $("tr:eq(" + (current_row_id) + ") img:eq(0)", summary_table).attr('src', App.data.ok_indicator_url);
            uploads_ok++;
          } // if
          upload_single_file();
        } ,
        error:      function() {
          $("tr:eq(" + (current_row_id) + ") img:eq(0)", summary_table).attr('src', App.data.error_indicator_url);
          uploads_failed++;
          upload_single_file();
        }
      });
      
      // upload button functionality
      $('#upload_files').click(function () {
        submit_multiupload_form();
      });
    });
    
  }
  
}

/** File: modules/discussions/javascript/main.js **/

App.discussions = {
  controllers : {},
  models      : {}
};

/**
 * Main discussions JS file
 */
App.discussions.controllers.discussions = {
  view : function() {
    $(document).ready(function() {
      $('#object_quick_option_details').click(function () {
        $('.discussion_details_toggled').toggle();
        return false;
      });
    });
  }
}