/*  Copyright Mihai Bazon, 2002-2005  |  www.bazon.net/mishoo
 * -----------------------------------------------------------
 *
 * The DHTML Calendar, version 1.0 "It is happening again"
 *
 * Details and latest version at:
 * www.dynarch.com/projects/calendar
 *
 * This script is developed by Dynarch.com.  Visit us at www.dynarch.com.
 *
 * This script is distributed under the GNU Lesser General Public License.
 * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
 */

// $Id: calendar.js,v 1.51 2005/03/07 16:44:31 mishoo Exp $

/** The Calendar object constructor. */
Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) {
	// member variables
	this.activeDiv = null;
	this.currentDateEl = null;
	this.getDateStatus = null;
	this.getDateToolTip = null;
	this.getDateText = null;
	this.timeout = null;
	this.onSelected = onSelected || null;
	this.onClose = onClose || null;
	this.dragging = false;
	this.hidden = false;
	this.minYear = 1970;
	this.maxYear = 2050;
	this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"];
	this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"];
	this.isPopup = true;
	this.weekNumbers = true;
	this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc.
	this.showsOtherMonths = false;
	this.dateStr = dateStr;
	this.ar_days = null;
	this.showsTime = false;
	this.time24 = true;
	this.yearStep = 2;
	this.hiliteToday = true;
	this.multiple = null;
	// HTML elements
	this.table = null;
	this.element = null;
	this.tbody = null;
	this.firstdayname = null;
	// Combo boxes
	this.monthsCombo = null;
	this.yearsCombo = null;
	this.hilitedMonth = null;
	this.activeMonth = null;
	this.hilitedYear = null;
	this.activeYear = null;
	// Information
	this.dateClicked = false;

	// one-time initializations
	if (typeof Calendar._SDN == "undefined") {
		// table of short day names
		if (typeof Calendar._SDN_len == "undefined")
			Calendar._SDN_len = 3;
		var ar = new Array();
		for (var i = 8; i > 0;) {
			ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len);
		}
		Calendar._SDN = ar;
		// table of short month names
		if (typeof Calendar._SMN_len == "undefined")
			Calendar._SMN_len = 3;
		ar = new Array();
		for (var i = 12; i > 0;) {
			ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len);
		}
		Calendar._SMN = ar;
	}
};

// ** constants

/// "static", needed for event handlers.
Calendar._C = null;

/// detect a special case of "web browser"
Calendar.is_ie = ( /msie/i.test(navigator.userAgent) &&
		   !/opera/i.test(navigator.userAgent) );

Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) );

/// detect Opera browser
Calendar.is_opera = /opera/i.test(navigator.userAgent);

/// detect KHTML-based browsers
Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);

// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate
//        library, at some point.

Calendar.getAbsolutePos = function(el) {
	var SL = 0, ST = 0;
	var is_div = /^div$/i.test(el.tagName);
	if (is_div && el.scrollLeft)
		SL = el.scrollLeft;
	if (is_div && el.scrollTop)
		ST = el.scrollTop;
	var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
	if (el.offsetParent) {
		var tmp = this.getAbsolutePos(el.offsetParent);
		r.x += tmp.x;
		r.y += tmp.y;
	}
	return r;
};

Calendar.isRelated = function (el, evt) {
	var related = evt.relatedTarget;
	if (!related) {
		var type = evt.type;
		if (type == "mouseover") {
			related = evt.fromElement;
		} else if (type == "mouseout") {
			related = evt.toElement;
		}
	}
	while (related) {
		if (related == el) {
			return true;
		}
		related = related.parentNode;
	}
	return false;
};

Calendar.removeClass = function(el, className) {
	if (!(el && el.className)) {
		return;
	}
	var cls = el.className.split(" ");
	var ar = new Array();
	for (var i = cls.length; i > 0;) {
		if (cls[--i] != className) {
			ar[ar.length] = cls[i];
		}
	}
	el.className = ar.join(" ");
};

Calendar.addClass = function(el, className) {
	Calendar.removeClass(el, className);
	el.className += " " + className;
};

// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately.
Calendar.getElement = function(ev) {
	var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget;
	while (f.nodeType != 1 || /^div$/i.test(f.tagName))
		f = f.parentNode;
	return f;
};

Calendar.getTargetElement = function(ev) {
	var f = Calendar.is_ie ? window.event.srcElement : ev.target;
	while (f.nodeType != 1)
		f = f.parentNode;
	return f;
};

Calendar.stopEvent = function(ev) {
	ev || (ev = window.event);
	if (Calendar.is_ie) {
		ev.cancelBubble = true;
		ev.returnValue = false;
	} else {
		ev.preventDefault();
		ev.stopPropagation();
	}
	return false;
};

Calendar.addEvent = function(el, evname, func) {
	if (el.attachEvent) { // IE
		el.attachEvent("on" + evname, func);
	} else if (el.addEventListener) { // Gecko / W3C
		el.addEventListener(evname, func, true);
	} else {
		el["on" + evname] = func;
	}
};

Calendar.removeEvent = function(el, evname, func) {
	if (el.detachEvent) { // IE
		el.detachEvent("on" + evname, func);
	} else if (el.removeEventListener) { // Gecko / W3C
		el.removeEventListener(evname, func, true);
	} else {
		el["on" + evname] = null;
	}
};

Calendar.createElement = function(type, parent) {
	var el = null;
	if (document.createElementNS) {
		// use the XHTML namespace; IE won't normally get here unless
		// _they_ "fix" the DOM2 implementation.
		el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
	} else {
		el = document.createElement(type);
	}
	if (typeof parent != "undefined") {
		parent.appendChild(el);
	}
	return el;
};

// END: UTILITY FUNCTIONS

// BEGIN: CALENDAR STATIC FUNCTIONS

/** Internal -- adds a set of events to make some element behave like a button. */
Calendar._add_evs = function(el) {
	with (Calendar) {
		addEvent(el, "mouseover", dayMouseOver);
		addEvent(el, "mousedown", dayMouseDown);
		addEvent(el, "mouseout", dayMouseOut);
		if (is_ie) {
			addEvent(el, "dblclick", dayMouseDblClick);
			el.setAttribute("unselectable", true);
		}
	}
};

Calendar.findMonth = function(el) {
	if (typeof el.month != "undefined") {
		return el;
	} else if (typeof el.parentNode.month != "undefined") {
		return el.parentNode;
	}
	return null;
};

Calendar.findYear = function(el) {
	if (typeof el.year != "undefined") {
		return el;
	} else if (typeof el.parentNode.year != "undefined") {
		return el.parentNode;
	}
	return null;
};

Calendar.showMonthsCombo = function () {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	var cal = cal;
	var cd = cal.activeDiv;
	var mc = cal.monthsCombo;
	if (cal.hilitedMonth) {
		Calendar.removeClass(cal.hilitedMonth, "hilite");
	}
	if (cal.activeMonth) {
		Calendar.removeClass(cal.activeMonth, "active");
	}
	var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];
	Calendar.addClass(mon, "active");
	cal.activeMonth = mon;
	var s = mc.style;
	s.display = "block";
	if (cd.navtype < 0)
		s.left = cd.offsetLeft + "px";
	else {
		var mcw = mc.offsetWidth;
		if (typeof mcw == "undefined")
			// Konqueror brain-dead techniques
			mcw = 50;
		s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px";
	}
	s.top = (cd.offsetTop + cd.offsetHeight) + "px";
};

Calendar.showYearsCombo = function (fwd) {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	var cal = cal;
	var cd = cal.activeDiv;
	var yc = cal.yearsCombo;
	if (cal.hilitedYear) {
		Calendar.removeClass(cal.hilitedYear, "hilite");
	}
	if (cal.activeYear) {
		Calendar.removeClass(cal.activeYear, "active");
	}
	cal.activeYear = null;
	var Y = cal.date.getFullYear() + (fwd ? 1 : -1);
	var yr = yc.firstChild;
	var show = false;
	for (var i = 12; i > 0; --i) {
		if (Y >= cal.minYear && Y <= cal.maxYear) {
			yr.innerHTML = Y;
			yr.year = Y;
			yr.style.display = "block";
			show = true;
		} else {
			yr.style.display = "none";
		}
		yr = yr.nextSibling;
		Y += fwd ? cal.yearStep : -cal.yearStep;
	}
	if (show) {
		var s = yc.style;
		s.display = "block";
		if (cd.navtype < 0)
			s.left = cd.offsetLeft + "px";
		else {
			var ycw = yc.offsetWidth;
			if (typeof ycw == "undefined")
				// Konqueror brain-dead techniques
				ycw = 50;
			s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px";
		}
		s.top = (cd.offsetTop + cd.offsetHeight) + "px";
	}
};

// event handlers

Calendar.tableMouseUp = function(ev) {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	if (cal.timeout) {
		clearTimeout(cal.timeout);
	}
	var el = cal.activeDiv;
	if (!el) {
		return false;
	}
	var target = Calendar.getTargetElement(ev);
	ev || (ev = window.event);
	Calendar.removeClass(el, "active");
	if (target == el || target.parentNode == el) {
		Calendar.cellClick(el, ev);
	}
	var mon = Calendar.findMonth(target);
	var date = null;
	if (mon) {
		date = new Date(cal.date);
		if (mon.month != date.getMonth()) {
			date.setMonth(mon.month);
			cal.setDate(date);
			cal.dateClicked = false;
			cal.callHandler();
		}
	} else {
		var year = Calendar.findYear(target);
		if (year) {
			date = new Date(cal.date);
			if (year.year != date.getFullYear()) {
				date.setFullYear(year.year);
				cal.setDate(date);
				cal.dateClicked = false;
				cal.callHandler();
			}
		}
	}
	with (Calendar) {
		removeEvent(document, "mouseup", tableMouseUp);
		removeEvent(document, "mouseover", tableMouseOver);
		removeEvent(document, "mousemove", tableMouseOver);
		cal._hideCombos();
		_C = null;
		return stopEvent(ev);
	}
};

Calendar.tableMouseOver = function (ev) {
	var cal = Calendar._C;
	if (!cal) {
		return;
	}
	var el = cal.activeDiv;
	var target = Calendar.getTargetElement(ev);
	if (target == el || target.parentNode == el) {
		Calendar.addClass(el, "hilite active");
		Calendar.addClass(el.parentNode, "rowhilite");
	} else {
		if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2)))
			Calendar.removeClass(el, "active");
		Calendar.removeClass(el, "hilite");
		Calendar.removeClass(el.parentNode, "rowhilite");
	}
	ev || (ev = window.event);
	if (el.navtype == 50 && target != el) {
		var pos = Calendar.getAbsolutePos(el);
		var w = el.offsetWidth;
		var x = ev.clientX;
		var dx;
		var decrease = true;
		if (x > pos.x + w) {
			dx = x - pos.x - w;
			decrease = false;
		} else
			dx = pos.x - x;

		if (dx < 0) dx = 0;
		var range = el._range;
		var current = el._current;
		var count = Math.floor(dx / 10) % range.length;
		for (var i = range.length; --i >= 0;)
			if (range[i] == current)
				break;
		while (count-- > 0)
			if (decrease) {
				if (--i < 0)
					i = range.length - 1;
			} else if ( ++i >= range.length )
				i = 0;
		var newval = range[i];
		el.innerHTML = newval;

		cal.onUpdateTime();
	}
	var mon = Calendar.findMonth(target);
	if (mon) {
		if (mon.month != cal.date.getMonth()) {
			if (cal.hilitedMonth) {
				Calendar.removeClass(cal.hilitedMonth, "hilite");
			}
			Calendar.addClass(mon, "hilite");
			cal.hilitedMonth = mon;
		} else if (cal.hilitedMonth) {
			Calendar.removeClass(cal.hilitedMonth, "hilite");
		}
	} else {
		if (cal.hilitedMonth) {
			Calendar.removeClass(cal.hilitedMonth, "hilite");
		}
		var year = Calendar.findYear(target);
		if (year) {
			if (year.year != cal.date.getFullYear()) {
				if (cal.hilitedYear) {
					Calendar.removeClass(cal.hilitedYear, "hilite");
				}
				Calendar.addClass(year, "hilite");
				cal.hilitedYear = year;
			} else if (cal.hilitedYear) {
				Calendar.removeClass(cal.hilitedYear, "hilite");
			}
		} else if (cal.hilitedYear) {
			Calendar.removeClass(cal.hilitedYear, "hilite");
		}
	}
	return Calendar.stopEvent(ev);
};

Calendar.tableMouseDown = function (ev) {
	if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) {
		return Calendar.stopEvent(ev);
	}
};

Calendar.calDragIt = function (ev) {
	var cal = Calendar._C;
	if (!(cal && cal.dragging)) {
		return false;
	}
	var posX;
	var posY;
	if (Calendar.is_ie) {
		posY = window.event.clientY + document.body.scrollTop;
		posX = window.event.clientX + document.body.scrollLeft;
	} else {
		posX = ev.pageX;
		posY = ev.pageY;
	}
	cal.hideShowCovered();
	var st = cal.element.style;
	st.left = (posX - cal.xOffs) + "px";
	st.top = (posY - cal.yOffs) + "px";
	return Calendar.stopEvent(ev);
};

Calendar.calDragEnd = function (ev) {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	cal.dragging = false;
	with (Calendar) {
		removeEvent(document, "mousemove", calDragIt);
		removeEvent(document, "mouseup", calDragEnd);
		tableMouseUp(ev);
	}
	cal.hideShowCovered();
};

Calendar.dayMouseDown = function(ev) {
	var el = Calendar.getElement(ev);
	if (el.disabled) {
		return false;
	}
	var cal = el.calendar;
	cal.activeDiv = el;
	Calendar._C = cal;
	if (el.navtype != 300) with (Calendar) {
		if (el.navtype == 50) {
			el._current = el.innerHTML;
			addEvent(document, "mousemove", tableMouseOver);
		} else
			addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver);
		addClass(el, "hilite active");
		addEvent(document, "mouseup", tableMouseUp);
	} else if (cal.isPopup) {
		cal._dragStart(ev);
	}
	if (el.navtype == -1 || el.navtype == 1) {
		if (cal.timeout) clearTimeout(cal.timeout);
		cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250);
	} else if (el.navtype == -2 || el.navtype == 2) {
		if (cal.timeout) clearTimeout(cal.timeout);
		cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250);
	} else {
		cal.timeout = null;
	}
	return Calendar.stopEvent(ev);
};

Calendar.dayMouseDblClick = function(ev) {
	Calendar.cellClick(Calendar.getElement(ev), ev || window.event);
	if (Calendar.is_ie) {
		document.selection.empty();
	}
};

Calendar.dayMouseOver = function(ev) {
	var el = Calendar.getElement(ev);
	if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) {
		return false;
	}
	if (el.ttip) {
		if (el.ttip.substr(0, 1) == "_") {
			el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1);
		}
		el.calendar.tooltips.innerHTML = el.ttip;
	}
	if (el.navtype != 300) {
		Calendar.addClass(el, "hilite");
		if (el.caldate) {
			Calendar.addClass(el.parentNode, "rowhilite");
		}
	}
	return Calendar.stopEvent(ev);
};

Calendar.dayMouseOut = function(ev) {
	with (Calendar) {
		var el = getElement(ev);
		if (isRelated(el, ev) || _C || el.disabled)
			return false;
		removeClass(el, "hilite");
		if (el.caldate)
			removeClass(el.parentNode, "rowhilite");
		if (el.calendar)
			el.calendar.tooltips.innerHTML = _TT["SEL_DATE"];
		return stopEvent(ev);
	}
};

/**
 *  A generic "click" handler :) handles all types of buttons defined in this
 *  calendar.
 */
Calendar.cellClick = function(el, ev) {
	var cal = el.calendar;
	var closing = false;
	var newdate = false;
	var date = null;
	if (typeof el.navtype == "undefined") {
		if (cal.currentDateEl) {
			Calendar.removeClass(cal.currentDateEl, "selected");
			Calendar.addClass(el, "selected");
			closing = (cal.currentDateEl == el);
			if (!closing) {
				cal.currentDateEl = el;
			}
		}
		cal.date.setDateOnly(el.caldate);
		date = cal.date;
		var other_month = !(cal.dateClicked = !el.otherMonth);
		if (!other_month && !cal.currentDateEl)
			cal._toggleMultipleDate(new Date(date));
		else
			newdate = !el.disabled;
		// a date was clicked
		if (other_month)
			cal._init(cal.firstDayOfWeek, date);
	} else {
		if (el.navtype == 200) {
			Calendar.removeClass(el, "hilite");
			cal.callCloseHandler();
			return;
		}
		date = new Date(cal.date);
		if (el.navtype == 0)
			date.setDateOnly(new Date()); // TODAY
		// unless "today" was clicked, we assume no date was clicked so
		// the selected handler will know not to close the calenar when
		// in single-click mode.
		// cal.dateClicked = (el.navtype == 0);
		cal.dateClicked = false;
		var year = date.getFullYear();
		var mon = date.getMonth();
		function setMonth(m) {
			var day = date.getDate();
			var max = date.getMonthDays(m);
			if (day > max) {
				date.setDate(max);
			}
			date.setMonth(m);
		};
		switch (el.navtype) {
		    case 400:
			Calendar.removeClass(el, "hilite");
			var text = Calendar._TT["ABOUT"];
			if (typeof text != "undefined") {
				text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : "";
			} else {
				// FIXME: this should be removed as soon as lang files get updated!
				text = "Help and about box text is not translated into this language.\n" +
					"If you know this language and you feel generous please update\n" +
					"the corresponding file in \"lang\" subdir to match calendar-en.js\n" +
					"and send it back to <mihai_bazon@yahoo.com> to get it into the distribution  ;-)\n\n" +
					"Thank you!\n" +
					"http://dynarch.com/mishoo/calendar.epl\n";
			}
			alert(text);
			return;
		    case -2:
			if (year > cal.minYear) {
				date.setFullYear(year - 1);
			}
			break;
		    case -1:
			if (mon > 0) {
				setMonth(mon - 1);
			} else if (year-- > cal.minYear) {
				date.setFullYear(year);
				setMonth(11);
			}
			break;
		    case 1:
			if (mon < 11) {
				setMonth(mon + 1);
			} else if (year < cal.maxYear) {
				date.setFullYear(year + 1);
				setMonth(0);
			}
			break;
		    case 2:
			if (year < cal.maxYear) {
				date.setFullYear(year + 1);
			}
			break;
		    case 100:
			cal.setFirstDayOfWeek(el.fdow);
			return;
		    case 50:
			var range = el._range;
			var current = el.innerHTML;
			for (var i = range.length; --i >= 0;)
				if (range[i] == current)
					break;
			if (ev && ev.shiftKey) {
				if (--i < 0)
					i = range.length - 1;
			} else if ( ++i >= range.length )
				i = 0;
			var newval = range[i];
			el.innerHTML = newval;
			cal.onUpdateTime();
			return;
		    case 0:
			// TODAY will bring us here
			if ((typeof cal.getDateStatus == "function") &&
			    cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) {
				return false;
			}
			break;
		}
		if (!date.equalsTo(cal.date)) {
			cal.setDate(date);
			newdate = true;
		} else if (el.navtype == 0)
			newdate = closing = true;
	}
	if (newdate) {
		ev && cal.callHandler();
	}
	if (closing) {
		Calendar.removeClass(el, "hilite");
		ev && cal.callCloseHandler();
	}
};

// END: CALENDAR STATIC FUNCTIONS

// BEGIN: CALENDAR OBJECT FUNCTIONS

/**
 *  This function creates the calendar inside the given parent.  If _par is
 *  null than it creates a popup calendar inside the BODY element.  If _par is
 *  an element, be it BODY, then it creates a non-popup calendar (still
 *  hidden).  Some properties need to be set before calling this function.
 */
