Personal tools
You are here: Home OSCAR Users EMR and Case Management Resources eForms eForms for download Ob/Gyn Maternity Care Calendar Maternity Care Calendar 2011
 

Maternity Care Calendar 2011

Updated to push and pull EDD and LMP measurements to and from Oscar Measurements

MaternityCalender.html — HTML, 86Kb

File contents

<html>	

<head>
<title>Maternity Care Calendar</title>

<!-- CSS Script that removes textarea and textbox borders when printing ---(put this inbetween <header></header>)----------------->
<style type="text/css" media="print">
.DoNotPrint {
	display: none;
}

input.noborder {
	border : 0px;
	background: transparent;
}
textarea.noborder {
	scrollbar-3dlight-color: transparent;
	scrollbar-3dlight-color: transparent;
	scrollbar-arrow-color: transparent;
	scrollbar-base-color: transparent;
	scrollbar-darkshadow-color: transparent;
	scrollbar-face-color: transparent;
	scrollbar-highlight-color: transparent;
	scrollbar-shadow-color: transparent;
	scrollbar-track-color: transparent;
	background: transparent;
	overflow: hidden;
	border : 0px;
}


</style>
<style type="text/css" >
p, input
	{
	font-family: arial, sans-serif;
	font-size: 10;
	}
</style>
<script type="text/javascript">
var calendarLMP, calendarEDDDates, calendarEDDUS, calendarToday, calendarGA, calendarUS1, calendarUS2; /*must be declared in global scope*/
/*put the calendar initializations in the window's onload() method*/
window.onload = function() {
	calendarLMP = new Epoch('CalLMP','popup',document.getElementById('LMP'),false);
	calendarEDDDates = new Epoch('CalEDDDates','popup',document.getElementById('EDDDates'),false);
	calendarEDDUS = new Epoch('CalEDDUS','popup',document.getElementById('EDDUS'),false);
	calendarToday = new Epoch('CalToday','popup',document.getElementById('CurrentDate'),false);
	calendarGA = new Epoch('CalGA','popup',document.getElementById('GADate'),false);
	calendarUS1 = new Epoch('CalUS1','popup',document.getElementById('US1Date'),false);
	calendarUS2 = new Epoch('CalUS2','popup',document.getElementById('US2Date'),false);
	fillToday();
	highlightEDD();
};
</script>
<style type="text/css">
/*!!
Epoch DHTML JavaScript Calendar - Version 2.0.2
English Edition
CSS Style File
(c) 2006-2007 MeanFreePath
Free for NON-COMMERCIAL use - see website for details and updates
http://www.meanfreepath.com/javascript_calendar/index.html
!!*/

table.calendar {
	font-family: Helvetica, Arial, sans-serif;
	font-size: 0.8em;
	border-collapse: collapse;
	background-color: white;
	border: solid #999999 1px;
	background-color: white;
	width: 215px;
	text-align: center;
	/*prevent user from selecting text in Mozilla & Safari - check calendar constructor for IE code)*/
	-moz-user-select: none;
    /*-khtml-user-select: none;*/
}
table.calendar a {
}
table.calendar a:hover {
}
table.calendar input, table.calendar select {
	font-size: 10px;
}
table.calendar td, table.calendar th {
	border: 0;
	font-size: 10px;
	text-align: center;
}
div.mainheading {
	margin: 2px;
}
.closeBtn {
	/*float: right;
	width: 15px;
	/*font-size: 1.5em;
	height: 13px;

	padding: 0 0 3px 0;
	margin: 1px 8px 0 0;
	border: solid black 1px;*/
}
/*all styles related to the main calendar grid*/
table.cells {
	border-collapse: collapse;
	border: solid #CCCCCC 1px;
	cursor: pointer;
	empty-cells: show;
	margin: 0 6px 0 6px;
}
/*the day headings*/
table.cells th {
	border: solid #CCCCCC 1px;
	text-align: left;
	font-weight: bold;
	color: #0054E3;
	width: 22px;
}
table.cells th.wkhead {
	border-right: double #CCCCCC 3px;
	cursor: default;
	width: 22px;
}
/*The date cells*/
table.cells td {
	border: solid #CCCCCC 1px;
	vertical-align: top;
	text-align: left;
	font-weight: bold;
	height: 20px; /*IE doesn't like ems*/
}
table.cells td.wkhead {
	background-color: white;
	text-align: center;
	border-right: double #CCCCCC 3px;
	color: #0054E3;
}
table.cells td.noselect {
	background-color: #EEEEEE;
	color: #BBBBBB;
	text-decoration: line-through;
	cursor: default;
}
table.cells td.hlday {
	background-color: #99FF99;
}
table.cells td.wkday {
	background-color: #DDDDDD;
}
table.cells td.wkend {
	background-color: #DDDDDD;
}
table.cells td.curdate {
	background-color: #AAAADD;
}
table.cells td.cell_selected {
	background-color: #99CCFF;
	color: black;
}
table.cells td.notmnth {
	background-color: #FFFFFF;
	color: #CCCCCC;
}
table.cells td.notallowed {
	background-color: white;
	color: #EEEEEE;
	font-style: italic;
}
table.cells td.hover {
	background-color: #999999;
}
table.cells td div {
	padding: 1px;
	margin: 0;
}

</style>
<script type="text/javascript">
/*!!
Epoch DHTML JavaScript Calendar - Version 2.0.2
English Edition
Primary JavaScript File
(c) 2006-2007 MeanFreePath
Free for NON-COMMERCIAL use - see website for details and updates
http://www.meanfreepath.com/javascript_calendar/index.html
!!*/

