/*
 * 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';

/**
 * The first two numbers in the century to be used when decoding a two digit year. Since a two digit year is ambiguous (and date.setYear
 * only works with numbers < 99 and so doesn't allow you to set years after 2000) we need to use this to disambiguate the two digit year codes.
 *
 * @name format
 * @type String
 * @cat Plugins/Methods/Date
 * @author Kelvin Luck
 */
Date.fullYearStart = '20';

(function() {

	/**
	 * Adds a given method under the given name 
	 * to the Date prototype if it doesn't
	 * currently exist.
	 *
	 * @private
	 */
	var add = function(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.getFullYear() + '').substring(2))
			.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.setFullYear(Number(Date.fullYearStart + 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 :(
	};
	
})();/**
 * 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;
    }
};
(function(D){D.fn.extend({renderCalendar:function(P){var X=function(Y){return document.createElement(Y)};P=D.extend({month:null,year:null,renderCallback:null,showHeader:D.dpConst.SHOW_HEADER_SHORT,dpController:null,hoverClass:"dp-hover"},P);if(P.showHeader!=D.dpConst.SHOW_HEADER_NONE){var M=D(X("tr"));for(var S=Date.firstDayOfWeek;S<Date.firstDayOfWeek+7;S++){var H=S%7;var R=Date.dayNames[H];M.append(jQuery(X("th")).attr({scope:"col",abbr:R,title:R,"class":(H==0||H==6?"weekend":"weekday")}).html(P.showHeader==D.dpConst.SHOW_HEADER_SHORT?R.substr(0,1):R))}}var E=D(X("table")).attr({cellspacing:2,className:"jCalendar"}).append((P.showHeader!=D.dpConst.SHOW_HEADER_NONE?D(X("thead")).append(M):X("thead")));var F=D(X("tbody"));var U=(new Date()).zeroTime();var W=P.month==undefined?U.getMonth():P.month;var N=P.year||U.getFullYear();var K=new Date(N,W,1);var J=Date.firstDayOfWeek-K.getDay()+1;if(J>1){J-=7}var O=Math.ceil(((-1*J+1)+K.getDaysInMonth())/7);K.addDays(J-1);var V=function(){if(P.hoverClass){D(this).addClass(P.hoverClass)}};var G=function(){if(P.hoverClass){D(this).removeClass(P.hoverClass)}};var L=0;while(L++<O){var Q=jQuery(X("tr"));for(var S=0;S<7;S++){var I=K.getMonth()==W;var T=D(X("td")).text(K.getDate()+"").attr("className",(I?"current-month ":"other-month ")+(K.isWeekend()?"weekend ":"weekday ")+(I&&K.getTime()==U.getTime()?"today ":"")).hover(V,G);if(P.renderCallback){P.renderCallback(T,K,W,N)}Q.append(T);K.addDays(1)}F.append(Q)}E.append(F);return this.each(function(){D(this).empty().append(E)})},datePicker:function(E){if(!D.event._dpCache){D.event._dpCache=[]}E=D.extend({month:undefined,year:undefined,startDate:undefined,endDate:undefined,inline:false,renderCallback:[],createButton:true,showYearNavigation:true,closeOnSelect:true,displayClose:false,selectMultiple:false,clickInput:false,verticalPosition:D.dpConst.POS_TOP,horizontalPosition:D.dpConst.POS_LEFT,verticalOffset:0,horizontalOffset:0,hoverClass:"dp-hover"},E);return this.each(function(){var G=D(this);var I=true;if(!this._dpId){this._dpId=D.event.guid++;D.event._dpCache[this._dpId]=new A(this);I=false}if(E.inline){E.createButton=false;E.displayClose=false;E.closeOnSelect=false;G.empty()}var F=D.event._dpCache[this._dpId];F.init(E);if(!I&&E.createButton){F.button=D('<a href="#" class="dp-choose-date" title="'+D.dpText.TEXT_CHOOSE_DATE+'">'+D.dpText.TEXT_CHOOSE_DATE+"</a>").bind("click",function(){G.dpDisplay(this);this.blur();return false});G.after(F.button)}if(!I&&G.is(":text")){G.bind("dateSelected",function(K,J,L){this.value=J.asString()}).bind("change",function(){var J=Date.fromString(this.value);if(J){F.setSelected(J,true,true)}});if(E.clickInput){G.bind("click",function(){G.dpDisplay()})}var H=Date.fromString(this.value);if(this.value!=""&&H){F.setSelected(H,true,true)}}G.addClass("dp-applied")})},dpSetDisabled:function(E){return B.call(this,"setDisabled",E)},dpSetStartDate:function(E){return B.call(this,"setStartDate",E)},dpSetEndDate:function(E){return B.call(this,"setEndDate",E)},dpGetSelected:function(){var E=C(this[0]);if(E){return E.getSelected()}return null},dpSetSelected:function(G,F,E){if(F==undefined){F=true}if(E==undefined){E=true}return B.call(this,"setSelected",Date.fromString(G),F,E)},dpSetDisplayedMonth:function(E,F){return B.call(this,"setDisplayedMonth",Number(E),Number(F))},dpDisplay:function(E){return B.call(this,"display",E)},dpSetRenderCallback:function(E){return B.call(this,"setRenderCallback",E)},dpSetPosition:function(E,F){return B.call(this,"setPosition",E,F)},dpSetOffset:function(E,F){return B.call(this,"setOffset",E,F)},dpClose:function(){return B.call(this,"_closeCalendar",false,this[0])},_dpDestroy:function(){}});var B=function(G,F,E,H){return this.each(function(){var I=C(this);if(I){I[G](F,E,H)}})};function A(E){this.ele=E;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"}D.extend(A.prototype,{init:function(E){this.setStartDate(E.startDate);this.setEndDate(E.endDate);this.setDisplayedMonth(Number(E.month),Number(E.year));this.setRenderCallback(E.renderCallback);this.showYearNavigation=E.showYearNavigation;this.closeOnSelect=E.closeOnSelect;this.displayClose=E.displayClose;this.selectMultiple=E.selectMultiple;this.verticalPosition=E.verticalPosition;this.horizontalPosition=E.horizontalPosition;this.hoverClass=E.hoverClass;this.setOffset(E.verticalOffset,E.horizontalOffset);this.inline=E.inline;if(this.inline){this.context=this.ele;this.display()}},setStartDate:function(E){if(E){this.startDate=Date.fromString(E)}if(!this.startDate){this.startDate=(new Date()).zeroTime()}this.setDisplayedMonth(this.displayedMonth,this.displayedYear)},setEndDate:function(E){if(E){this.endDate=Date.fromString(E)}if(!this.endDate){this.endDate=(new Date("12/31/2999"))}if(this.endDate.getTime()<this.startDate.getTime()){this.endDate=this.startDate}this.setDisplayedMonth(this.displayedMonth,this.displayedYear)},setPosition:function(E,F){this.verticalPosition=E;this.horizontalPosition=F},setOffset:function(E,F){this.verticalOffset=parseInt(E)||0;this.horizontalOffset=parseInt(F)||0},setDisabled:function(E){$e=D(this.ele);$e[E?"addClass":"removeClass"]("dp-disabled");if(this.button){$but=D(this.button);$but[E?"addClass":"removeClass"]("dp-disabled");$but.attr("title",E?"":D.dpText.TEXT_CHOOSE_DATE)}if($e.is(":text")){$e.attr("disabled",E?"disabled":"")}},setDisplayedMonth:function(E,I){if(this.startDate==undefined||this.endDate==undefined){return}var G=new Date(this.startDate.getTime());G.setDate(1);var H=new Date(this.endDate.getTime());H.setDate(1);var F;if((!E&&!I)||(isNaN(E)&&isNaN(I))){F=new Date().zeroTime();F.setDate(1)}else{if(isNaN(E)){F=new Date(I,this.displayedMonth,1)}else{if(isNaN(I)){F=new Date(this.displayedYear,E,1)}else{F=new Date(I,E,1)}}}if(F.getTime()<G.getTime()){F=G}else{if(F.getTime()>H.getTime()){F=H}}this.displayedMonth=F.getMonth();this.displayedYear=F.getFullYear()},setSelected:function(G,E,F){if(this.selectMultiple==false){this.selectedDates={};D("td.selected",this.context).removeClass("selected")}if(F){this.setDisplayedMonth(G.getMonth(),G.getFullYear())}this.selectedDates[G.toString()]=E},isSelected:function(E){return this.selectedDates[E.toString()]},getSelected:function(){var E=[];for(s in this.selectedDates){if(this.selectedDates[s]==true){E.push(Date.parse(s))}}return E},display:function(E){if(D(this.ele).is(".dp-disabled")){return}E=E||this.ele;var L=this;var H=D(E);var K=H.offset();var M;var N;var G;var I;if(L.inline){M=D(this.ele);N={id:"calendar-"+this.ele._dpId,className:"dp-popup dp-popup-inline"};I={}}else{M=D("body");N={id:"dp-popup",className:"dp-popup"};I={top:K.top+L.verticalOffset,left:K.left+L.horizontalOffset};var J=function(Q){var O=Q.target;var P=D("#dp-popup")[0];while(true){if(O==P){return true}else{if(O==document){L._closeCalendar();return false}else{O=D(O).parent()[0]}}}};this._checkMouse=J;this._closeCalendar(true)}M.append(D("<div></div>").attr(N).css(I).append(D("<h2></h2>"),D('<div class="dp-nav-prev"></div>').append(D('<a class="dp-nav-prev-year" href="#" title="'+D.dpText.TEXT_PREV_YEAR+'">&laquo;</a>').bind("click",function(){return L._displayNewMonth.call(L,this,0,-1)}),D('<a class="dp-nav-prev-month" href="#" title="'+D.dpText.TEXT_PREV_MONTH+'">&lt;</a>').bind("click",function(){return L._displayNewMonth.call(L,this,-1,0)})),D('<div class="dp-nav-next"></div>').append(D('<a class="dp-nav-next-year" href="#" title="'+D.dpText.TEXT_NEXT_YEAR+'">&raquo;</a>').bind("click",function(){return L._displayNewMonth.call(L,this,0,1)}),D('<a class="dp-nav-next-month" href="#" title="'+D.dpText.TEXT_NEXT_MONTH+'">&gt;</a>').bind("click",function(){return L._displayNewMonth.call(L,this,1,0)})),D("<div></div>").attr("className","dp-calendar")).bgIframe());var F=this.inline?D(".dp-popup",this.context):D("#dp-popup");if(this.showYearNavigation==false){D(".dp-nav-prev-year, .dp-nav-next-year",L.context).css("display","none")}if(this.displayClose){F.append(D('<a href="#" id="dp-close">'+D.dpText.TEXT_CLOSE+"</a>").bind("click",function(){L._closeCalendar();return false}))}L._renderCalendar();D(this.ele).trigger("dpDisplayed",F);if(!L.inline){if(this.verticalPosition==D.dpConst.POS_BOTTOM){F.css("top",K.top+H.height()-F.height()+L.verticalOffset)}if(this.horizontalPosition==D.dpConst.POS_RIGHT){F.css("left",K.left+H.width()-F.width()+L.horizontalOffset)}D(document).bind("mousedown",this._checkMouse)}},setRenderCallback:function(E){if(E&&typeof(E)=="function"){E=[E]}this.renderCallback=this.renderCallback.concat(E)},cellRender:function(J,E,H,G){var K=this.dpController;var I=new Date(E.getTime());J.bind("click",function(){var M=D(this);if(!M.is(".disabled")){K.setSelected(I,!M.is(".selected")||!K.selectMultiple);var L=K.isSelected(I);D(K.ele).trigger("dateSelected",[I,J,L]);D(K.ele).trigger("change");if(K.closeOnSelect){K._closeCalendar()}else{M[L?"addClass":"removeClass"]("selected")}}});if(K.isSelected(I)){J.addClass("selected")}for(var F=0;F<K.renderCallback.length;F++){K.renderCallback[F].apply(this,arguments)}},_displayNewMonth:function(F,E,G){if(!D(F).is(".disabled")){this.setDisplayedMonth(this.displayedMonth+E,this.displayedYear+G);this._clearCalendar();this._renderCalendar();D(this.ele).trigger("dpMonthChanged",[this.displayedMonth,this.displayedYear])}F.blur();return false},_renderCalendar:function(){D("h2",this.context).html(Date.monthNames[this.displayedMonth]+" "+this.displayedYear);D(".dp-calendar",this.context).renderCalendar({month:this.displayedMonth,year:this.displayedYear,renderCallback:this.cellRender,dpController:this,hoverClass:this.hoverClass});if(this.displayedYear==this.startDate.getFullYear()&&this.displayedMonth==this.startDate.getMonth()){D(".dp-nav-prev-year",this.context).addClass("disabled");D(".dp-nav-prev-month",this.context).addClass("disabled");D(".dp-calendar td.other-month",this.context).each(function(){var H=D(this);if(Number(H.text())>20){H.addClass("disabled")}});var G=this.startDate.getDate();D(".dp-calendar td.current-month",this.context).each(function(){var H=D(this);if(Number(H.text())<G){H.addClass("disabled")}})}else{D(".dp-nav-prev-year",this.context).removeClass("disabled");D(".dp-nav-prev-month",this.context).removeClass("disabled");var G=this.startDate.getDate();if(G>20){var F=new Date(this.startDate.getTime());F.addMonths(1);if(this.displayedYear==F.getFullYear()&&this.displayedMonth==F.getMonth()){D("dp-calendar td.other-month",this.context).each(function(){var H=D(this);if(Number(H.text())<G){H.addClass("disabled")}})}}}if(this.displayedYear==this.endDate.getFullYear()&&this.displayedMonth==this.endDate.getMonth()){D(".dp-nav-next-year",this.context).addClass("disabled");D(".dp-nav-next-month",this.context).addClass("disabled");D(".dp-calendar td.other-month",this.context).each(function(){var H=D(this);if(Number(H.text())<14){H.addClass("disabled")}});var G=this.endDate.getDate();D(".dp-calendar td.current-month",this.context).each(function(){var H=D(this);if(Number(H.text())>G){H.addClass("disabled")}})}else{D(".dp-nav-next-year",this.context).removeClass("disabled");D(".dp-nav-next-month",this.context).removeClass("disabled");var G=this.endDate.getDate();if(G<13){var E=new Date(this.endDate.getTime());E.addMonths(-1);if(this.displayedYear==E.getFullYear()&&this.displayedMonth==E.getMonth()){D(".dp-calendar td.other-month",this.context).each(function(){var H=D(this);if(Number(H.text())>G){H.addClass("disabled")}})}}}},_closeCalendar:function(E,F){if(!F||F==this.ele){D(document).unbind("mousedown",this._checkMouse);this._clearCalendar();D("#dp-popup a").unbind();D("#dp-popup").empty().remove();if(!E){D(this.ele).trigger("dpClosed",[this.getSelected()])}}},_clearCalendar:function(){D(".dp-calendar td",this.context).unbind();D(".dp-calendar",this.context).empty()}});D.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};D.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"};D.dpVersion="$Id: jquery.datePicker.js 3739 2007-10-25 13:55:30Z kelvin.luck $";function C(E){if(E._dpId){return D.event._dpCache[E._dpId]}return false}if(D.fn.bgIframe==undefined){D.fn.bgIframe=function(){return this}}D(window).bind("unload",function(){var F=D.event._dpCache||[];for(var E in F){D(F[E].ele)._dpDestroy()}})})(jQuery);/**
 * n2dimmable 0.1
 */

(function($) {
    $.fn.n2dimmable = function(options) {
        var selector = this.selector;
        options = $.extend(options, { dimmerClass: "dimmed", valuesSelector: "input[type='text'], input[type='file']" });
        var toggleDimmer = function() {
            var $t = $(this).closest(selector);
            $t.siblings().addClass(options.dimmerClass);
            $t.removeClass(options.dimmerClass);
        };
        var checkDimming = function() {
            var $t = $(this).closest(selector);
            var $inputs = $t.siblings().andSelf().contents().filter(options.valuesSelector);
            $inputs.each(function() {
                if (this.value) {
                    toggleDimmer.call(this);
                }
            });
        };
        this.click(toggleDimmer)
    					.contents().filter("input")
    						.focus(toggleDimmer)
    						.blur(checkDimming);
    };
})(jQuery);
(function($) {
	$.fn.n2expandable = function(args) {
		var $children = this.children();
		if (args.visible)
			$children = $children.not(args.visible);

		if ($children.length == 0)
			return;

		var text = "Details";
		if (text = this.attr("title"))
			this.attr("title", "");

		var $expander = (args.expander)
			? $(args.expander)
			: $("<a href='#' class='expander'>" + text + "</a>");

		$expander.prependTo(this);

		var self = this;
		$expander.click(function(e) {
			if (self.is(".expandable-expanded")) {
				$children.hide();
				self.removeClass("expandable-expanded");
				self.addClass("expandable-contracted");
			} else {
				$children.fadeIn();
				self.addClass("expandable-expanded");
				self.removeClass("expandable-contracted");
			}
			e.preventDefault();
			e.stopPropagation();
		});
		this.click(function(e) {
			if (!self.is(".expandable-expanded")) {
				$children.fadeIn();
				self.addClass("expandable-expanded");
				self.removeClass("expandable-contracted");
			}
		});

		$children.hide();
		this.addClass("expandable-contracted");
	};
})(jQuery);/**
 * n2glow 0.1
 */

(function($) {
    var left = 0;
    var width = 80;
    var bgWidth = 80;

    var over = function() {
        var $t = $(this);
        left = $t.position().left;
        width = $t.width();
        $t.css({ backgroundPosition: "50% 0px" });
    };

    var out = function(e) {
        $(this).animate({ backgroundPosition: "0 0" });
    }

    var move = function(e) {
        var pixels = (e.clientX - left) - bgWidth / 2;
        $(this).css({ backgroundPosition: pixels + "px 10px" });
    };

    $.fn.n2glow = function() {
        return this.hover(over, out).mousemove(move);
    };
})(jQuery);
/**
* n2name 0.1
*/

(function($) {
    function getName(titleid, whitespace, tolower, replacements){
        var titleBox=document.getElementById(titleid);
        var name = titleBox.value.replace(/[.]+/g, '-')
	        .replace(/[%?&/+:<>]/g, '')
	        .replace(/\s+/g, whitespace)
	        .replace(/[-]+/g, '-')
	        .replace(/[-]+$/g, '');
        if(tolower) name = name.toLowerCase();
        for (var i in replacements){
	        name = name.replace(replacements[i].pattern, replacements[i].value);
        }
        return name;
    };
    
    function updateName(titleid, nameid, whitespace, tolower, replacements, checkboxid){
        var name = getName(titleid, whitespace, tolower, replacements);
        if(checkboxid && document.getElementById(checkboxid).checked)
	        document.getElementById(nameid).value = name;
    };

    function checkboxHandler(){
        var checked = $(this).find('input').attr('checked');
        if (checked) $(this).removeClass('unchecked').siblings('input').removeAttr('disabled');
        else         $(this).addClass('unchecked').siblings('input').attr('disabled', true);
    };
    
    function toggleChecked($cb){
        if($cb.attr("checked"))
            $cb.removeAttr("checked");
        else
            $cb.attr("checked", true);
    };
    
    $.fn.n2name = function(options) {
        var invokeUpdateName = function(){
	        updateName(options.titleId, options.nameId, options.whitespaceReplacement, options.toLower, options.replacements, options.keepUpdatedBoxId);
        };
        if(options.keepUpdatedBoxId){
            var $ku = $(this).siblings(".keepUpdated");
            
            $ku.click(function(e,stop) {
                toggleChecked($(this).find('input'));
                checkboxHandler.call(this);
            });
            
            $("#" + options.titleId).keyup(invokeUpdateName);

            var expected = getName(options.titleId, options.whitespaceReplacement, options.toLower, options.replacements);
            var actual = $("#" + options.nameId).attr("value");
            if(!expected || !actual || (expected == actual))
                $ku.each(checkboxHandler)
            else
                $ku.trigger('click');
        }
    };
})(jQuery);
/**
 * n2optionmenu 0.1
 */

(function($) {
    $.fn.n2optionmenu = function(options) {
        settings = {
            wrapper: "<div class='commandOptions closed'></div>",
            opener: "<span class='opener'><img src='img/ico/png/bullet_arrow_down.png' alt='more options'/></span>",
            closedClass: "closed"
        };
        $.extend(settings, options || {});

        var closable = false;
        var $menu = this;

        var $wrapper = $menu.wrap(settings.wrapper);
        var closeMenu = function() {
            if (closable)
                $wrapper.parent().addClass(settings.closedClass);
        };
        var openMenu = function(e) {
            e.stopPropagation();
            e.preventDefault();
            closable = false;
            $wrapper.parent().toggleClass(settings.closedClass);
            setTimeout(function() { closable = true; }, 10);
        };

        var $firstEnabled = $menu.children().not("a[disabled='disabled']").not("a[disabled='true']").slice(0, 1);
        $firstEnabled.clone(true).insertBefore($menu)
			.bind('contextmenu', openMenu)
			.after(settings.opener)
			.next().click(openMenu);
        $(document.body).click(closeMenu);
        return $menu;
    }
})(jQuery);

/*
 * n2tabs 0.2 - Copyright (c) 2007 Cristian Libardo
 */

(function($) {
	// initializes elements in query selection as tabs
	$.fn.n2tabs = function(tabGroupName, initial, tabContainer) {
		if (this.length > 0) {
			if (!tabGroupName) tabGroupName = "tab";
			if (!tabContainer) tabContainer = this.n2tabs_createContainer(this.get(0));

			// ensure each tab content has an id
			this.each(function(i) {
				if (!this.id) this.id = tabGroupName + i;
				this.n2tab = { index: i,
					group: tabGroupName
				};
			});

			// ensure there's an initial tab
			var $current = this.filter(initial);
			if ($current.length == 0) {
				// try to select enclosing tab when nested tab is selected
				var $vertical = $(initial).parents(this.selector);
				$current = this.filter(function() { return $vertical.filter(this).length > 0 });
			}
			if ($current.length == 0)
				$current = $(this[0]);

			// store information about this tab group
			var tabSettings = {
				query: this,
				container: $(tabContainer),
				current: $current,
				tabs: new Array()
			};
			this.n2tabs_groups[tabGroupName] = tabSettings;

			this.n2tabs_buildTabs(tabSettings);

			this.addClass("tabContentHidden");
			this.n2tabs_show(tabSettings.current);

			document.documentElement.scrollTop = 0;
		}

		return this;
	}

	// an array of tab groups (multiple tabs are supported)
	$.fn.n2tabs_groups = new Array();

	// creates a tab container element
	$.fn.n2tabs_createContainer = function(firstContents) {
		return $(firstContents).before("<ul class='tabs'></ul>").prev().get(0);
	}

	// creates a tab element
	$.fn.n2tabs_createTab = function(containerQuery, tabContents, index) {
		var li = "<li>";
		if (index == 0)
			li = "<li class='first'>";
		containerQuery.append(li + "<a href='#" + tabContents.id + "'>" + tabContents.title + "</a></li>");
		tabContents.title = "";
	}

	// creates tab elements (ul:s and li:s) above the first tab content element
	$.fn.n2tabs_buildTabs = function(tabSettings) {
		var lastIndex = tabSettings.query.length - 1;
		tabSettings.query.each(function(i) {
			var className = "tab";
			if (i == 0) className = className + " first";
			if (i == lastIndex) className = className + " last";
			tabSettings.container.n2tabs_createTab(tabSettings.container, this, className);
		});
		$("a", tabSettings.container).each(function(i) {
			tabSettings.tabs[i] = $(this);
		}).click(function() {
			if (this.hash != location.hash)
				$.fn.n2tabs_show($(this.hash), $(this));
			else
				return false;
		});
	}

	$.fn.n2tabs_handlePostBack = function(tabId) {
		if (tabId && document.forms.length > 0) {
			var f = document.forms[0];
			var index = f.action.indexOf("#");
			if (index > 0)
				f.action = f.action.substr(0, index) + "#" + tabId;
			else
				f.action += "#" + tabId;
		}
	}

	// gets the settings for the first tab content in query selection
	$.fn.n2tab_settings = function() {
		var first = this.get(0).n2tab.group;
		return this.n2tabs_groups[first];
	}

	// gets the tab for the first tab content in query selection
	$.fn.n2tab_getTab = function() {
		var t = this.get(0).n2tab;
		return this.n2tabs_groups[t.group].tabs[t.index];
	}

	// show contents defined by the given expression
	$.fn.n2tabs_show = function(contents, tab) {
		var tabSettings = contents.n2tab_settings();

		// show tab contents    
		tabSettings.current.addClass("tabContentHidden");
		tabSettings.current = contents;
		contents.removeClass("tabContentHidden");

		// select tab
		if (!tab) tab = contents.n2tab_getTab();
		$(".selected", tabSettings.container).removeClass("selected");
		tab.blur().parent().addClass("selected");

		// this prevents page from scrolling (stolen from jquery.tabs)
		var toShowId = contents.attr('id');
		contents.attr('id', '');
		setTimeout(function() {
			contents.attr('id', toShowId); // restore id
		}, 200);
		this.n2tabs_handlePostBack(toShowId);
	}
})(jQuery);$.fn.SimpleTree = function(opt) {
	this.each(function() {
		var TREE = this;
		var ROOT = $('li:first', this);
		TREE.option = {
			animate: false, 	// this parameter has a value "true/false" (enable/disable animation for expanding/collapsing menu items) 
			autoclose: false, // this parameter has a value "true/false" (enable/disable collapse of neighbor branches)
			speed: 'fast', 	// speed open/close folder
			success: false, 	// this parameter defines function, which executes after ajax is loaded (set to "false" by default)
			click: false		// this parameter defines function, which is executed after item clicked (set to "false" by default) 

		};
		TREE.option = $.extend(TREE.option, opt);
		TREE.setAjaxNodes = function(obj) {
			var url = $.trim($('>li', obj).text());
			if (url && url.indexOf('url:')) {
				url = $.trim(url.replace(/.*\{url:(.*)\}/i, '$1'));
				$.ajax({
					type: "GET",
					url: url,
					contentType: 'html',
					cache: false,
					success: function(response) {
						if (response) {
							obj.removeAttr('class');
							obj.html(response);
							TREE.setTreeNodes(obj, true);
							if (typeof TREE.option.success == 'function') {
								TREE.option.success(obj);
							}
						} else {
							var parent = obj.parent();
							var pClassName = parent.attr('class');
							pClassName = pClassName.replace('folder-open', 'leaf');
							parent.attr('class', pClassName);
							obj.remove();
							$('.toggler', parent).remove();
						}
					}
				});
			}
		};
		TREE.closeNearby = function(obj) {
			$(obj).siblings().filter('.folder-open, .folder-open-last').each(function() {
				var childUl = $('>ul', this);
				var className = this.className;
				className = className.replace('open', 'close');
				$(this).attr('class', className);
				if (TREE.option.animate) {
					childUl.animate({ height: "toggle" }, TREE.option.speed);
				} else {
					childUl.hide();
				}
			});
		};
		TREE.setEventToggler = function(obj) {
			$(obj).prepend('<a class="toggler" href="#">&nbsp;</a>');
			$('>.toggler', obj).bind('click', function(e) {
				e.preventDefault();
				
				var childUl = $('>ul', obj);
				var className = obj.className;
				if (childUl.is(':visible')) {
					className = className.replace('open', 'close');
					$(obj).attr('class', className);
					if (TREE.option.animate) {
						childUl.animate({ height: "toggle" }, TREE.option.speed);
					} else {
						childUl.hide();
					}
				} else {
					className = className.replace('close', 'open');
					$(obj).attr('class', className);
					if (TREE.option.animate) {
						childUl.animate({ height: "toggle" }, TREE.option.speed, function() {
							if (TREE.option.autoclose) TREE.closeNearby(obj);
							if (childUl.is('.ajax')) TREE.setAjaxNodes(childUl);
						});
					} else {
						childUl.show();
						if (TREE.option.autoclose) TREE.closeNearby(obj);
						if (childUl.is('.ajax')) TREE.setAjaxNodes(childUl);
					}
				}
			});
		};
		TREE.setTreeNodes = function(obj, useParent) {
			obj = useParent ? obj.parent() : obj;
			$('li', obj).each(function(i) {
				var className = this.className;
				var open = false;
				var childNode = $('>ul', this);

				if (childNode.size() > 0) {
					var setClassName = 'folder-';
					if (className && className.indexOf('open') >= 0) {
						setClassName = setClassName + 'open';
						open = true;
					} else {
						setClassName = setClassName + 'close';
					}
					this.className = setClassName + ($(this).is(':last-child') ? '-last' : '');
					TREE.setEventToggler(this);
					if (!open || className.indexOf('ajax') >= 0) childNode.hide();

				} else {
					var setClassName = 'leaf';
					this.className = setClassName + ($(this).is(':last-child') ? '-last' : '');
				}
				//				$('>.text, >.active',this).bind('click', function(){
				//					$('.active',TREE).attr('class','text');
				//					$(this).attr('class','active');
				//					if(typeof TREE.option.click == 'function')
				//					{
				//						TREE.option.click(this);
				//					}
				//				});
			});
		};


		TREE.init = function(obj) {
			TREE.setTreeNodes(obj);
		};
		TREE.init(ROOT);
	});
}/*
* jQuery.splitter.js - two-pane splitter window plugin
*
* version 1.51 (2009/01/09) 
* 
* Dual licensed under the MIT and GPL licenses: 
*   http://www.opensource.org/licenses/mit-license.php 
*   http://www.gnu.org/licenses/gpl.html 
*/

/**
* The splitter() plugin implements a two-pane resizable splitter window.
* The selected elements in the jQuery object are converted to a splitter;
* each selected element should have two child elements, used for the panes
* of the splitter. The plugin adds a third child element for the splitbar.
* 
* For more details see: http://methvin.com/splitter/
*
*
* @example $('#MySplitter').splitter();
* @desc Create a vertical splitter with default settings 
*
* @example $('#MySplitter').splitter({type: 'h', accessKey: 'M'});
* @desc Create a horizontal splitter resizable via Alt+Shift+M
*
* @name splitter
* @type jQuery
* @param Object options Options for the splitter (not required)
* @cat Plugins/Splitter
* @return jQuery
* @author Dave Methvin (dave.methvin@gmail.com)
*/
; (function($) {

    $.fn.splitter = function(args) {
        args = args || {};
        return this.each(function() {
            var zombie; 	// left-behind splitbar for outline resizes
            function startSplitMouse(evt) {
                if (opts.outline)
                    zombie = zombie || bar.clone(false).insertAfter(A);
                panes.css("-webkit-user-select", "none"); // Safari selects A/B text on a move
                bar.addClass(opts.activeClass).parent().addClass(opts.containerActiveClass);
                A._posSplit = A[0][opts.pxSplit] - evt[opts.eventPos];
                $(document)
				.bind("mousemove", doSplitMouse)
				.bind("mouseup", endSplitMouse);
                opts.onStart.call(bar, evt);
            }
            function doSplitMouse(evt) {
                var newPos = A._posSplit + evt[opts.eventPos];
                if (opts.outline) {
                    newPos = Math.max(0, Math.min(newPos, splitter._DA - bar._DA));
                    bar.css(opts.origin, newPos);
                } else
                    resplit(newPos);
            }
            function endSplitMouse(evt) {
                bar.removeClass(opts.activeClass).parent().removeClass(opts.containerActiveClass);
                var newPos = A._posSplit + evt[opts.eventPos];
                if (opts.outline) {
                    zombie.remove(); zombie = null;
                    resplit(newPos);
                }
                panes.css("-webkit-user-select", "text"); // let Safari select text again
                $(document)
				.unbind("mousemove", doSplitMouse)
				.unbind("mouseup", endSplitMouse);
                opts.onStop.call(bar, evt);
            }
            function resplit(newPos) {
                // Constrain new splitbar position to fit pane size limits
                newPos = Math.max(A._min, splitter._DA - B._max,
					Math.min(newPos, A._max, splitter._DA - bar._DA - B._min));
                // Resize/position the two panes
                bar._DA = bar[0][opts.pxSplit]; 	// bar size may change during dock
                bar.css(opts.origin, newPos).css(opts.fixed, splitter._DF);
                A.css(opts.origin, 0).css(opts.split, newPos).css(opts.fixed, splitter._DF);
                B.css(opts.origin, newPos + bar._DA)
				.css(opts.split, splitter._DA - bar._DA - newPos).css(opts.fixed, splitter._DF);
                // IE fires resize for us; all others pay cash
                if (!$.browser.msie)
                    panes.trigger("resize");
            }
            function dimSum(jq, dims) {
                // Opera returns -1 for missing min/max width, turn into 0
                var sum = 0;
                for (var i = 1; i < arguments.length; i++)
                    sum += Math.max(parseInt(jq.css(arguments[i])) || 0, 0);
                return sum;
            }

            // Determine settings based on incoming opts, element classes, and defaults
            var vh = (args.splitHorizontal ? 'h' : args.splitVertical ? 'v' : args.type) || 'v';
            var opts = $.extend({
                activeClass: 'active', // class name for active splitter
                onStart: function(){},
                onStop: function(){},
                pxPerKey: 8, 		// splitter px moved per keypress
                tabIndex: 0, 		// tab order indicator
                accessKey: ''			// accessKey for splitbar
            }, {
                v: {					// Vertical splitters:
                    keyLeft: 39, keyRight: 37, cursor: "e-resize",
                    splitbarClass: "vsplitbar", outlineClass: "voutline",
                    type: 'v', eventPos: "pageX", origin: "left",
                    split: "width", pxSplit: "offsetWidth", side1: "Left", side2: "Right",
                    fixed: "height", pxFixed: "offsetHeight", side3: "Top", side4: "Bottom"
                },
                h: {					// Horizontal splitters:
                    keyTop: 40, keyBottom: 38, cursor: "n-resize",
                    splitbarClass: "hsplitbar", outlineClass: "houtline",
                    type: 'h', eventPos: "pageY", origin: "top",
                    split: "height", pxSplit: "offsetHeight", side1: "Top", side2: "Bottom",
                    fixed: "width", pxFixed: "offsetWidth", side3: "Left", side4: "Right"
                }
}[vh], args);

                // Create jQuery object closures for splitter and both panes
                var splitter = $(this).css({ position: "relative" });
                var panes = $(">*", splitter[0]).css({
                    position: "absolute", 			// positioned inside splitter container
                    "z-index": "1", 				// splitbar is positioned above
                    "-moz-outline-style": "none"	// don't show dotted outline
                });
                var A = $(panes[0]); 	// left  or top
                var B = $(panes[1]); 	// right or bottom

                // Focuser element, provides keyboard support; title is shown by Opera accessKeys
                var focuser = $('<a href="javascript:void(0)"></a>')
			.attr({ accessKey: opts.accessKey, tabIndex: opts.tabIndex, title: opts.splitbarClass })
			.bind($.browser.opera ? "click" : "focus", function() { this.focus(); bar.addClass(opts.activeClass) })
			.bind("keydown", function(e) {
			    var key = e.which || e.keyCode;
			    var dir = key == opts["key" + opts.side1] ? 1 : key == opts["key" + opts.side2] ? -1 : 0;
			    if (dir)
			        resplit(A[0][opts.pxSplit] + dir * opts.pxPerKey, false);
			})
			.bind("blur", function() { bar.removeClass(opts.activeClass) });

                // Splitbar element, can be already in the doc or we create one
                var bar = $(panes[2] || '<div></div>')
			.insertAfter(A).css("z-index", "100").append(focuser)
			.attr({ "class": opts.splitbarClass, unselectable: "on" })
			.css({ position: "absolute", "user-select": "none", "-webkit-user-select": "none",
			    "-khtml-user-select": "none", "-moz-user-select": "none"
			})
			.bind("mousedown", startSplitMouse);
                // Use our cursor unless the style specifies a non-default cursor
                if (/^(auto|default|)$/.test(bar.css("cursor")))
                    bar.css("cursor", opts.cursor);

                // Cache several dimensions for speed, rather than re-querying constantly
                bar._DA = bar[0][opts.pxSplit];
                splitter._PBF = $.boxModel ? dimSum(splitter, "border" + opts.side3 + "Width", "border" + opts.side4 + "Width") : 0;
                splitter._PBA = $.boxModel ? dimSum(splitter, "border" + opts.side1 + "Width", "border" + opts.side2 + "Width") : 0;
                A._pane = opts.side1;
                B._pane = opts.side2;
                $.each([A, B], function() {
                    this._min = opts["min" + this._pane] || dimSum(this, "min-" + opts.split);
                    this._max = opts["max" + this._pane] || dimSum(this, "max-" + opts.split) || 9999;
                    this._init = opts["size" + this._pane] === true ?
				parseInt($.curCSS(this[0], opts.split)) : opts["size" + this._pane];
                });

                // Determine initial position, get from cookie if specified
                var initPos = A._init;
                if (!isNaN(B._init))	// recalc initial B size as an offset from the top or left side
                    initPos = splitter[0][opts.pxSplit] - splitter._PBA - B._init - bar._DA;
                if (opts.cookie) {
                    if (!$.cookie)
                        alert('jQuery.splitter(): jQuery cookie plugin required');
                    var ckpos = parseInt($.cookie(opts.cookie));
                    if (!isNaN(ckpos))
                        initPos = ckpos;
                    $(window).bind("unload", function() {
                        var state = String(bar.css(opts.origin)); // current location of splitbar
                        $.cookie(opts.cookie, state, { expires: opts.cookieExpires || 365,
                            path: opts.cookiePath || document.location.pathname
                        });
                    });
                }
                if (isNaN(initPos))	// King Solomon's algorithm
                    initPos = Math.round((splitter[0][opts.pxSplit] - splitter._PBA - bar._DA) / 2);

                // Resize event propagation and splitter sizing
                if (opts.anchorToWindow) {
                    // Account for margin or border on the splitter container and enforce min height
                    splitter._hadjust = dimSum(splitter, "borderTopWidth", "borderBottomWidth", "marginBottom");
                    splitter._hmin = Math.max(dimSum(splitter, "minHeight"), 20);
                    $(window).bind("resize", function() {
                        var top = splitter.offset().top;
                        var wh = $(window).height();
                        splitter.css("height", Math.max(wh - top - splitter._hadjust, splitter._hmin) + "px");
                        if (!$.browser.msie) splitter.trigger("resize");
                    }).trigger("resize");
                }
                else if (opts.resizeToWidth && !$.browser.msie)
                    $(window).bind("resize", function() {
                        splitter.trigger("resize");
                    });

                // Resize event handler; triggered immediately to set initial position
                splitter.bind("resize", function(e, size) {
                    // Custom events bubble in jQuery 1.3; don't Yo Dawg
                    if (e.target != this) return;
                    // Determine new width/height of splitter container
                    splitter._DF = splitter[0][opts.pxFixed] - splitter._PBF;
                    splitter._DA = splitter[0][opts.pxSplit] - splitter._PBA;
                    // Bail if splitter isn't visible or content isn't there yet
                    if (splitter._DF <= 0 || splitter._DA <= 0) return;
                    // Re-divvy the adjustable dimension; maintain size of the preferred pane
                    resplit(!isNaN(size) ? size : (!(opts.sizeRight || opts.sizeBottom) ? A[0][opts.pxSplit] :
				splitter._DA - B[0][opts.pxSplit] - bar._DA));
                }).trigger("resize", [initPos]);
            });
        };

    })(jQuery);// NAVIGATION
var n2nav = new Object();

n2nav.linkContainerId = null;
n2nav.hostName = window.location.hostname;
n2nav.toRelativeUrl = function(absoluteUrl) {
    if(absoluteUrl.indexOf(n2nav.hostName)>0)
        return absoluteUrl.replace(/.*?:\/\/.*?\//, "/");
    return absoluteUrl;
}
n2nav.onUrlSelected = null;
n2nav.findLink = function(el) {
	while(el && el.tagName != "A")
		el = el.parentNode;
	return el;
}

n2nav.displaySelection = function(el){
    $(".selected").removeClass("selected");
    $(el).addClass("selected");
}

n2nav.getPath = function(a) {
	return $(a).attr("data-path");
}
n2nav.onTargetClick = function(el){
    n2nav.displaySelection(el);
    if(n2nav.onUrlSelected)
    	n2nav.onUrlSelected(n2nav.getPath(el));
}

n2nav.handlers = {
	fallback: function(e) {
		n2nav.onTargetClick(this)
		n2nav.setupToolbar(n2nav.getPath(this), this.href);
	}
};

n2nav.setupToolbar = function(path, url) {
	n2ctx.update({ path: path, previewUrl: url });
}



// EDIT
var n2toggle = {
    show: function(btn, bar) {
        $(btn).addClass("toggled").blur();
        $(bar).show();
        $.cookie(bar, "show");
    },
    hide: function(btn, bar) {
        $(btn).removeClass("toggled").blur();
        $(bar).hide();
        $.cookie(bar, null)
    }
};

var initn2context = function(w) {
	if (w.n2ctx)
		return w.n2ctx;

	try {
		if (w.name != "top" && w != w.parent) {
			w.n2ctx = initn2context(w.parent);
			return w.n2ctx;
		}
	} catch (e) { }

	w.n2ctx = {
		selectedPath: "/",
		_path: "/",
		selectedUrl: null,
		memorizedPath: null,
		actionType: null,

		// whether there is a top frame
		hasTop: function() {
			return false;
		},

		// selects a toolbar item by name
		toolbarSelect: function(name, context) {
			w.n2.select(name);
		},

		// copy/paste
		memorize: function(selected, action) {
			this.memorizedPath = selected;
			this.actionType = action;
		},
		getSelected: function() {
			return this.selectedPath;
		},
		path: function(value) {
			if (arguments.length == 0)
				return this._path;

			this._path = value;
			return this;
		},
		getSelectedUrl: function() {
			return this.selectedUrl;
		},
		getMemory: function() {
			return encodeURIComponent(this.memorizedPath);
		},
		getAction: function() {
			return encodeURIComponent(this.actionType);
		},

		initToolbar: function() {
			$("a.command").click(function(e) {
				if (this.hash == "#stop")
					e.preventDefault();
			});
		},

		// selection memory
		update: function(options) {
			if (!this.hasTop()) return;

			options.previewUrl = options.previewUrl || this.selectedUrl;
			var memory = this.getMemory();
			var action = this.getAction();
			this.selectedPath = options.path;
			this.selectedUrl = options.previewUrl;

			if (typeof (toolbarPlugIns) == "undefined")
				return;
			for (var i = 0; i < toolbarPlugIns.length; i++) {
				var a = w.document.getElementById(toolbarPlugIns[i].linkId);
				var href = toolbarPlugIns[i].urlFormat;
				var formats = { url: options.previewUrl, selected: options.path, memory: memory, action: action };
				for (var key in formats) {
					var format = "{" + key + "}";
					if (href.indexOf(format) >= 0 && formats[key] == "null") {
						href = "#stop";
						$(a).addClass("disabled");
						break;
					}
					else $(a).removeClass("disabled");

					href = href.replace(format, formats[key]);
				}
				a.href = href;

			}
		},

		append: function(url, data) {
			return url + (url.indexOf('?') >= 0 ? "&" : "?") + jQuery.param(data);
		},

		/// update frames
		/// * previewUrl: url to load preview frame
		/// * navigationUrl: url to load navigation frame
		/// * force: force navigation refresh (default true)
		/// * path: update path to
		refresh: function(options) {
			options = jQuery.extend({ previewUrl: null, navigationUrl: null, force: true }, options);

			if (this.hasTop()) {
				if (options.previewUrl) {
					var previewFrame = w.document.getElementById("previewFrame");
					previewFrame.src = options.previewUrl;
				}
				if (options.navigationUrl) {
					var navigationFrame = w.document.getElementById("navigationFrame");
					navigationFrame.src = this.append(options.navigationUrl, { location: this.location });
				}
			} else if (options.previewUrl) {
				window.location = options.previewUrl;
			}
			if (options.path)
				this.path(options.path);
			this.update(options);
		},

		// toolbar selection
		select: function(name) {
			if (!name) return;

			$s = jQuery("#" + name);
			n2.unselectFrame($s.find("a").attr("target"));
			$s.addClass("selected");
			jQuery(document.body).addClass(name + "Selected");
		},
		unselectFrame: function(frame) {
			$(".selected a").filter(function() { return this.target === frame || !this.target; })
                .closest(".selected")
                .each(function() {
                	n2.unselect(this.id);
                });
		},
		unselect: function(name) {
			if (!name) return;

			jQuery("#" + name).removeClass("selected");
			jQuery(document.body).removeClass(name + "Selected");
		}
	};

	return w.n2ctx;
};
window.n2 = initn2context(window);

window.n2.frameManager = {
    init: function() {
        var self = this;
        self.repaint();
        $("#splitter").splitter({
            type: 'v',
            cookie: 'n2spl',
            anchorToWindow: true,
            onStart: function() {
                this.parent().addClass("activeSplitter");
            },
            onStop: function() {
                this.parent().removeClass("activeSplitter");
                self.repaint();
            },
            sizeLeft: true
        });
        $(window).bind("resize", function() {
            self.repaint();
        });
        setTimeout(function() { self.repaint.call(self); }, 100); // chrome hack
    },
    repaint: function() {
        var h = $(document).height() - $('#top').height();
        jQuery("#splitter,.pane").height(h);
    },
    contentHeight: function() {
        return ;
    }
};