Calendar.prototype.create = function (_par) {
	var parent = null;
	if (! _par) {
		// default parent is the document body, in which case we create
		// a popup calendar.
		parent = document.getElementsByTagName("body")[0];
		this.isPopup = true;
	} else {
		parent = _par;
		this.isPopup = false;
	}
	this.date = this.dateStr ? new Date(this.dateStr) : new Date();

	var table = Calendar.createElement("table");
	this.table = table;
	table.cellSpacing = 0;
	table.cellPadding = 0;
	table.calendar = this;
	Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown);

	var div = Calendar.createElement("div");
	this.element = div;
	div.className = "calendar";
	if (this.isPopup) {
		div.style.position = "absolute";
		div.style.display = "none";
	}
	div.appendChild(table);

	var thead = Calendar.createElement("thead", table);
	var cell = null;
	var row = null;

	var cal = this;
	var hh = function (text, cs, navtype) {
		cell = Calendar.createElement("td", row);
		cell.colSpan = cs;
		cell.className = "button";
		if (navtype != 0 && Math.abs(navtype) <= 2)
			cell.className += " nav";
		Calendar._add_evs(cell);
		cell.calendar = cal;
		cell.navtype = navtype;
		cell.innerHTML = "<div unselectable='on'>" + text + "</div>";
		return cell;
	};

	row = Calendar.createElement("tr", thead);
	var title_length = 6;
	(this.isPopup) && --title_length;
	(this.weekNumbers) && ++title_length;

	hh("?", 1, 400).ttip = Calendar._TT["INFO"];
	this.title = hh("", title_length, 300);
	this.title.className = "title";
	if (this.isPopup) {
		this.title.ttip = Calendar._TT["DRAG_TO_MOVE"];
		this.title.style.cursor = "move";
		hh("&#x00d7;", 1, 200).ttip = Calendar._TT["CLOSE"];
	}

	row = Calendar.createElement("tr", thead);
	row.className = "headrow";

	this._nav_py = hh("&#x00ab;", 1, -2);
	this._nav_py.ttip = Calendar._TT["PREV_YEAR"];

	this._nav_pm = hh("&#x2039;", 1, -1);
	this._nav_pm.ttip = Calendar._TT["PREV_MONTH"];

	this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0);
	this._nav_now.ttip = Calendar._TT["GO_TODAY"];

	this._nav_nm = hh("&#x203a;", 1, 1);
	this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"];

	this._nav_ny = hh("&#x00bb;", 1, 2);
	this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"];

	// day names
	row = Calendar.createElement("tr", thead);
	row.className = "daynames";
	if (this.weekNumbers) {
		cell = Calendar.createElement("td", row);
		cell.className = "name wn";
		cell.innerHTML = Calendar._TT["WK"];
	}
	for (var i = 7; i > 0; --i) {
		cell = Calendar.createElement("td", row);
		if (!i) {
			cell.navtype = 100;
			cell.calendar = this;
			Calendar._add_evs(cell);
		}
	}
	this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild;
	this._displayWeekdays();

	var tbody = Calendar.createElement("tbody", table);
	this.tbody = tbody;

	for (i = 6; i > 0; --i) {
		row = Calendar.createElement("tr", tbody);
		if (this.weekNumbers) {
			cell = Calendar.createElement("td", row);
		}
		for (var j = 7; j > 0; --j) {
			cell = Calendar.createElement("td", row);
			cell.calendar = this;
			Calendar._add_evs(cell);
		}
	}

	if (this.showsTime) {
		row = Calendar.createElement("tr", tbody);
		row.className = "time";

		cell = Calendar.createElement("td", row);
		cell.className = "time";
		cell.colSpan = 2;
		cell.innerHTML = Calendar._TT["TIME"] || "&nbsp;";

		cell = Calendar.createElement("td", row);
		cell.className = "time";
		cell.colSpan = this.weekNumbers ? 4 : 3;

		(function(){
			function makeTimePart(className, init, range_start, range_end) {
				var part = Calendar.createElement("span", cell);
				part.className = className;
				part.innerHTML = init;
				part.calendar = cal;
				part.ttip = Calendar._TT["TIME_PART"];
				part.navtype = 50;
				part._range = [];
				if (typeof range_start != "number")
					part._range = range_start;
				else {
					for (var i = range_start; i <= range_end; ++i) {
						var txt;
						if (i < 10 && range_end >= 10) txt = '0' + i;
						else txt = '' + i;
						part._range[part._range.length] = txt;
					}
				}
				Calendar._add_evs(part);
				return part;
			};
			var hrs = cal.date.getHours();
			var mins = cal.date.getMinutes();
			var t12 = !cal.time24;
			var pm = (hrs > 12);
			if (t12 && pm) hrs -= 12;
			var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23);
			var span = Calendar.createElement("span", cell);
			span.innerHTML = ":";
			span.className = "colon";
			var M = makeTimePart("minute", mins, 0, 59);
			var AP = null;
			cell = Calendar.createElement("td", row);
			cell.className = "time";
			cell.colSpan = 2;
			if (t12)
				AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]);
			else
				cell.innerHTML = "&nbsp;";

			cal.onSetTime = function() {
				var pm, hrs = this.date.getHours(),
					mins = this.date.getMinutes();
				if (t12) {
					pm = (hrs >= 12);
					if (pm) hrs -= 12;
					if (hrs == 0) hrs = 12;
					AP.innerHTML = pm ? "pm" : "am";
				}
				H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs;
				M.innerHTML = (mins < 10) ? ("0" + mins) : mins;
			};

			cal.onUpdateTime = function() {
				var date = this.date;
				var h = parseInt(H.innerHTML, 10);
				if (t12) {
					if (/pm/i.test(AP.innerHTML) && h < 12)
						h += 12;
					else if (/am/i.test(AP.innerHTML) && h == 12)
						h = 0;
				}
				var d = date.getDate();
				var m = date.getMonth();
				var y = date.getFullYear();
				date.setHours(h);
				date.setMinutes(parseInt(M.innerHTML, 10));
				date.setFullYear(y);
				date.setMonth(m);
				date.setDate(d);
				this.dateClicked = false;
				this.callHandler();
			};
		})();
	} else {
		this.onSetTime = this.onUpdateTime = function() {};
	}

	var tfoot = Calendar.createElement("tfoot", table);

	row = Calendar.createElement("tr", tfoot);
	row.className = "footrow";

	cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300);
	cell.className = "ttip";
	if (this.isPopup) {
		cell.ttip = Calendar._TT["DRAG_TO_MOVE"];
		cell.style.cursor = "move";
	}
	this.tooltips = cell;

	div = Calendar.createElement("div", this.element);
	this.monthsCombo = div;
	div.className = "combo";
	for (i = 0; i < Calendar._MN.length; ++i) {
		var mn = Calendar.createElement("div");
		mn.className = Calendar.is_ie ? "label-IEfix" : "label";
		mn.month = i;
		mn.innerHTML = Calendar._SMN[i];
		div.appendChild(mn);
	}

	div = Calendar.createElement("div", this.element);
	this.yearsCombo = div;
	div.className = "combo";
	for (i = 12; i > 0; --i) {
		var yr = Calendar.createElement("div");
		yr.className = Calendar.is_ie ? "label-IEfix" : "label";
		div.appendChild(yr);
	}

	this._init(this.firstDayOfWeek, this.date);
	parent.appendChild(this.element);
};

/** keyboard navigation, only for popup calendars */
Calendar._keyEvent = function(ev) {
	var cal = window._dynarch_popupCalendar;
	if (!cal || cal.multiple)
		return false;
	(Calendar.is_ie) && (ev = window.event);
	var act = (Calendar.is_ie || ev.type == "keypress"),
		K = ev.keyCode;
	if (ev.ctrlKey) {
		switch (K) {
		    case 37: // KEY left
			act && Calendar.cellClick(cal._nav_pm);
			break;
		    case 38: // KEY up
			act && Calendar.cellClick(cal._nav_py);
			break;
		    case 39: // KEY right
			act && Calendar.cellClick(cal._nav_nm);
			break;
		    case 40: // KEY down
			act && Calendar.cellClick(cal._nav_ny);
			break;
		    default:
			return false;
		}
	} else switch (K) {
	    case 32: // KEY space (now)
		Calendar.cellClick(cal._nav_now);
		break;
	    case 27: // KEY esc
		act && cal.callCloseHandler();
		break;
	    case 37: // KEY left
	    case 38: // KEY up
	    case 39: // KEY right
	    case 40: // KEY down
		if (act) {
			var prev, x, y, ne, el, step;
			prev = K == 37 || K == 38;
			step = (K == 37 || K == 39) ? 1 : 7;
			function setVars() {
				el = cal.currentDateEl;
				var p = el.pos;
				x = p & 15;
				y = p >> 4;
				ne = cal.ar_days[y][x];
			};setVars();
			function prevMonth() {
				var date = new Date(cal.date);
				date.setDate(date.getDate() - step);
				cal.setDate(date);
			};
			function nextMonth() {
				var date = new Date(cal.date);
				date.setDate(date.getDate() + step);
				cal.setDate(date);
			};
			while (1) {
				switch (K) {
				    case 37: // KEY left
					if (--x >= 0)
						ne = cal.ar_days[y][x];
					else {
						x = 6;
						K = 38;
						continue;
					}
					break;
				    case 38: // KEY up
					if (--y >= 0)
						ne = cal.ar_days[y][x];
					else {
						prevMonth();
						setVars();
					}
					break;
				    case 39: // KEY right
					if (++x < 7)
						ne = cal.ar_days[y][x];
					else {
						x = 0;
						K = 40;
						continue;
					}
					break;
				    case 40: // KEY down
					if (++y < cal.ar_days.length)
						ne = cal.ar_days[y][x];
					else {
						nextMonth();
						setVars();
					}
					break;
				}
				break;
			}
			if (ne) {
				if (!ne.disabled)
					Calendar.cellClick(ne);
				else if (prev)
					prevMonth();
				else
					nextMonth();
			}
		}
		break;
	    case 13: // KEY enter
		if (act)
			Calendar.cellClick(cal.currentDateEl, ev);
		break;
	    default:
		return false;
	}
	return Calendar.stopEvent(ev);
};

/**
 *  (RE)Initializes the calendar to the given date and firstDayOfWeek
 */
Calendar.prototype._init = function (firstDayOfWeek, date) {
	var today = new Date(),
		TY = today.getFullYear(),
		TM = today.getMonth(),
		TD = today.getDate();
	this.table.style.visibility = "hidden";
	var year = date.getFullYear();
	if (year < this.minYear) {
		year = this.minYear;
		date.setFullYear(year);
	} else if (year > this.maxYear) {
		year = this.maxYear;
		date.setFullYear(year);
	}
	this.firstDayOfWeek = firstDayOfWeek;
	this.date = new Date(date);
	var month = date.getMonth();
	var mday = date.getDate();
	var no_days = date.getMonthDays();

	// calendar voodoo for computing the first day that would actually be
	// displayed in the calendar, even if it's from the previous month.
	// WARNING: this is magic. ;-)
	date.setDate(1);
	var day1 = (date.getDay() - this.firstDayOfWeek) % 7;
	if (day1 < 0)
		day1 += 7;
	date.setDate(-day1);
	date.setDate(date.getDate() + 1);

	var row = this.tbody.firstChild;
	var MN = Calendar._SMN[month];
	var ar_days = this.ar_days = new Array();
	var weekend = Calendar._TT["WEEKEND"];
	var dates = this.multiple ? (this.datesCells = {}) : null;
	for (var i = 0; i < 6; ++i, row = row.nextSibling) {
		var cell = row.firstChild;
		if (this.weekNumbers) {
			cell.className = "day wn";
			cell.innerHTML = date.getWeekNumber();
			cell = cell.nextSibling;
		}
		row.className = "daysrow";
		var hasdays = false, iday, dpos = ar_days[i] = [];
		for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) {
			iday = date.getDate();
			var wday = date.getDay();
			cell.className = "day";
			cell.pos = i << 4 | j;
			dpos[j] = cell;
			var current_month = (date.getMonth() == month);
			if (!current_month) {
				if (this.showsOtherMonths) {
					cell.className += " othermonth";
					cell.otherMonth = true;
				} else {
					cell.className = "emptycell";
					cell.innerHTML = "&nbsp;";
					cell.disabled = true;
					continue;
				}
			} else {
				cell.otherMonth = false;
				hasdays = true;
			}
			cell.disabled = false;
			cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday;
			if (dates)
				dates[date.print("%Y%m%d")] = cell;
			if (this.getDateStatus) {
				var status = this.getDateStatus(date, year, month, iday);
				if (this.getDateToolTip) {
					var toolTip = this.getDateToolTip(date, year, month, iday);
					if (toolTip)
						cell.title = toolTip;
				}
				if (status === true) {
					cell.className += " disabled";
					cell.disabled = true;
				} else {
					if (/disabled/i.test(status))
						cell.disabled = true;
					cell.className += " " + status;
				}
			}
			if (!cell.disabled) {
				cell.caldate = new Date(date);
				cell.ttip = "_";
				if (!this.multiple && current_month
				    && iday == mday && this.hiliteToday) {
					cell.className += " selected";
					this.currentDateEl = cell;
				}
				if (date.getFullYear() == TY &&
				    date.getMonth() == TM &&
				    iday == TD) {
					cell.className += " today";
					cell.ttip += Calendar._TT["PART_TODAY"];
				}
				if (weekend.indexOf(wday.toString()) != -1)
					cell.className += cell.otherMonth ? " oweekend" : " weekend";
			}
		}
		if (!(hasdays || this.showsOtherMonths))
			row.className = "emptyrow";
	}
	this.title.innerHTML = Calendar._MN[month] + ", " + year;
	this.onSetTime();
	this.table.style.visibility = "visible";
	this._initMultipleDates();
	// PROFILE
	// this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms";
};

Calendar.prototype._initMultipleDates = function() {
	if (this.multiple) {
		for (var i in this.multiple) {
			var cell = this.datesCells[i];
			var d = this.multiple[i];
			if (!d)
				continue;
			if (cell)
				cell.className += " selected";
		}
	}
};

Calendar.prototype._toggleMultipleDate = function(date) {
	if (this.multiple) {
		var ds = date.print("%Y%m%d");
		var cell = this.datesCells[ds];
		if (cell) {
			var d = this.multiple[ds];
			if (!d) {
				Calendar.addClass(cell, "selected");
				this.multiple[ds] = date;
			} else {
				Calendar.removeClass(cell, "selected");
				delete this.multiple[ds];
			}
		}
	}
};

Calendar.prototype.setDateToolTipHandler = function (unaryFunction) {
	this.getDateToolTip = unaryFunction;
};

/**
 *  Calls _init function above for going to a certain date (but only if the
 *  date is different than the currently selected one).
 */
Calendar.prototype.setDate = function (date) {
	if (!date.equalsTo(this.date)) {
		this._init(this.firstDayOfWeek, date);
	}
};

/**
 *  Refreshes the calendar.  Useful if the "disabledHandler" function is
 *  dynamic, meaning that the list of disabled date can change at runtime.
 *  Just * call this function if you think that the list of disabled dates
 *  should * change.
 */
Calendar.prototype.refresh = function () {
	this._init(this.firstDayOfWeek, this.date);
};

/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */
Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) {
	this._init(firstDayOfWeek, this.date);
	this._displayWeekdays();
};

/**
 *  Allows customization of what dates are enabled.  The "unaryFunction"
 *  parameter must be a function object that receives the date (as a JS Date
 *  object) and returns a boolean value.  If the returned value is true then
 *  the passed date will be marked as disabled.
 */
Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) {
	this.getDateStatus = unaryFunction;
};

/** Customization of allowed year range for the calendar. */
Calendar.prototype.setRange = function (a, z) {
	this.minYear = a;
	this.maxYear = z;
};

/** Calls the first user handler (selectedHandler). */
Calendar.prototype.callHandler = function () {
	if (this.onSelected) {
		this.onSelected(this, this.date.print(this.dateFormat));
	}
};

/** Calls the second user handler (closeHandler). */
Calendar.prototype.callCloseHandler = function () {
	if (this.onClose) {
		this.onClose(this);
	}
	this.hideShowCovered();
};

/** Removes the calendar object from the DOM tree and destroys it. */
Calendar.prototype.destroy = function () {
	var el = this.element.parentNode;
	el.removeChild(this.element);
	Calendar._C = null;
	window._dynarch_popupCalendar = null;
};

/**
 *  Moves the calendar element to a different section in the DOM tree (changes
 *  its parent).
 */
Calendar.prototype.reparent = function (new_parent) {
	var el = this.element;
	el.parentNode.removeChild(el);
	new_parent.appendChild(el);
};

// This gets called when the user presses a mouse button anywhere in the
// document, if the calendar is shown.  If the click was outside the open
// calendar this function closes it.
Calendar._checkCalendar = function(ev) {
	var calendar = window._dynarch_popupCalendar;
	if (!calendar) {
		return false;
	}
	var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev);
	for (; el != null && el != calendar.element; el = el.parentNode);
	if (el == null) {
		// calls closeHandler which should hide the calendar.
		window._dynarch_popupCalendar.callCloseHandler();
		return Calendar.stopEvent(ev);
	}
};

/** Shows the calendar. */
Calendar.prototype.show = function () {
	var rows = this.table.getElementsByTagName("tr");
	for (var i = rows.length; i > 0;) {
		var row = rows[--i];
		Calendar.removeClass(row, "rowhilite");
		var cells = row.getElementsByTagName("td");
		for (var j = cells.length; j > 0;) {
			var cell = cells[--j];
			Calendar.removeClass(cell, "hilite");
			Calendar.removeClass(cell, "active");
		}
	}
	this.element.style.display = "block";
	this.hidden = false;
	if (this.isPopup) {
		window._dynarch_popupCalendar = this;
		Calendar.addEvent(document, "keydown", Calendar._keyEvent);
		Calendar.addEvent(document, "keypress", Calendar._keyEvent);
		Calendar.addEvent(document, "mousedown", Calendar._checkCalendar);
	}
	this.hideShowCovered();
};

/**
 *  Hides the calendar.  Also removes any "hilite" from the class of any TD
 *  element.
 */
Calendar.prototype.hide = function () {
	if (this.isPopup) {
		Calendar.removeEvent(document, "keydown", Calendar._keyEvent);
		Calendar.removeEvent(document, "keypress", Calendar._keyEvent);
		Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar);
	}
	this.element.style.display = "none";
	this.hidden = true;
	this.hideShowCovered();
};

/**
 *  Shows the calendar at a given absolute position (beware that, depending on
 *  the calendar element style -- position property -- this might be relative
 *  to the parent's containing rectangle).
 */
Calendar.prototype.showAt = function (x, y) {
	var s = this.element.style;
	s.left = x + "px";
	s.top = y + "px";
	this.show();
};

/** Shows the calendar near a given element. */
Calendar.prototype.showAtElement = function (el, opts) {
	var self = this;
	var p = Calendar.getAbsolutePos(el);
	if (!opts || typeof opts != "string") {
		this.showAt(p.x, p.y + el.offsetHeight);
		return true;
	}
	function fixPosition(box) {
		if (box.x < 0)
			box.x = 0;
		if (box.y < 0)
			box.y = 0;
		var cp = document.createElement("div");
		var s = cp.style;
		s.position = "absolute";
		s.right = s.bottom = s.width = s.height = "0px";
		document.body.appendChild(cp);
		var br = Calendar.getAbsolutePos(cp);
		document.body.removeChild(cp);
		if (Calendar.is_ie) {
			br.y += document.body.scrollTop;
			br.x += document.body.scrollLeft;
		} else {
			br.y += window.scrollY;
			br.x += window.scrollX;
		}
		var tmp = box.x + box.width - br.x;
		if (tmp > 0) box.x -= tmp;
		tmp = box.y + box.height - br.y;
		if (tmp > 0) box.y -= tmp;
	};
	this.element.style.display = "block";
	Calendar.continuation_for_the_fucking_khtml_browser = function() {
		var w = self.element.offsetWidth;
		var h = self.element.offsetHeight;
		self.element.style.display = "none";
		var valign = opts.substr(0, 1);
		var halign = "l";
		if (opts.length > 1) {
			halign = opts.substr(1, 1);
		}
		// vertical alignment
		switch (valign) {
		    case "T": p.y -= h; break;
		    case "B": p.y += el.offsetHeight; break;
		    case "C": p.y += (el.offsetHeight - h) / 2; break;
		    case "t": p.y += el.offsetHeight - h; break;
		    case "b": break; // already there
		}
		// horizontal alignment
		switch (halign) {
		    case "L": p.x -= w; break;
		    case "R": p.x += el.offsetWidth; break;
		    case "C": p.x += (el.offsetWidth - w) / 2; break;
		    case "l": p.x += el.offsetWidth - w; break;
		    case "r": break; // already there
		}
		p.width = w;
		p.height = h + 40;
		self.monthsCombo.style.display = "none";
		fixPosition(p);
		self.showAt(p.x, p.y);
	};
	if (Calendar.is_khtml)
		setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
	else
		Calendar.continuation_for_the_fucking_khtml_browser();
};

/** Customizes the date format. */
Calendar.prototype.setDateFormat = function (str) {
	this.dateFormat = str;
};

/** Customizes the tooltip date format. */
Calendar.prototype.setTtDateFormat = function (str) {
	this.ttDateFormat = str;
};

/**
 *  Tries to identify the date represented in a string.  If successful it also
 *  calls this.setDate which moves the calendar to the given date.
 */
Calendar.prototype.parseDate = function(str, fmt) {
	if (!fmt)
		fmt = this.dateFormat;
	this.setDate(Date.parseDate(str, fmt));
};

Calendar.prototype.hideShowCovered = function () {
	if (!Calendar.is_ie && !Calendar.is_opera)
		return;
	function getVisib(obj){
		var value = obj.style.visibility;
		if (!value) {
			if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
				if (!Calendar.is_khtml)
					value = document.defaultView.
						getComputedStyle(obj, "").getPropertyValue("visibility");
				else
					value = '';
			} else if (obj.currentStyle) { // IE
				value = obj.currentStyle.visibility;
			} else
				value = '';
		}
		return value;
	};

	var tags = new Array("applet", "iframe", "select");
	var el = this.element;

	var p = Calendar.getAbsolutePos(el);
	var EX1 = p.x;
	var EX2 = el.offsetWidth + EX1;
	var EY1 = p.y;
	var EY2 = el.offsetHeight + EY1;

	for (var k = tags.length; k > 0; ) {
		var ar = document.getElementsByTagName(tags[--k]);
		var cc = null;

		for (var i = ar.length; i > 0;) {
			cc = ar[--i];

			p = Calendar.getAbsolutePos(cc);
			var CX1 = p.x;
			var CX2 = cc.offsetWidth + CX1;
			var CY1 = p.y;
			var CY2 = cc.offsetHeight + CY1;

			if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
				if (!cc.__msh_save_visibility) {
					cc.__msh_save_visibility = getVisib(cc);
				}
				cc.style.visibility = cc.__msh_save_visibility;
			} else {
				if (!cc.__msh_save_visibility) {
					cc.__msh_save_visibility = getVisib(cc);
				}
				cc.style.visibility = "hidden";
			}
		}
	}
};

/** Internal function; it displays the bar with the names of the weekday. */
Calendar.prototype._displayWeekdays = function () {
	var fdow = this.firstDayOfWeek;
	var cell = this.firstdayname;
	var weekend = Calendar._TT["WEEKEND"];
	for (var i = 0; i < 7; ++i) {
		cell.className = "day name";
		var realday = (i + fdow) % 7;
		if (i) {
			cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]);
			cell.navtype = 100;
			cell.calendar = this;
			cell.fdow = realday;
			Calendar._add_evs(cell);
		}
		if (weekend.indexOf(realday.toString()) != -1) {
			Calendar.addClass(cell, "weekend");
		}
		cell.innerHTML = Calendar._SDN[(i + fdow) % 7];
		cell = cell.nextSibling;
	}
};

/** Internal function.  Hides all combo boxes that might be displayed. */
Calendar.prototype._hideCombos = function () {
	this.monthsCombo.style.display = "none";
	this.yearsCombo.style.display = "none";
};

/** Internal function.  Starts dragging the element. */
Calendar.prototype._dragStart = function (ev) {
	if (this.dragging) {
		return;
	}
	this.dragging = true;
	var posX;
	var posY;
	if (Calendar.is_ie) {
		posY = window.event.clientY + document.body.scrollTop;
		posX = window.event.clientX + document.body.scrollLeft;
	} else {
		posY = ev.clientY + window.scrollY;
		posX = ev.clientX + window.scrollX;
	}
	var st = this.element.style;
	this.xOffs = posX - parseInt(st.left);
	this.yOffs = posY - parseInt(st.top);
	with (Calendar) {
		addEvent(document, "mousemove", calDragIt);
		addEvent(document, "mouseup", calDragEnd);
	}
};

// BEGIN: DATE OBJECT PATCHES

/** Adds the number of days array to the Date object. */
Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);

/** Constants used for time computations */
Date.SECOND = 1000 /* milliseconds */;
Date.MINUTE = 60 * Date.SECOND;
Date.HOUR   = 60 * Date.MINUTE;
Date.DAY    = 24 * Date.HOUR;
Date.WEEK   =  7 * Date.DAY;