/**
* The main Epoch class.  All publicly-accessible methods and properties are called from this class
*/
function Epoch(name,mode,targetelement,multiselect) {
	var self = this; //workaround due to varying definitions of "this" in variable scopes. see http://www.meanfreepath.com/support/epoch/epoch.html#self for details
	//DEFINE PRIVATE METHODS
	//-----------------------------------------------------------------------------
	/**
	* Declares and initializes the calendar variables.  All the variables here can be safely changed
	* (within reason ;) by the developer
	*/
	function calConfig() {
		self.versionNumber = '2.0.2';
		self.displayYearInitial = self.curDate.getFullYear(); //the initial year to display on load
		self.displayMonthInitial = self.curDate.getMonth(); //the initial month to display on load (0-11)
		self.displayYear = self.displayYearInitial;
		self.displayMonth = self.displayMonthInitial;
		self.minDate = new Date(2006,0,1);
		self.maxDate = new Date(2012,11,31);
		self.startDay = 0; // the day the week will 'start' on: 0(Sun) to 6(Sat)
		self.showWeeks = true; //whether the week numbers will be shown
		self.selCurMonthOnly = true; //allow user to only select dates in the currently displayed month
	}
	//-----------------------------------------------------------------------------
	/**
	* All language settings for Epoch are made here.
	* Check Date.dateFormat() for the Date object's language settings
	*/
	function setLang() {
		self.daylist = new Array('S','M','T','W','T','F','S','S','M','T','W','T','F','S');
		self.months_sh = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
		self.monthup_title = 'Go to the next month';
		self.monthdn_title = 'Go to the previous month';
		self.clearbtn_caption = 'Clear';
		self.clearbtn_title = 'Clears any dates selected on the calendar';
		self.maxrange_caption = 'This is the maximum range';
		self.closebtn_caption = 'Close';
		self.closebtn_title = 'Close the calendar';
	}
	//-----------------------------------------------------------------------------
	/**
	* Initializes the standard Gregorian Calendar parameters
	*/
	function setDays() {
		self.daynames = new Array();
		var j=0;
		for(var i=self.startDay;i<self.startDay + 7;i++) {
			self.daynames[j++] = self.daylist[i];
		}
		self.monthDayCount = new Array(31,((self.curDate.getFullYear() - 2000) % 4 ? 28 : 29),31,30,31,30,31,31,30,31,30,31);
	}
	//-----------------------------------------------------------------------------
	/**
	* Creates the full DOM implementation of the calendar
	*/
	function createCalendar() {
		var tbody, tr, td;
		self.calendar = document.createElement('table');
		self.calendar.setAttribute('id',self.name+'_calendar');
		setClass(self.calendar,'calendar');
		self.calendar.style.display = 'none'; //default to invisible
		//to prevent IE from selecting text when clicking on the calendar
		addEventHandler(self.calendar,'selectstart', function() {return false;});
		addEventHandler(self.calendar,'drag', function() {return false;});
		tbody = document.createElement('tbody');

		//create the Main Calendar Heading
		tr = document.createElement('tr');
		td = document.createElement('td');
		td.appendChild(createMainHeading());
		tr.appendChild(td);
		tbody.appendChild(tr);

		//create the calendar Day Heading & the calendar Day Cells
		tr = document.createElement('tr');
		td = document.createElement('td');
		self.calendar.celltable = document.createElement('table');
		setClass(self.calendar.celltable,'cells');
		self.calendar.celltable.appendChild(createDayHeading());
		self.calendar.celltable.appendChild(createCalCells());
		td.appendChild(self.calendar.celltable);
		tr.appendChild(td);
		tbody.appendChild(tr);

		//create the calendar footer
		tr = document.createElement('tr');
		td = document.createElement('td');
		td.appendChild(createFooter());
		tr.appendChild(td);
		tbody.appendChild(tr);

		//add the tbody element to the main calendar table
		self.calendar.appendChild(tbody);

		//and add the onmouseover events to the calendar table
		addEventHandler(self.calendar,'mouseover',cal_onmouseover);
		addEventHandler(self.calendar,'mouseout',cal_onmouseout);
	}
	//-----------------------------------------------------------------------------
	/**
	* Creates the primary calendar heading, with months & years
	*/
	function createMainHeading() {
		//create the containing <div> element
		var container = document.createElement('div');
		setClass(container,'mainheading');
		//create the child elements and other variables
		self.monthSelect = document.createElement('select');
		self.yearSelect = document.createElement('select');
		var monthDn = document.createElement('input'), monthUp = document.createElement('input');
		var opt, i;
		//fill the month select box
		for(i=0;i<12;i++) {
			opt = document.createElement('option');
			opt.setAttribute('value',i);
			if(self.displayMonth == i) {
				opt.setAttribute('selected','selected');
			}
			opt.appendChild(document.createTextNode(self.months_sh[i]));
			self.monthSelect.appendChild(opt);
		}
		//and fill the year select box
		var yrMax = self.maxDate.getFullYear(), yrMin = self.minDate.getFullYear();
		for(i=yrMin;i<=yrMax;i++) {
			opt = document.createElement('option');
			opt.setAttribute('value',i);
			if(self.displayYear == i) {
				opt.setAttribute('selected','selected');
			}
			opt.appendChild(document.createTextNode(i));
			self.yearSelect.appendChild(opt);
		}
		//add the appropriate children for the month buttons
		monthUp.setAttribute('type','button');
		monthUp.setAttribute('value','>');
		monthUp.setAttribute('title',self.monthup_title);
		monthDn.setAttribute('type','button');
		monthDn.setAttribute('value','<');
		monthDn.setAttribute('title',self.monthdn_title);
		self.monthSelect.owner = self.yearSelect.owner = monthUp.owner = monthDn.owner = self;  //hack to allow us to access self calendar in the events (<fix>??)

		//assign the event handlers for the controls
		function selectonchange()	{
			if(self.goToMonth(self.yearSelect.value,self.monthSelect.value)) {
				self.displayMonth = self.monthSelect.value;
				self.displayYear = self.yearSelect.value;
			}
			else {
				self.monthSelect.value = self.displayMonth;
				self.yearSelect.value = self.displayYear;
			}
		}
		addEventHandler(monthUp,'click',function(){self.nextMonth();});
		addEventHandler(monthDn,'click',function(){self.prevMonth();});
		addEventHandler(self.monthSelect,'change',selectonchange);
		addEventHandler(self.yearSelect,'change',selectonchange);

		//and finally add the elements to the containing div
		container.appendChild(monthDn);
		container.appendChild(self.monthSelect);
		container.appendChild(self.yearSelect);
		container.appendChild(monthUp);
		return container;
	}
	//-----------------------------------------------------------------------------
	/**
	* Creates the footer of the calendar - goes under the calendar cells
	*/
	function createFooter() {
		var container = document.createElement('div');
		var clearSelected = document.createElement('input');
		clearSelected.setAttribute('type','button');
		clearSelected.setAttribute('value',self.clearbtn_caption);
		clearSelected.setAttribute('title',self.clearbtn_title);
		clearSelected.owner = self;
		addEventHandler(clearSelected,'click',function() {self.resetSelections(false);});
		container.appendChild(clearSelected);
		if(self.mode == 'popup') {
			var closeBtn = document.createElement('input');
			closeBtn.setAttribute('type','button');
			closeBtn.setAttribute('value',self.closebtn_caption);
			closeBtn.setAttribute('title',self.closebtn_title);
			addEventHandler(closeBtn,'click',function(){self.hide();});
			setClass(closeBtn,'closeBtn');
			container.appendChild(closeBtn);
		}
		return container;
	}
	//-----------------------------------------------------------------------------
	/**
	* Creates the heading containing the day names
	*/
	function createDayHeading() {
		//create the table element
		self.calHeading = document.createElement('thead');
		setClass(self.calHeading,'caldayheading');
		var tr = document.createElement('tr'), th;
		self.cols = new Array(false,false,false,false,false,false,false);

		//if we're showing the week headings, create an empty <td> for filler
		if(self.showWeeks) {
			th = document.createElement('th');
			setClass(th,'wkhead');
			tr.appendChild(th);
		}
		//populate the day titles
		for(var dow=0;dow<7;dow++) {
			th = document.createElement('th');
			th.appendChild(document.createTextNode(self.daynames[dow]));
			if(self.selectMultiple) { //if selectMultiple is true, assign the cell a CalHeading Object to handle all events
				th.headObj = new CalHeading(self,th,(dow + self.startDay < 7 ? dow + self.startDay : dow + self.startDay - 7));
			}
			tr.appendChild(th);
		}
		self.calHeading.appendChild(tr);
		return self.calHeading;
	}
	//-----------------------------------------------------------------------------
	/**
	* Creates the table containing the calendar day cells
	*/
	function createCalCells() {
		self.rows = new Array(false,false,false,false,false,false);
		self.cells = new Array();
		var row = -1, totalCells = (self.showWeeks ? 48 : 42);
		var beginDate = new Date(self.displayYear,self.displayMonth,1);
		var endDate = new Date(self.displayYear,self.displayMonth,self.monthDayCount[self.displayMonth]);
		var sdt = new Date(beginDate);
		sdt.setDate(sdt.getDate() + (self.startDay - beginDate.getDay()) - (self.startDay - beginDate.getDay() > 0 ? 7 : 0) );
		//create the table element to hold the cells
		self.calCells = document.createElement('tbody');
		var tr,td;
		var cellIdx = 0, cell, week, dayval;

		for(var i=0;i<totalCells;i++) {
			if(self.showWeeks) { //if we are showing the week headings
				if(i % 8 == 0) {
					row++;
					week = sdt.getWeek(self.startDay);
					tr = document.createElement('tr');
					td = document.createElement('td');
					if(self.selectMultiple) { //if selectMultiple is enabled, create the associated weekObj objects
						td.weekObj = new WeekHeading(self,td,week,row)
					}
					else {//otherwise just set the class of the td for consistent look
						setClass(td,'wkhead');
					}
					td.appendChild(document.createTextNode(week));
					tr.appendChild(td);
					i++;
				}
			}
			else if(i % 7 == 0) { //otherwise, new row every 7 cells
				row++;
				week = sdt.getWeek(self.startDay);
				tr = document.createElement('tr');
			}
			//create the day cells
			dayval = sdt.getDate();
			td = document.createElement('td');
			td.appendChild(document.createTextNode(dayval));
			cell = new CalCell(self,td,sdt,row,week);//,'normal',sdt.getTime() >= self.minDate.getTime() && sdt.getTime() <= self.maxDate.getTime());
			self.cells[cellIdx] = cell;
			td.cellObj = cell;
			tr.appendChild(td);
			self.calCells.appendChild(tr);
			self.reDraw(cellIdx++); //and paint the cell according to its properties
			sdt.setDate(dayval + 1); //increment the date
		}
		return self.calCells;
	}
	//-----------------------------------------------------------------------------
	/**
	* Runs all the operations necessary to change the mode of the calendar
	* @param HTMLInputElement targetelement
	*/
	function setMode(targetelement)	{
		if(self.mode == 'popup') { //set positioning to absolute for popup
			self.calendar.style.position = 'absolute';
		}
		//if a target element has been set, append the calendar to it
		if(targetelement) {
			switch(self.mode) {
				case 'flat':
					self.tgt = targetelement;
					self.tgt.appendChild(self.calendar);
					self.visible = true;
					break;
				case 'popup':
					self.calendar.style.position = 'absolute';
					document.body.appendChild(self.calendar);
					self.setTarget(targetelement,false);
					break;
			}
		}
		else { //otherwise, add the calendar to the document.body (useful if targetelement will not be defined until after the calendar is initialized)
			document.body.appendChild(self.calendar);
			self.visible = false;
		}
	}
	//-----------------------------------------------------------------------------
	/**
	* Removes the calendar table cells from the DOM (does not delete the cell objects associated with them)
	*/
	function deleteCells() {
		self.calendar.celltable.removeChild(self.calendar.celltable.childNodes[1]); //remove the tbody element from the cell table
	}
	//-----------------------------------------------------------------------------
	/**
	* Sets the CSS class of the element, W3C & IE
	* @param HTMLElement element
	* @param string className
	*/
	function setClass(element,className) {
		element.setAttribute('class',className);
		element.setAttribute('className',className); //<iehack>
	}
	/**
	* Updates a cell's data, including css class and selection properties
	* @param int cellindex
	*/
	function setCellProperties(cellindex) {
		var cell = self.cells[cellindex];
		var date;
		idx = self.dateInArray(self.dates,cell.date);
		if(idx > -1) {
			date = self.dates[idx]; //reduce indirection
			cell.date.selected = date.selected || false;
			cell.date.type = date.type;
			cell.date.canSelect = date.canSelect;
			cell.setTitle(date.title);
			cell.setURL(date.href);
			cell.setHTML(date.cellHTML);
		}
		else {
			cell.date.selected = false; //if the cell's date isn't in the dates array, set it's selected value to false
		}
		//make all cells lying outside the min and max dates un-selectable
		if(cell.date.getTime() < self.minDate.getTime() || cell.date.getTime() > self.maxDate.getTime()) {
			cell.date.canSelect = false;
		}
		cell.setClass();
	}
	//-----------------------------------------------------------------------------
	function cal_onmouseover() {
		self.mousein = true;
	}
	//-----------------------------------------------------------------------------
	function cal_onmouseout()	{
		self.mousein = false;
	}
	//-----------------------------------------------------------------------------
	/**
	 * Updates the calendar's selectedDates pointer array
	 */
	function updateSelectedDates() {
		var idx = 0;
		self.selectedDates = new Array();
		for(i=0;i<self.dates.length;i++) {
			if(self.dates[i].selected) {
				self.selectedDates[idx++] = self.dates[i];
			}
		}
	}
	//PUBLIC METHODS
	//-----------------------------------------------------------------------------
	/**
	* Find a date in the given array, returning its index if found, -1 if not
	* @param array arr
	* @param Date searchVal
	* @param int startIndex
	* @return int
	*/
	self.dateInArray = function(arr,searchVal,startIndex) {
		startIndex = (startIndex != null ? startIndex : 0); //default startIndex to 0, if not set
		for(var i=startIndex;i<arr.length;i++) {
			if(searchVal.getUeDay() == arr[i].getUeDay()) {
				return i;
			}
		}
		return -1;
	};
	//-----------------------------------------------------------------------------
	/**
	* Changes the target element of this calendar to another input.
	* Many thanks to Jake Olefsky - jake@olefsky.com
	* @param HTMLInputElement targetelement
	* @param bool focus
	*/
	self.setTarget = function (targetelement, focus)
	{
		//if this is a popup calendar
		if(self.mode == 'popup') {
			//declare the event handlers for the target element
			function popupFocus() {
				self.show();
			}
			function popupBlur() {
				if(!self.mousein){
					self.hide();
				}
			}
			function popupKeyDown() {
				self.hide();
			}
			//unset old target element event handlers (if there is one yet)
			if(self.tgt) {
				removeEventHandler(self.tgt,'focus',popupFocus);
				removeEventHandler(self.tgt,'blur',popupBlur);
				removeEventHandler(self.tgt,'keydown',popupKeyDown);
			}
			//and set the new target element
			self.tgt = targetelement;
			//create a pointer to the INPUT's date object and init the new data array
			var dto = self.tgt.dateObj,pdateArr = new Array;
			//if a date is set for the target element
			if(dto) {
				if(self.tgt.value.length) { //load it into the calendar...
					pdateArr[0] = dto;
				}
				self.goToMonth(dto.getFullYear(),dto.getMonth()); //...and go to the target's month/year
			}
			self.selectDates(pdateArr,true,true,true);

			self.topOffset = self.tgt.offsetHeight; // the vertical distance (in pixels) to display the calendar from the Top of its input element
			self.leftOffset = 0; 					// the horizontal distance (in pixels) to display the calendar from the Left of its input element
			self.updatePos(self.tgt);
			//and add the event handlers to the new element
			addEventHandler(self.tgt,'focus',popupFocus);
			addEventHandler(self.tgt,'blur',popupBlur);
			addEventHandler(self.tgt,'keydown',popupKeyDown);
			if(focus !== false) { //focus the target element immediately, unless otherwise specified
				popupFocus();
			}
		}
		else { //if this is a flat or inline calendar
			//if the target is already set, remove the calendar's DOM representation from it
			if(self.tgt) {
				self.tgt.removeChild(self.calendar);
			}
			//now, set the calendar's target to the new target element, and show the calendar
			self.tgt = targetelement;
			self.tgt.appendChild(self.calendar);
			self.show();
		}
	};
	//-----------------------------------------------------------------------------
	/**
	* Go to the next month.  if the month is December, go to January of the next year
	* Returns true if the month will be incremented
	* @return bool
	*/
	self.nextMonth = function () {
		var month = self.displayMonth;
		var year = self.displayYear;
		//increment the month/year values, provided they're within the min/max ranges
		if(self.displayMonth < 11) { //i.e. if currently in the year
			month++;
		}
		else if(self.yearSelect.value < self.maxDate.getFullYear()) { //if not, increment the year as well
			month = 0;
			year++;
		}
		return self.goToMonth(year,month);
	};
	//-----------------------------------------------------------------------------
	/**
	* Go to the previous month - if the month is January, go to December of the previous year.
	* Returns true if the month will be decremented
	* @return bool
	*/
	self.prevMonth = function () {
		var month = self.displayMonth;
		var year = self.displayYear;
		//increment the month/year values, provided they're within the min/max ranges
		if(self.displayMonth > 0) { //i.e. if currently in the year
			month--;
		}
		else { //if not, decrement the year as well
			month = 11;
			year--;
		}
		return self.goToMonth(year,month);
	};
	//-----------------------------------------------------------------------------
	/**
	* Sets the calendar to display the requested month/year, returning true if the
	* date is within the minimum and maximum allowed dates
	* @param int year
	* @param int month
	* @return bool
	*/
	self.goToMonth = function (year,month) {
		var testdatemin = new Date(year, month, 31);
		var testdatemax = new Date(year, month, 1);
		if(testdatemin >= self.minDate && testdatemax <= self.maxDate) {
			self.monthSelect.value = self.displayMonth = month;
			self.yearSelect.value = self.displayYear = year;
			//recreate the calendar for the new month
			createCalCells();
			deleteCells();
			self.calendar.celltable.appendChild(self.calCells);
			return true;
		}
		else {
			alert(self.maxrange_caption);
			return false;
		}
	};
	//-----------------------------------------------------------------------------
	/**
	* Moves the calendar's position to the target element's location (popup mode only)
	*/
	self.updatePos = function (target) {
		if(self.mode == 'popup') {
			self.calendar.style.top = getTop(target) + self.topOffset + 'px';
			self.calendar.style.left = getLeft(target) + self.leftOffset + 'px';
		}
	};
	//-----------------------------------------------------------------------------
	/**
	* Displays the calendar
	*/
	self.show = function ()	{
		self.updatePos(self.tgt); //update the calendar position, in case the page layout has changed since loading
		self.calendar.style.display = 'block'; //'table'; //<iehack> 'table' is the W3C-recommended spec, but IE isn't a fan of those
		self.visible = true;
	};
	//-----------------------------------------------------------------------------
	/**
	* Hides the calendar
	*/
	self.hide = function () {
		self.calendar.style.display = 'none';
		self.visible = false;
	};
	//-----------------------------------------------------------------------------
	/**
	* Toggles (shows/hides) the calendar depending on its current state
	*/
	self.toggle = function () {
		self.visible ? self.hide() : self.show();
	};
	//-----------------------------------------------------------------------------
	/**
	* Adds the array "dates" to the calendar's dates array, removing duplicate dates,
	* and redraws the calendar if redraw is true
	* @param array dates
	* @param bool redraw
	*/
	self.addDates = function (dates,redraw) {
		var i;
		for(i=0;i<dates.length;i++) {
			if(self.dateInArray(self.dates,dates[i]) == -1) { //if the date isn't already in the array, add it!
				self.dates[self.dates.length] = dates[i];
			}
		}
		//now rebuild the selectedDates pointer array
		updateSelectedDates();
		if(redraw != false) { //redraw  the calendar if "redraw" is false or undefined
			self.reDraw();
		}
	};
	//-----------------------------------------------------------------------------
	/**
	* Removes the dates from the calendar's dates array and redraws the calendar
	* if redraw is true
	* @param array dates
	* @param bool redraw
	*/
	self.removeDates = function (dates,redraw) {
		var idx;
		for(var i=0;i<dates.length;i++) {
			idx = self.dateInArray(self.dates,dates[i]);
			if(idx != -1) { //search for the dates in the dates array, removing them if the dates match
				self.dates.splice(idx,1);
			}
		}
		updateSelectedDates();
		if(redraw != false) { //redraw  the calendar if "redraw" is true or undefined
			self.reDraw();
		}
	};
	//-----------------------------------------------------------------------------
	/**
	* Selects or Deselects an array of dates
	* @param Array inpdates
	* @param bool selectVal
	* @param bool redraw
	* @param bool removeothers
	*/
	self.selectDates = function (inpdates,selectVal,redraw,removeothers) {
		var i, idx;
		if(removeothers == true) {
			for(i=0;i<self.dates.length;i++) {
				self.dates[i].selected = false;
			}
		}
		for(i=0;i<inpdates.length;i++) {
			idx = self.dateInArray(self.dates,inpdates[i]);
			if(selectVal == true) {
				inpdates[i].selected = true;
				if(idx == -1) { //if the date does not exist in the calendar's dates array, add it
					self.dates[self.dates.length] = inpdates[i];
				}
				else { //if not, just select it
					self.dates[idx].selected = true;
				}
			}
			else { //if deselecting...
				if(idx > -1) { //if the date is found, deselect and/or remove it from the calendar's dates array
					self.dates[idx].selected = inpdates[i].selected = false;
					if(self.dates[idx].type == 'normal') { //remove 'normal' dates from the dates array, since they're useless unless selected
						self.dates.splice(idx,1);
					}
				}
			}
		}
		//now rebuild the selectedDates pointer array
		updateSelectedDates();
		if(redraw != false) { //redraw the calendar if "redraw" is false or undefined
			self.reDraw();
		}
	};
	//-----------------------------------------------------------------------------
	/**
	* Adds the dates in dates as hidden inputs to the form "form".  inputname
	* is the name of each hidden element. "form" can either be a pointer to the form's
	* DOM element or its id string.
	* @param mixed form
	* @param string inputname
	*/
	self.sendForm = function(form,inputname) {
		var inpname = inputname || 'epochdates', f, inp;
		f = (typeof(form) == 'string' ? document.getElementById(form) : form);
		if(!f) {
			alert('ERROR: Invalid form input');
			return false;
		}
		for(var i=0;i<self.dates.length;i++) {
			inp = document.createElement('input');
			inp.setAttribute('type','hidden');
			inp.setAttribute('name',inpname + '['+i+']');
			inp.setAttribute('value',encodeURIComponent(self.dates[i].dateFormat('Y-m-d')));  //default to the ISO date format
			f.appendChild(inp);
		}
		return true;
	};
	//-----------------------------------------------------------------------------
	/**
	* Erases the dates array and resets the calendar's selection variables to defaults.
	* If retMonth is true, the calendar will return to the initial default month/year
	* @param bool retMonth
	*/
	self.resetSelections = function (retMonth) {
		var dateArray = new Array();
		var dt = self.dates;
		for(var i=0;i<dt.length;i++) {
			if(dt[i].selected) {
				dateArray[dateArray.length] = dt[i];
			}
		}
		self.selectDates(dateArray,false,false);
		self.rows = new Array(false,false,false,false,false,false,false);
		self.cols = new Array(false,false,false,false,false,false,false);
		if(self.mode == 'popup') { //hide the calendar and clear the input element if in popup mode
			self.tgt.value = '';
			self.hide();
		}
		retMonth == true ? self.goToMonth(self.displayYearInitial,self.displayMonthInitial) : self.reDraw();
	};
	//-----------------------------------------------------------------------------
	/**
	* Reapplies all the CSS classes for the calendar cells - usually called after changing their state
	* If index is specified, it will redraw that cell only.
	* @param int index
	*/
	self.reDraw = function (index) {
		self.state = 1;
		var len = index ? index + 1 : self.cells.length;
		for(var i = index || 0;i<len;i++) {
			setCellProperties(i);
		}
		self.state = 2;
	};
	//-----------------------------------------------------------------------------
	/**
	* Returns the index of the cell whose date value matches "date", or -1 if not found
	* @param Date date
	* @return int
	*/
	self.getCellIndex = function(date) {
		for(var i=0;i<self.cells.length;i++) {
			if(self.cells[i].date.getUeDay() == date.getUeDay()) {
				return i;
			}
		}
		return -1;
	};
	//-----------------------------------------------------------------------------
	//begin constructor code:

	//PUBLIC VARIABLES
	self.state = 0;
	self.name = name;
	self.curDate = new Date();
	self.mode = mode;
	self.selectMultiple = (multiselect == true); //'false' if not true or not set at all
	//the various calendar variables
	self.dates = new Array();
	self.selectedDates = new Array();

	self.calendar;
	self.calHeading;
	self.calCells;
	self.rows;
	self.cols;
	self.cells = new Array();
	//The controls
	self.monthSelect;
	self.yearSelect;
	self.mousein = false;

	//Initialize the calendar and its variables{
	calConfig();
	setLang();
	setDays();
	createCalendar(); //create the calendar DOM element and its children, and their related objects
	targetelement = typeof(targetelement) == 'string' ? document.getElementById(targetelement) : targetelement;
	setMode(targetelement);
	self.state = 2; //0: initializing, 1: redrawing, 2: finished!
	self.visible ? self.show() : self.hide();
}
//-----------------------------------------------------------------------------
/*****************************************************************************/
/**
* Object that contains the methods and properties for the calendar day headings
*/
function CalHeading(owner,tableCell,dayOfWeek) {
	//-----------------------------------------------------------------------------
	function DayHeadingonclick() {//selects/deselects the days for this object's day of week
		//reduce indirection:
		var sdates = owner.dates;
		var cells = owner.cells;
		var dateArray = new Array();
		owner.cols[dayOfWeek] = !owner.cols[dayOfWeek];
		for(var i=0;i<cells.length;i++) { //cycle through all the cells in the calendar, selecting all cells with the same dayOfWeek as this heading
			if(cells[i].dayOfWeek == dayOfWeek && cells[i].date.canSelect && (!owner.selCurMonthOnly || cells[i].date.getMonth() == owner.displayMonth && cells[i].date.getFullYear() == owner.displayYear)) { //if the cell's DoW matches, with other conditions
				dateArray[dateArray.length] = cells[i].date;
			}
		}
		owner.selectDates(dateArray,owner.cols[dayOfWeek],true);
	}
	//-----------------------------------------------------------------------------
	var self = this;
	self.dayOfWeek = dayOfWeek;
	addEventHandler(tableCell,'mouseup',DayHeadingonclick);
}
/*****************************************************************************/
/**
* Object that contains the methods and properties for the calendar week headings
*/
function WeekHeading(owner,tableCell,week,tableRow) {
	//-----------------------------------------------------------------------------
	function weekHeadingonclick() {
		//reduce indirection:
		var cells = owner.cells;
		var sdates = owner.dates;
		var dateArray = new Array();
		owner.rows[tableRow] = !owner.rows[tableRow];
		for(var i=0;i<cells.length;i++) {
			if(cells[i].tableRow == tableRow && cells[i].date.canSelect && (!owner.selCurMonthOnly || cells[i].date.getMonth() == owner.displayMonth && cells[i].date.getFullYear() == owner.displayYear)) { //if the cell's DoW matches, with other conditions)
				dateArray[dateArray.length] = cells[i].date;
			}
		}
		owner.selectDates(dateArray,owner.rows[tableRow],true);
	}
	//-----------------------------------------------------------------------------
	var self = this;
	self.week = week;
	tableCell.setAttribute('class','wkhead');
	tableCell.setAttribute('className','wkhead'); //<iehack>
	addEventHandler(tableCell,'mouseup',weekHeadingonclick);
}
/*****************************************************************************/
/**
* Object that holds all data & code related to a calendar cell
*/
/**
 * The CalCell constructor function
 * @param Epoch owner
 * @param HTMLTableCellElement tableCell
 * @param Date dateObj
 * @param int row
 * @param int week
 */
function CalCell(owner,tableCell,dateObj,row,week) {
	var self = this;
	//-----------------------------------------------------------------------------
	function calCellonclick() {
		if(self.date.canSelect) {
			if(owner.selectMultiple == true) { //if we can select multiple cells simultaneously, add the currently selected self's date to the dates array
				owner.selectDates(new Array(self.date),!self.date.selected,false);
				self.setClass(); //update the current cell's style to reflect the changes - a full redraw isn't necessary
			}
			else { //if we can only select one date at a time
				owner.selectDates(new Array(self.date),true,false,true);
				if(owner.mode == 'popup') { //update the target element's value and hide the calendar if in popup mode
					owner.tgt.value = self.date.dateFormat(); //use the default date format defined in dateFormat
					owner.tgt.dateObj = new Date(self.date); //add a Date object to the target element for later reference
					owner.hide();
				}
				owner.reDraw(); //redraw all the calendar cells
			}
		}
	}
	//-----------------------------------------------------------------------------
	/**
	* Replicate the CSS :hover effect for non-supporting browsers <iehack>
	*/
	function calCellonmouseover() {
		if(self.date.canSelect) {
			tableCell.setAttribute('class',self.cellClass + ' hover');
			tableCell.setAttribute('className',self.cellClass + ' hover');
		}
	}
	//-----------------------------------------------------------------------------
	/**
	* Replicate the CSS :hover effect for non-supporting browsers <iehack>
	*/
	function calCellonmouseout() {
		self.setClass();
	}
	//-----------------------------------------------------------------------------
	/**
	* Sets the CSS class of the cell based on the specified criteria
	*/
	self.setClass = function ()
	{
		if(self.date.canSelect !== false) {
			if(self.date.selected) {
				self.cellClass = 'cell_selected';
			}
			else if(owner.displayMonth != self.date.getMonth() ) {
				self.cellClass = 'notmnth';
			}
			else if(self.date.type == 'holiday') {
				self.cellClass = 'hlday';
			}
			else if(self.dayOfWeek > 0 && self.dayOfWeek < 6) {
				self.cellClass = 'wkday';
			}
			else {
				self.cellClass = 'wkend';
			}
		}
		else {
			self.cellClass = 'noselect';
		}
		//highlight the current date
		if(self.date.getUeDay() == owner.curDate.getUeDay()) {
			self.cellClass = self.cellClass + ' curdate';
		}
		tableCell.setAttribute('class',self.cellClass);
		tableCell.setAttribute('className',self.cellClass); //<iehack>
	};
	//-----------------------------------------------------------------------------
	/**
	* Sets the cell's hyperlink, if declared
	* @param string href
	* @param string type ('anchor' or 'js' - default 'anchor')
	*/
	self.setURL = function(href,type) {
		if(href) {
			if(type == 'js') { //Make the WHOLE cell be a clickable link
				addEventHandler(self.tableCell,'mousedown',function(){window.location.href = href;});
			}
			else { //make only the date number of the cell a clickable link:
				var url = document.createElement('a');
				url.setAttribute('href',href);
				url.appendChild(document.createTextNode(self.date.getDate()));
				self.tableCell.replaceChild(url,self.tableCell.firstChild); //assumes the first child of the cell DOM node is the date text
			}
		}
	};
	//-----------------------------------------------------------------------------
	/**
	* Sets the title (i.e. tooltip) that appears when a user holds their mouse cursor over a cell
	* @param string titleStr
	*/
	self.setTitle = function(titleStr) {
		if(titleStr && titleStr.length > 0) {
			self.title = titleStr;
			self.tableCell.setAttribute('title',titleStr);
		}
	};
	//-----------------------------------------------------------------------------
	/**
	* Sets the internal html of the cell, using a string containing html markup
	* @param string html
	*/
	self.setHTML = function(html) {
		if(html && html.length > 0) {
			if(self.tableCell.childNodes[1]) {
				self.tableCell.childNodes[1].innerHTML = html;
			}
			else {
				var htmlCont = document.createElement('div');
				htmlCont.innerHTML = html;
				self.tableCell.appendChild(htmlCont);
			}
		}
	};
	//-----------------------------------------------------------------------------
	self.cellClass;			//the CSS class of the cell
	self.tableRow = row;
	self.tableCell = tableCell;
	self.date = new Date(dateObj);
	self.date.canSelect = true; //whether this cell can be selected or not - always true unless set otherwise externally
	self.date.type = 'normal';  //i.e. normal date, holiday, etc - always true unless set otherwise externally
	self.date.selected = false;	//whether the cell is selected (and is therefore stored in the owner's dates array)
	self.date.cellHTML = '';
	self.dayOfWeek = self.date.getDay();
	self.week = week;
	//assign the event handlers for the table cell element
	addEventHandler(tableCell,'click', calCellonclick);
	addEventHandler(tableCell,'mouseover', calCellonmouseover);
	addEventHandler(tableCell,'mouseout', calCellonmouseout);
	self.setClass();
}
/*****************************************************************************/
Date.prototype.getDayOfYear = function () //returns the day of the year for this date
{
	return parseInt((this.getTime() - new Date(this.getFullYear(),0,1).getTime())/86400000 + 1);
};
//-----------------------------------------------------------------------------
/**
 * Returns the week number for this date.  dowOffset is the day of week the week
 * "starts" on for your locale - it can be from 0 to 6. If dowOffset is 1 (Monday),
 * the week returned is the ISO 8601 week number.
 * @param int dowOffset
 * @return int
 */