Date.parseDate = function(str, fmt) {
	var today = new Date();
	var y = 0;
	var m = -1;
	var d = 0;
	var a = str.split(/\W+/);
	var b = fmt.match(/%./g);
	var i = 0, j = 0;
	var hr = 0;
	var min = 0;
	for (i = 0; i < a.length; ++i) {
		if (!a[i])
			continue;
		switch (b[i]) {
		    case "%d":
		    case "%e":
			d = parseInt(a[i], 10);
			break;

		    case "%m":
			m = parseInt(a[i], 10) - 1;
			break;

		    case "%Y":
		    case "%y":
			y = parseInt(a[i], 10);
			(y < 100) && (y += (y > 29) ? 1900 : 2000);
			break;

		    case "%b":
		    case "%B":
			for (j = 0; j < 12; ++j) {
				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
			}
			break;

		    case "%H":
		    case "%I":
		    case "%k":
		    case "%l":
			hr = parseInt(a[i], 10);
			break;

		    case "%P":
		    case "%p":
			if (/pm/i.test(a[i]) && hr < 12)
				hr += 12;
			else if (/am/i.test(a[i]) && hr >= 12)
				hr -= 12;
			break;

		    case "%M":
			min = parseInt(a[i], 10);
			break;
		}
	}
	if (isNaN(y)) y = today.getFullYear();
	if (isNaN(m)) m = today.getMonth();
	if (isNaN(d)) d = today.getDate();
	if (isNaN(hr)) hr = today.getHours();
	if (isNaN(min)) min = today.getMinutes();
	if (y != 0 && m != -1 && d != 0)
		return new Date(y, m, d, hr, min, 0);
	y = 0; m = -1; d = 0;
	for (i = 0; i < a.length; ++i) {
		if (a[i].search(/[a-zA-Z]+/) != -1) {
			var t = -1;
			for (j = 0; j < 12; ++j) {
				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
			}
			if (t != -1) {
				if (m != -1) {
					d = m+1;
				}
				m = t;
			}
		} else if (parseInt(a[i], 10) <= 12 && m == -1) {
			m = a[i]-1;
		} else if (parseInt(a[i], 10) > 31 && y == 0) {
			y = parseInt(a[i], 10);
			(y < 100) && (y += (y > 29) ? 1900 : 2000);
		} else if (d == 0) {
			d = a[i];
		}
	}
	if (y == 0)
		y = today.getFullYear();
	if (m != -1 && d != 0)
		return new Date(y, m, d, hr, min, 0);
	return today;
};

/** Returns the number of days in the current month */
Date.prototype.getMonthDays = function(month) {
	var year = this.getFullYear();
	if (typeof month == "undefined") {
		month = this.getMonth();
	}
	if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
		return 29;
	} else {
		return Date._MD[month];
	}
};

/** Returns the number of day in the year. */
Date.prototype.getDayOfYear = function() {
	var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
	var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
	var time = now - then;
	return Math.floor(time / Date.DAY);
};

/** Returns the number of the week in year, as defined in ISO 8601. */
Date.prototype.getWeekNumber = function() {
	var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
	var DoW = d.getDay();
	d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
	var ms = d.valueOf(); // GMT
	d.setMonth(0);
	d.setDate(4); // Thu in Week 1
	return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
};

/** Checks date and time equality */
Date.prototype.equalsTo = function(date) {
	return ((this.getFullYear() == date.getFullYear()) &&
		(this.getMonth() == date.getMonth()) &&
		(this.getDate() == date.getDate()) &&
		(this.getHours() == date.getHours()) &&
		(this.getMinutes() == date.getMinutes()));
};

/** Set only the year, month, date parts (keep existing time) */
Date.prototype.setDateOnly = function(date) {
	var tmp = new Date(date);
	this.setDate(1);
	this.setFullYear(tmp.getFullYear());
	this.setMonth(tmp.getMonth());
	this.setDate(tmp.getDate());
};

/** Prints the date in a string according to the given format. */
Date.prototype.print = function (str) {
	var m = this.getMonth();
	var d = this.getDate();
	var y = this.getFullYear();
	var wn = this.getWeekNumber();
	var w = this.getDay();
	var s = {};
	var hr = this.getHours();
	var pm = (hr >= 12);
	var ir = (pm) ? (hr - 12) : hr;
	var dy = this.getDayOfYear();
	if (ir == 0)
		ir = 12;
	var min = this.getMinutes();
	var sec = this.getSeconds();
	s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N]
	s["%A"] = Calendar._DN[w]; // full weekday name
	s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N]
	s["%B"] = Calendar._MN[m]; // full month name
	// FIXME: %c : preferred date and time representation for the current locale
	s["%C"] = 1 + Math.floor(y / 100); // the century number
	s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
	s["%e"] = d; // the day of the month (range 1 to 31)
	// FIXME: %D : american date style: %m/%d/%y
	// FIXME: %E, %F, %G, %g, %h (man strftime)
	s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
	s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
	s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
	s["%k"] = hr;		// hour, range 0 to 23 (24h format)
	s["%l"] = ir;		// hour, range 1 to 12 (12h format)
	s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
	s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
	s["%n"] = "\n";		// a newline character
	s["%p"] = pm ? "PM" : "AM";
	s["%P"] = pm ? "pm" : "am";
	// FIXME: %r : the time in am/pm notation %I:%M:%S %p
	// FIXME: %R : the time in 24-hour notation %H:%M
	s["%s"] = Math.floor(this.getTime() / 1000);
	s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
	s["%t"] = "\t";		// a tab character
	// FIXME: %T : the time in 24-hour notation (%H:%M:%S)
	s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
	s["%u"] = w + 1;	// the day of the week (range 1 to 7, 1 = MON)
	s["%w"] = w;		// the day of the week (range 0 to 6, 0 = SUN)
	// FIXME: %x : preferred date representation for the current locale without the time
	// FIXME: %X : preferred time representation for the current locale without the date
	s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
	s["%Y"] = y;		// year with the century
	s["%%"] = "%";		// a literal '%' character

	var re = /%./g;
	if (!Calendar.is_ie5 && !Calendar.is_khtml)
		return str.replace(re, function (par) { return s[par] || par; });

	var a = str.match(re);
	for (var i = 0; i < a.length; i++) {
		var tmp = s[a[i]];
		if (tmp) {
			re = new RegExp(a[i], 'g');
			str = str.replace(re, tmp);
		}
	}

	return str;
};

Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear;
Date.prototype.setFullYear = function(y) {
	var d = new Date(this);
	d.__msh_oldSetFullYear(y);
	if (d.getMonth() != this.getMonth())
		this.setDate(28);
	this.__msh_oldSetFullYear(y);
};

// END: DATE OBJECT PATCHES


// global object that remembers the calendar
window._dynarch_popupCalendar = null;








/*  Copyright Mihai Bazon, 2002, 2003  |  http://dynarch.com/mishoo/
 * ---------------------------------------------------------------------------
 *
 * The DHTML Calendar
 *
 * Details and latest version at:
 * http://dynarch.com/mishoo/calendar.epl
 *
 * This script is distributed under the GNU Lesser General Public License.
 * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
 *
 * This file defines helper functions for setting up the calendar.  They are
 * intended to help non-programmers get a working calendar on their site
 * quickly.  This script should not be seen as part of the calendar.  It just
 * shows you what one can do with the calendar, while in the same time
 * providing a quick and simple method for setting it up.  If you need
 * exhaustive customization of the calendar creation process feel free to
 * modify this code to suit your needs (this is recommended and much better
 * than modifying calendar.js itself).
 */

// $Id: calendar-setup.js,v 1.25 2005/03/07 09:51:33 mishoo Exp $

/**
 *  This function "patches" an input field (or other element) to use a calendar
 *  widget for date selection.
 *
 *  The "params" is a single object that can have the following properties:
 *
 *    prop. name   | description
 *  -------------------------------------------------------------------------------------------------
 *   inputField    | the ID of an input field to store the date
 *   displayArea   | the ID of a DIV or other element to show the date
 *   button        | ID of a button or other element that will trigger the calendar
 *   eventName     | event that will trigger the calendar, without the "on" prefix (default: "click")
 *   ifFormat      | date format that will be stored in the input field
 *   daFormat      | the date format that will be used to display the date in displayArea
 *   singleClick   | (true/false) wether the calendar is in single click mode or not (default: true)
 *   firstDay      | numeric: 0 to 6.  "0" means display Sunday first, "1" means display Monday first, etc.
 *   align         | alignment (default: "Br"); if you don't know what's this see the calendar documentation
 *   range         | array with 2 elements.  Default: [1900, 2999] -- the range of years available
 *   weekNumbers   | (true/false) if it's true (default) the calendar will display week numbers
 *   flat          | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID
 *   flatCallback  | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar)
 *   disableFunc   | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
 *   onSelect      | function that gets called when a date is selected.  You don't _have_ to supply this (the default is generally okay)
 *   onClose       | function that gets called when the calendar is closed.  [default]
 *   onUpdate      | function that gets called after the date is updated in the input field.  Receives a reference to the calendar.
 *   date          | the date that the calendar will be initially displayed to
 *   showsTime     | default: false; if true the calendar will include a time selector
 *   timeFormat    | the time format; can be "12" or "24", default is "12"
 *   electric      | if true (default) then given fields/date areas are updated for each move; otherwise they're updated only on close
 *   step          | configures the step of the years in drop-down boxes; default: 2
 *   position      | configures the calendar absolute position; default: null
 *   cache         | if "true" (but default: "false") it will reuse the same calendar object, where possible
 *   showOthers    | if "true" (but default: "false") it will show days from other months too
 *
 *  None of them is required, they all have default values.  However, if you
 *  pass none of "inputField", "displayArea" or "button" you'll get a warning
 *  saying "nothing to setup".
 */
Calendar.setup = function (params) {
	function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };

	param_default("inputField",     null);
	param_default("displayArea",    null);
	param_default("button",         null);
	param_default("eventName",      "click");
	param_default("ifFormat",       "%Y/%m/%d");
	param_default("daFormat",       "%Y/%m/%d");
	param_default("singleClick",    true);
	param_default("disableFunc",    null);
	param_default("dateStatusFunc", params["disableFunc"]);	// takes precedence if both are defined
	param_default("dateText",       null);
	param_default("firstDay",       null);
	param_default("align",          "Br");
	param_default("range",          [1900, 2999]);
	param_default("weekNumbers",    true);
	param_default("flat",           null);
	param_default("flatCallback",   null);
	param_default("onSelect",       null);
	param_default("onClose",        null);
	param_default("onUpdate",       null);
	param_default("date",           null);
	param_default("showsTime",      false);
	param_default("timeFormat",     "24");
	param_default("electric",       true);
	param_default("step",           2);
	param_default("position",       null);
	param_default("cache",          false);
	param_default("showOthers",     false);
	param_default("multiple",       null);

	var tmp = ["inputField", "displayArea", "button"];
	for (var i in tmp) {
		if (typeof params[tmp[i]] == "string") {
			params[tmp[i]] = document.getElementById(params[tmp[i]]);
		}
	}
	if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) {
		alert("Calendar.setup:\n  Nothing to setup (no fields found).  Please check your code");
		return false;
	}

	function onSelect(cal) {
		var p = cal.params;
		var update = (cal.dateClicked || p.electric);
		if (update && p.inputField) {
			p.inputField.value = cal.date.print(p.ifFormat);
			if (typeof p.inputField.onchange == "function")
				p.inputField.onchange();
		}
		if (update && p.displayArea)
			p.displayArea.innerHTML = cal.date.print(p.daFormat);
		if (update && typeof p.onUpdate == "function")
			p.onUpdate(cal);
		if (update && p.flat) {
			if (typeof p.flatCallback == "function")
				p.flatCallback(cal);
		}
		if (update && p.singleClick && cal.dateClicked)
			cal.callCloseHandler();
	};

	if (params.flat != null) {
		if (typeof params.flat == "string")
			params.flat = document.getElementById(params.flat);
		if (!params.flat) {
			alert("Calendar.setup:\n  Flat specified but can't find parent.");
			return false;
		}
		var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect);
		cal.showsOtherMonths = params.showOthers;
		cal.showsTime = params.showsTime;
		cal.time24 = (params.timeFormat == "24");
		cal.params = params;
		cal.weekNumbers = params.weekNumbers;
		cal.setRange(params.range[0], params.range[1]);
		cal.setDateStatusHandler(params.dateStatusFunc);
		cal.getDateText = params.dateText;
		if (params.ifFormat) {
			cal.setDateFormat(params.ifFormat);
		}
		if (params.inputField && typeof params.inputField.value == "string") {
			cal.parseDate(params.inputField.value);
		}
		cal.create(params.flat);
		cal.show();
		return false;
	}

	var triggerEl = params.button || params.displayArea || params.inputField;
	triggerEl["on" + params.eventName] = function() {
		var dateEl = params.inputField || params.displayArea;
		var dateFmt = params.inputField ? params.ifFormat : params.daFormat;
		var mustCreate = false;
		var cal = window.calendar;
		if (dateEl)
			params.date = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt);
		if (!(cal && params.cache)) {
			window.calendar = cal = new Calendar(params.firstDay,
							     params.date,
							     params.onSelect || onSelect,
							     params.onClose || function(cal) { cal.hide(); });
			cal.showsTime = params.showsTime;
			cal.time24 = (params.timeFormat == "24");
			cal.weekNumbers = params.weekNumbers;
			mustCreate = true;
		} else {
			if (params.date)
				cal.setDate(params.date);
			cal.hide();
		}
		if (params.multiple) {
			cal.multiple = {};
			for (var i = params.multiple.length; --i >= 0;) {
				var d = params.multiple[i];
				var ds = d.print("%Y%m%d");
				cal.multiple[ds] = d;
			}
		}
		cal.showsOtherMonths = params.showOthers;
		cal.yearStep = params.step;
		cal.setRange(params.range[0], params.range[1]);
		cal.params = params;
		cal.setDateStatusHandler(params.dateStatusFunc);
		cal.getDateText = params.dateText;
		cal.setDateFormat(dateFmt);
		if (mustCreate)
			cal.create();
		cal.refresh();
		if (!params.position)
			cal.showAtElement(params.button || params.displayArea || params.inputField, params.align);
		else
			cal.showAt(params.position[0], params.position[1]);
		return false;
	};

	return cal;
};




// ** I18N

// Calendar EN language
// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
// Encoding: any
// Distributed under the same terms as the calendar itself.

// For translators: please use UTF-8 if possible.  We strongly believe that
// Unicode is the answer to a real internationalized world.  Also please
// include your contact information in the header, as can be seen above.

// full day names

try {
Calendar._DN = new Array
("Pazar",
 "Pazartesi",
 "Sali",
 "Carsamba",
 "Persembe",
 "Cuma",
 "Cumartesi",
 "Pazar");

// Please note that the following array of short day names (and the same goes
// for short month names, _SMN) isn't absolutely necessary.  We give it here
// for exemplification on how one can customize the short day names, but if
// they are simply the first N letters of the full name you can simply say:
//
//   Calendar._SDN_len = N; // short day name length
//   Calendar._SMN_len = N; // short month name length
//
// If N = 3 then this is not needed either since we assume a value of 3 if not
// present, to be compatible with translation files that were written before
// this feature.

// short day names
Calendar._SDN = new Array
("Paz",
 "Pts",
 "Sal",
 "Car",
 "Per",
 "Cum",
 "Cts",
 "Paz");

// First day of the week. "0" means display Sunday first, "1" means display
// Monday first, etc.
Calendar._FD = 1;

// full month names
Calendar._MN = new Array
("Ocak",
 "Subat",
 "Mart",
 "Nisan",
 "Mayis",
 "Haziran",
 "Temmuz",
 "Agustos",
 "Eylul",
 "Ekim",
 "Kasim",
 "Aralik");

// short month names
Calendar._SMN = new Array
("Oca",
 "Sub",
 "Mar",
 "Nis",
 "May",
 "Haz",
 "Tem",
 "Agu",
 "Eyl",
 "Eki",
 "Kas",
 "Ara");

// tooltips
Calendar._TT = {};
Calendar._TT["INFO"] = "Tarihi Sil";
Calendar._TT["ABOUT"] = "";
Calendar._TT["PREV_YEAR"] = "Onceki Yil (Menu icin basili tutunuz)";
Calendar._TT["PREV_MONTH"] = "Onceki Ay (Menu icin basili tutunuz)";
Calendar._TT["GO_TODAY"] = "Bugune git";
Calendar._TT["NEXT_MONTH"] = "Sonraki Ay (Menu icin basili tutunuz)";
Calendar._TT["NEXT_YEAR"] = "Sonraki Yil (Menu icin basili tutunuz)";
Calendar._TT["SEL_DATE"] = "Tarih seciniz";
Calendar._TT["DRAG_TO_MOVE"] = "Tasimak icin surukleyiniz";
Calendar._TT["PART_TODAY"] = " (bugun)";

// the following is to inform that "%s" is to be the first day of week
// %s will be replaced with the day name.
Calendar._TT["DAY_FIRST"] = "%s'i once goster";

// This may be locale-dependent.  It specifies the week-end days, as an array
// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
// means Monday, etc.
Calendar._TT["WEEKEND"] = "6,0";

Calendar._TT["CLOSE"] = "Kapat";
Calendar._TT["TODAY"] = "Bugun";
Calendar._TT["TIME_PART"] = "(Shift-)Tiklayin ya da degistirmek icin surukleyin";

// date formats
Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";

Calendar._TT["WK"] = "hafta";
Calendar._TT["TIME"] = "Saat:";

Calendar._TT["DEL"] = "Sil";

} catch (e) {
//alert("msg" + e.message);
}



//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006 Valerio Proietti, <http://mad4milk.net>, MIT Style License.

eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('o ci={cj:\'1.11\'};k $77(N){m(N!=9N)};k $F(N){B(!$77(N))m O;B(N.5i)m\'G\';o F=7c N;B(F==\'2I\'&&N.ch){22(N.84){Y 1:m\'G\';Y 3:m(/\\S/).2v(N.ax)?\'cg\':\'cd\'}}B(F==\'2I\'||F==\'k\'){22(N.9C){Y 2t:m\'1z\';Y 7y:m\'5C\';Y 18:m\'4R\'}B(7c N.V==\'4M\'){B(N.3r)m\'ce\';B(N.8t)m\'1b\'}}m F};k $2a(){o 54={};M(o i=0;i<1b.V;i++){M(o K 1a 1b[i]){o ap=1b[i][K];o 6d=54[K];B(6d&&$F(ap)==\'2I\'&&$F(6d)==\'2I\')54[K]=$2a(6d,ap);14 54[K]=ap}}m 54};o $R=k(){o 1p=1b;B(!1p[1])1p=[c,1p[0]];M(o K 1a 1p[1])1p[0][K]=1p[1][K];m 1p[0]};o $5e=k(){M(o i=0,l=1b.V;i<l;i++){1b[i].R=k(1U){M(o 1V 1a 1U){B(!c.1L[1V])c.1L[1V]=1U[1V];B(!c[1V])c[1V]=$5e.6x(1V)}}}};$5e.6x=k(1V){m k(W){m c.1L[1V].4j(W,2t.1L.bh.1X(1b,1))}};$5e(7Z,2t,6i,aN);k $2A(N){m!!(N||N===0)};k $4T(N,aY){m $77(N)?N:aY};k $8c(3s,1D){m 1c.9q(1c.8c()*(1D-3s+1)+3s)};k $3A(){m L 96().9w()};k $55(1H){cf(1H);ck(1H);m 1n};o 3M=k(N){N=N||{};N.R=$R;m N};o cl=L 3M(U);o cr=L 3M(Q);Q.6e=Q.33(\'6e\')[0];U.4a=!!(Q.5r);B(U.9o)U.2P=U[U.6C?\'cs\':\'ag\']=1e;14 B(Q.aC&&!Q.cq&&!cp.cm)U.4x=U[U.4a?\'cn\':\'5x\']=1e;14 B(Q.co!=1n)U.8r=1e;U.cc=U.4x;8X.R=$R;B(7c 5B==\'9N\'){o 5B=k(){};B(U.4x)Q.aJ("cb");5B.1L=(U.4x)?U["[[bZ.1L]]"]:{}}5B.1L.5i=k(){};B(U.ag)5j{Q.c0("c1",O,1e)}5c(e){};o 18=k(1J){o 5Z=k(){m(1b[0]!==1n&&c.1i&&$F(c.1i)==\'k\')?c.1i.4j(c,1b):c};$R(5Z,c);5Z.1L=1J;5Z.9C=18;m 5Z};18.1l=k(){};18.1L={R:k(1J){o 7m=L c(1n);M(o K 1a 1J){o 9m=7m[K];7m[K]=18.9l(9m,1J[K])}m L 18(7m)},3i:k(){M(o i=0,l=1b.V;i<l;i++)$R(c.1L,1b[i])}};18.9l=k(2l,2i){B(2l&&2l!=2i){o F=$F(2i);B(F!=$F(2l))m 2i;22(F){Y\'k\':o 8i=k(){c.1r=1b.8t.1r;m 2i.4j(c,1b)};8i.1r=2l;m 8i;Y\'2I\':m $2a(2l,2i)}}m 2i};o 7u=L 18({bY:k(fn){c.4v=c.4v||[];c.4v.1k(fn);m c},7z:k(){B(c.4v&&c.4v.V)c.4v.aK().2g(10,c)},bX:k(){c.4v=[]}});o 2p=L 18({1B:k(F,fn){B(fn!=18.1l){c.$19=c.$19||{};c.$19[F]=c.$19[F]||[];c.$19[F].5S(fn)}m c},1h:k(F,1p,2g){B(c.$19&&c.$19[F]){c.$19[F].1q(k(fn){fn.3a({\'W\':c,\'2g\':2g,\'1b\':1p})()},c)}m c},4C:k(F,fn){B(c.$19&&c.$19[F])c.$19[F].2K(fn);m c}});o 43=L 18({2Y:k(){c.C=$2a.4j(1n,[c.C].R(1b));B(c.1B){M(o 3z 1a c.C){B($F(c.C[3z]==\'k\')&&(/^67[A-Z]/).2v(3z))c.1B(3z,c.C[3z])}}m c}});2t.R({7b:k(fn,W){M(o i=0,j=c.V;i<j;i++)fn.1X(W,c[i],i,c)},36:k(fn,W){o 4Y=[];M(o i=0,j=c.V;i<j;i++){B(fn.1X(W,c[i],i,c))4Y.1k(c[i])}m 4Y},2D:k(fn,W){o 4Y=[];M(o i=0,j=c.V;i<j;i++)4Y[i]=fn.1X(W,c[i],i,c);m 4Y},4F:k(fn,W){M(o i=0,j=c.V;i<j;i++){B(!fn.1X(W,c[i],i,c))m O}m 1e},bU:k(fn,W){M(o i=0,j=c.V;i<j;i++){B(fn.1X(W,c[i],i,c))m 1e}m O},3k:k(3r,15){o 3S=c.V;M(o i=(15<0)?1c.1D(0,3S+15):15||0;i<3S;i++){B(c[i]===3r)m i}m-1},8e:k(1g,V){1g=1g||0;B(1g<0)1g=c.V+1g;V=V||(c.V-1g);o 8g=[];M(o i=0;i<V;i++)8g[i]=c[1g++];m 8g},2K:k(3r){o i=0;o 3S=c.V;6Z(i<3S){B(c[i]===3r){c.74(i,1);3S--}14{i++}}m c},1j:k(3r,15){m c.3k(3r,15)!=-1},bV:k(1O){o N={},V=1c.3s(c.V,1O.V);M(o i=0;i<V;i++)N[1O[i]]=c[i];m N},R:k(1z){M(o i=0,j=1z.V;i<j;i++)c.1k(1z[i]);m c},2a:k(1z){M(o i=0,l=1z.V;i<l;i++)c.5S(1z[i]);m c},5S:k(3r){B(!c.1j(3r))c.1k(3r);m c},bW:k(){m c[$8c(0,c.V-1)]||1n},80:k(){m c[c.V-1]||1n}});2t.1L.1q=2t.1L.7b;2t.1q=2t.7b;k $A(1z){m 2t.8e(1z)};k $1q(41,fn,W){B(41&&7c 41.V==\'4M\'&&$F(41)!=\'2I\'){2t.7b(41,fn,W)}14{M(o 1w 1a 41)fn.1X(W||41,41[1w],1w)}};2t.1L.2v=2t.1L.1j;6i.R({2v:k(79,2U){m(($F(79)==\'2z\')?L 7y(79,2U):79).2v(c)},3d:k(){m 5O(c,10)},aH:k(){m 66(c)},8a:k(){m c.3g(/-\\D/g,k(31){m 31.8d(1).7A()})},aL:k(){m c.3g(/\\w[A-Z]/g,k(31){m(31.8d(0)+\'-\'+31.8d(1).5L())})},8R:k(){m c.3g(/\\b[a-z]/g,k(31){m 31.7A()})},5T:k(){m c.3g(/^\\s+|\\s+$/g,\'\')},7r:k(){m c.3g(/\\s{2,}/g,\' \').5T()},5E:k(1z){o 1s=c.31(/\\d{1,3}/g);m(1s)?1s.5E(1z):O},5G:k(1z){o 3C=c.31(/^#?(\\w{1,2})(\\w{1,2})(\\w{1,2})$/);m(3C)?3C.bh(1).5G(1z):O},1j:k(2z,s){m(s)?(s+c+s).3k(s+2z+s)>-1:c.3k(2z)>-1},b5:k(){m c.3g(/([.*+?^${}()|[\\]\\/\\\\])/g,\'\\\\$1\')}});2t.R({5E:k(1z){B(c.V<3)m O;B(c.V==4&&c[3]==0&&!1z)m\'c2\';o 3C=[];M(o i=0;i<3;i++){o 5d=(c[i]-0).4l(16);3C.1k((5d.V==1)?\'0\'+5d:5d)}m 1z?3C:\'#\'+3C.2c(\'\')},5G:k(1z){B(c.V!=3)m O;o 1s=[];M(o i=0;i<3;i++){1s.1k(5O((c[i].V==1)?c[i]+c[i]:c[i],16))}m 1z?1s:\'1s(\'+1s.2c(\',\')+\')\'}});7Z.R({3a:k(C){o fn=c;C=$2a({\'W\':fn,\'I\':O,\'1b\':1n,\'2g\':O,\'4f\':O,\'6f\':O},C);B($2A(C.1b)&&$F(C.1b)!=\'1z\')C.1b=[C.1b];m k(I){o 1p;B(C.I){I=I||U.I;1p=[(C.I===1e)?I:L C.I(I)];B(C.1b)1p.R(C.1b)}14 1p=C.1b||1b;o 3N=k(){m fn.4j($4T(C.W,fn),1p)};B(C.2g)m 9M(3N,C.2g);B(C.4f)m c3(3N,C.4f);B(C.6f)5j{m 3N()}5c(c9){m O};m 3N()}},bT:k(1p,W){m c.3a({\'1b\':1p,\'W\':W})},6f:k(1p,W){m c.3a({\'1b\':1p,\'W\':W,\'6f\':1e})()},W:k(W,1p){m c.3a({\'W\':W,\'1b\':1p})},c8:k(W,1p){m c.3a({\'W\':W,\'I\':1e,\'1b\':1p})},2g:k(2g,W,1p){m c.3a({\'2g\':2g,\'W\':W,\'1b\':1p})()},4f:k(aV,W,1p){m c.3a({\'4f\':aV,\'W\':W,\'1b\':1p})()}});aN.R({3d:k(){m 5O(c)},aH:k(){m 66(c)},1F:k(3s,1D){m 1c.3s(1D,1c.1D(3s,c))},2q:k(5Y){5Y=1c.3w(10,5Y||0);m 1c.2q(c*5Y)/5Y},c7:k(fn){M(o i=0;i<c;i++)fn(i)}});o P=L 18({1i:k(el,1U){B($F(el)==\'2z\'){B(U.2P&&1U&&(1U.1w||1U.F)){o 1w=(1U.1w)?\' 1w="\'+1U.1w+\'"\':\'\';o F=(1U.F)?\' F="\'+1U.F+\'"\':\'\';57 1U.1w;57 1U.F;el=\'<\'+el+1w+F+\'>\'}el=Q.aJ(el)}el=$(el);m(!1U||!el)?el:el.2j(1U)}});o 26=L 18({1i:k(T){m(T)?$R(T,c):c}});26.R=k(1U){M(o 1V 1a 1U){c.1L[1V]=1U[1V];c[1V]=$5e.6x(1V)}};k $(el){B(!el)m 1n;B(el.5i)m 2F.52(el);B([U,Q].1j(el))m el;o F=$F(el);B(F==\'2z\'){el=Q.6W(el);F=(el)?\'G\':O}B(F!=\'G\')m 1n;B(el.5i)m 2F.52(el);B([\'2I\',\'c4\'].1j(el.6S.5L()))m el;$R(el,P.1L);el.5i=k(){};m 2F.52(el)};Q.6Y=Q.33;k $$(){o T=[];M(o i=0,j=1b.V;i<j;i++){o 1S=1b[i];22($F(1S)){Y\'G\':T.1k(1S);Y\'c5\':1C;Y O:1C;Y\'2z\':1S=Q.6Y(1S,1e);62:T.R(1S)}}m $$.5M(T)};$$.5M=k(1z){o T=[];M(o i=0,l=1z.V;i<l;i++){B(1z[i].$6r)6l;o G=$(1z[i]);B(G&&!G.$6r){G.$6r=1e;T.1k(G)}}M(o n=0,d=T.V;n<d;n++)T[n].$6r=1n;m L 26(T)};26.73=k(K){m k(){o 1p=1b;o 1x=[];o T=1e;M(o i=0,j=c.V,3N;i<j;i++){3N=c[i][K].4j(c[i],1p);B($F(3N)!=\'G\')T=O;1x.1k(3N)};m(T)?$$.5M(1x):1x}};P.R=k(1J){M(o K 1a 1J){5B.1L[K]=1J[K];P.1L[K]=1J[K];P[K]=$5e.6x(K);o aB=(2t.1L[K])?K+\'26\':K;26.1L[aB]=26.73(K)}};P.R({2j:k(1U){M(o 1V 1a 1U){o 4m=1U[1V];22(1V){Y\'8J\':c.4A(4m);1C;Y\'19\':B(c.6j)c.6j(4m);1C;Y\'1J\':c.6o(4m);1C;62:c.7l(1V,4m)}}m c},28:k(el,ay){el=$(el);22(ay){Y\'9k\':el.3n.91(c,el);1C;Y\'94\':o 3x=el.8I();B(!3x)el.3n.86(c);14 el.3n.91(c,3x);1C;Y\'1o\':o 8Z=el.88;B(8Z){el.91(c,8Z);1C}62:el.86(c)}m c},7Y:k(el){m c.28(el,\'9k\')},6v:k(el){m c.28(el,\'94\')},c6:k(el){m c.28(el,\'3P\')},ct:k(el){m c.28(el,\'1o\')},b2:k(){o T=[];$1q(1b,k(4t){T=T.7P(4t)});$$(T).28(c);m c},2K:k(){m c.3n.bl(c)},9G:k(9V){o el=$(c.cu(9V!==O));B(!el.$19)m el;el.$19={};M(o F 1a c.$19)el.$19[F]={\'1O\':$A(c.$19[F].1O),\'1I\':$A(c.$19[F].1I)};m el.78()},cT:k(el){el=$(el);c.3n.cU(el,c);m el},bn:k(1K){c.86(Q.cS(1K));m c},7s:k(1A){m c.1A.1j(1A,\' \')},9z:k(1A){B(!c.7s(1A))c.1A=(c.1A+\' \'+1A).7r();m c},9E:k(1A){c.1A=c.1A.3g(L 7y(\'(^|\\\\s)\'+1A+\'(?:\\\\s|$)\'),\'$1\').7r();m c},cR:k(1A){m c.7s(1A)?c.9E(1A):c.9z(1A)},1P:k(K,J){22(K){Y\'21\':m c.bk(66(J));Y\'cO\':K=(U.2P)?\'cP\':\'cQ\'}K=K.8a();22($F(J)){Y\'4M\':B(![\'cV\',\'ak\'].1j(K))J+=\'4W\';1C;Y\'1z\':J=\'1s(\'+J.2c(\',\')+\')\'}c.1N[K]=J;m c},4A:k(1Z){22($F(1Z)){Y\'2I\':P.72(c,\'1P\',1Z);1C;Y\'2z\':c.1N.87=1Z}m c},bk:k(21){B(21==0){B(c.1N.4z!="4O")c.1N.4z="4O"}14{B(c.1N.4z!="8G")c.1N.4z="8G"}B(!c.6p||!c.6p.cW)c.1N.ak=1;B(U.2P)c.1N.36=(21==1)?\'\':"7d(21="+21*35+")";c.1N.21=c.$1W.21=21;m c},2h:k(K){K=K.8a();o 1M=c.1N[K];B(!$2A(1M)){B(K==\'21\')m c.$1W.21;1M=[];M(o 1N 1a P.4c){B(K==1N){P.4c[1N].1q(k(s){o 1N=c.2h(s);1M.1k(5O(1N)?1N:\'bo\')},c);B(K==\'2R\'){o 4F=1M.4F(k(5d){m(5d==1M[0])});m(4F)?1M[0]:O}m 1M.2c(\' \')}}B(K.1j(\'2R\')){B(P.4c.2R.1j(K)){m[\'bf\',\'7T\',\'2Q\'].2D(k(p){m c.2h(K+p)},c).2c(\' \')}14 B(P.97.1j(K)){m[\'bi\',\'bs\',\'az\',\'a6\'].2D(k(p){m c.2h(\'2R\'+p+K.3g(\'2R\',\'\'))},c).2c(\' \')}}B(Q.aF)1M=Q.aF.d2(c,1n).d3(K.aL());14 B(c.6p)1M=c.6p[K]}B(U.2P)1M=P.b6(K,1M,c);B(1M&&K.2v(/2E/i)&&1M.1j(\'1s\')){m 1M.68(\'1s\').74(1,4).2D(k(2E){m 2E.5E()}).2c(\' \')}m 1M},bg:k(){m P.7H(c,\'2h\',1b)},61:k(6u,1g){6u+=\'d1\';o el=(1g)?c[1g]:c[6u];6Z(el&&$F(el)!=\'G\')el=el[6u];m $(el)},9W:k(){m c.61(\'2l\')},8I:k(){m c.61(\'3x\')},d0:k(){m c.61(\'3x\',\'88\')},80:k(){m c.61(\'2l\',\'cX\')},cY:k(){m $(c.3n)},8H:k(){m $$(c.aC)},8o:k(el){m!!$A(c.33(\'*\')).1j(el)},5R:k(K){o 25=P.6A[K];B(25)m c[25];o 7V=P.a3[K]||0;B(!U.2P||7V)m c.cZ(K,7V);o 81=c.cN[K];m(81)?81.ax:1n},cM:k(K){o 25=P.6A[K];B(25)c[25]=\'\';14 c.a7(K);m c},cA:k(){m P.7H(c,\'5R\',1b)},7l:k(K,J){o 25=P.6A[K];B(25)c[25]=J;14 c.cB(K,J);m c},6o:k(1Z){m P.72(c,\'7l\',1Z)},5s:k(){c.b3=$A(1b).2c(\'\');m c},cC:k(1K){o 3q=c.4D();B([\'1N\',\'2s\'].1j(3q)){B(U.2P){B(3q==\'1N\')c.b4.87=1K;14 B(3q==\'2s\')c.7l(\'1K\',1K);m c}14{c.bl(c.88);m c.bn(1K)}}c[$77(c.83)?\'83\':\'b1\']=1K;m c},cz:k(){o 3q=c.4D();B([\'1N\',\'2s\'].1j(3q)){B(U.2P){B(3q==\'1N\')m c.b4.87;14 B(3q==\'2s\')m c.5R(\'1K\')}14{m c.b3}}m($4T(c.83,c.b1))},4D:k(){m c.6S.5L()},1l:k(){2F.3V(c.33(\'*\'));m c.5s(\'\')}});P.b6=k(K,1M,G){B($2A(5O(1M)))m 1M;B([\'2N\',\'2y\'].1j(K)){o 1I=(K==\'2y\')?[\'1u\',\'4n\']:[\'1o\',\'3P\'];o 3l=0;1I.1q(k(J){3l+=G.2h(\'2R-\'+J+\'-2y\').3d()+G.2h(\'4w-\'+J).3d()});m G[\'1E\'+K.8R()]-3l+\'4W\'}14 B(K.2v(/2R(.+)bf|34|4w/)){m\'bo\'}m 1M};P.4c={\'2R\':[],\'4w\':[],\'34\':[]};[\'bi\',\'bs\',\'az\',\'a6\'].1q(k(9v){M(o 1N 1a P.4c)P.4c[1N].1k(1N+9v)});P.97=[\'cy\',\'cv\',\'cw\'];P.7H=k(el,23,1O){o 1M={};$1q(1O,k(1t){1M[1t]=el[23](1t)});m 1M};P.72=k(el,23,7G){M(o 1t 1a 7G)el[23](1t,7G[1t]);m el};P.6A=L 3M({\'4R\':\'1A\',\'M\':\'cx\',\'cD\':\'cE\',\'cK\':\'cL\',\'cJ\':\'cI\',\'cF\':\'cG\',\'cH\':\'d4\',\'bI\':\'bN\',\'bB\':\'bJ\',\'J\':\'J\',\'7D\':\'7D\',\'7E\':\'7E\',\'7J\':\'7J\',\'7Q\':\'7Q\'});P.a3={\'4N\':2,\'4s\':2};P.2H={6J:{2C:k(F,fn){B(c.8j)c.8j(F,fn,O);14 c.bD(\'67\'+F,fn);m c},3h:k(F,fn){B(c.a4)c.a4(F,fn,O);14 c.bP(\'67\'+F,fn);m c}}};U.R(P.2H.6J);Q.R(P.2H.6J);P.R(P.2H.6J);o 2F={T:[],52:k(el){B(!el.$1W){2F.T.1k(el);el.$1W={\'21\':1}}m el},3V:k(T){M(o i=0,j=T.V,el;i<j;i++){B(!(el=T[i])||!el.$1W)6l;B(el.$19)el.1h(\'3V\').78();M(o p 1a el.$1W)el.$1W[p]=1n;M(o d 1a P.1L)el[d]=1n;2F.T[2F.T.3k(el)]=1n;el.5i=el.$1W=el=1n}2F.T.2K(1n)},1l:k(){2F.52(U);2F.52(Q);2F.3V(2F.T)}};U.2C(\'9t\',k(){U.2C(\'7v\',2F.1l);B(U.2P)U.2C(\'7v\',bH)});o 2X=L 18({1i:k(I){B(I&&I.$bq)m I;c.$bq=1e;I=I||U.I;c.I=I;c.F=I.F;c.3v=I.3v||I.bF;B(c.3v.84==3)c.3v=c.3v.3n;c.aK=I.bx;c.bG=I.bC;c.bK=I.bz;c.bO=I.by;B([\'8b\',\'5a\'].1j(c.F)){c.bS=(I.9p)?I.9p/bQ:-(I.bE||0)/3}14 B(c.F.1j(\'1t\')){c.6O=I.9K||I.bL;M(o 1w 1a 2X.1O){B(2X.1O[1w]==c.6O){c.1t=1w;1C}}B(c.F==\'9X\'){o 6Q=c.6O-bM;B(6Q>0&&6Q<13)c.1t=\'f\'+6Q}c.1t=c.1t||6i.bA(c.6O).5L()}14 B(c.F.2v(/(6h|3m|bw)/)){c.1Y={\'x\':I.8E||I.9f+Q.2Z.5V,\'y\':I.8w||I.at+Q.2Z.63};c.9B={\'x\':I.8E?I.8E-U.99:I.9f,\'y\':I.8w?I.8w-U.9i:I.at};c.bR=(I.9K==3)||(I.bv==2);22(c.F){Y\'90\':c.2o=I.2o||I.ca;1C;Y\'8Y\':c.2o=I.2o||I.8A}c.aU()}m c},1R:k(){m c.6U().6X()},6U:k(){B(c.I.6U)c.I.6U();14 c.I.db=1e;m c},6X:k(){B(c.I.6X)c.I.6X();14 c.I.eK=O;m c}});2X.6m={2o:k(){B(c.2o&&c.2o.84==3)c.2o=c.2o.3n},aD:k(){5j{2X.6m.2o.1X(c)}5c(e){c.2o=c.3v}}};2X.1L.aU=(U.8r)?2X.6m.aD:2X.6m.2o;2X.1O=L 3M({\'eL\':13,\'6P\':38,\'eJ\':40,\'1u\':37,\'4n\':39,\'eI\':27,\'eF\':32,\'eG\':8,\'eH\':9,\'57\':46});P.2H.2p={1B:k(F,fn){c.$19=c.$19||{};c.$19[F]=c.$19[F]||{\'1O\':[],\'1I\':[]};B(c.$19[F].1O.1j(fn))m c;c.$19[F].1O.1k(fn);o 76=F;o 2w=P.2p[F];B(2w){B(2w.7F)2w.7F.1X(c,fn);B(2w.2D)fn=2w.2D;B(2w.F)76=2w.F}B(!c.8j)fn=fn.3a({\'W\':c,\'I\':1e});c.$19[F].1I.1k(fn);m(P.8V.1j(76))?c.2C(76,fn):c},4C:k(F,fn){B(!c.$19||!c.$19[F])m c;o 1m=c.$19[F].1O.3k(fn);B(1m==-1)m c;o 1t=c.$19[F].1O.74(1m,1)[0];o J=c.$19[F].1I.74(1m,1)[0];o 2w=P.2p[F];B(2w){B(2w.2K)2w.2K.1X(c,fn);B(2w.F)F=2w.F}m(P.8V.1j(F))?c.3h(F,J):c},6j:k(1Z){m P.72(c,\'1B\',1Z)},78:k(F){B(!c.$19)m c;B(!F){M(o 6g 1a c.$19)c.78(6g);c.$19=1n}14 B(c.$19[F]){c.$19[F].1O.1q(k(fn){c.4C(F,fn)},c);c.$19[F]=1n}m c},1h:k(F,1p,2g){B(c.$19&&c.$19[F]){c.$19[F].1O.1q(k(fn){fn.3a({\'W\':c,\'2g\':2g,\'1b\':1p})()},c)}m c},au:k(15,F){B(!15.$19)m c;B(!F){M(o 6g 1a 15.$19)c.au(15,6g)}14 B(15.$19[F]){15.$19[F].1O.1q(k(fn){c.1B(F,fn)},c)}m c}};U.R(P.2H.2p);Q.R(P.2H.2p);P.R(P.2H.2p);P.2p=L 3M({\'8N\':{F:\'90\',2D:k(I){I=L 2X(I);B(I.2o!=c&&!c.8o(I.2o))c.1h(\'8N\',I)}},\'8P\':{F:\'8Y\',2D:k(I){I=L 2X(I);B(I.2o!=c&&!c.8o(I.2o))c.1h(\'8P\',I)}},\'5a\':{F:(U.8r)?\'8b\':\'5a\'}});P.8V=[\'6h\',\'eM\',\'5z\',\'5n\',\'5a\',\'8b\',\'90\',\'8Y\',\'2M\',\'9X\',\'eN\',\'eS\',\'4e\',\'7v\',\'9t\',\'eT\',\'5o\',\'eR\',\'eQ\',\'3F\',\'eO\',\'eP\',\'48\',\'aE\',\'8s\',\'eE\',\'2G\'];7Z.R({3e:k(W,1p){m c.3a({\'W\':W,\'1b\':1p,\'I\':2X})}});26.R({eV:k(3q){m L 26(c.36(k(el){m(P.4D(el)==3q)}))},a8:k(1A,2J){o T=c.36(k(el){m(el.1A&&el.1A.1j(1A,\' \'))});m(2J)?T:L 26(T)},a2:k(4u,2J){o T=c.36(k(el){m(el.4u==4u)});m(2J)?T:L 26(T)},a9:k(1w,82,J,2J){o T=c.36(k(el){o 2i=P.5R(el,1w);B(!2i)m O;B(!82)m 1e;22(82){Y\'=\':m(2i==J);Y\'*=\':m(2i.1j(J));Y\'^=\':m(2i.6K(0,J.V)==J);Y\'$=\':m(2i.6K(2i.V-J.V)==J);Y\'!=\':m(2i!=J);Y\'~=\':m 2i.1j(J,\' \')}m O});m(2J)?T:L 26(T)}});k $E(1S,36){m($(36)||Q).9P(1S)};k $et(1S,36){m($(36)||Q).6Y(1S)};$$.3B={\'5C\':/^(\\w*|\\*)(?:#([\\w-]+)|\\.([\\w-]+))?(?:\\[(\\w+)(?:([!*^$]?=)["\']?([^"\'\\]]*)["\']?)?])?$/,\'4a\':{7L:k(1x,3b,1d,i){o 2r=[3b.eu?\'7N:\':\'\',1d[1]];B(1d[2])2r.1k(\'[@4u="\',1d[2],\'"]\');B(1d[3])2r.1k(\'[1j(7P(" ", @4R, " "), " \',1d[3],\' ")]\');B(1d[4]){B(1d[5]&&1d[6]){22(1d[5]){Y\'*=\':2r.1k(\'[1j(@\',1d[4],\', "\',1d[6],\'")]\');1C;Y\'^=\':2r.1k(\'[es-er(@\',1d[4],\', "\',1d[6],\'")]\');1C;Y\'$=\':2r.1k(\'[eo(@\',1d[4],\', 2z-V(@\',1d[4],\') - \',1d[6].V,\' + 1) = "\',1d[6],\'"]\');1C;Y\'=\':2r.1k(\'[@\',1d[4],\'="\',1d[6],\'"]\');1C;Y\'!=\':2r.1k(\'[@\',1d[4],\'!="\',1d[6],\'"]\')}}14{2r.1k(\'[@\',1d[4],\']\')}}1x.1k(2r.2c(\'\'));m 1x},7O:k(1x,3b,2J){o T=[];o 4a=Q.5r(\'.//\'+1x.2c(\'//\'),3b,$$.3B.ac,ep.eq,1n);M(o i=0,j=4a.ev;i<j;i++)T.1k(4a.ew(i));m(2J)?T:L 26(T.2D($))}},\'9T\':{7L:k(1x,3b,1d,i){B(i==0){B(1d[2]){o el=3b.6W(1d[2]);B(!el||((1d[1]!=\'*\')&&(P.4D(el)!=1d[1])))m O;1x=[el]}14{1x=$A(3b.33(1d[1]))}}14{1x=$$.3B.33(1x,1d[1]);B(1d[2])1x=26.a2(1x,1d[2],1e)}B(1d[3])1x=26.a8(1x,1d[3],1e);B(1d[4])1x=26.a9(1x,1d[4],1d[5],1d[6],1e);m 1x},7O:k(1x,3b,2J){m(2J)?1x:$$.5M(1x)}},ac:k(9Z){m(9Z==\'7N\')?\'9Y://aS.eB.eC/eA/7N\':O},33:k(3b,6S){o 7M=[];M(o i=0,j=3b.V;i<j;i++)7M.R(3b[i].33(6S));m 7M}};$$.3B.23=(U.4a)?\'4a\':\'9T\';P.2H.7R={6N:k(1S,2J){o 1x=[];1S=1S.5T().68(\' \');M(o i=0,j=1S.V;i<j;i++){o 9U=1S[i];o 1d=9U.31($$.3B.5C);B(!1d)1C;1d[1]=1d[1]||\'*\';o 2r=$$.3B[$$.3B.23].7L(1x,c,1d,i);B(!2r)1C;1x=2r}m $$.3B[$$.3B.23].7O(1x,c,2J)},9P:k(1S){m $(c.6N(1S,1e)[0]||O)},6Y:k(1S,2J){o T=[];1S=1S.68(\',\');M(o i=0,j=1S.V;i<j;i++)T=T.7P(c.6N(1S[i],1e));m(2J)?T:$$.5M(T)}};P.R({6W:k(4u){o el=Q.6W(4u);B(!el)m O;M(o 1r=el.3n;1r!=c;1r=1r.3n){B(!1r)m O}m el},ez:k(1A){m c.6N(\'.\'+1A)}});Q.R(P.2H.7R);P.R(P.2H.7R);P.R({44:k(){22(c.4D()){Y\'48\':o 1I=[];$1q(c.C,k(3z){B(3z.7Q)1I.1k($4T(3z.J,3z.1K))});m(c.7J)?1I:1I[0];Y\'ab\':B(!(c.7E&&[\'ex\',\'ey\'].1j(c.F))&&![\'4O\',\'1K\',\'eU\'].1j(c.F))1C;Y\'ad\':m c.J}m O},ae:k(){m $$(c.33(\'ab\'),c.33(\'48\'),c.33(\'ad\'))},5A:k(){o 5f=[];c.ae().1q(k(el){o 1w=el.1w;o J=el.44();B(J===O||!1w||el.7D)m;o 7C=k(4m){5f.1k(1w+\'=\'+7e(4m))};B($F(J)==\'1z\')J.1q(7C);14 7C(J)});m 5f.2c(\'&\')}});P.R({3G:k(x,y){c.5V=x;c.63=y},7g:k(){m{\'2G\':{\'x\':c.5V,\'y\':c.63},\'3l\':{\'x\':c.4b,\'y\':c.3R},\'7h\':{\'x\':c.71,\'y\':c.5P}}},3p:k(2k){2k=2k||[];o el=c,1u=0,1o=0;do{1u+=el.fp||0;1o+=el.fh||0;el=el.fj}6Z(el);2k.1q(k(G){1u-=G.5V||0;1o-=G.63||0});m{\'x\':1u,\'y\':1o}},aQ:k(2k){m c.3p(2k).y},aP:k(2k){m c.3p(2k).x},4E:k(2k){o 1v=c.3p(2k);o N={\'2y\':c.4b,\'2N\':c.3R,\'1u\':1v.x,\'1o\':1v.y};N.4n=N.1u+N.2y;N.3P=N.1o+N.2N;m N}});P.2p.7S={7F:k(fn){B(U.6B){fn.1X(c);m}o 5X=k(){B(U.6B)m;U.6B=1e;U.1H=$55(U.1H);c.1h(\'7S\')}.W(c);B(Q.5m&&U.4x){U.1H=k(){B([\'6B\',\'8p\'].1j(Q.5m))5X()}.4f(50)}14 B(Q.5m&&U.2P){B(!$(\'7I\')){o 4s=(U.5k.ff==\'fi:\')?\'://0\':\'8q:fk(0)\';Q.fg(\'<2s 4u="7I" fd 4s="\'+4s+\'"><\\/2s>\');$(\'7I\').7i=k(){B(c.5m==\'8p\')5X()}}}14{U.2C("4e",5X);Q.2C("fe",5X)}}};U.fm=k(fn){m c.1B(\'7S\',fn)};U.R({8m:k(){B(c.5x)m c.fl;B(c.9a)m Q.4B.9c;m Q.2Z.9c},8n:k(){B(c.5x)m c.fo;B(c.9a)m Q.4B.9d;m Q.2Z.9d},93:k(){B(c.2P)m 1c.1D(Q.2Z.4b,Q.2Z.71);B(c.4x)m Q.4B.71;m Q.2Z.71},92:k(){B(c.2P)m 1c.1D(Q.2Z.3R,Q.2Z.5P);B(c.4x)m Q.4B.5P;m Q.2Z.5P},8u:k(){m c.99||Q.2Z.5V},8v:k(){m c.9i||Q.2Z.63},7g:k(){m{\'3l\':{\'x\':c.8m(),\'y\':c.8n()},\'7h\':{\'x\':c.93(),\'y\':c.92()},\'2G\':{\'x\':c.8u(),\'y\':c.8v()}}},3p:k(){m{\'x\':0,\'y\':0}}});o 1f={};1f.2T=L 18({C:{3X:18.1l,1Q:18.1l,7w:18.1l,2f:k(p){m-(1c.av(1c.7W*p)-1)/2},49:fb,2x:\'4W\',3T:1e,98:50},1i:k(C){c.G=c.G||1n;c.2Y(C);B(c.C.1i)c.C.1i.1X(c)},2n:k(){o 3A=$3A();B(3A<c.3A+c.C.49){c.4p=c.C.2f((3A-c.3A)/c.C.49);c.4q();c.4k()}14{c.1R(1e);c.2j(c.17);c.1h(\'1Q\',c.G,10);c.7z()}},2j:k(17){c.12=17;c.4k();m c},4q:k(){c.12=c.4o(c.15,c.17)},4o:k(15,17){m(17-15)*c.4p+15},1g:k(15,17){B(!c.C.3T)c.1R();14 B(c.1H)m c;c.15=15;c.17=17;c.3F=c.17-c.15;c.3A=$3A();c.1H=c.2n.4f(1c.2q(bd/c.C.98),c);c.1h(\'3X\',c.G);m c},1R:k(29){B(!c.1H)m c;c.1H=$55(c.1H);B(!29)c.1h(\'7w\',c.G);m c},2w:k(15,17){m c.1g(15,17)},f1:k(29){m c.1R(29)}});1f.2T.3i(L 7u,L 2p,L 43);1f.3t={48:k(K,17){B(K.2v(/2E/i))m c.2Q;o F=$F(17);B((F==\'1z\')||(F==\'2z\'&&17.1j(\' \')))m c.73;m c.9j},2V:k(el,K,5b){B(!5b.1k)5b=[5b];o 15=5b[0],17=5b[1];B(!$2A(17)){17=15;15=el.2h(K)}o 1y=c.48(K,17);m{\'15\':1y.2V(15),\'17\':1y.2V(17),\'1y\':1y}}};1f.3t.9j={2V:k(J){m 66(J)},56:k(15,17,2O){m 2O.4o(15,17)},44:k(J,2x,K){B(2x==\'4W\'&&K!=\'21\')J=1c.2q(J);m J+2x}};1f.3t.73={2V:k(J){m J.1k?J:J.68(\' \').2D(k(v){m 66(v)})},56:k(15,17,2O){o 12=[];M(o i=0;i<15.V;i++)12[i]=2O.4o(15[i],17[i]);m 12},44:k(J,2x,K){B(2x==\'4W\'&&K!=\'21\')J=J.2D(1c.2q);m J.2c(2x+\' \')+2x}};1f.3t.2Q={2V:k(J){m J.1k?J:J.5G(1e)},56:k(15,17,2O){o 12=[];M(o i=0;i<15.V;i++)12[i]=1c.2q(2O.4o(15[i],17[i]));m 12},44:k(J){m\'1s(\'+J.2c(\',\')+\')\'}};1f.7T=1f.2T.R({1i:k(el,K,C){c.G=$(el);c.K=K;c.1r(C)},3Z:k(){m c.2j(0)},4q:k(){c.12=c.1y.56(c.15,c.17,c)},2j:k(17){c.1y=1f.3t.48(c.K,17);m c.1r(c.1y.2V(17))},1g:k(15,17){B(c.1H&&c.C.3T)m c;o 2e=1f.3t.2V(c.G,c.K,[15,17]);c.1y=2e.1y;m c.1r(2e.15,2e.17)},4k:k(){c.G.1P(c.K,c.1y.44(c.12,c.C.2x,c.K))}});P.R({f2:k(K,C){m L 1f.7T(c,K,C)}});1f.4c=1f.2T.R({1i:k(el,C){c.G=$(el);c.1r(C)},4q:k(){M(o p 1a c.15)c.12[p]=c.1y[p].56(c.15[p],c.17[p],c)},2j:k(17){o 2e={};c.1y={};M(o p 1a 17){c.1y[p]=1f.3t.48(p,17[p]);2e[p]=c.1y[p].2V(17[p])}m c.1r(2e)},1g:k(N){B(c.1H&&c.C.3T)m c;c.12={};c.1y={};o 15={},17={};M(o p 1a N){o 2e=1f.3t.2V(c.G,p,N[p]);15[p]=2e.15;17[p]=2e.17;c.1y[p]=2e.1y}m c.1r(15,17)},4k:k(){M(o p 1a c.12)c.G.1P(p,c.1y[p].44(c.12[p],c.C.2x,p))}});P.R({3U:k(C){m L 1f.4c(c,C)}});1f.26=1f.2T.R({1i:k(T,C){c.T=$$(T);c.1r(C)},4q:k(){M(o i 1a c.15){o 5Q=c.15[i],47=c.17[i],3u=c.1y[i],5U=c.12[i]={};M(o p 1a 5Q)5U[p]=3u[p].56(5Q[p],47[p],c)}},2j:k(17){o 2e={};c.1y={};M(o i 1a 17){o 47=17[i],3u=c.1y[i]={},9u=2e[i]={};M(o p 1a 47){3u[p]=1f.3t.48(p,47[p]);9u[p]=3u[p].2V(47[p])}}m c.1r(2e)},1g:k(N){B(c.1H&&c.C.3T)m c;c.12={};c.1y={};o 15={},17={};M(o i 1a N){o 85=N[i],5Q=15[i]={},47=17[i]={},3u=c.1y[i]={};M(o p 1a 85){o 2e=1f.3t.2V(c.T[i],p,85[p]);5Q[p]=2e.15;47[p]=2e.17;3u[p]=2e.1y}}m c.1r(15,17)},4k:k(){M(o i 1a c.12){o 5U=c.12[i],3u=c.1y[i];M(o p 1a 5U)c.T[i].1P(p,3u[p].44(5U[p],c.C.2x,p))}}});1f.ah=1f.2T.R({C:{2k:[],1E:{\'x\':0,\'y\':0},9r:1e},1i:k(G,C){c.12=[];c.G=$(G);c.1G={\'1R\':c.1R.W(c,O)};c.1r(C);B(c.C.9r){c.1B(\'3X\',k(){Q.1B(\'5a\',c.1G.1R)}.W(c));c.1B(\'1Q\',k(){Q.4C(\'5a\',c.1G.1R)}.W(c))}},4q:k(){M(o i=0;i<2;i++)c.12[i]=c.4o(c.15[i],c.17[i])},3G:k(x,y){B(c.1H&&c.C.3T)m c;o el=c.G.7g();o 1I={\'x\':x,\'y\':y};M(o z 1a el.3l){o 1D=el.7h[z]-el.3l[z];B($2A(1I[z]))1I[z]=($F(1I[z])==\'4M\')?1I[z].1F(0,1D):1D;14 1I[z]=el.2G[z];1I[z]+=c.C.1E[z]}m c.1g([el.2G.x,el.2G.y],[1I.x,1I.y])},f0:k(){m c.3G(O,0)},eZ:k(){m c.3G(O,\'bu\')},eW:k(){m c.3G(0,O)},eX:k(){m c.3G(\'bu\',O)},8A:k(el){o 1r=c.G.3p(c.C.2k);o 3v=$(el).3p(c.C.2k);m c.3G(3v.x-1r.x,3v.y-1r.y)},4k:k(){c.G.3G(c.12[0],c.12[1])}});1f.eY=1f.2T.R({C:{2b:\'8Q\'},1i:k(el,C){c.G=$(el);c.3c=L P(\'4Z\',{\'8J\':$R(c.G.bg(\'34\'),{\'9y\':\'4O\'})}).6v(c.G).b2(c.G);c.G.1P(\'34\',0);c.2Y(C);c.12=[];c.1r(c.C);c.4X=1e;c.1B(\'1Q\',k(){c.4X=(c.12[0]===0)});B(U.5x)c.1B(\'1Q\',k(){B(c.4X)c.G.2K().28(c.3c)})},4q:k(){M(o i=0;i<2;i++)c.12[i]=c.4o(c.15[i],c.17[i])},8Q:k(){c.34=\'34-1o\';c.64=\'2N\';c.1E=c.G.3R},8M:k(){c.34=\'34-1u\';c.64=\'2y\';c.1E=c.G.4b},ba:k(2b){c[2b||c.C.2b]();m c.1g([c.G.2h(c.34).3d(),c.3c.2h(c.64).3d()],[0,c.1E])},bb:k(2b){c[2b||c.C.2b]();m c.1g([c.G.2h(c.34).3d(),c.3c.2h(c.64).3d()],[-c.1E,0])},3Z:k(2b){c[2b||c.C.2b]();c.4X=O;m c.2j([-c.1E,0])},4d:k(2b){c[2b||c.C.2b]();c.4X=1e;m c.2j([0,c.1E])},f3:k(2b){B(c.3c.3R==0||c.3c.4b==0)m c.ba(2b);m c.bb(2b)},4k:k(){c.G.1P(c.34,c.12[0]+c.C.2x);c.3c.1P(c.64,c.12[1]+c.C.2x)}});1f.7U=k(2f,2U){2U=2U||[];B($F(2U)!=\'1z\')2U=[2U];m $R(2f,{f4:k(1m){m 2f(1m,2U)},f9:k(1m){m 1-2f(1-1m,2U)},fa:k(1m){m(1m<=0.5)?2f(2*1m,2U)/2:(2-2f(2*(1-1m),2U))/2}})};1f.3o=L 3M({fc:k(p){m p}});1f.3o.R=k(7B){M(o 2f 1a 7B){1f.3o[2f]=L 1f.7U(7B[2f]);1f.3o.7X(2f)}};1f.3o.7X=k(2f){[\'f8\',\'f7\',\'f5\'].1q(k(89){1f.3o[2f.5L()+89]=1f.3o[2f][\'f6\'+89]})};1f.3o.R({eD:k(p,x){m 1c.3w(p,x[0]||6)},em:k(p){m 1c.3w(2,8*(p-1))},dw:k(p){m 1-1c.bj(1c.dx(p))},dy:k(p){m 1-1c.bj((1-p)*1c.7W/2)},dv:k(p,x){x=x[0]||1.du;m 1c.3w(p,2)*((x+1)*p-x)},dr:k(p){o J;M(o a=0,b=1;1;a+=b,b/=2){B(p>=(7-4*a)/11){J=-1c.3w((11-6*a-11*p)/4,2)+b*b;1C}}m J},ds:k(p,x){m 1c.3w(2,10*--p)*1c.av(20*p*1c.7W*(x[0]||1)/3)}});[\'dt\',\'dz\',\'dA\',\'dG\'].1q(k(2f,i){1f.3o[2f]=L 1f.7U(k(p){m 1c.3w(p,[i+2])});1f.3o.7X(2f)});o 4g={};4g.2T=L 18({C:{3J:O,2x:\'4W\',3X:18.1l,al:18.1l,1Q:18.1l,as:18.1l,8S:18.1l,1F:O,3E:{x:\'1u\',y:\'1o\'},4P:O,6M:6},1i:k(el,C){c.2Y(C);c.G=$(el);c.3J=$(c.C.3J)||c.G;c.3m={\'12\':{},\'1m\':{}};c.J={\'1g\':{},\'12\':{}};c.1G={\'1g\':c.1g.3e(c),\'4i\':c.4i.3e(c),\'3D\':c.3D.3e(c),\'1R\':c.1R.W(c)};c.6V();B(c.C.1i)c.C.1i.1X(c)},6V:k(){c.3J.1B(\'5n\',c.1G.1g);m c},9F:k(){c.3J.4C(\'5n\',c.1G.1g);m c},1g:k(I){c.1h(\'al\',c.G);c.3m.1g=I.1Y;o 1F=c.C.1F;c.1F={\'x\':[],\'y\':[]};M(o z 1a c.C.3E){B(!c.C.3E[z])6l;c.J.12[z]=c.G.2h(c.C.3E[z]).3d();c.3m.1m[z]=I.1Y[z]-c.J.12[z];B(1F&&1F[z]){M(o i=0;i<2;i++){B($2A(1F[z][i]))c.1F[z][i]=($F(1F[z][i])==\'k\')?1F[z][i]():1F[z][i]}}}B($F(c.C.4P)==\'4M\')c.C.4P={\'x\':c.C.4P,\'y\':c.C.4P};Q.2C(\'2M\',c.1G.4i);Q.2C(\'5z\',c.1G.1R);c.1h(\'3X\',c.G);I.1R()},4i:k(I){o ao=1c.2q(1c.dH(1c.3w(I.1Y.x-c.3m.1g.x,2)+1c.3w(I.1Y.y-c.3m.1g.y,2)));B(ao>c.C.6M){Q.3h(\'2M\',c.1G.4i);Q.2C(\'2M\',c.1G.3D);c.3D(I);c.1h(\'as\',c.G)}I.1R()},3D:k(I){c.69=O;c.3m.12=I.1Y;M(o z 1a c.C.3E){B(!c.C.3E[z])6l;c.J.12[z]=c.3m.12[z]-c.3m.1m[z];B(c.1F[z]){B($2A(c.1F[z][1])&&(c.J.12[z]>c.1F[z][1])){c.J.12[z]=c.1F[z][1];c.69=1e}14 B($2A(c.1F[z][0])&&(c.J.12[z]<c.1F[z][0])){c.J.12[z]=c.1F[z][0];c.69=1e}}B(c.C.4P[z])c.J.12[z]-=(c.J.12[z]%c.C.4P[z]);c.G.1P(c.C.3E[z],c.J.12[z]+c.C.2x)}c.1h(\'8S\',c.G);I.1R()},1R:k(){Q.3h(\'2M\',c.1G.4i);Q.3h(\'2M\',c.1G.3D);Q.3h(\'5z\',c.1G.1R);c.1h(\'1Q\',c.G)}});4g.2T.3i(L 2p,L 43);P.R({dF:k(C){m L 4g.2T(c,$2a({3E:{x:\'2y\',y:\'2N\'}},C))}});4g.aM=4g.2T.R({C:{6c:[],2d:O,2k:[]},1i:k(el,C){c.2Y(C);c.G=$(el);c.6c=$$(c.C.6c);c.2d=$(c.C.2d);c.1v={\'G\':c.G.2h(\'1v\'),\'2d\':O};B(c.2d)c.1v.2d=c.2d.2h(\'1v\');B(![\'70\',\'3Y\',\'4V\'].1j(c.1v.G))c.1v.G=\'3Y\';o 1o=c.G.2h(\'1o\').3d();o 1u=c.G.2h(\'1u\').3d();B(c.1v.G==\'3Y\'&&![\'70\',\'3Y\',\'4V\'].1j(c.1v.2d)){1o=$2A(1o)?1o:c.G.aQ(c.C.2k);1u=$2A(1u)?1u:c.G.aP(c.C.2k)}14{1o=$2A(1o)?1o:0;1u=$2A(1u)?1u:0}c.G.4A({\'1o\':1o,\'1u\':1u,\'1v\':c.1v.G});c.1r(c.G)},1g:k(I){c.3f=1n;B(c.2d){o 4r=c.2d.4E();o el=c.G.4E();B(c.1v.G==\'3Y\'&&![\'70\',\'3Y\',\'4V\'].1j(c.1v.2d)){c.C.1F={\'x\':[4r.1u,4r.4n-el.2y],\'y\':[4r.1o,4r.3P-el.2N]}}14{c.C.1F={\'y\':[0,4r.2N-el.2N],\'x\':[0,4r.2y-el.2y]}}}c.1r(I)},3D:k(I){c.1r(I);o 3f=c.69?O:c.6c.36(c.aO,c).80();B(c.3f!=3f){B(c.3f)c.3f.1h(\'dE\',[c.G,c]);c.3f=3f?3f.1h(\'dB\',[c.G,c]):1n}m c},aO:k(el){el=el.4E(c.C.2k);o 12=c.3m.12;m(12.x>el.1u&&12.x<el.4n&&12.y<el.3P&&12.y>el.1o)},1R:k(){B(c.3f&&!c.69)c.3f.1h(\'dC\',[c.G,c]);14 c.G.1h(\'dD\',c);c.1r();m c}});P.R({dq:k(C){m L 4g.aM(c,C)}});o 6n=L 18({C:{23:\'59\',be:1e,9g:18.1l,5h:18.1l,6w:18.1l,aG:1e,5J:\'dp-8\',aZ:O,4J:{}},7q:k(){c.2u=(U.6C)?L 6C():(U.2P?L 9o(\'en.dc\'):O);m c},1i:k(C){c.7q().2Y(C);c.C.5D=c.C.5D||c.5D;c.4J={};B(c.C.aG&&c.C.23==\'59\'){o 5J=(c.C.5J)?\'; dd=\'+c.C.5J:\'\';c.5l(\'9R-F\',\'9J/x-aS-da-d9\'+5J)}B(c.C.1i)c.C.1i.1X(c)},9s:k(){B(c.2u.5m!=4||!c.4Q)m;c.4Q=O;o 4I=0;5j{4I=c.2u.4I}5c(e){};B(c.C.5D.1X(c,4I))c.5h();14 c.6w();c.2u.7i=18.1l},5D:k(4I){m((4I>=d6)&&(4I<d7))},5h:k(){c.3L={\'1K\':c.2u.d8,\'5t\':c.2u.de};c.1h(\'5h\',[c.3L.1K,c.3L.5t]);c.7z()},6w:k(){c.1h(\'6w\',c.2u)},5l:k(1w,J){c.4J[1w]=J;m c},6a:k(2L,1T){B(c.C.aZ)c.95();14 B(c.4Q)m c;c.4Q=1e;B(1T&&c.C.23==\'5q\'){2L=2L+(2L.1j(\'?\')?\'&\':\'?\')+1T;1T=1n}c.2u.4X(c.C.23.7A(),2L,c.C.be);c.2u.7i=c.9s.W(c);B((c.C.23==\'59\')&&c.2u.d5)c.5l(\'df\',\'dl\');$R(c.4J,c.C.4J);M(o F 1a c.4J)5j{c.2u.dm(F,c.4J[F])}5c(e){};c.1h(\'9g\');c.2u.6a($4T(1T,1n));m c},95:k(){B(!c.4Q)m c;c.4Q=O;c.2u.8s();c.2u.7i=18.1l;c.7q();c.1h(\'7w\');m c}});6n.3i(L 7u,L 2p,L 43);o 9b=6n.R({C:{1T:1n,7x:1n,1Q:18.1l,6R:O,7p:O},1i:k(2L,C){c.1B(\'5h\',c.1Q);c.2Y(C);c.C.1T=c.C.1T||c.C.dn;B(![\'59\',\'5q\'].1j(c.C.23)){c.5H=\'5H=\'+c.C.23;c.C.23=\'59\'}c.1r();c.5l(\'X-dk-dj\',\'6C\');c.5l(\'dg\',\'1K/8q, 1K/dh, 9J/5t, 1K/5t, */*\');c.2L=2L},1Q:k(){B(c.C.7x)$(c.C.7x).1l().5s(c.3L.1K);B(c.C.6R||c.C.7p)c.6R();c.1h(\'1Q\',[c.3L.1K,c.3L.5t],20)},9h:k(1T){1T=1T||c.C.1T;22($F(1T)){Y\'G\':1T=$(1T).5A();1C;Y\'2I\':1T=8X.5A(1T)}B(c.5H)1T=(1T)?[c.5H,1T].2c(\'&\'):c.5H;m c.6a(c.2L,1T)},6R:k(){o 2s,3y;B(c.C.7p||(/(di|dI)2s/).2v(c.af(\'9R-F\')))3y=c.3L.1K;14{3y=[];o 5C=/<2s[^>]*>([\\s\\S]*?)<\\/2s>/dJ;6Z((2s=5C.e9(c.3L.1K)))3y.1k(2s[1]);3y=3y.2c(\'\\n\')}B(3y)(U.9O)?U.9O(3y):U.9M(3y,0)},af:k(1w){5j{m c.2u.ea(1w)}5c(e){};m 1n}});8X.5A=k(1Z){o 5f=[];M(o K 1a 1Z)5f.1k(7e(K)+\'=\'+7e(1Z[K]));m 5f.2c(\'&\')};P.R({6a:k(C){m L 9b(c.5R(\'eb\'),$2a({1T:c.5A()},C,{23:\'59\'})).9h()}});o 3H=L 3M({C:{7o:O,7k:O,49:O,5g:O},2j:k(1t,J,C){C=$2a(c.C,C);J=7e(J);B(C.7o)J+=\'; 7o=\'+C.7o;B(C.7k)J+=\'; 7k=\'+C.7k;B(C.49){o 6k=L 96();6k.e8(6k.9w()+C.49*24*60*60*bd);J+=\'; e7=\'+6k.e4()}B(C.5g)J+=\'; 5g\';Q.4K=1t+\'=\'+J;m $R(C,{\'1t\':1t,\'J\':J})},5q:k(1t){o J=Q.4K.31(\'(?:^|;)\\\\s*\'+1t.b5()+\'=([^;]*)\');m J?e5(J[1]):O},2K:k(4K,C){B($F(4K)==\'2I\')c.2j(4K.1t,\'\',$2a(4K,{49:-1}));14 c.2j(4K,\'\',$2a(C,{49:-1}))}});o 3I={4l:k(N){22($F(N)){Y\'2z\':m\'"\'+N.3g(/(["\\\\])/g,\'\\\\$1\')+\'"\';Y\'1z\':m\'[\'+N.2D(3I.4l).2c(\',\')+\']\';Y\'2I\':o 2z=[];M(o K 1a N)2z.1k(3I.4l(K)+\':\'+3I.4l(N[K]));m\'{\'+2z.2c(\',\')+\'}\';Y\'4M\':B(e6(N))1C;Y O:m\'1n\'}m 6i(N)},5r:k(4H,5g){m(($F(4H)!=\'2z\')||(5g&&!4H.2v(/^("(\\\\.|[^"\\\\\\n\\r])*?"|[,:{}\\[\\]0-9.\\-+ec-u \\n\\r\\t])+?$/)))?1n:ed(\'(\'+4H+\')\')}};3I.ej=6n.R({1i:k(2L,C){c.2L=2L;c.1B(\'5h\',c.1Q);c.1r(C);c.5l(\'X-ek\',\'ei\')},6a:k(N){m c.1r(c.2L,\'eh=\'+3I.4l(N))},1Q:k(){c.1h(\'1Q\',[3I.5r(c.3L.1K,c.C.5g)])}});o ar=L 3M({8q:k(1Z,1J){1J=$2a({\'5N\':18.1l},1J);o 2s=L P(\'2s\',{\'4s\':1Z}).6j({\'4e\':1J.5N,\'ee\':k(){B(c.5m==\'8p\')c.1h(\'4e\')}});57 1J.5N;m 2s.6o(1J).28(Q.6e)},1y:k(1Z,1J){m L P(\'4y\',$2a({\'a1\':\'ef\',\'eg\':\'e3\',\'F\':\'1K/1y\',\'4N\':1Z},1J)).28(Q.6e)},4S:k(1Z,1J){1J=$2a({\'5N\':18.1l,\'e2\':18.1l,\'dP\':18.1l},1J);o 4S=L dQ();4S.4s=1Z;o G=L P(\'8x\',{\'4s\':1Z});[\'4e\',\'8s\',\'aE\'].1q(k(F){o I=1J[\'67\'+F];57 1J[\'67\'+F];G.1B(F,k(){c.4C(F,1b.8t);I.1X(c)})});B(4S.2y&&4S.2N)G.1h(\'4e\',G,1);m G.6o(1J)},6s:k(58,C){C=$2a({1Q:18.1l,an:18.1l},C);B(!58.1k)58=[58];o 6s=[];o 6q=0;58.1q(k(1Z){o 8x=L ar.4S(1Z,{\'5N\':k(){C.an.1X(c,6q);6q++;B(6q==58.V)C.1Q()}});6s.1k(8x)});m L 26(6s)}});o 3O=L 18({V:0,1i:k(2I){c.N=2I||{};c.5K()},5q:k(1t){m(c.6t(1t))?c.N[1t]:1n},6t:k(1t){m(1t 1a c.N)},2j:k(1t,J){B(!c.6t(1t))c.V++;c.N[1t]=J;m c},5K:k(){c.V=0;M(o p 1a c.N)c.V++;m c},2K:k(1t){B(c.6t(1t)){57 c.N[1t];c.V--}m c},1q:k(fn,W){$1q(c.N,fn,W)},R:k(N){$R(c.N,N);m c.5K()},2a:k(){c.N=$2a.4j(1n,[c.N].R(1b));m c.5K()},1l:k(){c.N={};c.V=0;m c},1O:k(){o 1O=[];M(o K 1a c.N)1O.1k(K);m 1O},1I:k(){o 1I=[];M(o K 1a c.N)1I.1k(c.N[K]);m 1I}});k $H(N){m L 3O(N)};3O.3H=3O.R({1i:k(1w,C){c.1w=1w;c.C=$R({\'aw\':1e},C||{});c.4e()},aX:k(){B(c.V==0){3H.2K(c.1w,c.C);m 1e}o 4H=3I.4l(c.N);B(4H.V>dR)m O;3H.2j(c.1w,4H,c.C);m 1e},4e:k(){c.N=3I.5r(3H.5q(c.1w),1e)||{};c.5K()}});3O.3H.2H={};[\'R\',\'2j\',\'2a\',\'1l\',\'2K\'].1q(k(23){3O.3H.2H[23]=k(){3O.1L[23].4j(c,1b);B(c.C.aw)c.aX();m c}});3O.3H.3i(3O.3H.2H);o 2Q=L 18({1i:k(2E,F){F=F||(2E.1k?\'1s\':\'3C\');o 1s,2m;22(F){Y\'1s\':1s=2E;2m=1s.8h();1C;Y\'2m\':1s=2E.b9();2m=2E;1C;62:1s=2E.5G(1e);2m=1s.8h()}1s.2m=2m;1s.3C=1s.5E();m $R(1s,2Q.1L)},54:k(){o 5I=$A(1b);o 7d=($F(5I[5I.V-1])==\'4M\')?5I.dO():50;o 1s=c.8e();5I.1q(k(2E){2E=L 2Q(2E);M(o i=0;i<3;i++)1s[i]=1c.2q((1s[i]/ 35 * (35 - 7d)) + (2E[i] /35*7d))});m L 2Q(1s,\'1s\')},dN:k(){m L 2Q(c.2D(k(J){m 51-J}))},dK:k(J){m L 2Q([J,c.2m[1],c.2m[2]],\'2m\')},dL:k(7a){m L 2Q([c.2m[0],7a,c.2m[2]],\'2m\')},dM:k(7a){m L 2Q([c.2m[0],c.2m[1],7a],\'2m\')}});k $dS(r,g,b){m L 2Q([r,g,b],\'1s\')};k $dT(h,s,b){m L 2Q([h,s,b],\'2m\')};2t.R({8h:k(){o 5W=c[0],65=c[1],75=c[2];o 2W,6y,8k;o 1D=1c.1D(5W,65,75),3s=1c.3s(5W,65,75);o 4p=1D-3s;8k=1D/51;6y=(1D!=0)?4p/1D:0;B(6y==0){2W=0}14{o 8l=(1D-5W)/4p;o 8W=(1D-65)/4p;o br=(1D-75)/4p;B(5W==1D)2W=br-8W;14 B(65==1D)2W=2+8l-br;14 2W=4+8W-8l;2W/=6;B(2W<0)2W++}m[1c.2q(2W*bc),1c.2q(6y*35),1c.2q(8k*35)]},b9:k(){o br=1c.2q(c[2]/35*51);B(c[1]==0){m[br,br,br]}14{o 2W=c[0]%bc;o f=2W%60;o p=1c.2q((c[2]*(35-c[1]))/dZ*51);o q=1c.2q((c[2]*(b7-c[1]*f))/bm*51);o t=1c.2q((c[2]*(b7-c[1]*(60-f)))/bm*51);22(1c.9q(2W/60)){Y 0:m[br,t,p];Y 1:m[q,br,p];Y 2:m[p,br,t];Y 3:m[p,q,br];Y 4:m[t,p,br];Y 5:m[br,p,q]}}m O}});o 9x=L 18({C:{6b:20,8O:1,6F:k(x,y){c.G.3G(x,y)}},1i:k(G,C){c.2Y(C);c.G=$(G);c.8y=([U,Q].1j(G))?$(Q.4B):c.G},1g:k(){c.8z=c.9A.3e(c);c.8y.2C(\'2M\',c.8z)},1R:k(){c.8y.3h(\'2M\',c.8z);c.1H=$55(c.1H)},9A:k(I){c.1Y=(c.G==U)?I.9B:I.1Y;B(!c.1H)c.1H=c.2G.4f(50,c)},2G:k(){o el=c.G.7g();o 1m=c.G.3p();o 3F={\'x\':0,\'y\':0};M(o z 1a c.1Y){B(c.1Y[z]<(c.C.6b+1m[z])&&el.2G[z]!=0)3F[z]=(c.1Y[z]-c.C.6b-1m[z])*c.C.8O;14 B(c.1Y[z]+c.C.6b>(el.3l[z]+1m[z])&&el.2G[z]+el.3l[z]!=el.7h[z])3F[z]=(c.1Y[z]-el.3l[z]+c.C.6b-1m[z])*c.C.8O}B(3F.y||3F.x)c.1h(\'6F\',[el.2G.x+3F.x,el.2G.y+3F.y])}});9x.3i(L 2p,L 43);o 8B=L 18({C:{6F:18.1l,1Q:18.1l,8L:k(1m){c.4h.1P(c.p,1m)},2b:\'8M\',6E:35,1E:0},1i:k(el,4h,C){c.G=$(el);c.4h=$(4h);c.2Y(C);c.8K=-1;c.8D=-1;c.2n=-1;c.G.1B(\'5n\',c.9D.3e(c));o 6H,1E;22(c.C.2b){Y\'8M\':c.z=\'x\';c.p=\'1u\';6H={\'x\':\'1u\',\'y\':O};1E=\'4b\';1C;Y\'8Q\':c.z=\'y\';c.p=\'1o\';6H={\'x\':O,\'y\':\'1o\'};1E=\'3R\'}c.1D=c.G[1E]-c.4h[1E]+(c.C.1E*2);c.a5=c.4h[1E]/2;c.ai=c.G[\'5q\'+c.p.8R()].W(c.G);c.4h.1P(\'1v\',\'70\').1P(c.p,-c.C.1E);o 8U={};8U[c.z]=[-c.C.1E,c.1D-c.C.1E];c.3D=L 4g.2T(c.4h,{1F:8U,3E:6H,6M:0,3X:k(){c.6L()}.W(c),8S:k(){c.6L()}.W(c),1Q:k(){c.6L();c.29()}.W(c)});B(c.C.1i)c.C.1i.1X(c)},2j:k(2n){c.2n=2n.1F(0,c.C.6E);c.6G();c.29();c.1h(\'8L\',c.a0(c.2n));m c},9D:k(I){o 1v=I.1Y[c.z]-c.ai()-c.a5;1v=1v.1F(-c.C.1E,c.1D-c.C.1E);c.2n=c.8C(1v);c.6G();c.29();c.1h(\'8L\',1v)},6L:k(){c.2n=c.8C(c.3D.J.12[c.z]);c.6G()},6G:k(){B(c.8K!=c.2n){c.8K=c.2n;c.1h(\'6F\',c.2n)}},29:k(){B(c.8D!==c.2n){c.8D=c.2n;c.1h(\'1Q\',c.2n+\'\')}},8C:k(1v){m 1c.2q((1v+c.C.1E)/c.1D*c.C.6E)},a0:k(2n){m c.1D*2n/c.C.6E}});8B.3i(L 2p);8B.3i(L 43);o e0=1f.ah.R({1i:k(C){c.1r(U,C);c.5w=(c.C.5w)?$$(c.C.5w):$$(Q.5w);o 5k=U.5k.4N.31(/^[^#]*/)[0]+\'#\';c.5w.1q(k(4y){B(4y.4N.3k(5k)!=0)m;o 3K=4y.4N.6K(5k.V);B(3K&&$(3K))c.9L(4y,3K)},c);B(!U.5x)c.1B(\'1Q\',k(){U.5k.e1=c.3K})},9L:k(4y,3K){4y.1B(\'6h\',k(I){c.3K=3K;c.8A(3K);I.1R()}.3e(c))}});o 9S=L 18({C:{4L:O,3X:18.1l,1Q:18.1l,2S:1e,6M:3,9H:k(G,2S){2S.1P(\'21\',0.7);G.1P(\'21\',0.7)},9e:k(G,2S){G.1P(\'21\',1);2S.2K();c.3V.2K()}},1i:k(5p,C){c.2Y(C);c.5p=$(5p);c.T=c.5p.8H();c.4L=(c.C.4L)?$$(c.C.4L):c.T;c.1G={\'1g\':[],\'5y\':c.5y.3e(c)};M(o i=0,l=c.4L.V;i<l;i++){c.1G.1g[i]=c.1g.3e(c,c.T[i])}c.6V();B(c.C.1i)c.C.1i.1X(c);c.1G.5o=c.5o.3e(c);c.1G.29=c.29.W(c)},6V:k(){c.4L.1q(k(3J,i){3J.1B(\'5n\',c.1G.1g[i])},c)},9F:k(){c.4L.1q(k(3J,i){3J.4C(\'5n\',c.1G.1g[i])},c)},1g:k(I,el){c.4G=el;c.8F=c.5p.4E();B(c.C.2S){o 1v=el.3p();c.1E=I.1Y.y-1v.y;c.3V=L P(\'4Z\').28(Q.4B);c.2S=el.9G().28(c.3V).4A({\'1v\':\'3Y\',\'1u\':1v.x,\'1o\':I.1Y.y-c.1E});Q.2C(\'2M\',c.1G.5y);c.1h(\'9H\',[el,c.2S])}Q.2C(\'2M\',c.1G.5o);Q.2C(\'5z\',c.1G.29);c.1h(\'3X\',el);I.1R()},5y:k(I){o J=I.1Y.y-c.1E;J=J.1F(c.8F.1o,c.8F.3P-c.2S.3R);c.2S.1P(\'1o\',J);I.1R()},5o:k(I){o 12=I.1Y.y;c.2l=c.2l||12;o 6P=((c.2l-12)>0);o 6T=c.4G.9W();o 3x=c.4G.8I();B(6T&&6P&&12<6T.4E().3P)c.4G.7Y(6T);B(3x&&!6P&&12>3x.4E().1o)c.4G.6v(3x);c.2l=12},dY:k(9Q){m c.5p.8H().2D(9Q||k(el){m c.T.3k(el)},c)},29:k(){c.2l=1n;Q.3h(\'2M\',c.1G.5o);Q.3h(\'5z\',c.1G.29);B(c.C.2S){Q.3h(\'2M\',c.1G.5y);c.1h(\'9e\',[c.4G,c.2S])}c.1h(\'1Q\',c.4G)}});9S.3i(L 2p,L 43);o aI=L 18({C:{aT:k(3W){3W.1P(\'4z\',\'8G\')},aW:k(3W){3W.1P(\'4z\',\'4O\')},8T:30,bp:35,bt:35,1A:\'dX\',5F:{\'x\':16,\'y\':16},4V:O},1i:k(T,C){c.2Y(C);c.45=L P(\'4Z\',{\'4R\':c.C.1A+\'-3W\',\'8J\':{\'1v\':\'3Y\',\'1o\':\'0\',\'1u\':\'0\',\'4z\':\'4O\'}}).28(Q.4B);c.3c=L P(\'4Z\').28(c.45);$$(T).1q(c.9I,c);B(c.C.1i)c.C.1i.1X(c)},9I:k(el){el.$1W.42=(el.4N&&el.4D()==\'a\')?el.4N.3g(\'9Y://\',\'\'):(el.a1||O);B(el.53){o 6z=el.53.68(\'::\');B(6z.V>1){el.$1W.42=6z[0].5T();el.$1W.5u=6z[1].5T()}14{el.$1W.5u=el.53}el.a7(\'53\')}14{el.$1W.5u=O}B(el.$1W.42&&el.$1W.42.V>c.C.8T)el.$1W.42=el.$1W.42.6K(0,c.C.8T-1)+"&dU;";el.1B(\'8N\',k(I){c.1g(el);B(!c.C.4V)c.8f(I);14 c.1v(el)}.W(c));B(!c.C.4V)el.1B(\'2M\',c.8f.3e(c));o 29=c.29.W(c);el.1B(\'8P\',29);el.1B(\'3V\',29)},1g:k(el){c.3c.1l();B(el.$1W.42){c.53=L P(\'b0\').28(L P(\'4Z\',{\'4R\':c.C.1A+\'-53\'}).28(c.3c)).5s(el.$1W.42)}B(el.$1W.5u){c.1K=L P(\'b0\').28(L P(\'4Z\',{\'4R\':c.C.1A+\'-1K\'}).28(c.3c)).5s(el.$1W.5u)}$55(c.1H);c.1H=c.4d.2g(c.C.bp,c)},29:k(I){$55(c.1H);c.1H=c.3Z.2g(c.C.bt,c)},1v:k(G){o 1m=G.3p();c.45.4A({\'1u\':1m.x+c.C.5F.x,\'1o\':1m.y+c.C.5F.y})},8f:k(I){o am={\'x\':U.8m(),\'y\':U.8n()};o 2G={\'x\':U.8u(),\'y\':U.8v()};o 3W={\'x\':c.45.4b,\'y\':c.45.3R};o 1V={\'x\':\'1u\',\'y\':\'1o\'};M(o z 1a 1V){o 1m=I.1Y[z]+c.C.5F[z];B((1m+3W[z]-2G[z])>am[z])1m=I.1Y[z]-c.C.5F[z]-3W[z];c.45.1P(1V[z],1m)}},4d:k(){B(c.C.aq)c.1H=c.3Z.2g(c.C.aq,c);c.1h(\'aT\',[c.45])},3Z:k(){c.1h(\'aW\',[c.45])}});aI.3i(L 2p,L 43);o dV=L 18({1i:k(){c.6D=$A(1b);c.19={};c.4U={}},1B:k(F,fn){c.4U[F]=c.4U[F]||{};c.19[F]=c.19[F]||[];B(c.19[F].1j(fn))m O;14 c.19[F].1k(fn);c.6D.1q(k(5v,i){5v.1B(F,c.4i.W(c,[F,5v,i]))},c);m c},4i:k(F,5v,i){c.4U[F][i]=1e;o 4F=c.6D.4F(k(2i,j){m c.4U[F][j]||O},c);B(!4F)m;c.4U[F]={};c.19[F].1q(k(I){I.1X(c,c.6D,5v)},c)}});o 7t=1f.26.R({C:{7K:18.1l,aa:18.1l,3Q:0,4d:O,2N:1e,2y:O,21:1e,7f:O,7n:O,3T:O,6I:O},1i:k(){o C,2B,T,2d;$1q(1b,k(4t,i){22($F(4t)){Y\'2I\':C=4t;1C;Y\'G\':2d=$(4t);1C;62:o 2r=$$(4t);B(!2B)2B=2r;14 T=2r}});c.2B=2B||[];c.T=T||[];c.2d=$(2d);c.2Y(C);c.2l=-1;B(c.C.6I)c.C.3T=1e;B($2A(c.C.4d)){c.C.3Q=O;c.2l=c.C.4d}B(c.C.1g){c.C.3Q=O;c.C.4d=O}c.3U={};B(c.C.21)c.3U.21=\'b8\';B(c.C.2y)c.3U.2y=c.C.7n?\'aj\':\'4b\';B(c.C.2N)c.3U.2N=c.C.7f?\'9n\':\'5P\';M(o i=0,l=c.2B.V;i<l;i++)c.aR(c.2B[i],c.T[i]);c.T.1q(k(el,i){B(c.C.4d===i){c.1h(\'7K\',[c.2B[i],el])}14{M(o 2O 1a c.3U)el.1P(2O,0)}},c);c.1r(c.T);B($2A(c.C.3Q))c.3Q(c.C.3Q)},aR:k(3j,G,1m){3j=$(3j);G=$(G);o 2v=c.2B.1j(3j);o 3S=c.2B.V;c.2B.5S(3j);c.T.5S(G);B(3S&&(!2v||1m)){1m=$4T(1m,3S-1);3j.7Y(c.2B[1m]);G.6v(3j)}14 B(c.2d&&!2v){3j.28(c.2d);G.28(c.2d)}o aA=c.2B.3k(3j);3j.1B(\'6h\',c.3Q.W(c,aA));B(c.C.2N)G.4A({\'4w-1o\':0,\'2R-1o\':\'7j\',\'4w-3P\':0,\'2R-3P\':\'7j\'});B(c.C.2y)G.4A({\'4w-1u\':0,\'2R-1u\':\'7j\',\'4w-4n\':0,\'2R-4n\':\'7j\'});G.b8=1;B(c.C.7n)G.aj=c.C.7n;B(c.C.7f)G.9n=c.C.7f;G.1P(\'9y\',\'4O\');B(!2v){M(o 2O 1a c.3U)G.1P(2O,0)}m c},3Q:k(25){25=($F(25)==\'G\')?c.T.3k(25):25;B((c.1H&&c.C.3T)||(25===c.2l&&!c.C.6I))m c;c.2l=25;o N={};c.T.1q(k(el,i){N[i]={};o 3Z=(i!=25)||(c.C.6I&&(el.3R>0));c.1h(3Z?\'aa\':\'7K\',[c.2B[i],el]);M(o 2O 1a c.3U)N[i][2O]=3Z?0:el[c.3U[2O]]},c);m c.1g(N)},dW:k(25){m c.3Q(25)}});1f.7t=7t;',62,956,'||||||||||||this||||||||function||return||var|||||||||||||if|options|||type|element||event|value|property|new|for|obj|false|Element|document|extend||elements|window|length|bind||case||||now||else|from||to|Class|events|in|arguments|Math|param|true|Fx|start|fireEvent|initialize|contains|push|empty|pos|null|top|args|each|parent|rgb|key|left|position|name|items|css|array|className|addEvent|break|max|offset|limit|bound|timer|values|properties|text|prototype|result|style|keys|setStyle|onComplete|stop|selector|data|props|prop|tmp|call|page|source||opacity|switch|method||index|Elements||inject|end|merge|mode|join|container|parsed|transition|delay|getStyle|current|set|overflown|previous|hsb|step|relatedTarget|Events|round|temp|script|Array|transport|test|custom|unit|width|string|chk|togglers|addListener|map|color|Garbage|scroll|Methods|object|nocash|remove|url|mousemove|height|fx|ie|Color|border|ghost|Base|params|parse|hue|Event|setOptions|documentElement||match||getElementsByTagName|margin|100|filter||||create|context|wrapper|toInt|bindWithEvent|overed|replace|removeListener|implement|toggler|indexOf|size|mouse|parentNode|Transitions|getPosition|tag|item|min|CSS|iCss|target|pow|next|scripts|option|time|shared|hex|drag|modifiers|change|scrollTo|Cookie|Json|handle|anchor|response|Abstract|returns|Hash|bottom|display|offsetHeight|len|wait|effects|trash|tip|onStart|absolute|hide||iterable|myTitle|Options|getValue|toolTip||iTo|select|duration|xpath|offsetWidth|Styles|show|load|periodical|Drag|knob|check|apply|increase|toString|val|right|compute|delta|setNow|cont|src|argument|id|chains|padding|webkit|link|visibility|setStyles|body|removeEvent|getTag|getCoordinates|every|active|str|status|headers|cookie|handles|number|href|hidden|grid|running|class|image|pick|checker|fixed|px|open|results|div||255|collect|title|mix|clear|getNow|delete|sources|post|mousewheel|fromTo|catch|bit|native|queryString|secure|onSuccess|htmlElement|try|location|setHeader|readyState|mousedown|move|list|get|evaluate|setHTML|xml|myText|instance|links|webkit419|moveGhost|mouseup|toQueryString|HTMLElement|regexp|isSuccess|rgbToHex|offsets|hexToRgb|_method|colors|encoding|setLength|toLowerCase|unique|onload|parseInt|scrollHeight|iFrom|getProperty|include|trim|iNow|scrollLeft|red|domReady|precision|klass||walk|default|scrollTop|layout|green|parseFloat|on|split|out|send|area|droppables|mp|head|attempt|evType|click|String|addEvents|date|continue|fix|XHR|setProperties|currentStyle|counter|included|images|hasKey|brother|injectAfter|onFailure|generic|saturation|dual|Properties|loaded|XMLHttpRequest|instances|steps|onChange|checkStep|mod|alwaysHide|Listeners|substr|draggedKnob|snap|getElements|code|up|fKey|evalScripts|tagName|prev|stopPropagation|attach|getElementById|preventDefault|getElementsBySelector|while|relative|scrollWidth|setMany|Multi|splice|blue|realType|defined|removeEvents|regex|percent|forEach|typeof|alpha|encodeURIComponent|fixedHeight|getSize|scrollSize|onreadystatechange|none|path|setProperty|proto|fixedWidth|domain|evalResponse|setTransport|clean|hasClass|Accordion|Chain|unload|onCancel|update|RegExp|callChain|toUpperCase|transitions|qs|disabled|checked|add|pairs|getMany|ie_ready|multiple|onActive|getParam|found|xhtml|getItems|concat|selected|Dom|domready|Style|Transition|flag|PI|compat|injectBefore|Function|getLast|node|operator|innerText|nodeType|iProps|appendChild|cssText|firstChild|easeType|camelCase|DOMMouseScroll|random|charAt|copy|locate|newArray|rgbToHsb|merged|addEventListener|brightness|rr|getWidth|getHeight|hasChild|complete|javascript|gecko|abort|callee|getScrollLeft|getScrollTop|pageY|img|mousemover|coord|toElement|Slider|toStep|previousEnd|pageX|coordinates|visible|getChildren|getNext|styles|previousChange|onTick|horizontal|mouseenter|velocity|mouseleave|vertical|capitalize|onDrag|maxTitleChars|lim|NativeEvents|gr|Object|mouseout|first|mouseover|insertBefore|getScrollHeight|getScrollWidth|after|cancel|Date|borderShort|fps|pageXOffset|opera|Ajax|clientWidth|clientHeight|onDragComplete|clientX|onRequest|request|pageYOffset|Single|before|Merge|pp|fullHeight|ActiveXObject|wheelDelta|floor|wheelStops|onStateChange|beforeunload|iParsed|direction|getTime|Scroller|overflow|addClass|getCoords|client|constructor|clickedElement|removeClass|detach|clone|onDragStart|build|application|which|useLink|setTimeout|undefined|execScript|getElement|converter|Content|Sortables|normal|sel|contents|getPrevious|keydown|http|prefix|toPosition|rel|filterById|PropertiesIFlag|removeEventListener|half|Left|removeAttribute|filterByClass|filterByAttribute|onBackground|input|resolver|textarea|getFormElements|getHeader|ie6|Scroll|getPos|fullWidth|zoom|onBeforeStart|win|onProgress|distance||timeout|Asset|onSnap|clientY|cloneEvents|cos|autoSave|nodeValue|where|Bottom|idx|elementsProperty|childNodes|relatedTargetGecko|error|defaultView|urlEncoded|toFloat|Tips|createElement|shift|hyphenate|Move|Number|checkAgainst|getLeft|getTop|addSection|www|onShow|fixRelatedTarget|interval|onHide|save|picked|autoCancel|span|textContent|adopt|innerHTML|styleSheet|escapeRegExp|fixStyle|6000|fullOpacity|hsbToRgb|slideIn|slideOut|360|1000|async|Width|getStyles|slice|Top|sin|setOpacity|removeChild|600000|appendText|0px|showDelay|extended||Right|hideDelay|full|button|menu|shiftKey|metaKey|altKey|fromCharCode|frameborder|ctrlKey|attachEvent|detail|srcElement|control|CollectGarbage|readonly|frameBorder|alt|keyCode|111|readOnly|meta|detachEvent|120|rightClick|wheel|pass|some|associate|getRandom|clearChain|chain|DOMElement|execCommand|BackgroundImageCache|transparent|setInterval|embed|boolean|injectInside|times|bindAsEventListener|err|fromElement|iframe|khtml|whitespace|collection|clearTimeout|textnode|nodeName|MooTools|version|clearInterval|Window|taintEnabled|webkit420|getBoxObjectFor|navigator|all|Document|ie7|injectTop|cloneNode|borderStyle|borderColor|htmlFor|borderWidth|getText|getProperties|setAttribute|setText|colspan|colSpan|tabindex|tabIndex|maxlength|accessKey|accesskey|rowspan|rowSpan|removeProperty|attributes|float|styleFloat|cssFloat|toggleClass|createTextNode|replaceWith|replaceChild|zIndex|hasLayout|lastChild|getParent|getAttribute|getFirst|Sibling|getComputedStyle|getPropertyValue|maxLength|overrideMimeType|200|300|responseText|urlencoded|form|cancelBubble|XMLHTTP|charset|responseXML|Connection|Accept|html|ecma|With|Requested|close|setRequestHeader|postBody||utf|makeDraggable|Bounce|Elastic|Quad|618|Back|Circ|acos|Sine|Cubic|Quart|over|drop|emptydrop|leave|makeResizable|Quint|sqrt|java|gi|setHue|setSaturation|setBrightness|invert|pop|onerror|Image|4096|RGB|HSB|hellip|Group|showThisHideOpen|tool|serialize|10000|SmoothScroll|hash|onabort|screen|toGMTString|decodeURIComponent|isFinite|expires|setTime|exec|getResponseHeader|action|Eaeflnr|eval|readystatechange|stylesheet|media|json|JSON|Remote|Request||Expo|Microsoft|substring|XPathResult|UNORDERED_NODE_SNAPSHOT_TYPE|with|starts|ES|namespaceURI|snapshotLength|snapshotItem|checkbox|radio|getElementsByClassName|1999|w3|org|Pow|contextmenu|space|backspace|tab|esc|down|returnValue|enter|dblclick|keypress|submit|reset|blur|focus|keyup|resize|password|filterByTag|toLeft|toRight|Slide|toBottom|toTop|clearTimer|effect|toggle|easeIn|InOut|ease|Out|In|easeOut|easeInOut|500|linear|defer|DOMContentLoaded|protocol|write|offsetTop|https|offsetParent|void|innerWidth|onDomReady||innerHeight|offsetLeft'.split('|'),0,{}))