Date.prototype.getWeek = function (dowOffset) {
	dowOffset = typeof(dowOffset) == 'int' ? dowOffset : 0; //default dowOffset to zero
	var newYear = new Date(this.getFullYear(),0,1);
	var day = newYear.getDay() - dowOffset; //the day of week the year begins on
	day = (day >= 0 ? day : day + 7);
	var weeknum, daynum = Math.floor((this.getTime() - newYear.getTime() - (this.getTimezoneOffset()-newYear.getTimezoneOffset())*60000)/86400000) + 1;
	//if the year starts before the middle of a week
	if(day < 4) {
		weeknum = Math.floor((daynum+day-1)/7) + 1;
		if(weeknum > 52) {
			nYear = new Date(this.getFullYear() + 1,0,1);
			nday = nYear.getDay() - dowOffset;
			nday = nday >= 0 ? nday : nday + 7;
			weeknum = nday < 4 ? 1 : 53; //if the next year starts before the middle of the week, it is week #1 of that year
		}
	}
	else {
		weeknum = Math.floor((daynum+day-1)/7);
	}
	return weeknum;
};
//-----------------------------------------------------------------------------
Date.prototype.getUeDay = function () //returns the number of DAYS since the UNIX Epoch - good for comparing the date portion
{
	return parseInt(Math.floor((this.getTime() - this.getTimezoneOffset() * 60000)/86400000)); //must take into account the local timezone
};
//-----------------------------------------------------------------------------
Date.prototype.dateFormat = function(format)
{
	if(!format) { // the default date format to use - can be customized to the current locale
		format = 'Y-m-d';
	}
	LZ = function(x) {return(x < 0 || x > 9 ? '' : '0') + x};
	var MONTH_NAMES = new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	var DAY_NAMES = new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=this.getFullYear().toString();
	var M=this.getMonth()+1;
	var d=this.getDate();
	var E=this.getDay();
	var H=this.getHours();
	var m=this.getMinutes();
	var s=this.getSeconds();
	value = {
		Y: y.toString(),
		y: y.substring(2),
		n: M,
		m: LZ(M),
		F: MONTH_NAMES[M-1],
		M: MONTH_NAMES[M+11],
		j: d,
		d: LZ(d),
		D: DAY_NAMES[E+7],
		l: DAY_NAMES[E],
		G: H,
		H: LZ(H)
	};
	if (H==0) {value['g']=12;}
	else if (H>12){value['g']=H-12;}
	else {value['g']=H;}
	value['h']=LZ(value['g']);
	if (H > 11) {value['a']='pm'; value['A'] = 'PM';}
	else { value['a']='am'; value['A'] = 'AM';}
	value['i']=LZ(m);
	value['s']=LZ(s);
	//construct the result string
	while (i_format < format.length) {
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
		}
		if (value[token] != null) { result=result + value[token]; }
		else { result=result + token; }
	}
	return result;
};
/*****************************************************************************/
//-----------------------------------------------------------------------------
function addEventHandler(element, type, func) { //unfortunate hack to deal with Internet Explorer's horrible DOM event model <iehack>
	if(element.addEventListener) {
		element.addEventListener(type,func,false);
	}
	else if (element.attachEvent) {
		element.attachEvent('on'+type,func);
	}
}
//-----------------------------------------------------------------------------
function removeEventHandler(element, type, func) { //unfortunate hack to deal with Internet Explorer's horrible DOM event model <iehack>
	if(element.removeEventListener) {
		element.removeEventListener(type,func,false);
	}
	else if (element.attachEvent) {
		element.detachEvent('on'+type,func);
	}
}
//-----------------------------------------------------------------------------
function getTop(element) {//returns the absolute Top value of element, in pixels
	var oNode = element;
	var iTop = 0;

	while(oNode.tagName != 'HTML') {
		iTop += oNode.offsetTop || 0;
		if(oNode.offsetParent) { //i.e. the parent element is not hidden
			oNode = oNode.offsetParent;
		}
		else {
			break;
		}
	}
	return iTop;
}
//-----------------------------------------------------------------------------
function getLeft(element) { //returns the absolute Left value of element, in pixels
	var oNode = element;
	var iLeft = 0;
	while(oNode.tagName != 'HTML') {
		iLeft += oNode.offsetLeft || 0;
		if(oNode.offsetParent) { //i.e. the parent element is not hidden
			oNode = oNode.offsetParent;
		}
		else {
			break;
		}
	}
	return iLeft;
}
//-----------------------------------------------------------------------------

</script>
<script type="text/javascript">
/**
 * Version: 1.0 Alpha-1 
 * Build Date: 13-Nov-2007
 * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
 * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
 * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
 */