//
// openWYSIWYG v1.0 Copyright (c) 2006 openWebWare.com
// This copyright notice MUST stay intact for use.
//
// An open source WYSIWYG editor for use in web based applications.
// For full source code and docs, visit http://www.openwebware.com/
//
// This library is free software; you can redistribute it and/or modify 
// it under the terms of the GNU Lesser General Public License as published 
// by the Free Software Foundation; either version 2.1 of the License, or 
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
// License for more details.
//
// You should have received a copy of the GNU Lesser General Public License along 
// with this library; if not, write to the Free Software Foundation, Inc., 59 
// Temple Place, Suite 330, Boston, MA 02111-1307 USA 


/* ---------------------------------------------------------------------- *\
  Global Variables: Set global variables such as images directory, 
	                  WYSIWYG Height, Width, and CSS Directory.
\* ---------------------------------------------------------------------- */

// Images Directory
imagesDir = "icons/";

// CSS Directory
cssDir = "styles/";

// Popups Directory
popupsDir = "popups/";

// WYSIWYG Width and Height
wysiwygWidth = 400;
wysiwygHeight = 430;

// Include Style Sheet
document.write('<link rel="stylesheet" type="text/css" href="' +cssDir+ 'styles.css">\n');


/* ---------------------------------------------------------------------- *\
  Toolbar Settings: Set the features and buttons available in the WYSIWYG
	                  Toolbar.
\* ---------------------------------------------------------------------- */