Date.CultureInfo={name:"en-US",englishName:"English (United States)",nativeName:"English (United States)",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbreviatedDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],shortestDayNames:["Su","Mo","Tu","We","Th","Fr","Sa"],firstLetterDayNames:["S","M","T","W","T","F","S"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbreviatedMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],amDesignator:"AM",pmDesignator:"PM",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"mdy",formatPatterns:{shortDate:"M/d/yyyy",longDate:"dddd, MMMM dd, yyyy",shortTime:"h:mm tt",longTime:"h:mm:ss tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"MMMM dd",yearMonth:"MMMM, yyyy"},regexPatterns:{jan:/^jan(uary)?/i,feb:/^feb(ruary)?/i,mar:/^mar(ch)?/i,apr:/^apr(il)?/i,may:/^may/i,jun:/^jun(e)?/i,jul:/^jul(y)?/i,aug:/^aug(ust)?/i,sep:/^sep(t(ember)?)?/i,oct:/^oct(ober)?/i,nov:/^nov(ember)?/i,dec:/^dec(ember)?/i,sun:/^su(n(day)?)?/i,mon:/^mo(n(day)?)?/i,tue:/^tu(e(s(day)?)?)?/i,wed:/^we(d(nesday)?)?/i,thu:/^th(u(r(s(day)?)?)?)?/i,fri:/^fr(i(day)?)?/i,sat:/^sa(t(urday)?)?/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|after|from)/i,subtract:/^(\-|before|ago)/i,yesterday:/^yesterday/i,today:/^t(oday)?/i,tomorrow:/^tomorrow/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^min(ute)?s?/i,hour:/^h(ou)?rs?/i,week:/^w(ee)?k/i,month:/^m(o(nth)?s?)?/i,day:/^d(ays?)?/i,year:/^y((ea)?rs?)?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a|p)/i},abbreviatedTimeZoneStandard:{GMT:"-000",EST:"-0400",CST:"-0500",MST:"-0600",PST:"-0700"},abbreviatedTimeZoneDST:{GMT:"-000",EDT:"-0500",CDT:"-0600",MDT:"-0700",PDT:"-0800"}};
Date.getMonthNumberFromName=function(name){var n=Date.CultureInfo.monthNames,m=Date.CultureInfo.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
return-1;};Date.getDayNumberFromName=function(name){var n=Date.CultureInfo.dayNames,m=Date.CultureInfo.abbreviatedDayNames,o=Date.CultureInfo.shortestDayNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
return-1;};Date.isLeapYear=function(year){return(((year%4===0)&&(year%100!==0))||(year%400===0));};Date.getDaysInMonth=function(year,month){return[31,(Date.isLeapYear(year)?29:28),31,30,31,30,31,31,30,31,30,31][month];};Date.getTimezoneOffset=function(s,dst){return(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST[s.toUpperCase()]:Date.CultureInfo.abbreviatedTimeZoneStandard[s.toUpperCase()];};Date.getTimezoneAbbreviation=function(offset,dst){var n=(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST:Date.CultureInfo.abbreviatedTimeZoneStandard,p;for(p in n){if(n[p]===offset){return p;}}
return null;};Date.prototype.clone=function(){return new Date(this.getTime());};Date.prototype.compareTo=function(date){if(isNaN(this)){throw new Error(this);}
if(date instanceof Date&&!isNaN(date)){return(this>date)?1:(this<date)?-1:0;}else{throw new TypeError(date);}};Date.prototype.equals=function(date){return(this.compareTo(date)===0);};Date.prototype.between=function(start,end){var t=this.getTime();return t>=start.getTime()&&t<=end.getTime();};Date.prototype.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};Date.prototype.addSeconds=function(value){return this.addMilliseconds(value*1000);};Date.prototype.addMinutes=function(value){return this.addMilliseconds(value*60000);};Date.prototype.addHours=function(value){return this.addMilliseconds(value*3600000);};Date.prototype.addDays=function(value){return this.addMilliseconds(value*86400000);};Date.prototype.addWeeks=function(value){return this.addMilliseconds(value*604800000);};Date.prototype.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,this.getDaysInMonth()));return this;};Date.prototype.addYears=function(value){return this.addMonths(value*12);};Date.prototype.add=function(config){if(typeof config=="number"){this._orient=config;return this;}
var x=config;if(x.millisecond||x.milliseconds){this.addMilliseconds(x.millisecond||x.milliseconds);}
if(x.second||x.seconds){this.addSeconds(x.second||x.seconds);}
if(x.minute||x.minutes){this.addMinutes(x.minute||x.minutes);}
if(x.hour||x.hours){this.addHours(x.hour||x.hours);}
if(x.month||x.months){this.addMonths(x.month||x.months);}
if(x.year||x.years){this.addYears(x.year||x.years);}
if(x.day||x.days){this.addDays(x.day||x.days);}
return this;};Date._validate=function(value,min,max,name){if(typeof value!="number"){throw new TypeError(value+" is not a Number.");}else if(value<min||value>max){throw new RangeError(value+" is not a valid value for "+name+".");}
return true;};Date.validateMillisecond=function(n){return Date._validate(n,0,999,"milliseconds");};Date.validateSecond=function(n){return Date._validate(n,0,59,"seconds");};Date.validateMinute=function(n){return Date._validate(n,0,59,"minutes");};Date.validateHour=function(n){return Date._validate(n,0,23,"hours");};Date.validateDay=function(n,year,month){return Date._validate(n,1,Date.getDaysInMonth(year,month),"days");};Date.validateMonth=function(n){return Date._validate(n,0,11,"months");};Date.validateYear=function(n){return Date._validate(n,1,9999,"seconds");};Date.prototype.set=function(config){var x=config;if(!x.millisecond&&x.millisecond!==0){x.millisecond=-1;}
if(!x.second&&x.second!==0){x.second=-1;}
if(!x.minute&&x.minute!==0){x.minute=-1;}
if(!x.hour&&x.hour!==0){x.hour=-1;}
if(!x.day&&x.day!==0){x.day=-1;}
if(!x.month&&x.month!==0){x.month=-1;}
if(!x.year&&x.year!==0){x.year=-1;}
if(x.millisecond!=-1&&Date.validateMillisecond(x.millisecond)){this.addMilliseconds(x.millisecond-this.getMilliseconds());}
if(x.second!=-1&&Date.validateSecond(x.second)){this.addSeconds(x.second-this.getSeconds());}
if(x.minute!=-1&&Date.validateMinute(x.minute)){this.addMinutes(x.minute-this.getMinutes());}
if(x.hour!=-1&&Date.validateHour(x.hour)){this.addHours(x.hour-this.getHours());}
if(x.month!==-1&&Date.validateMonth(x.month)){this.addMonths(x.month-this.getMonth());}
if(x.year!=-1&&Date.validateYear(x.year)){this.addYears(x.year-this.getFullYear());}
if(x.day!=-1&&Date.validateDay(x.day,this.getFullYear(),this.getMonth())){this.addDays(x.day-this.getDate());}
if(x.timezone){this.setTimezone(x.timezone);}
if(x.timezoneOffset){this.setTimezoneOffset(x.timezoneOffset);}
return this;};Date.prototype.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};Date.prototype.isLeapYear=function(){var y=this.getFullYear();return(((y%4===0)&&(y%100!==0))||(y%400===0));};Date.prototype.isWeekday=function(){return!(this.is().sat()||this.is().sun());};Date.prototype.getDaysInMonth=function(){return Date.getDaysInMonth(this.getFullYear(),this.getMonth());};Date.prototype.moveToFirstDayOfMonth=function(){return this.set({day:1});};Date.prototype.moveToLastDayOfMonth=function(){return this.set({day:this.getDaysInMonth()});};Date.prototype.moveToDayOfWeek=function(day,orient){var diff=(day-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};Date.prototype.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};Date.prototype.getDayOfYear=function(){return Math.floor((this-new Date(this.getFullYear(),0,1))/86400000);};Date.prototype.getWeekOfYear=function(firstDayOfWeek){var y=this.getFullYear(),m=this.getMonth(),d=this.getDate();var dow=firstDayOfWeek||Date.CultureInfo.firstDayOfWeek;var offset=7+1-new Date(y,0,1).getDay();if(offset==8){offset=1;}
var daynum=((Date.UTC(y,m,d,0,0,0)-Date.UTC(y,0,1,0,0,0))/86400000)+1;var w=Math.floor((daynum-offset+7)/7);if(w===dow){y--;var prevOffset=7+1-new Date(y,0,1).getDay();if(prevOffset==2||prevOffset==8){w=53;}else{w=52;}}
return w;};Date.prototype.isDST=function(){console.log('isDST');return this.toString().match(/(E|C|M|P)(S|D)T/)[2]=="D";};Date.prototype.getTimezone=function(){return Date.getTimezoneAbbreviation(this.getUTCOffset,this.isDST());};Date.prototype.setTimezoneOffset=function(s){var here=this.getTimezoneOffset(),there=Number(s)*-6/10;this.addMinutes(there-here);return this;};Date.prototype.setTimezone=function(s){return this.setTimezoneOffset(Date.getTimezoneOffset(s));};Date.prototype.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r[0]+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};Date.prototype.getDayName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedDayNames[this.getDay()]:Date.CultureInfo.dayNames[this.getDay()];};Date.prototype.getMonthName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedMonthNames[this.getMonth()]:Date.CultureInfo.monthNames[this.getMonth()];};Date.prototype._toString=Date.prototype.toString;Date.prototype.toString=function(format){var self=this;var p=function p(s){return(s.toString().length==1)?"0"+s:s;};return format?format.replace(/dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?/g,function(format){switch(format){case"hh":return p(self.getHours()<13?self.getHours():(self.getHours()-12));case"h":return self.getHours()<13?self.getHours():(self.getHours()-12);case"HH":return p(self.getHours());case"H":return self.getHours();case"mm":return p(self.getMinutes());case"m":return self.getMinutes();case"ss":return p(self.getSeconds());case"s":return self.getSeconds();case"yyyy":return self.getFullYear();case"yy":return self.getFullYear().toString().substring(2,4);case"dddd":return self.getDayName();case"ddd":return self.getDayName(true);case"dd":return p(self.getDate());case"d":return self.getDate().toString();case"MMMM":return self.getMonthName();case"MMM":return self.getMonthName(true);case"MM":return p((self.getMonth()+1));case"M":return self.getMonth()+1;case"t":return self.getHours()<12?Date.CultureInfo.amDesignator.substring(0,1):Date.CultureInfo.pmDesignator.substring(0,1);case"tt":return self.getHours()<12?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;case"zzz":case"zz":case"z":return"";}}):this._toString();};
Date.now=function(){return new Date();};Date.today=function(){return Date.now().clearTime();};Date.prototype._orient=+1;Date.prototype.next=function(){this._orient=+1;return this;};Date.prototype.last=Date.prototype.prev=Date.prototype.previous=function(){this._orient=-1;return this;};Date.prototype._is=false;Date.prototype.is=function(){this._is=true;return this;};Number.prototype._dateElement="day";Number.prototype.fromNow=function(){var c={};c[this._dateElement]=this;return Date.now().add(c);};Number.prototype.ago=function(){var c={};c[this._dateElement]=this*-1;return Date.now().add(c);};(function(){var $D=Date.prototype,$N=Number.prototype;var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),de;var df=function(n){return function(){if(this._is){this._is=false;return this.getDay()==n;}
return this.moveToDayOfWeek(n,this._orient);};};for(var i=0;i<dx.length;i++){$D[dx[i]]=$D[dx[i].substring(0,3)]=df(i);}
var mf=function(n){return function(){if(this._is){this._is=false;return this.getMonth()===n;}
return this.moveToMonth(n,this._orient);};};for(var j=0;j<mx.length;j++){$D[mx[j]]=$D[mx[j].substring(0,3)]=mf(j);}
var ef=function(j){return function(){if(j.substring(j.length-1)!="s"){j+="s";}
return this["add"+j](this._orient);};};var nf=function(n){return function(){this._dateElement=n;return this;};};for(var k=0;k<px.length;k++){de=px[k].toLowerCase();$D[de]=$D[de+"s"]=ef(px[k]);$N[de]=$N[de+"s"]=nf(de);}}());Date.prototype.toJSONString=function(){return this.toString("yyyy-MM-ddThh:mm:ssZ");};Date.prototype.toShortDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortDatePattern);};Date.prototype.toLongDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.longDatePattern);};Date.prototype.toShortTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortTimePattern);};Date.prototype.toLongTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.longTimePattern);};Date.prototype.getOrdinal=function(){switch(this.getDate()){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};
(function(){Date.Parsing={Exception:function(s){this.message="Parse error at '"+s.substring(0,10)+" ...'";}};var $P=Date.Parsing;var _=$P.Operators={rtoken:function(r){return function(s){var mx=s.match(r);if(mx){return([mx[0],s.substring(mx[0].length)]);}else{throw new $P.Exception(s);}};},token:function(s){return function(s){return _.rtoken(new RegExp("^\s*"+s+"\s*"))(s);};},stoken:function(s){return _.rtoken(new RegExp("^"+s));},until:function(p){return function(s){var qx=[],rx=null;while(s.length){try{rx=p.call(this,s);}catch(e){qx.push(rx[0]);s=rx[1];continue;}
break;}
return[qx,s];};},many:function(p){return function(s){var rx=[],r=null;while(s.length){try{r=p.call(this,s);}catch(e){return[rx,s];}
rx.push(r[0]);s=r[1];}
return[rx,s];};},optional:function(p){return function(s){var r=null;try{r=p.call(this,s);}catch(e){return[null,s];}
return[r[0],r[1]];};},not:function(p){return function(s){try{p.call(this,s);}catch(e){return[null,s];}
throw new $P.Exception(s);};},ignore:function(p){return p?function(s){var r=null;r=p.call(this,s);return[null,r[1]];}:null;},product:function(){var px=arguments[0],qx=Array.prototype.slice.call(arguments,1),rx=[];for(var i=0;i<px.length;i++){rx.push(_.each(px[i],qx));}
return rx;},cache:function(rule){var cache={},r=null;return function(s){try{r=cache[s]=(cache[s]||rule.call(this,s));}catch(e){r=cache[s]=e;}
if(r instanceof $P.Exception){throw r;}else{return r;}};},any:function(){var px=arguments;return function(s){var r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;}
try{r=(px[i].call(this,s));}catch(e){r=null;}
if(r){return r;}}
throw new $P.Exception(s);};},each:function(){var px=arguments;return function(s){var rx=[],r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;}
try{r=(px[i].call(this,s));}catch(e){throw new $P.Exception(s);}
rx.push(r[0]);s=r[1];}
return[rx,s];};},all:function(){var px=arguments,_=_;return _.each(_.optional(px));},sequence:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;if(px.length==1){return px[0];}
return function(s){var r=null,q=null;var rx=[];for(var i=0;i<px.length;i++){try{r=px[i].call(this,s);}catch(e){break;}
rx.push(r[0]);try{q=d.call(this,r[1]);}catch(ex){q=null;break;}
s=q[1];}
if(!r){throw new $P.Exception(s);}
if(q){throw new $P.Exception(q[1]);}
if(c){try{r=c.call(this,r[1]);}catch(ey){throw new $P.Exception(r[1]);}}
return[rx,(r?r[1]:s)];};},between:function(d1,p,d2){d2=d2||d1;var _fn=_.each(_.ignore(d1),p,_.ignore(d2));return function(s){var rx=_fn.call(this,s);return[[rx[0][0],r[0][2]],rx[1]];};},list:function(p,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return(p instanceof Array?_.each(_.product(p.slice(0,-1),_.ignore(d)),p.slice(-1),_.ignore(c)):_.each(_.many(_.each(p,_.ignore(d))),px,_.ignore(c)));},set:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return function(s){var r=null,p=null,q=null,rx=null,best=[[],s],last=false;for(var i=0;i<px.length;i++){q=null;p=null;r=null;last=(px.length==1);try{r=px[i].call(this,s);}catch(e){continue;}
rx=[[r[0]],r[1]];if(r[1].length>0&&!last){try{q=d.call(this,r[1]);}catch(ex){last=true;}}else{last=true;}
if(!last&&q[1].length===0){last=true;}
if(!last){var qx=[];for(var j=0;j<px.length;j++){if(i!=j){qx.push(px[j]);}}
p=_.set(qx,d).call(this,q[1]);if(p[0].length>0){rx[0]=rx[0].concat(p[0]);rx[1]=p[1];}}
if(rx[1].length<best[1].length){best=rx;}
if(best[1].length===0){break;}}
if(best[0].length===0){return best;}
if(c){try{q=c.call(this,best[1]);}catch(ey){throw new $P.Exception(best[1]);}
best[1]=q[1];}
return best;};},forward:function(gr,fname){return function(s){return gr[fname].call(this,s);};},replace:function(rule,repl){return function(s){var r=rule.call(this,s);return[repl,r[1]];};},process:function(rule,fn){return function(s){var r=rule.call(this,s);return[fn.call(this,r[0]),r[1]];};},min:function(min,rule){return function(s){var rx=rule.call(this,s);if(rx[0].length<min){throw new $P.Exception(s);}
return rx;};}};var _generator=function(op){return function(){var args=null,rx=[];if(arguments.length>1){args=Array.prototype.slice.call(arguments);}else if(arguments[0]instanceof Array){args=arguments[0];}
if(args){for(var i=0,px=args.shift();i<px.length;i++){args.unshift(px[i]);rx.push(op.apply(null,args));args.shift();return rx;}}else{return op.apply(null,arguments);}};};var gx="optional not ignore cache".split(/\s/);for(var i=0;i<gx.length;i++){_[gx[i]]=_generator(_[gx[i]]);}
var _vector=function(op){return function(){if(arguments[0]instanceof Array){return op.apply(null,arguments[0]);}else{return op.apply(null,arguments);}};};var vx="each any all".split(/\s/);for(var j=0;j<vx.length;j++){_[vx[j]]=_vector(_[vx[j]]);}}());(function(){var flattenAndCompact=function(ax){var rx=[];for(var i=0;i<ax.length;i++){if(ax[i]instanceof Array){rx=rx.concat(flattenAndCompact(ax[i]));}else{if(ax[i]){rx.push(ax[i]);}}}
return rx;};Date.Grammar={};Date.Translator={hour:function(s){return function(){this.hour=Number(s);};},minute:function(s){return function(){this.minute=Number(s);};},second:function(s){return function(){this.second=Number(s);};},meridian:function(s){return function(){this.meridian=s.slice(0,1).toLowerCase();};},timezone:function(s){return function(){var n=s.replace(/[^\d\+\-]/g,"");if(n.length){this.timezoneOffset=Number(n);}else{this.timezone=s.toLowerCase();}};},day:function(x){var s=x[0];return function(){this.day=Number(s.match(/\d+/)[0]);};},month:function(s){return function(){this.month=((s.length==3)?Date.getMonthNumberFromName(s):(Number(s)-1));};},year:function(s){return function(){var n=Number(s);this.year=((s.length>2)?n:(n+(((n+2000)<Date.CultureInfo.twoDigitYearMax)?2000:1900)));};},rday:function(s){return function(){switch(s){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0;this.now=true;break;}};},finishExact:function(x){x=(x instanceof Array)?x:[x];var now=new Date();this.year=now.getFullYear();this.month=now.getMonth();this.day=1;this.hour=0;this.minute=0;this.second=0;for(var i=0;i<x.length;i++){if(x[i]){x[i].call(this);}}
this.hour=(this.meridian=="p"&&this.hour<13)?this.hour+12:this.hour;if(this.day>Date.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");}
var r=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);if(this.timezone){r.set({timezone:this.timezone});}else if(this.timezoneOffset){r.set({timezoneOffset:this.timezoneOffset});}
return r;},finish:function(x){x=(x instanceof Array)?flattenAndCompact(x):[x];if(x.length===0){return null;}
for(var i=0;i<x.length;i++){if(typeof x[i]=="function"){x[i].call(this);}}
if(this.now){return new Date();}
var today=Date.today();var method=null;var expression=!!(this.days!=null||this.orient||this.operator);if(expression){var gap,mod,orient;orient=((this.orient=="past"||this.operator=="subtract")?-1:1);if(this.weekday){this.unit="day";gap=(Date.getDayNumberFromName(this.weekday)-today.getDay());mod=7;this.days=gap?((gap+(orient*mod))%mod):(orient*mod);}
if(this.month){this.unit="month";gap=(this.month-today.getMonth());mod=12;this.months=gap?((gap+(orient*mod))%mod):(orient*mod);this.month=null;}
if(!this.unit){this.unit="day";}
if(this[this.unit+"s"]==null||this.operator!=null){if(!this.value){this.value=1;}
if(this.unit=="week"){this.unit="day";this.value=this.value*7;}
this[this.unit+"s"]=this.value*orient;}
return today.add(this);}else{if(this.meridian&&this.hour){this.hour=(this.hour<13&&this.meridian=="p")?this.hour+12:this.hour;}
if(this.weekday&&!this.day){this.day=(today.addDays((Date.getDayNumberFromName(this.weekday)-today.getDay()))).getDate();}
if(this.month&&!this.day){this.day=1;}
return today.set(this);}}};var _=Date.Parsing.Operators,g=Date.Grammar,t=Date.Translator,_fn;g.datePartDelimiter=_.rtoken(/^([\s\-\.\,\/\x27]+)/);g.timePartDelimiter=_.stoken(":");g.whiteSpace=_.rtoken(/^\s*/);g.generalDelimiter=_.rtoken(/^(([\s\,]|at|on)+)/);var _C={};g.ctoken=function(keys){var fn=_C[keys];if(!fn){var c=Date.CultureInfo.regexPatterns;var kx=keys.split(/\s+/),px=[];for(var i=0;i<kx.length;i++){px.push(_.replace(_.rtoken(c[kx[i]]),kx[i]));}
fn=_C[keys]=_.any.apply(null,px);}
return fn;};g.ctoken2=function(key){return _.rtoken(Date.CultureInfo.regexPatterns[key]);};g.h=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),t.hour));g.hh=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/),t.hour));g.H=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),t.hour));g.HH=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/),t.hour));g.m=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.minute));g.mm=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.minute));g.s=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.second));g.ss=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.second));g.hms=_.cache(_.sequence([g.H,g.mm,g.ss],g.timePartDelimiter));g.t=_.cache(_.process(g.ctoken2("shortMeridian"),t.meridian));g.tt=_.cache(_.process(g.ctoken2("longMeridian"),t.meridian));g.z=_.cache(_.process(_.rtoken(/^(\+|\-)?\s*\d\d\d\d?/),t.timezone));g.zz=_.cache(_.process(_.rtoken(/^(\+|\-)\s*\d\d\d\d/),t.timezone));g.zzz=_.cache(_.process(g.ctoken2("timezone"),t.timezone));g.timeSuffix=_.each(_.ignore(g.whiteSpace),_.set([g.tt,g.zzz]));g.time=_.each(_.optional(_.ignore(_.stoken("T"))),g.hms,g.timeSuffix);g.d=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.dd=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.ddd=g.dddd=_.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"),function(s){return function(){this.weekday=s;};}));g.M=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/),t.month));g.MM=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/),t.month));g.MMM=g.MMMM=_.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),t.month));g.y=_.cache(_.process(_.rtoken(/^(\d\d?)/),t.year));g.yy=_.cache(_.process(_.rtoken(/^(\d\d)/),t.year));g.yyy=_.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/),t.year));g.yyyy=_.cache(_.process(_.rtoken(/^(\d\d\d\d)/),t.year));_fn=function(){return _.each(_.any.apply(null,arguments),_.not(g.ctoken2("timeContext")));};g.day=_fn(g.d,g.dd);g.month=_fn(g.M,g.MMM);g.year=_fn(g.yyyy,g.yy);g.orientation=_.process(g.ctoken("past future"),function(s){return function(){this.orient=s;};});g.operator=_.process(g.ctoken("add subtract"),function(s){return function(){this.operator=s;};});g.rday=_.process(g.ctoken("yesterday tomorrow today now"),t.rday);g.unit=_.process(g.ctoken("minute hour day week month year"),function(s){return function(){this.unit=s;};});g.value=_.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/),function(s){return function(){this.value=s.replace(/\D/g,"");};});g.expression=_.set([g.rday,g.operator,g.value,g.unit,g.orientation,g.ddd,g.MMM]);_fn=function(){return _.set(arguments,g.datePartDelimiter);};g.mdy=_fn(g.ddd,g.month,g.day,g.year);g.ymd=_fn(g.ddd,g.year,g.month,g.day);g.dmy=_fn(g.ddd,g.day,g.month,g.year);g.date=function(s){return((g[Date.CultureInfo.dateElementOrder]||g.mdy).call(this,s));};g.format=_.process(_.many(_.any(_.process(_.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(fmt){if(g[fmt]){return g[fmt];}else{throw Date.Parsing.Exception(fmt);}}),_.process(_.rtoken(/^[^dMyhHmstz]+/),function(s){return _.ignore(_.stoken(s));}))),function(rules){return _.process(_.each.apply(null,rules),t.finishExact);});var _F={};var _get=function(f){return _F[f]=(_F[f]||g.format(f)[0]);};g.formats=function(fx){if(fx instanceof Array){var rx=[];for(var i=0;i<fx.length;i++){rx.push(_get(fx[i]));}
return _.any.apply(null,rx);}else{return _get(fx);}};g._formats=g.formats(["yyyy-MM-ddTHH:mm:ss","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","d"]);g._start=_.process(_.set([g.date,g.time,g.expression],g.generalDelimiter,g.whiteSpace),t.finish);g.start=function(s){try{var r=g._formats.call({},s);if(r[1].length===0){return r;}}catch(e){}
return g._start.call({},s);};}());Date._parse=Date.parse;Date.parse=function(s){var r=null;if(!s){return null;}
try{r=Date.Grammar.start.call({},s);}catch(e){return null;}
return((r[1].length===0)?r[0]:null);};Date.getParseFunction=function(fx){var fn=Date.Grammar.formats(fx);return function(s){var r=null;try{r=fn.call({},s);}catch(e){return null;}
return((r[1].length===0)?r[0]:null);};};Date.parseExact=function(s,fx){return Date.getParseFunction(fx)(s);};