// List of available font types
  var Fonts = new Array();
  Fonts[0] = "Arial";
  Fonts[1] = "Sans Serif";
  Fonts[2] = "Tahoma";
	Fonts[3] = "Verdana";
	Fonts[4] = "Courier New";
	Fonts[5] = "Georgia";
	Fonts[6] = "Times New Roman";
	Fonts[7] = "Impact";
  Fonts[8] = "Comic Sans MS";

// List of available block formats (not in use)
var BlockFormats = new Array();
  BlockFormats[0]  = "Address";
  BlockFormats[1]  = "Bulleted List";
  BlockFormats[2]  = "Definition";
	BlockFormats[3]  = "Definition Term";
	BlockFormats[4]  = "Directory List";
	BlockFormats[5]  = "Formatted";
	BlockFormats[6]  = "Heading 1";
	BlockFormats[7]  = "Heading 2";
	BlockFormats[8]  = "Heading 3";
	BlockFormats[9]  = "Heading 4";
	BlockFormats[10] = "Heading 5";
	BlockFormats[11] = "Heading 6";
	BlockFormats[12] = "Menu List";
	BlockFormats[13] = "Normal";
	BlockFormats[14] = "Numbered List";

// List of available font sizes
var FontSizes = new Array();
  FontSizes[0]  = "1";
  FontSizes[1]  = "2";
  FontSizes[2]  = "3";
	FontSizes[3]  = "4";
	FontSizes[4]  = "5";
	FontSizes[5]  = "6";
	FontSizes[6]  = "7";

// Order of available commands in toolbar one
var buttonName = new Array();
  buttonName[0]  = "bold";
  buttonName[1]  = "italic";
  buttonName[2]  = "underline";
	//buttonName[3]  = "strikethrough";
  buttonName[4]  = "seperator";
	buttonName[5]  = "subscript";
	buttonName[6]  = "superscript";
	buttonName[7]  = "seperator";
	buttonName[8]  = "justifyleft";
	buttonName[9]  = "justifycenter";
	buttonName[10] = "justifyright";
	buttonName[11] = "seperator";
	buttonName[12] = "unorderedlist";
	buttonName[13] = "orderedlist";
	buttonName[14] = "outdent";
	buttonName[15] = "indent";

// Order of available commands in toolbar two
var buttonName2 = new Array();
  buttonName2[0]  = "forecolor";
	buttonName2[1]  = "backcolor";
	buttonName2[2]  = "seperator";
	buttonName2[3]  = "cut";
	buttonName2[4]  = "copy";
	buttonName2[5]  = "paste";
	buttonName2[6]  = "seperator";
  buttonName2[7]  = "undo";
	buttonName2[8]  = "redo";
  buttonName2[9]  = "seperator";
	buttonName2[10]  = "inserttable";
  buttonName2[11]  = "insertimage";
  buttonName2[12]  = "createlink";
	buttonName2[13]  = "seperator";
	buttonName2[14]  = "viewSource";
	buttonName2[15]  = "seperator";
  buttonName2[16]  = "help";
	
// List of available actions and their respective ID and images
var ToolbarList = {
//Name              buttonID                 buttonTitle           buttonImage                            buttonImageRollover
  "bold":           ['Bold',                 'Bold',               imagesDir + 'bold.gif',               imagesDir + 'bold_on.gif'],
  "italic":         ['Italic',               'Italic',             imagesDir + 'italics.gif',            imagesDir + 'italics_on.gif'],
  "underline":      ['Underline',            'Underline',          imagesDir + 'underline.gif',          imagesDir + 'underline_on.gif'],
	"strikethrough":  ['Strikethrough',        'Strikethrough',      imagesDir + 'strikethrough.gif',      imagesDir + 'strikethrough_on.gif'],
	"seperator":      ['',                     '',                   imagesDir + 'seperator.gif',          imagesDir + 'seperator.gif'],
	"subscript":      ['Subscript',            'Subscript',          imagesDir + 'subscript.gif',          imagesDir + 'subscript_on.gif'],
	"superscript":    ['Superscript',          'Superscript',        imagesDir + 'superscript.gif',        imagesDir + 'superscript_on.gif'],
	"justifyleft":    ['Justifyleft',          'Justifyleft',        imagesDir + 'justify_left.gif',       imagesDir + 'justify_left_on.gif'],
	"justifycenter":  ['Justifycenter',        'Justifycenter',      imagesDir + 'justify_center.gif',     imagesDir + 'justify_center_on.gif'],
	"justifyright":   ['Justifyright',         'Justifyright',       imagesDir + 'justify_right.gif',      imagesDir + 'justify_right_on.gif'],
	"unorderedlist":  ['InsertUnorderedList',  'InsertUnorderedList',imagesDir + 'list_unordered.gif',     imagesDir + 'list_unordered_on.gif'],
	"orderedlist":    ['InsertOrderedList',    'InsertOrderedList',  imagesDir + 'list_ordered.gif',       imagesDir + 'list_ordered_on.gif'],
	"outdent":        ['Outdent',              'Outdent',            imagesDir + 'indent_left.gif',        imagesDir + 'indent_left_on.gif'],
	"indent":         ['Indent',               'Indent',             imagesDir + 'indent_right.gif',       imagesDir + 'indent_right_on.gif'],
	"cut":            ['Cut',                  'Cut',                imagesDir + 'cut.gif',                imagesDir + 'cut_on.gif'],
	"copy":           ['Copy',                 'Copy',               imagesDir + 'copy.gif',               imagesDir + 'copy_on.gif'],
  "paste":          ['Paste',                'Paste',              imagesDir + 'paste.gif',              imagesDir + 'paste_on.gif'],
	"forecolor":      ['ForeColor',            'ForeColor',          imagesDir + 'forecolor.gif',          imagesDir + 'forecolor_on.gif'],
	"backcolor":      ['BackColor',            'BackColor',          imagesDir + 'backcolor.gif',          imagesDir + 'backcolor_on.gif'],
	"undo":           ['Undo',                 'Undo',               imagesDir + 'undo.gif',               imagesDir + 'undo_on.gif'],
	"redo":           ['Redo',                 'Redo',               imagesDir + 'redo.gif',               imagesDir + 'redo_on.gif'],
	"inserttable":    ['InsertTable',          'InsertTable',        imagesDir + 'insert_table.gif',       imagesDir + 'insert_table_on.gif'],
	"insertimage":    ['InsertImage',          'InsertImage',        imagesDir + 'insert_picture.gif',     imagesDir + 'insert_picture_on.gif'],
	"createlink":     ['CreateLink',           'CreateLink',         imagesDir + 'insert_hyperlink.gif',   imagesDir + 'insert_hyperlink_on.gif'],
	"viewSource":     ['ViewSource',           'ViewSource',         imagesDir + 'view_source.gif',        imagesDir + 'view_source_on.gif'],
	"viewText":       ['ViewText',             'ViewText',           imagesDir + 'view_text.gif',          imagesDir + 'view_text_on.gif'],
	"help":           ['Help',                 'Help',               imagesDir + 'help.gif',               imagesDir + 'help_on.gif'],
	"selectfont":     ['SelectFont',           'SelectFont',         imagesDir + 'select_font.gif',        imagesDir + 'select_font_on.gif'],
	"selectsize":     ['SelectSize',           'SelectSize',         imagesDir + 'select_size.gif',        imagesDir + 'select_size_on.gif']
};



/* ---------------------------------------------------------------------- *\
  Function    : insertAdjacentHTML(), insertAdjacentText() and insertAdjacentElement()
  Description : Emulates insertAdjacentHTML(), insertAdjacentText() and 
	              insertAdjacentElement() three functions so they work with 
								Netscape 6/Mozilla
  Notes       : by Thor Larholm me@jscript.dk
\* ---------------------------------------------------------------------- */
if(typeof HTMLElement!="undefined" && !HTMLElement.prototype.insertAdjacentElement){
  HTMLElement.prototype.insertAdjacentElement = function
  (where,parsedNode)
	{
	  switch (where){
		case 'beforeBegin':
			this.parentNode.insertBefore(parsedNode,this)
			break;
		case 'afterBegin':
			this.insertBefore(parsedNode,this.firstChild);
			break;
		case 'beforeEnd':
			this.appendChild(parsedNode);
			break;
		case 'afterEnd':
			if (this.nextSibling) 
      this.parentNode.insertBefore(parsedNode,this.nextSibling);
			else this.parentNode.appendChild(parsedNode);
			break;
		}
	}

	HTMLElement.prototype.insertAdjacentHTML = function
  (where,htmlStr)
	{
		var r = this.ownerDocument.createRange();
		r.setStartBefore(this);
		var parsedHTML = r.createContextualFragment(htmlStr);
		this.insertAdjacentElement(where,parsedHTML)
	}


	HTMLElement.prototype.insertAdjacentText = function
  (where,txtStr)
	{
		var parsedText = document.createTextNode(txtStr)
		this.insertAdjacentElement(where,parsedText)
	}
};


// Create viewTextMode global variable and set to 0
// enabling all toolbar commands while in HTML mode
viewTextMode = 0;