</script>
<script type="text/javascript">
var EDD = "";
function fillToday(){
	var t = Date.today().toString('yyyy-MM-dd');
	document.getElementById('CurrentDate').value = t;
}

function highlightEDD(){
x = document.getElementById('EDDtype').value;
	if (x == "LMP"){
		document.getElementById('EDDDatesRow').style.background = 'yellow';
		document.getElementById('EDDDatesRow').style.outline = ' thin solid black';
		document.getElementById('EDDUS1Row').style.background = 'white';
		document.getElementById('EDDUS1Row').style.outline = 'thin none black';
		document.getElementById('EDDUS2Row').style.background = 'white';
		document.getElementById('EDDUS2Row').style.outline = 'thin none black';
	} else if (x == "US1"){
		document.getElementById('EDDDatesRow').style.background = 'white';
		document.getElementById('EDDDatesRow').style.outline = ' thin none black';
		document.getElementById('EDDUS1Row').style.background = 'yellow';
		document.getElementById('EDDUS1Row').style.outline = 'thin solid black';
		document.getElementById('EDDUS2Row').style.background = 'white';
		document.getElementById('EDDUS2Row').style.outline = 'thin none black';

	} else if (x == "US2"){
		document.getElementById('EDDDatesRow').style.background = 'white';
		document.getElementById('EDDDatesRow').style.outline = ' thin none black';
		document.getElementById('EDDUS1Row').style.background = 'white';
		document.getElementById('EDDUS1Row').style.outline = 'thin none black';
		document.getElementById('EDDUS2Row').style.background = 'yellow';
		document.getElementById('EDDUS2Row').style.outline = 'thin solid black';
	}else{
		document.getElementById('EDDDatesRow').style.background = 'white';
		document.getElementById('EDDDatesRow').style.outline = ' thin none black';
		document.getElementById('EDDUS1Row').style.background = 'white';
		document.getElementById('EDDUS1Row').style.outline = 'thin none black';
		document.getElementById('EDDUS2Row').style.background = 'white';
		document.getElementById('EDDUS2Row').style.outline = 'thin none black';
	}
}

function calcEDD(){
	var d1 = Date.parse(document.getElementById('LMP').value);

	if (d1){
		var d1EDD = d1.clone().addWeeks(40);
		document.getElementById('EDDDates').value = d1EDD.toString('yyyy-MM-dd');
		
		if (!d2 && !d3){
			EDD = "LMP";
		}
	}
	var d2 = Date.parse(document.getElementById('US1Date').value);
	var d2Trimester = 0;
	if (d2){
		var US1Week = document.getElementById('US1Week').value;
			if (!US1Week){ US1Week = 0};
		var US1Day = document.getElementById('US1Day').value;
			if (!US1Day) {US1Day = 0};
		var d2DaysPassed = (parseInt(US1Week * 7)) + parseInt(US1Day);
			if (d2DaysPassed < (14 * 7)){
				d2Trimester = 1;
			}else if (d2DaysPassed >= (14 * 7)){
				d2Trimester = 2;
			}
		var d2DaysToEDD = 280 - d2DaysPassed;
		var d2EDD = d2.clone().add({days:d2DaysToEDD});
		document.getElementById('EDDUS1').value = d2EDD.toString('yyyy-MM-dd');
		
		if (!d1 && !d3){ 
			EDD = "US1";
		}
		if ((d1 && !d3)){
			var diff = Math.abs(d1EDD - d2EDD); //in milliseconds
			var diffDays =  diff/1000/60/60/24; // in days
			if (d2Trimester == 1){
				if (diffDays > 5){
						EDD = "US1";
				} else if (diffDays <=5){
						EDD = "LMP";
				}
			}else if (d2Trimester == 2){
				if (diffDays > 10){
						EDD = "US1";
					} else if (diffDays <=10){
						EDD = "LMP";
					}
			}
		}
		if (d3 && (d2<d3)){
			var diff = Math.abs(d1EDD - d2EDD); //in milliseconds
			var diffDays =  diff/1000/60/60/24; // in days
			if (d2Trimester == 1){
				if (diffDays > 5){
						EDD = "US1";
				} else if (diffDays <=5){
						EDD = "LMP";
				}
			}else if (d2Trimester == 2){
				if (diffDays > 10){
						EDD = "US1";
					} else if (diffDays <=10){
						EDD = "LMP";
					}
			}
		}
	}

	var d3 = Date.parse(document.getElementById('US2Date').value);
	var d3Trimester = 0;
	if (d3){
		var US2Week = document.getElementById('US2Week').value;
			if (!US2Week){ US2Week = 0};
		var US2Day = document.getElementById('US2Day').value;
			if (!US2Day) {US2Day = 0};
		var d3DaysPassed = (parseInt(US2Week)*7) + parseInt(US2Day);
			if (d3DaysPassed < (14 * 7)){
				d3Trimester = 1;
			}else if (d3DaysPassed >= (14 * 7)){
				d3Trimester = 2;
			}
		var d3DaysToEDD = 280 - d3DaysPassed;
		var d3EDD = d3.clone().add({days:d3DaysToEDD});
		document.getElementById('EDDUS2').value = d3EDD.toString('yyyy-MM-dd');

		if (!d1 && !d2){ 
			EDD = "US2";
		}
		if (d1 && !d2){
			var diff = Math.abs(d1EDD - d3EDD); //in milliseconds
			var diffDays =  diff/1000/60/60/24; // in days
			if (d3Trimester == 1){
				if (diffDays > 5){
						EDD = "US2";
				} else if (diffDays <=5){
						EDD = "LMP";
				}
			}else if (d3Trimester == 2){
				if (diffDays > 10){
						EDD = "US2";
					} else if (diffDays <=10){
						EDD = "LMP";
					}
			}
		}
		if (d2 && (d3<d2)){
			var diff = Math.abs(d1EDD - d3EDD); //in milliseconds
			var diffDays =  diff/1000/60/60/24; // in days
			if (d3Trimester == 1){
				if (diffDays > 5){
						EDD = "US2";
				} else if (diffDays <=5){
						EDD = "LMP";
				}
			}else if (d3Trimester == 2){
				if (diffDays > 10){
						EDD = "US2";
					} else if (diffDays <=10){
						EDD = "LMP";
					}
			}
		}
	}


	if (EDD == "LMP"){
		document.getElementById('EDDDate4').value = d1EDD.toString('yyyy-MM-dd');
	} 
        if (EDD == "US1"){
		document.getElementById('EDDDate4').value= d2EDD.toString('yyyy-MM-dd');
	} if (EDD== "US2"){
		document.getElementById('EDDDate4').value= d3EDD.toString('yyyy-MM-dd');
	}
	if (document.getElementById('LMP').value !== document.getElementById('LMPDate1').value){
		document.getElementById('LMPDate2').value = d1.toString('yyyy-MM-dd');
	} 
	if (document.getElementById('LMP').value == document.getElementById('LMPDate1').value){
		document.getElementById('LMPDate2').value = "";
	}

	var d5 = Date.parse(document.getElementById('EDDDate4').value);
	if (document.getElementById('EDDDate5').value !== document.getElementById('EDDDate4').value){
		document.getElementById('EDDDate6').value = d5.toString('yyyy-MM-dd');
	} 
	if (document.getElementById('EDDDate5').value == document.getElementById('EDDDate4').value){
		document.getElementById('EDDDate6').value = "";
	}


	document.getElementById('EDDtype').value = EDD;
	highlightEDD();
	fillGA();
}