/* ---------------------------------------------------------------------- *\
  Function    : generate_wysiwyg()
  Description : replace textarea with wysiwyg editor
  Usage       : generate_wysiwyg("textarea_id");
  Arguments   : textarea_id - ID of textarea to replace
\* ---------------------------------------------------------------------- */
function generate_wysiwyg(textareaID) {
 
  	// Hide the textarea 
	document.getElementById(textareaID).style.display = 'none'; 
	
  // Pass the textareaID to the "n" variable.
  var n = textareaID;
	
	// Toolbars width is 2 pixels wider than the wysiwygs
	toolbarWidth = parseFloat(wysiwygWidth) + 2;
	
  // Generate WYSIWYG toolbar one
  var toolbar;
  toolbar =  '<table cellpadding="0" cellspacing="0" border="0" class="toolbar1" style="width:' + toolbarWidth + 'px;"><tr><td style="width: 6px;"><img src="' +imagesDir+ 'seperator2.gif" alt="" hspace="3"></td>';
  
	// Create IDs for inserting Font Type and Size drop downs
	toolbar += '<td style="width: 90px;"><span id="FontSelect' + n + '"></span></td>';
	toolbar += '<td style="width: 60px;"><span id="FontSizes'  + n + '"></span></td>';
  
	// Output all command buttons that belong to toolbar one
	for (var i = 0; i <= buttonName.length;) { 
    if (buttonName[i]) {
	    var buttonObj            = ToolbarList[buttonName[i]];
		  var buttonID             = buttonObj[0];
	    var buttonTitle          = buttonObj[1];
      var buttonImage          = buttonObj[2];
		  var buttonImageRollover  = buttonObj[3];
	    
			if (buttonName[i] == "seperator") {
		    toolbar += '<td style="width: 12px;" align="center"><img src="' +buttonImage+ '" border=0 unselectable="on" width="2" height="18" hspace="2" unselectable="on"></td>';
			}
	    else {
		    toolbar += '<td style="width: 22px;"><img src="' +buttonImage+ '" border=0 unselectable="on" title="' +buttonTitle+ '" id="' +buttonID+ '" class="button" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'button\'){className=\'buttonOver\'}; this.src=\'' + buttonImageRollover + '\';" onmouseout="if(className==\'buttonOver\'){className=\'button\'}; this.src=\'' + buttonImage + '\';" unselectable="on" width="20" height="20"></td>';
	    }
    }
    i++;
  }

  toolbar += '<td>&nbsp;</td></tr></table>';  

  // Generate WYSIWYG toolbar two
  var toolbar2;
  toolbar2 = '<table cellpadding="0" cellspacing="0" border="0" class="toolbar2" style="width:' + toolbarWidth + 'px;"><tr><td style="width: 6px;"><img src="' +imagesDir+ 'seperator2.gif" alt="" hspace="3"></td>';
 
  // Output all command buttons that belong to toolbar two
  for (var j = 0; j <= buttonName2.length;) {
    if (buttonName2[j]) {
	    var buttonObj            = ToolbarList[buttonName2[j]];
		  var buttonID             = buttonObj[0];
	    var buttonTitle          = buttonObj[1];
      var buttonImage          = buttonObj[2];
		  var buttonImageRollover  = buttonObj[3];
	  
		  if (buttonName2[j] == "seperator") {
		    toolbar2 += '<td style="width: 12px;" align="center"><img src="' +buttonImage+ '" border=0 unselectable="on" width="2" height="18" hspace="2" unselectable="on"></td>';
			}
	    else if (buttonName2[j] == "viewSource"){
		    toolbar2 += '<td style="width: 22px;">';
				toolbar2 += '<span id="HTMLMode' + n + '"><img src="'  +buttonImage+  '" border=0 unselectable="on" title="' +buttonTitle+ '" id="' +buttonID+ '" class="button" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'button\'){className=\'buttonOver\'}; this.src=\'' +buttonImageRollover+ '\';" onmouseout="if(className==\'buttonOver\'){className=\'button\'}; this.src=\'' + buttonImage + '\';" unselectable="on"  width="20" height="20"></span>';
				toolbar2 += '<span id="textMode' + n + '"><img src="' +imagesDir+ 'view_text.gif" border=0 unselectable="on" title="viewText"          id="ViewText"       class="button" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'button\'){className=\'buttonOver\'}; this.src=\'' +imagesDir+ 'view_text_on.gif\';"    onmouseout="if(className==\'buttonOver\'){className=\'button\'}; this.src=\'' +imagesDir+ 'view_text.gif\';" unselectable="on"  width="20" height="20"></span>';
	      toolbar2 += '</td>';
			}
	    else {
		    toolbar2 += '<td style="width: 22px;"><img src="' +buttonImage+ '" border=0 unselectable="on" title="' +buttonTitle+ '" id="' +buttonID+ '" class="button" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'button\'){className=\'buttonOver\'}; this.src=\'' +buttonImageRollover+ '\';" onmouseout="if(className==\'buttonOver\'){className=\'button\'}; this.src=\'' + buttonImage + '\';" unselectable="on" width="20" height="20"></td>';
	    }
    }
    j++;
  }

  toolbar2 += '<td>&nbsp;</td></tr></table>';  
	
 	
	// Create iframe which will be used for rich text editing
	var iframe = '<table cellpadding="0" cellspacing="0" border="0" style="width:' + wysiwygWidth + 'px; height:' + wysiwygHeight + 'px;border: 1px inset #CCCCCC;"><tr><td valign="top">\n'
  + '<iframe frameborder="0" id="wysiwyg' + n + '"></iframe>\n'
  + '</td></tr></table>\n';

  // Insert after the textArea both toolbar one and two
  document.getElementById(n).insertAdjacentHTML("afterEnd", toolbar + toolbar2 + iframe);
	
  // Insert the Font Type and Size drop downs into the toolbar
	outputFontSelect(n);
	outputFontSizes(n); 
	
  // Hide the dynamic drop down lists for the Font Types and Sizes
  hideFonts(n);
	hideFontSizes(n);
	
	// Hide the "Text Mode" button
	document.getElementById("textMode" + n).style.display = 'none'; 
	
	// Give the iframe the global wysiwyg height and width
  document.getElementById("wysiwyg" + n).style.height = wysiwygHeight + "px";
  document.getElementById("wysiwyg" + n).style.width = wysiwygWidth + "px";
	
	// Pass the textarea's existing text over to the content variable
  var content = document.getElementById(n).value;
	
	var doc = document.getElementById("wysiwyg" + n).contentWindow.document;
	
	// Write the textarea's content into the iframe
  doc.open();
  doc.write(content);
  doc.close();
	
	// Make the iframe editable in both Mozilla and IE
  doc.body.contentEditable = true;
  doc.designMode = "on";
	
  	// Update the textarea with content in WYSIWYG when user submits form
  var browserName = navigator.appName;
  if (browserName == "Microsoft Internet Explorer") {
    for (var idx=0; idx < document.forms.length; idx++) {
      document.forms[idx].attachEvent('onsubmit', function() { updateTextArea(n); });
    }
  }
  else {
  	for (var idx=0; idx < document.forms.length; idx++) {
    	document.forms[idx].addEventListener('submit',function OnSumbmit() { updateTextArea(n); }, true);
    }
  }
 	

};



/* ---------------------------------------------------------------------- *\
  Function    : formatText()
  Description : replace textarea with wysiwyg editor
  Usage       : formatText(id, n, selected);
  Arguments   : id - The execCommand (e.g. Bold)
                n  - The editor identifier that the command 
								     affects (the textarea's ID)
                selected - The selected value when applicable (e.g. Arial)
\* ---------------------------------------------------------------------- */
function formatText(id, n, selected) {

  // When user clicks toolbar button make sure it always targets its respective WYSIWYG
  document.getElementById("wysiwyg" + n).contentWindow.focus();
	
	// When in Text Mode these execCommands are disabled
	var formatIDs = new Array("FontSize","FontName","Bold","Italic","Underline","Subscript","Superscript","Strikethrough","Justifyleft","Justifyright","Justifycenter","InsertUnorderedList","InsertOrderedList","Indent","Outdent","ForeColor","BackColor","InsertImage","InsertTable","CreateLink");
  
	// Check if button clicked is in disabled list
	for (var i = 0; i <= formatIDs.length;) {
		if (formatIDs[i] == id) {
			 var disabled_id = 1; 
		}
	  i++;
	}
	
	// Check if in Text Mode and disabled button was clicked
	if (viewTextMode == 1 && disabled_id == 1) {
	  alert ("You are in HTML Mode. This feature has been disabled.");	
	}
	
	else {
	
	  // FontSize
	  if (id == "FontSize") {
      document.getElementById("wysiwyg" + n).contentWindow.document.execCommand("FontSize", false, selected);
	  }
	  
		// FontName
	  else if (id == "FontName") {
      document.getElementById("wysiwyg" + n).contentWindow.document.execCommand("FontName", false, selected);
	  }
	
	  // ForeColor and BackColor
    else if (id == 'ForeColor' || id == 'BackColor') {
      var w = screen.availWidth;
      var h = screen.availHeight;
      var popW = 210, popH = 165;
      var leftPos = (w-popW)/2, topPos = (h-popH)/2;
      var currentColor = _dec_to_rgb(document.getElementById("wysiwyg" + n).contentWindow.document.queryCommandValue(id));
   
	    window.open(popupsDir + 'select_color.html?color=' + currentColor + '&command=' + id + '&wysiwyg=' + n,'popup','location=0,status=0,scrollbars=0,width=' + popW + ',height=' + popH + ',top=' + topPos + ',left=' + leftPos);
    }
	  
		// InsertImage
	  else if (id == "InsertImage") {
      window.open(popupsDir + 'insert_image.html?wysiwyg=' + n,'popup','location=0,status=0,scrollbars=0,resizable=0,width=400,height=190');
	  }
	  
		// InsertTable
	  else if (id == "InsertTable") {
	    window.open(popupsDir + 'create_table.html?wysiwyg=' + n,'popup','location=0,status=0,scrollbars=0,resizable=0,width=400,height=360');
	  }
	  
		// CreateLink
	  else if (id == "CreateLink") {
	    window.open(popupsDir + 'insert_hyperlink.html?wysiwyg=' + n,'popup','location=0,status=0,scrollbars=0,resizable=0,width=300,height=110');
	  }
	  
		// ViewSource
    else if (id == "ViewSource") {
	    viewSource(n);
	  }
		
		// ViewText
		else if (id == "ViewText") {
	    viewText(n);
	  }

		// Help
		else if (id == "ViewSource") {
	    viewSource(n);
	  }
	  
		// Every other command
	  else {
      document.getElementById("wysiwyg" + n).contentWindow.document.execCommand(id, false, null);
		}
  }
};



/* ---------------------------------------------------------------------- *\
  Function    : insertHTML()
  Description : insert HTML into WYSIWYG in rich text
  Usage       : insertHTML(<b>hello</b>, "textareaID")
  Arguments   : html - The HTML being inserted (e.g. <b>hello</b>)
                n  - The editor identifier that the HTML 
								     will be inserted into (the textarea's ID)
\* ---------------------------------------------------------------------- */
function insertHTML(html, n) {

  var browserName = navigator.appName;
	 	 
	if (browserName == "Microsoft Internet Explorer") {	  
	  document.getElementById('wysiwyg' + n).contentWindow.document.selection.createRange().pasteHTML(html);   
	} 
	 
	else {
	  var div = document.getElementById('wysiwyg' + n).contentWindow.document.createElement("div");
		 
		div.innerHTML = html;
		var node = insertNodeAtSelection(div, n);		
	}
	
}


/* ---------------------------------------------------------------------- *\
  Function    : insertNodeAtSelection()
  Description : insert HTML into WYSIWYG in rich text (mozilla)
  Usage       : insertNodeAtSelection(insertNode, n)
  Arguments   : insertNode - The HTML being inserted (must be innerHTML 
	                           inserted within a div element)
                n          - The editor identifier that the HTML will be 
								             inserted into (the textarea's ID)
\* ---------------------------------------------------------------------- */
function insertNodeAtSelection(insertNode, n) {
  // get current selection
  var sel = document.getElementById('wysiwyg' + n).contentWindow.getSelection();

  // get the first range of the selection
  // (there's almost always only one range)
  var range = sel.getRangeAt(0);

  // deselect everything
  sel.removeAllRanges();

  // remove content of current selection from document
  range.deleteContents();

  // get location of current selection
  var container = range.startContainer;
  var pos = range.startOffset;

  // make a new range for the new selection
  range=document.createRange();

  if (container.nodeType==3 && insertNode.nodeType==3) {

    // if we insert text in a textnode, do optimized insertion
    container.insertData(pos, insertNode.nodeValue);

    // put cursor after inserted text
    range.setEnd(container, pos+insertNode.length);
    range.setStart(container, pos+insertNode.length);
  } 
	
	else {
    var afterNode;
    
		if (container.nodeType==3) {
      // when inserting into a textnode
      // we create 2 new textnodes
      // and put the insertNode in between

      var textNode = container;
      container = textNode.parentNode;
      var text = textNode.nodeValue;

      // text before the split
      var textBefore = text.substr(0,pos);
      // text after the split
      var textAfter = text.substr(pos);

      var beforeNode = document.createTextNode(textBefore);
      afterNode = document.createTextNode(textAfter);

      // insert the 3 new nodes before the old one
      container.insertBefore(afterNode, textNode);
      container.insertBefore(insertNode, afterNode);
      container.insertBefore(beforeNode, insertNode);

      // remove the old node
      container.removeChild(textNode);
    } 
	
	  else {
      // else simply insert the node
      afterNode = container.childNodes[pos];
      container.insertBefore(insertNode, afterNode);
    }

    range.setEnd(afterNode, 0);
    range.setStart(afterNode, 0);
  }

  sel.addRange(range);
};

	

/* ---------------------------------------------------------------------- *\
  Function    : _dec_to_rgb
  Description : convert a decimal color value to rgb hexadecimal
  Usage       : var hex = _dec_to_rgb('65535');   // returns FFFF00
  Arguments   : value   - dec value
\* ---------------------------------------------------------------------- */

function _dec_to_rgb(value) {
  var hex_string = "";
  for (var hexpair = 0; hexpair < 3; hexpair++) {
    var myByte = value & 0xFF;            // get low byte
    value >>= 8;                          // drop low byte
    var nybble2 = myByte & 0x0F;          // get low nybble (4 bits)
    var nybble1 = (myByte >> 4) & 0x0F;   // get high nybble
    hex_string += nybble1.toString(16);   // convert nybble to hex
    hex_string += nybble2.toString(16);   // convert nybble to hex
  }
  return hex_string.toUpperCase();
};



/* ---------------------------------------------------------------------- *\
  Function    : outputFontSelect()
  Description : creates the Font Select drop down and inserts it into 
	              the toolbar
  Usage       : outputFontSelect(n)
  Arguments   : n   - The editor identifier that the Font Select will update
	                    when making font changes (the textarea's ID)
\* ---------------------------------------------------------------------- */
function outputFontSelect(n) {

  var FontSelectObj        = ToolbarList['selectfont'];
  var FontSelect           = FontSelectObj[2];
  var FontSelectOn         = FontSelectObj[3];
  
	Fonts.sort();
	var FontSelectDropDown = new Array;
	FontSelectDropDown[n] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="document.getElementById(\'selectFont' + n + '\').src=\'' + FontSelectOn + '\';" onMouseOut="document.getElementById(\'selectFont' + n + '\').src=\'' + FontSelect + '\';"><img src="' + FontSelect + '" id="selectFont' + n + '" width="85" height="20" onClick="showFonts(\'' + n + '\');" unselectable="on"><br>';
	FontSelectDropDown[n] += '<span id="Fonts' + n + '" class="dropdown" style="width: 145px;">';

	for (var i = 0; i <= Fonts.length;) {
	  if (Fonts[i]) {
      FontSelectDropDown[n] += '<button type="button" onClick="formatText(\'FontName\',\'' + n + '\',\'' + Fonts[i] + '\')\; hideFonts(\'' + n + '\');" onMouseOver="this.className=\'mouseOver\'" onMouseOut="this.className=\'mouseOut\'" class="mouseOut" style="width: 120px;"><table cellpadding="0" cellspacing="0" border="0"><tr><td align="left" style="font-family:' + Fonts[i] + '; font-size: 12px;">' + Fonts[i] + '</td></tr></table></button><br>';	
    }	  
	  i++;
  }
	FontSelectDropDown[n] += '</span></td></tr></table>';
	document.getElementById('FontSelect' + n).insertAdjacentHTML("afterBegin", FontSelectDropDown[n]);
};



/* ---------------------------------------------------------------------- *\
  Function    : outputFontSizes()
  Description : creates the Font Sizes drop down and inserts it into 
	              the toolbar
  Usage       : outputFontSelect(n)
  Arguments   : n   - The editor identifier that the Font Sizes will update
	                    when making font changes (the textarea's ID)
\* ---------------------------------------------------------------------- */
function outputFontSizes(n) {

  var FontSizeObj        = ToolbarList['selectsize'];
  var FontSize           = FontSizeObj[2];
  var FontSizeOn         = FontSizeObj[3];

	FontSizes.sort();
	var FontSizesDropDown = new Array;
	FontSizesDropDown[n] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="document.getElementById(\'selectSize' + n + '\').src=\'' + FontSizeOn + '\';" onMouseOut="document.getElementById(\'selectSize' + n + '\').src=\'' + FontSize + '\';"><img src="' + FontSize + '" id="selectSize' + n + '" width="49" height="20" onClick="showFontSizes(\'' + n + '\');" unselectable="on"><br>';
  FontSizesDropDown[n] += '<span id="Sizes' + n + '" class="dropdown" style="width: 170px;">';

	for (var i = 0; i <= FontSizes.length;) {
	  if (FontSizes[i]) {
      FontSizesDropDown[n] += '<button type="button" onClick="formatText(\'FontSize\',\'' + n + '\',\'' + FontSizes[i] + '\')\;hideFontSizes(\'' + n + '\');" onMouseOver="this.className=\'mouseOver\'" onMouseOut="this.className=\'mouseOut\'" class="mouseOut" style="width: 145px;"><table cellpadding="0" cellspacing="0" border="0"><tr><td align="left" style="font-family: arial, verdana, helvetica;"><font size="' + FontSizes[i] + '">size ' + FontSizes[i] + '</font></td></tr></table></button><br>';	
    }	  
	  i++;
  }
	FontSizesDropDown[n] += '</span></td></tr></table>';
	document.getElementById('FontSizes' + n).insertAdjacentHTML("afterBegin", FontSizesDropDown[n]);
};



/* ---------------------------------------------------------------------- *\
  Function    : hideFonts()
  Description : Hides the list of font names in the font select drop down
  Usage       : hideFonts(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function hideFonts(n) {
  document.getElementById('Fonts' + n).style.display = 'none'; 
};



/* ---------------------------------------------------------------------- *\
  Function    : hideFontSizes()
  Description : Hides the list of font sizes in the font sizes drop down
  Usage       : hideFontSizes(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function hideFontSizes(n) {
  document.getElementById('Sizes' + n).style.display = 'none'; 
};



/* ---------------------------------------------------------------------- *\
  Function    : showFonts()
  Description : Shows the list of font names in the font select drop down
  Usage       : showFonts(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function showFonts(n) { 
  if (document.getElementById('Fonts' + n).style.display == 'block') {
    document.getElementById('Fonts' + n).style.display = 'none';
	}
  else {
    document.getElementById('Fonts' + n).style.display = 'block'; 
    document.getElementById('Fonts' + n).style.position = 'absolute';		
  }
};



/* ---------------------------------------------------------------------- *\
  Function    : showFontSizes()
  Description : Shows the list of font sizes in the font sizes drop down
  Usage       : showFonts(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function showFontSizes(n) { 
  if (document.getElementById('Sizes' + n).style.display == 'block') {
    document.getElementById('Sizes' + n).style.display = 'none';
	}
  else {
    document.getElementById('Sizes' + n).style.display = 'block'; 
    document.getElementById('Sizes' + n).style.position = 'absolute';		
  }
};



/* ---------------------------------------------------------------------- *\
  Function    : viewSource()
  Description : Shows the HTML source code generated by the WYSIWYG editor
  Usage       : showFonts(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function viewSource(n) {
  var getDocument = document.getElementById("wysiwyg" + n).contentWindow.document;
  var browserName = navigator.appName;
	
	// View Source for IE 	 
  if (browserName == "Microsoft Internet Explorer") {
    var iHTML = getDocument.body.innerHTML;
    getDocument.body.innerText = iHTML;
	}
 
  // View Source for Mozilla/Netscape
  else {
    var html = document.createTextNode(getDocument.body.innerHTML);
    getDocument.body.innerHTML = "";
    getDocument.body.appendChild(html);
	}
  
	// Hide the HTML Mode button and show the Text Mode button
  document.getElementById('HTMLMode' + n).style.display = 'none'; 
	document.getElementById('textMode' + n).style.display = 'block';
	
	// set the font values for displaying HTML source
	getDocument.body.style.fontSize = "12px";
	getDocument.body.style.fontFamily = "Courier New"; 
	
  viewTextMode = 1;
};



/* ---------------------------------------------------------------------- *\
  Function    : viewSource()
  Description : Shows the HTML source code generated by the WYSIWYG editor
  Usage       : showFonts(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function viewText(n) { 
  var getDocument = document.getElementById("wysiwyg" + n).contentWindow.document;
  var browserName = navigator.appName;
	
	// View Text for IE 	  	 
  if (browserName == "Microsoft Internet Explorer") {
    var iText = getDocument.body.innerText;
    getDocument.body.innerHTML = iText;
	}
  
	// View Text for Mozilla/Netscape
  else {
    var html = getDocument.body.ownerDocument.createRange();
    html.selectNodeContents(getDocument.body);
    getDocument.body.innerHTML = html.toString();
	}
  
	// Hide the Text Mode button and show the HTML Mode button
  document.getElementById('textMode' + n).style.display = 'none'; 
	document.getElementById('HTMLMode' + n).style.display = 'block';
	
	// reset the font values
  getDocument.body.style.fontSize = "";
	getDocument.body.style.fontFamily = ""; 
	viewTextMode = 0;
};



/* ---------------------------------------------------------------------- *\
  Function    : updateTextArea()
  Description : Updates the text area value with the HTML source of the WYSIWYG
  Usage       : updateTextArea(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function updateTextArea(n) {
  document.getElementById(n).value = document.getElementById("wysiwyg" + n).contentWindow.document.body.innerHTML;
};