function fillGA(){
	if (EDD == "LMP"){
		 var d2 = Date.parse(document.getElementById('EDDDates').value);  //use EDD by Dates
	}else if(EDD == "US1"){
		 var d2 = Date.parse(document.getElementById('EDDUS1').value);  //use EDD by 1st trimester US
	}else if(EDD == "US2"){
		 var d2 = Date.parse(document.getElementById('EDDUS2').value);  //use EDD by 2nd trimester US
	}

	for (w = 0; w <= 42; w++){
		var GAWeekLeft = parseInt(40 - w);
		var DateAtGA = d2.clone().addWeeks(-GAWeekLeft).toString('ddd, MMM dd, yy');
		var GAWeekInput = "Week" + w; 
		document.getElementById(GAWeekInput).value = DateAtGA;
	}
}


</script>
</head>

<body>
<form method="post" action="" name="FormName">

<div style="position: absolute; top: 10px; left: 10px;">
	<image src="${oscar_image_path}MaternityCareCalendar.png" width="750px" height="1000px">
</div>
<!-- You can remove ${oscar_image_path} as you develop the form, but make sure you put it back before uploading to OSCAR otherwise the image wouldn't show.
<!-- Also note: the image filename IS CASE SENSITIVE INCLUDING THE EXTENSION. It may work otherwise in Windows, but not in OSCAR because it's based on a Linux platform -->


<div style="position: absolute; top: 20px; left: 60px; width:120px">
	<p>Name:<input type="text" name="PatientName" id="PatientName" oscarDB=patient_name class="noborder"></p>
	<p>Today's Date(yyyy-mm-dd):<input type="text" name="CurrentDate" id="CurrentDate" class="noborder"></p>
	<p>LMP:<input type="text" name="LMP" id="LMP" oscarDB=m$LMP#value  class="noborder"></p>
	<P>1st ultrasound on
		<input type="text" name="US1Date" id="US1Date" class="noborder">:<br>
		<input type="text" name="US1Week" id="US1Week" style="width:20px;" value="0" class="noborder">Weeks<input type="text" name="US1Day" id="US1Day" style="width:20px;"  value="0" class="noborder">Days</p>
	<p>2nd ultrasound on
		<input type="text" name="US2Date" id="US2Date" class="noborder">:<br>
		<input type="text" name="US2Week" id="US2Week" style="width:20px;" value="0" class="noborder">Weeks<input type="text" name="US2Day" id="US2Day" style="width:20px;" value="0" class="noborder">Days</p>
	<p><input type="button" value="Calculate EDD" onClick="calcEDD();" class="DoNotPrint"></p>
	<p>The most accurate EDD, as per <a href="http://www.sogc.org/guidelines/documents/gui214CPG0809.pdf" target="_new">SOGC guidelines</a>, is highlighted below.</p>
		<table>
			<tr id="EDDDatesRow">
				<td><p>EDD by LMP:<input type="text" name="EDDDates" id="EDDDates" class="noborder"></p></td>
			</tr>
			<tr id="EDDUS1Row">
				<td><p>EDD by 1st US:<input type="text" name="EDDUS1" id="EDDUS1" class="noborder"></p></td>
			</tr>
			<tr id="EDDUS2Row">
				<td><p>EDD by 2nd US:<input type="text" name="EDDUS2" id="EDDUS2" class="noborder"></p></td>
			</tr>
			<input type="hidden" name="EDDtype" id="EDDtype">

<!--Measurement LMP-->
			<tr id="LMPDateTest1">
                                <td><input class="nodisplay" type="hidden" name="LMPDate1" id = "LMPDate1" oscarDB=m$LMP#value ></td>
			</tr>
<!--Output LMP-->
			<tr id="LMPDateTest2">
                                <td><input class="nodisplay" type="hidden" name="m$LMP#value" id = "LMPDate2"></td>
			</tr>
<!--Measurement EDD-->
			<tr id="EDDDateTest5">
                                <td><input class="nodisplay" type="hidden" name="EDDDate5" id = "EDDDate5" oscarDB=m$EDD#value></td>
			</tr>
<!--Calculated EDD-->
			<tr id="EDDDateTest4">
                                <td><input class="nodisplay" type="hidden" name="EDDDate4" id = "EDDDate4"></td>
			</tr>
<!-- Output EDD-->
			<tr id="EDDDateTest6">
                                <td><input class="nodisplay" type="hidden" name="m$EDD#value" id = "EDDDate6"></td>
			</tr>
		</table>
</div>


<input name="Week0" id="Week0" type="text" class="noborder" style="position:absolute; top:54px; left:327px; width:100px;" >
<input name="Week1" id="Week1" type="text" class="noborder" style="position:absolute; top:75px; left:327px; width:100px;" >
<input name="Week2" id="Week2" type="text" class="noborder" style="position:absolute; top:96px; left:327px; width:100px;" >
<input name="Week3" id="Week3" type="text" class="noborder" style="position:absolute; top:117px; left:327px; width:100px;">
<input name="Week4" id="Week4" type="text" class="noborder" style="position:absolute; top:138px; left:327px; width:100px;">
<input name="Week5" id="Week5" type="text" class="noborder" style="position:absolute; top:159px; left:327px; width:100px;">
<input name="Week6" id="Week6" type="text" class="noborder" style="position:absolute; top:180px; left:327px; width:100px;">
<input name="Week7" id="Week7" type="text" class="noborder" style="position:absolute; top:201px; left:327px; width:100px;">
<input name="Week8" id="Week8" type="text" class="noborder" style="position:absolute; top:222px; left:327px; width:100px;">
<input name="Week9" id="Week9" type="text" class="noborder" style="position:absolute; top:243px; left:327px; width:100px;">
<input name="Week10" id="Week10" type="text" class="noborder" style="position:absolute; top:264px; left:327px; width:100px;">
<input name="Week11" id="Week11" type="text" class="noborder" style="position:absolute; top:285px; left:327px; width:100px;">
<input name="Week12" id="Week12" type="text" class="noborder" style="position:absolute; top:306px; left:327px; width:100px;">
<input name="Week13" id="Week13" type="text" class="noborder" style="position:absolute; top:327px; left:327px; width:100px;">
<input name="Week14" id="Week14" type="text" class="noborder" style="position:absolute; top:348px; left:327px; width:100px;">
<input name="Week15" id="Week15" type="text" class="noborder" style="position:absolute; top:369px; left:327px; width:100px;">
<input name="Week16" id="Week16" type="text" class="noborder" style="position:absolute; top:390px; left:327px; width:100px;">
<input name="Week17" id="Week17" type="text" class="noborder" style="position:absolute; top:411px; left:327px; width:100px;">
<input name="Week18" id="Week18" type="text" class="noborder" style="position:absolute; top:432px; left:327px; width:100px;">
<input name="Week19" id="Week19" type="text" class="noborder" style="position:absolute; top:453px; left:327px; width:100px;">
<input name="Week20" id="Week20" type="text" class="noborder" style="position:absolute; top:474px; left:327px; width:100px;">
<input name="Week21" id="Week21" type="text" class="noborder" style="position:absolute; top:495px; left:327px; width:100px;">
<input name="Week22" id="Week22" type="text" class="noborder" style="position:absolute; top:516px; left:327px; width:100px;">
<input name="Week23" id="Week23" type="text" class="noborder" style="position:absolute; top:537px; left:327px; width:100px;">
<input name="Week24" id="Week24" type="text" class="noborder" style="position:absolute; top:558px; left:327px; width:100px;">
<input name="Week25" id="Week25" type="text" class="noborder" style="position:absolute; top:579px; left:327px; width:100px;">
<input name="Week26" id="Week26" type="text" class="noborder" style="position:absolute; top:600px; left:327px; width:100px;">
<input name="Week27" id="Week27" type="text" class="noborder" style="position:absolute; top:621px; left:327px; width:100px;">
<input name="Week28" id="Week28" type="text" class="noborder" style="position:absolute; top:642px; left:327px; width:100px;">
<input name="Week29" id="Week29" type="text" class="noborder" style="position:absolute; top:663px; left:327px; width:100px;">
<input name="Week30" id="Week30" type="text" class="noborder" style="position:absolute; top:684px; left:327px; width:100px;">
<input name="Week31" id="Week31" type="text" class="noborder" style="position:absolute; top:705px; left:327px; width:100px;">
<input name="Week32" id="Week32" type="text" class="noborder" style="position:absolute; top:726px; left:327px; width:100px;">
<input name="Week33" id="Week33" type="text" class="noborder" style="position:absolute; top:747px; left:327px; width:100px;">
<input name="Week34" id="Week34" type="text" class="noborder" style="position:absolute; top:768px; left:327px; width:100px;">
<input name="Week35" id="Week35" type="text" class="noborder" style="position:absolute; top:789px; left:327px; width:100px;">
<input name="Week36" id="Week36" type="text" class="noborder" style="position:absolute; top:810px; left:327px; width:100px;">
<input name="Week37" id="Week37" type="text" class="noborder" style="position:absolute; top:832px; left:327px; width:100px;">
<input name="Week38" id="Week38" type="text" class="noborder" style="position:absolute; top:853px; left:327px; width:100px;">
<input name="Week39" id="Week39" type="text" class="noborder" style="position:absolute; top:874px; left:327px; width:100px;">
<input name="Week40" id="Week40" type="text" class="noborder" style="position:absolute; top:895px; left:327px; width:100px;">
<input name="Week41" id="Week41" type="text" class="noborder" style="position:absolute; top:916px; left:327px; width:100px;">
<input name="Week42" id="Week42" type="text" class="noborder" style="position:absolute; top:937px; left:327px; width:100px;">

<!-- The submit/print/reset buttons ------------------------------------------------------------->
<div class="DoNotPrint" style="position:absolute; top:1000px;">
<table>
	<tr>
		<td>
			Subject: <input name="subject" size="40" type="text">
			<input value="Submit" name="B1" type="submit">
			<input value="Reset" name="B2" type="reset">
			<input value="Print" onclick="window.print()" type="button">
			<input value="Print and Submit" name="PrintSubmitButton" type="button" onClick="window.print(); document.FormName.submit()">
		</td>
	</tr>
</table>
</div>
</form>
<!-- ------End of submit/print/reset buttons----------------------------------------------------->
</body>
</html>
Document Actions
Help us support OSCAR!

 

Download button

DOWNLOAD OSCAR FOR TESTING

 

Demo Button

SEE OSCAR EMR IN ACTION


Subscribe Button

SUBSCRIBE TO DISCUSSION LIST

 (SEE ALL LISTS)

 Customize button

FIND PLUG-INS AND TWEAKS
FOR YOUR OSCAR EMR

 

 Join OCUS Button

 BECOME A MEMBER OF THE
OSCAR CANADA USERS SOCIETY
(OUR MISSION)

 

Help button

ACCESS THE ONLINE MANUALS
(OLD MANUALS)
(PAID SUPPORT)

 

Contact Us

Oscar Canada Users Society

#425 - 1917 West 4th Avenue

Vancouver  BC  V6J 1M7

OscarCanadaUserSociety@gmail.com