PageSourceSearch

https://auburnlodge.com/js/datepicker.js

js auburnlodge.com collected 2026-09-29 21:51:04 UTC 77,831 bytes, 2,062 lines download raw bytes

vendor: 4,295 bytes, lines 1-78
1/* jQuery UI - v1.11.4 - http://jqueryui.com
2* Includes: datepicker.js
3* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
4
5(function( factory ) {
6	if ( typeof define === "function" && define.amd ) {
7		define([ "jquery" ], factory );
8	} else {
9		factory( jQuery );
10	}
11}
12 (function( $ ) {
13$.ui = $.ui || {};
14
15$.extend($.ui, { datepicker: { version: "1.11.4" } });
16var datepicker_instActive;
17function datepicker_getZindex( elem ) {
18	var position, value;
19	while ( elem.length && elem[ 0 ] !== document ) {
20		// Ignore z-index if position is set to a value where z-index is ignored by the browser
21		// This makes behavior of this function consistent across browsers
22		// WebKit always returns auto if the element is positioned
23		position = elem.css( "position" );
24		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
25			// IE returns 0 when zIndex is not specified
26			// other browsers return a string
27			// we ignore the case of nested elements with an explicit value of 0
28			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
29			value = parseInt( elem.css( "zIndex" ), 10 );
30			if ( !isNaN( value ) && value !== 0 ) {
31				return value;
32			}
33		}
34		elem = elem.parent();
35	}
36	return 0;
37}
38/* Date picker manager.
39   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
40   Settings for (groups of) date pickers are maintained in an instance object,
41   allowing multiple different settings on the same page. */
42function Datepicker() {
43	this._curInst = null; // The current instance in use
44	this._keyEvent = false; // If the last event was a key event
45	this._disabledInputs = []; // List of date picker inputs that have been disabled
46	this._datepickerShowing = false; // True if the popup picker is showing , false if not
47	this._inDialog = false; // True if showing within a "dialog", false if not
48	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
49	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
50	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
51	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
52	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
53	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
54	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
55	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
56	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
57	this.regional = []; // Available regional settings, indexed by language code
58	this.regional[""] = { // Default regional settings
59		closeText: "Done", // Display text for close link
60		prevText: "Prev", // Display text for previous month link
61		nextText: "Next", // Display text for next month link
62		currentText: "Today", // Display text for current month link
63		monthNames: ["January","February","March","April","May","June",
64			"July","August","September","October","November","December"], // Names of months for drop-down and formatting
65		monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
66		dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
67		dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
68		dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
69		weekHeader: "Wk", // Column header for week of the year
70		dateFormat: "mm/dd/yy", // See format options on parseDate
71		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
72		isRTL: false, // True if right-to-left language, false if left-to-right
73		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
74		yearSuffix: "" // Additional text to append to the year in the month headers
75	};
76	this._defaults = { // Global defaults for all the date picker instances
77		showOn: "focus", // "focus" for popup on focus,
78			// "button" for trigger button, or "both" for either
vendor: 3,673 bytes, lines 79-130
79		showAnim: "fadeIn", // Name of jQuery animation for popup
80		showOptions: {}, // Options for enhanced animations
81		defaultDate: null, // Used when field is blank: actual date,
82			// +/-number for offset from today, null for today
83		appendText: "", // Display text following the input box, e.g. showing the format
84		buttonText: "...", // Text for trigger button
85		buttonImage: "", // URL for trigger button image
86		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
87		hideIfNoPrevNext: false, // True to hide next/previous month links
88			// if not applicable, false to just disable them
89		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
90		gotoCurrent: false, // True if today link goes back to current selection instead
91		changeMonth: false, // True if month can be selected directly, false if only prev/next
92		changeYear: false, // True if year can be selected directly, false if only prev/next
93		yearRange: "c-10:c+10", // Range of years to display in drop-down,
94			// either relative to today's year (-nn:+nn), relative to currently displayed year
95			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
96		showOtherMonths: false, // True to show dates in other months, false to leave blank
97		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
98		showWeek: false, // True to show week of the year, false to not show it
99		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
100			// takes a Date and returns the number of the week for it
101		shortYearCutoff: "+10", // Short year values < this are in the current century,
102			// > this are in the previous century,
103			// string value starting with "+" for current year + value
104		minDate: null, // The earliest selectable date, or null for no limit
105		maxDate: null, // The latest selectable date, or null for no limit
106		duration: "fast", // Duration of display/closure
107		beforeShowDay: null, // Function that takes a date and returns an array with
108			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
109			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
110		beforeShow: null, // Function that takes an input field and
111			// returns a set of custom settings for the date picker
112		onSelect: null, // Define a callback function when a date is selected
113		onChangeMonthYear: null, // Define a callback function when the month or year is changed
114		onClose: null, // Define a callback function when the datepicker is closed
115		numberOfMonths: 1, // Number of months to show at a time
116		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
117		stepMonths: 1, // Number of months to step back/forward
118		stepBigMonths: 12, // Number of months to step back/forward for the big links
119		altField: "", // Selector for an alternate field to store selected dates into
120		altFormat: "", // The date format to use for the alternate field
121		constrainInput: true, // The input is constrained by the current date format
122		showButtonPanel: false, // True to show button panel, false to not show it
123		autoSize: false, // True to size the input for the date format, false to leave as is
124		disabled: false // The initial disabled state
125	};
126	$.extend(this._defaults, this.regional[""]);
127	this.regional.en = $.extend( true, {}, this.regional[ "" ]);
128	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
129	this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
130}
vendor: 15,589 bytes, lines 130-577
130
131$.extend(Datepicker.prototype, {
132	/* Class name added to elements to indicate already configured with a date picker. */
133	markerClassName: "hasDatepicker",
134
135	//Keep track of the maximum number of rows displayed (see #7043)
136	maxRows: 4,
137
138	// TODO rename to "widget" when switching to widget factory
139	_widgetDatepicker: function() {
140		return this.dpDiv;
141	},
142
143	/* Override the default settings for all instances of the date picker.
144	 * @param  settings  object - the new settings to use as defaults (anonymous object)
145	 * @return the manager object
146	 */
147	setDefaults: function(settings) {
148		datepicker_extendRemove(this._defaults, settings || {});
149		return this;
150	},
151
152	/* Attach the date picker to a jQuery selection.
153	 * @param  target	element - the target input field or division or span
154	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
155	 */
156	_attachDatepicker: function(target, settings) {
157		var nodeName, inline, inst;
158		nodeName = target.nodeName.toLowerCase();
159		inline = (nodeName === "div" || nodeName === "span");
160		if (!target.id) {
161			this.uuid += 1;
162			target.id = "dp" + this.uuid;
163		}
164		inst = this._newInst($(target), inline);
165		inst.settings = $.extend({}, settings || {});
166		if (nodeName === "input") {
167			this._connectDatepicker(target, inst);
168		} else if (inline) {
169			this._inlineDatepicker(target, inst);
170		}
171	},
172
173	/* Create a new instance object. */
174	_newInst: function(target, inline) {
175		var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
176		return {id: id, input: target, // associated target
177			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
178			drawMonth: 0, drawYear: 0, // month being drawn
179			inline: inline, // is datepicker inline or not
180			dpDiv: (!inline ? this.dpDiv : // presentation div
181			datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
182	},
183
184	/* Attach the date picker to an input field. */
185	_connectDatepicker: function(target, inst) {
186		var input = $(target);
187		inst.append = $([]);
188		inst.trigger = $([]);
189		if (input.hasClass(this.markerClassName)) {
190			return;
191		}
192		this._attachments(input, inst);
193		input.addClass(this.markerClassName).keydown(this._doKeyDown).
194			keypress(this._doKeyPress).keyup(this._doKeyUp);
195		this._autoSize(inst);
196		$.data(target, "datepicker", inst);
197		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
198		if( inst.settings.disabled ) {
199			this._disableDatepicker( target );
200		}
201	},
202
203	/* Make attachments based on settings. */
204	_attachments: function(input, inst) {
205		var showOn, buttonText, buttonImage,
206			appendText = this._get(inst, "appendText"),
207			isRTL = this._get(inst, "isRTL");
208
209		if (inst.append) {
210			inst.append.remove();
211		}
212		if (appendText) {
213			inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
214			input[isRTL ? "before" : "after"](inst.append);
215		}
216
217		input.unbind("focus", this._showDatepicker);
218
219		if (inst.trigger) {
220			inst.trigger.remove();
221		}
222
223		showOn = this._get(inst, "showOn");
224		if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
225			input.focus(this._showDatepicker);
226		}
227		if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
228			buttonText = this._get(inst, "buttonText");
229			buttonImage = this._get(inst, "buttonImage");
230			inst.trigger = $(this._get(inst, "buttonImageOnly") ?
231				$("<img/>").addClass(this._triggerClass).
232					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
233				$("<button type='button'></button>").addClass(this._triggerClass).
234					html(!buttonImage ? buttonText : $("<img/>").attr(
235					{ src:buttonImage, alt:buttonText, title:buttonText })));
236			input[isRTL ? "before" : "after"](inst.trigger);
237			inst.trigger.click(function() {
238				if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
239					$.datepicker._hideDatepicker();
240				} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
241					$.datepicker._hideDatepicker();
242					$.datepicker._showDatepicker(input[0]);
243				} else {
244					$.datepicker._showDatepicker(input[0]);
245				}
246				return false;
247			});
248		}
249	},
250
251	/* Apply the maximum length for the date format. */
252	_autoSize: function(inst) {
253		if (this._get(inst, "autoSize") && !inst.inline) {
254			var findMax, max, maxI, i,
255				date = new Date(2009, 12 - 1, 20), // Ensure double digits
256				dateFormat = this._get(inst, "dateFormat");
257
258			if (dateFormat.match(/[DM]/)) {
259				findMax = function(names) {
260					max = 0;
261					maxI = 0;
262					for (i = 0; i < names.length; i++) {
263						if (names[i].length > max) {
264							max = names[i].length;
265							maxI = i;
266						}
267					}
268					return maxI;
269				};
270				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
271					"monthNames" : "monthNamesShort"))));
272				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
273					"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
274			}
275			inst.input.attr("size", this._formatDate(inst, date).length);
276		}
277	},
278
279	/* Attach an inline date picker to a div. */
280	_inlineDatepicker: function(target, inst) {
281		var divSpan = $(target);
282		if (divSpan.hasClass(this.markerClassName)) {
283			return;
284		}
285		divSpan.addClass(this.markerClassName).append(inst.dpDiv);
286		$.data(target, "datepicker", inst);
287		this._setDate(inst, this._getDefaultDate(inst), true);
288		this._updateDatepicker(inst);
289		this._updateAlternate(inst);
290		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
291		if( inst.settings.disabled ) {
292			this._disableDatepicker( target );
293		}
294		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
295		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
296		inst.dpDiv.css( "display", "block" );
297	},
298
299	/* Pop-up the date picker in a "dialog" box.
300	 * @param  input element - ignored
301	 * @param  date	string or Date - the initial date to display
302	 * @param  onSelect  function - the function to call when a date is selected
303	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
304	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
305	 *					event - with x/y coordinates or
306	 *					leave empty for default (screen centre)
307	 * @return the manager object
308	 */
309	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
310		var id, browserWidth, browserHeight, scrollX, scrollY,
311			inst = this._dialogInst; // internal instance
312
313		if (!inst) {
314			this.uuid += 1;
315			id = "dp" + this.uuid;
316			this._dialogInput = $("<input type='text' id='" + id +
317				"' style='position: absolute; top: -100px; width: 0px;'/>");
318			this._dialogInput.keydown(this._doKeyDown);
319			$("body").append(this._dialogInput);
320			inst = this._dialogInst = this._newInst(this._dialogInput, false);
321			inst.settings = {};
322			$.data(this._dialogInput[0], "datepicker", inst);
323		}
324		datepicker_extendRemove(inst.settings, settings || {});
325		date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
326		this._dialogInput.val(date);
327
328		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
329		if (!this._pos) {
330			browserWidth = document.documentElement.clientWidth;
331			browserHeight = document.documentElement.clientHeight;
332			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
333			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
334			this._pos = // should use actual width/height below
335				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
336		}
337
338		// move input on screen for focus, but hidden behind dialog
339		this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
340		inst.settings.onSelect = onSelect;
341		this._inDialog = true;
342		this.dpDiv.addClass(this._dialogClass);
343		this._showDatepicker(this._dialogInput[0]);
344		if ($.blockUI) {
345			$.blockUI(this.dpDiv);
346		}
347		$.data(this._dialogInput[0], "datepicker", inst);
348		return this;
349	},
350
351	/* Detach a datepicker from its control.
352	 * @param  target	element - the target input field or division or span
353	 */
354	_destroyDatepicker: function(target) {
355		var nodeName,
356			$target = $(target),
357			inst = $.data(target, "datepicker");
358
359		if (!$target.hasClass(this.markerClassName)) {
360			return;
361		}
362
363		nodeName = target.nodeName.toLowerCase();
364		$.removeData(target, "datepicker");
365		if (nodeName === "input") {
366			inst.append.remove();
367			inst.trigger.remove();
368			$target.removeClass(this.markerClassName).
369				unbind("focus", this._showDatepicker).
370				unbind("keydown", this._doKeyDown).
371				unbind("keypress", this._doKeyPress).
372				unbind("keyup", this._doKeyUp);
373		} else if (nodeName === "div" || nodeName === "span") {
374			$target.removeClass(this.markerClassName).empty();
375		}
376
377		if ( datepicker_instActive === inst ) {
378			datepicker_instActive = null;
379		}
380	},
381
382	/* Enable the date picker to a jQuery selection.
383	 * @param  target	element - the target input field or division or span
384	 */
385	_enableDatepicker: function(target) {
386		var nodeName, inline,
387			$target = $(target),
388			inst = $.data(target, "datepicker");
389
390		if (!$target.hasClass(this.markerClassName)) {
391			return;
392		}
393
394		nodeName = target.nodeName.toLowerCase();
395		if (nodeName === "input") {
396			target.disabled = false;
397			inst.trigger.filter("button").
398				each(function() { this.disabled = false; }).end().
399				filter("img").css({opacity: "1.0", cursor: ""});
400		} else if (nodeName === "div" || nodeName === "span") {
401			inline = $target.children("." + this._inlineClass);
402			inline.children().removeClass("ui-state-disabled");
403			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
404				prop("disabled", false);
405		}
406		this._disabledInputs = $.map(this._disabledInputs,
407			function(value) { return (value === target ? null : value); }); // delete entry
408	},
409
410	/* Disable the date picker to a jQuery selection.
411	 * @param  target	element - the target input field or division or span
412	 */
413	_disableDatepicker: function(target) {
414		var nodeName, inline,
415			$target = $(target),
416			inst = $.data(target, "datepicker");
417
418		if (!$target.hasClass(this.markerClassName)) {
419			return;
420		}
421
422		nodeName = target.nodeName.toLowerCase();
423		if (nodeName === "input") {
424			target.disabled = true;
425			inst.trigger.filter("button").
426				each(function() { this.disabled = true; }).end().
427				filter("img").css({opacity: "0.5", cursor: "default"});
428		} else if (nodeName === "div" || nodeName === "span") {
429			inline = $target.children("." + this._inlineClass);
430			inline.children().addClass("ui-state-disabled");
431			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
432				prop("disabled", true);
433		}
434		this._disabledInputs = $.map(this._disabledInputs,
435			function(value) { return (value === target ? null : value); }); // delete entry
436		this._disabledInputs[this._disabledInputs.length] = target;
437	},
438
439	/* Is the first field in a jQuery collection disabled as a datepicker?
440	 * @param  target	element - the target input field or division or span
441	 * @return boolean - true if disabled, false if enabled
442	 */
443	_isDisabledDatepicker: function(target) {
444		if (!target) {
445			return false;
446		}
447		for (var i = 0; i < this._disabledInputs.length; i++) {
448			if (this._disabledInputs[i] === target) {
449				return true;
450			}
451		}
452		return false;
453	},
454
455	/* Retrieve the instance data for the target control.
456	 * @param  target  element - the target input field or division or span
457	 * @return  object - the associated instance data
458	 * @throws  error if a jQuery problem getting data
459	 */
460	_getInst: function(target) {
461		try {
462			return $.data(target, "datepicker");
463		}
464		catch (err) {
465			throw "Missing instance data for this datepicker";
466		}
467	},
468
469	/* Update or retrieve the settings for a date picker attached to an input field or division.
470	 * @param  target  element - the target input field or division or span
471	 * @param  name	object - the new settings to update or
472	 *				string - the name of the setting to change or retrieve,
473	 *				when retrieving also "all" for all instance settings or
474	 *				"defaults" for all global defaults
475	 * @param  value   any - the new value for the setting
476	 *				(omit if above is an object or to retrieve a value)
477	 */
478	_optionDatepicker: function(target, name, value) {
479		var settings, date, minDate, maxDate,
480			inst = this._getInst(target);
481
482		if (arguments.length === 2 && typeof name === "string") {
483			return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
484				(inst ? (name === "all" ? $.extend({}, inst.settings) :
485				this._get(inst, name)) : null));
486		}
487
488		settings = name || {};
489		if (typeof name === "string") {
490			settings = {};
491			settings[name] = value;
492		}
493
494		if (inst) {
495			if (this._curInst === inst) {
496				this._hideDatepicker();
497			}
498
499			date = this._getDateDatepicker(target, true);
500			minDate = this._getMinMaxDate(inst, "min");
501			maxDate = this._getMinMaxDate(inst, "max");
502			datepicker_extendRemove(inst.settings, settings);
503			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
504			if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
505				inst.settings.minDate = this._formatDate(inst, minDate);
506			}
507			if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
508				inst.settings.maxDate = this._formatDate(inst, maxDate);
509			}
510			if ( "disabled" in settings ) {
511				if ( settings.disabled ) {
512					this._disableDatepicker(target);
513				} else {
514					this._enableDatepicker(target);
515				}
516			}
517			this._attachments($(target), inst);
518			this._autoSize(inst);
519			this._setDate(inst, date);
520			this._updateAlternate(inst);
521			this._updateDatepicker(inst);
522		}
523	},
524
525	// change method deprecated
526	_changeDatepicker: function(target, name, value) {
527		this._optionDatepicker(target, name, value);
528	},
529
530	/* Redraw the date picker attached to an input field or division.
531	 * @param  target  element - the target input field or division or span
532	 */
533	_refreshDatepicker: function(target) {
534		var inst = this._getInst(target);
535		if (inst) {
536			this._updateDatepicker(inst);
537		}
538	},
539
540	/* Set the dates for a jQuery selection.
541	 * @param  target element - the target input field or division or span
542	 * @param  date	Date - the new date
543	 */
544	_setDateDatepicker: function(target, date) {
545		var inst = this._getInst(target);
546		if (inst) {
547			this._setDate(inst, date);
548			this._updateDatepicker(inst);
549			this._updateAlternate(inst);
550		}
551	},
552
553	/* Get the date(s) for the first entry in a jQuery selection.
554	 * @param  target element - the target input field or division or span
555	 * @param  noDefault boolean - true if no default date is to be used
556	 * @return Date - the current date
557	 */
558	_getDateDatepicker: function(target, noDefault) {
559		var inst = this._getInst(target);
560		if (inst && !inst.inline) {
561			this._setDateFromField(inst, noDefault);
562		}
563		return (inst ? this._getDate(inst) : null);
564	},
565
566	/* Handle keystrokes. */
567	_doKeyDown: function(event) {
568		var onSelect, dateStr, sel,
569			inst = $.datepicker._getInst(event.target),
570			handled = true,
571			isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
572
573		inst._keyEvent = true;
574		if ($.datepicker._datepickerShowing) {
575			switch (event.keyCode) {
576				case 9: $.datepicker._hideDatepicker();
577						handled = false;
vendor: 4,495 bytes, lines 578-701
578						break; // hide on tab out
579				case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
580									$.datepicker._currentClass + ")", inst.dpDiv);
581						if (sel[0]) {
582							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
583						}
584
585						onSelect = $.datepicker._get(inst, "onSelect");
586						if (onSelect) {
587							dateStr = $.datepicker._formatDate(inst);
588
589							// trigger custom callback
590							onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
591						} else {
592							$.datepicker._hideDatepicker();
593						}
594
595						return false; // don't submit the form
596				case 27: $.datepicker._hideDatepicker();
597						break; // hide on escape
598				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
599							-$.datepicker._get(inst, "stepBigMonths") :
600							-$.datepicker._get(inst, "stepMonths")), "M");
601						break; // previous month/year on page up/+ ctrl
602				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
603							+$.datepicker._get(inst, "stepBigMonths") :
604							+$.datepicker._get(inst, "stepMonths")), "M");
605						break; // next month/year on page down/+ ctrl
606				case 35: if (event.ctrlKey || event.metaKey) {
607							$.datepicker._clearDate(event.target);
608						}
609						handled = event.ctrlKey || event.metaKey;
610						break; // clear on ctrl or command +end
611				case 36: if (event.ctrlKey || event.metaKey) {
612							$.datepicker._gotoToday(event.target);
613						}
614						handled = event.ctrlKey || event.metaKey;
615						break; // current on ctrl or command +home
616				case 37: if (event.ctrlKey || event.metaKey) {
617							$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
618						}
619						handled = event.ctrlKey || event.metaKey;
620						// -1 day on ctrl or command +left
621						if (event.originalEvent.altKey) {
622							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
623								-$.datepicker._get(inst, "stepBigMonths") :
624								-$.datepicker._get(inst, "stepMonths")), "M");
625						}
626						// next month/year on alt +left on Mac
627						break;
628				case 38: if (event.ctrlKey || event.metaKey) {
629							$.datepicker._adjustDate(event.target, -7, "D");
630						}
631						handled = event.ctrlKey || event.metaKey;
632						break; // -1 week on ctrl or command +up
633				case 39: if (event.ctrlKey || event.metaKey) {
634							$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
635						}
636						handled = event.ctrlKey || event.metaKey;
637						// +1 day on ctrl or command +right
638						if (event.originalEvent.altKey) {
639							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
640								+$.datepicker._get(inst, "stepBigMonths") :
641								+$.datepicker._get(inst, "stepMonths")), "M");
642						}
643						// next month/year on alt +right
644						break;
645				case 40: if (event.ctrlKey || event.metaKey) {
646							$.datepicker._adjustDate(event.target, +7, "D");
647						}
648						handled = event.ctrlKey || event.metaKey;
649						break; // +1 week on ctrl or command +down
650				default: handled = false;
651			}
652		} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
653			$.datepicker._showDatepicker(this);
654		} else {
655			handled = false;
656		}
657
658		if (handled) {
659			event.preventDefault();
660			event.stopPropagation();
661		}
662	},
663
664	/* Filter entered characters - based on date format. */
665	_doKeyPress: function(event) {
666		var chars, chr,
667			inst = $.datepicker._getInst(event.target);
668
669		if ($.datepicker._get(inst, "constrainInput")) {
670			chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
671			chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
672			return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
673		}
674	},
675
676	/* Synchronise manual entry and field/alternate field. */
677	_doKeyUp: function(event) {
678		var date,
679			inst = $.datepicker._getInst(event.target);
680
681		if (inst.input.val() !== inst.lastVal) {
682			try {
683				date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
684					(inst.input ? inst.input.val() : null),
685					$.datepicker._getFormatConfig(inst));
686
687				if (date) { // only if valid
688					$.datepicker._setDateFromField(inst);
689					$.datepicker._updateAlternate(inst);
690					$.datepicker._updateDatepicker(inst);
691				}
692			}
693			catch (err) {
694			}
695		}
696		return true;
697	},
698
699	/* Pop-up the date picker for a given input field.
700	 * If false returned from beforeShow event handler do not show.
701	 * @param  input  element - the input field attached to the date picker or
vendor: 9,398 bytes, lines 702-976
702	 *					event - if triggered by focus
703	 */
704	_showDatepicker: function(input) {
705		input = input.target || input;
706		if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
707			input = $("input", input.parentNode)[0];
708		}
709
710		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
711			return;
712		}
713
714		var inst, beforeShow, beforeShowSettings, isFixed,
715			offset, showAnim, duration;
716
717		inst = $.datepicker._getInst(input);
718		if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
719			$.datepicker._curInst.dpDiv.stop(true, true);
720			if ( inst && $.datepicker._datepickerShowing ) {
721				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
722			}
723		}
724
725		beforeShow = $.datepicker._get(inst, "beforeShow");
726		beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
727		if(beforeShowSettings === false){
728			return;
729		}
730		datepicker_extendRemove(inst.settings, beforeShowSettings);
731
732		inst.lastVal = null;
733		$.datepicker._lastInput = input;
734		$.datepicker._setDateFromField(inst);
735
736		if ($.datepicker._inDialog) { // hide cursor
737			input.value = "";
738		}
739		if (!$.datepicker._pos) { // position below input
740			$.datepicker._pos = $.datepicker._findPos(input);
741			$.datepicker._pos[1] += input.offsetHeight; // add the height
742		}
743
744		isFixed = false;
745		$(input).parents().each(function() {
746			isFixed |= $(this).css("position") === "fixed";
747			return !isFixed;
748		});
749
750		offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
751		$.datepicker._pos = null;
752		//to avoid flashes on Firefox
753		inst.dpDiv.empty();
754		// determine sizing offscreen
755		inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
756		$.datepicker._updateDatepicker(inst);
757		// fix width for dynamic number of date pickers
758		// and adjust position before showing
759		offset = $.datepicker._checkOffset(inst, offset, isFixed);
760		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
761			"static" : (isFixed ? "fixed" : "absolute")), display: "none",
762			left: offset.left + "px", top: offset.top + "px"});
763
764		if (!inst.inline) {
765			showAnim = $.datepicker._get(inst, "showAnim");
766			duration = $.datepicker._get(inst, "duration");
767			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
768			$.datepicker._datepickerShowing = true;
769
770			if ( $.effects && $.effects.effect[ showAnim ] ) {
771				inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
772			} else {
773				inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
774			}
775
776			if ( $.datepicker._shouldFocusInput( inst ) ) {
777				inst.input.focus();
778			}
779
780			$.datepicker._curInst = inst;
781		}
782	},
783
784	/* Generate the date picker content. */
785	_updateDatepicker: function(inst) {
786		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
787		datepicker_instActive = inst; // for delegate hover events
788		inst.dpDiv.empty().append(this._generateHTML(inst));
789		this._attachHandlers(inst);
790
791		var origyearshtml,
792			numMonths = this._getNumberOfMonths(inst),
793			cols = numMonths[1],
794			width = 17,
795			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
796
797		if ( activeCell.length > 0 ) {
798			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
799		}
800
801		inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
802		if (cols > 1) {
803			inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
804		}
805		inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
806			"Class"]("ui-datepicker-multi");
807		inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
808			"Class"]("ui-datepicker-rtl");
809
810		if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
811			inst.input.focus();
812		}
813
814		// deffered render of the years select (to avoid flashes on Firefox)
815		if( inst.yearshtml ){
816			origyearshtml = inst.yearshtml;
817			setTimeout(function(){
818				//assure that inst.yearshtml didn't change.
819				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
820					inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
821				}
822				origyearshtml = inst.yearshtml = null;
823			}, 0);
824		}
825	},
826
827	// #6694 - don't focus the input if it's already focused
828	// this breaks the change event in IE
829	// Support: IE and jQuery <1.9
830	_shouldFocusInput: function( inst ) {
831		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
832	},
833
834	/* Check positioning to remain on screen. */
835	_checkOffset: function(inst, offset, isFixed) {
836		var dpWidth = inst.dpDiv.outerWidth(),
837			dpHeight = inst.dpDiv.outerHeight(),
838			inputWidth = inst.input ? inst.input.outerWidth() : 0,
839			inputHeight = inst.input ? inst.input.outerHeight() : 0,
840			viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
841			viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
842
843		offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
844		offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
845		offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
846
847		// now check if datepicker is showing outside window viewport - move to a better place if so.
848		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
849			Math.abs(offset.left + dpWidth - viewWidth) : 0);
850		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
851			Math.abs(dpHeight + inputHeight) : 0);
852
853		return offset;
854	},
855
856	/* Find an object's position on the screen. */
857	_findPos: function(obj) {
858		var position,
859			inst = this._getInst(obj),
860			isRTL = this._get(inst, "isRTL");
861
862		while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
863			obj = obj[isRTL ? "previousSibling" : "nextSibling"];
864		}
865
866		position = $(obj).offset();
867		return [position.left, position.top];
868	},
869
870	/* Hide the date picker from view.
871	 * @param  input  element - the input field attached to the date picker
872	 */
873	_hideDatepicker: function(input) {
874		var showAnim, duration, postProcess, onClose,
875			inst = this._curInst;
876
877		if (!inst || (input && inst !== $.data(input, "datepicker"))) {
878			return;
879		}
880
881		if (this._datepickerShowing) {
882			showAnim = this._get(inst, "showAnim");
883			duration = this._get(inst, "duration");
884			postProcess = function() {
885				$.datepicker._tidyDialog(inst);
886			};
887
888			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
889			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
890				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
891			} else {
892				inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
893					(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
894			}
895
896			if (!showAnim) {
897				postProcess();
898			}
899			this._datepickerShowing = false;
900
901			onClose = this._get(inst, "onClose");
902			if (onClose) {
903				onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
904			}
905
906			this._lastInput = null;
907			if (this._inDialog) {
908				this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
909				if ($.blockUI) {
910					$.unblockUI();
911					$("body").append(this.dpDiv);
912				}
913			}
914			this._inDialog = false;
915		}
916	},
917
918	/* Tidy up after a dialog display. */
919	_tidyDialog: function(inst) {
920		inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
921	},
922
923	/* Close date picker if clicked elsewhere. */
924	_checkExternalClick: function(event) {
925		if (!$.datepicker._curInst) {
926			return;
927		}
928
929		var $target = $(event.target),
930			inst = $.datepicker._getInst($target[0]);
931
932		if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
933				$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
934				!$target.hasClass($.datepicker.markerClassName) &&
935				!$target.closest("." + $.datepicker._triggerClass).length &&
936				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
937			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
938				$.datepicker._hideDatepicker();
939		}
940	},
941
942	/* Adjust one of the date sub-fields. */
943	_adjustDate: function(id, offset, period) {
944		var target = $(id),
945			inst = this._getInst(target[0]);
946
947		if (this._isDisabledDatepicker(target[0])) {
948			return;
949		}
950		this._adjustInstDate(inst, offset +
951			(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
952			period);
953		this._updateDatepicker(inst);
954	},
955
956	/* Action for current link. */
957	_gotoToday: function(id) {
958		var date,
959			target = $(id),
960			inst = this._getInst(target[0]);
961
962		if (this._get(inst, "gotoCurrent") && inst.currentDay) {
963			inst.selectedDay = inst.currentDay;
964			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
965			inst.drawYear = inst.selectedYear = inst.currentYear;
966		} else {
967			date = new Date();
968			inst.selectedDay = date.getDate();
969			inst.drawMonth = inst.selectedMonth = date.getMonth();
970			inst.drawYear = inst.selectedYear = date.getFullYear();
971		}
972		this._notifyChange(inst);
973		this._adjustDate(target);
974	},
975
976	/* Action for selecting a new month/year. */
vendor: 4,436 bytes, lines 977-1108
977	_selectMonthYear: function(id, select, period) {
978		var target = $(id),
979			inst = this._getInst(target[0]);
980
981		inst["selected" + (period === "M" ? "Month" : "Year")] =
982		inst["draw" + (period === "M" ? "Month" : "Year")] =
983			parseInt(select.options[select.selectedIndex].value,10);
984
985		this._notifyChange(inst);
986		this._adjustDate(target);
987	},
988
989	/* Action for selecting a day. */
990	_selectDay: function(id, month, year, td) {
991		var inst,
992			target = $(id);
993
994		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
995			return;
996		}
997
998		inst = this._getInst(target[0]);
999		inst.selectedDay = inst.currentDay = $("a", td).html();
1000		inst.selectedMonth = inst.currentMonth = month;
1001		inst.selectedYear = inst.currentYear = year;
1002		this._selectDate(id, this._formatDate(inst,
1003			inst.currentDay, inst.currentMonth, inst.currentYear));
1004	},
1005
1006	/* Erase the input field and hide the date picker. */
1007	_clearDate: function(id) {
1008		var target = $(id);
1009		this._selectDate(target, "");
1010	},
1011
1012	/* Update the input field with the selected date. */
1013	_selectDate: function(id, dateStr) {
1014		var onSelect,
1015			target = $(id),
1016			inst = this._getInst(target[0]);
1017
1018		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
1019		if (inst.input) {
1020			inst.input.val(dateStr);
1021		}
1022		this._updateAlternate(inst);
1023
1024		onSelect = this._get(inst, "onSelect");
1025		if (onSelect) {
1026			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
1027		} else if (inst.input) {
1028			inst.input.trigger("change"); // fire the change event
1029		}
1030
1031		if (inst.inline){
1032			this._updateDatepicker(inst);
1033		} else {
1034			this._hideDatepicker();
1035			this._lastInput = inst.input[0];
1036			if (typeof(inst.input[0]) !== "object") {
1037				inst.input.focus(); // restore focus
1038			}
1039			this._lastInput = null;
1040		}
1041	},
1042
1043	/* Update any alternate field to synchronise with the main field. */
1044	_updateAlternate: function(inst) {
1045		var altFormat, date, dateStr,
1046			altField = this._get(inst, "altField");
1047
1048		if (altField) { // update alternate field too
1049			altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
1050			date = this._getDate(inst);
1051			dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
1052			$(altField).each(function() { $(this).val(dateStr); });
1053		}
1054	},
1055
1056	/* Set as beforeShowDay function to prevent selection of weekends.
1057	 * @param  date  Date - the date to customise
1058	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
1059	 */
1060	noWeekends: function(date) {
1061		var day = date.getDay();
1062		return [(day > 0 && day < 6), ""];
1063	},
1064
1065	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
1066	 * @param  date  Date - the date to get the week for
1067	 * @return  number - the number of the week within the year that contains this date
1068	 */
1069	iso8601Week: function(date) {
1070		var time,
1071			checkDate = new Date(date.getTime());
1072
1073		// Find Thursday of this week starting on Monday
1074		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
1075
1076		time = checkDate.getTime();
1077		checkDate.setMonth(0); // Compare with Jan 1
1078		checkDate.setDate(1);
1079		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
1080	},
1081
1082	/* Parse a string value into a date object.
1083	 * See formatDate below for the possible formats.
1084	 *
1085	 * @param  format string - the expected format of the date
1086	 * @param  value string - the date in the above format
1087	 * @param  settings Object - attributes include:
1088	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
1089	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
1090	 *					dayNames		string[7] - names of the days from Sunday (optional)
1091	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
1092	 *					monthNames		string[12] - names of the months (optional)
1093	 * @return  Date - the extracted date value or null if value is blank
1094	 */
1095	parseDate: function (format, value, settings) {
1096		if (format == null || value == null) {
1097			throw "Invalid arguments";
1098		}
1099
1100		value = (typeof value === "object" ? value.toString() : value + "");
1101		if (value === "") {
1102			return null;
1103		}
1104
1105		var iFormat, dim, extra,
1106			iValue = 0,
1107			shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
1108			shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp 
vendor: 5,261 bytes, lines 1108-1294
1108:
1109				new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
1110			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
1111			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
1112			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
1113			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
1114			year = -1,
1115			month = -1,
1116			day = -1,
1117			doy = -1,
1118			literal = false,
1119			date,
1120			// Check whether a format character is doubled
1121			lookAhead = function(match) {
1122				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
1123				if (matches) {
1124					iFormat++;
1125				}
1126				return matches;
1127			},
1128			// Extract a number from the string value
1129			getNumber = function(match) {
1130				var isDoubled = lookAhead(match),
1131					size = (match === "@" ? 14 : (match === "!" ? 20 :
1132					(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
1133					minSize = (match === "y" ? size : 1),
1134					digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
1135					num = value.substring(iValue).match(digits);
1136				if (!num) {
1137					throw "Missing number at position " + iValue;
1138				}
1139				iValue += num[0].length;
1140				return parseInt(num[0], 10);
1141			},
1142			// Extract a name from the string value and convert to an index
1143			getName = function(match, shortNames, longNames) {
1144				var index = -1,
1145					names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
1146						return [ [k, v] ];
1147					}).sort(function (a, b) {
1148						return -(a[1].length - b[1].length);
1149					});
1150
1151				$.each(names, function (i, pair) {
1152					var name = pair[1];
1153					if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
1154						index = pair[0];
1155						iValue += name.length;
1156						return false;
1157					}
1158				});
1159				if (index !== -1) {
1160					return index + 1;
1161				} else {
1162					throw "Unknown name at position " + iValue;
1163				}
1164			},
1165			// Confirm that a literal character matches the string value
1166			checkLiteral = function() {
1167				if (value.charAt(iValue) !== format.charAt(iFormat)) {
1168					throw "Unexpected literal at position " + iValue;
1169				}
1170				iValue++;
1171			};
1172
1173		for (iFormat = 0; iFormat < format.length; iFormat++) {
1174			if (literal) {
1175				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
1176					literal = false;
1177				} else {
1178					checkLiteral();
1179				}
1180			} else {
1181				switch (format.charAt(iFormat)) {
1182					case "d":
1183						day = getNumber("d");
1184						break;
1185					case "D":
1186						getName("D", dayNamesShort, dayNames);
1187						break;
1188					case "o":
1189						doy = getNumber("o");
1190						break;
1191					case "m":
1192						month = getNumber("m");
1193						break;
1194					case "M":
1195						month = getName("M", monthNamesShort, monthNames);
1196						break;
1197					case "y":
1198						year = getNumber("y");
1199						break;
1200					case "@":
1201						date = new Date(getNumber("@"));
1202						year = date.getFullYear();
1203						month = date.getMonth() + 1;
1204						day = date.getDate();
1205						break;
1206					case "!":
1207						date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
1208						year = date.getFullYear();
1209						month = date.getMonth() + 1;
1210						day = date.getDate();
1211						break;
1212					case "'":
1213						if (lookAhead("'")){
1214							checkLiteral();
1215						} else {
1216							literal = true;
1217						}
1218						break;
1219					default:
1220						checkLiteral();
1221				}
1222			}
1223		}
1224
1225		if (iValue < value.length){
1226			extra = value.substr(iValue);
1227			if (!/^\s+/.test(extra)) {
1228				throw "Extra/unparsed characters found in date: " + extra;
1229			}
1230		}
1231
1232		if (year === -1) {
1233			year = new Date().getFullYear();
1234		} else if (year < 100) {
1235			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
1236				(year <= shortYearCutoff ? 0 : -100);
1237		}
1238
1239		if (doy > -1) {
1240			month = 1;
1241			day = doy;
1242			do {
1243				dim = this._getDaysInMonth(year, month - 1);
1244				if (day <= dim) {
1245					break;
1246				}
1247				month++;
1248				day -= dim;
1249			} while (true);
1250		}
1251
1252		date = this._daylightSavingAdjust(new Date(year, month - 1, day));
1253		if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
1254			throw "Invalid date"; // E.g. 31/02/00
1255		}
1256		return date;
1257	},
1258
1259	/* Standard date formats. */
1260	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
1261	COOKIE: "D, dd M yy",
1262	ISO_8601: "yy-mm-dd",
1263	RFC_822: "D, d M y",
1264	RFC_850: "DD, dd-M-y",
1265	RFC_1036: "D, d M y",
1266	RFC_1123: "D, d M yy",
1267	RFC_2822: "D, d M yy",
1268	RSS: "D, d M y", // RFC 822
1269	TICKS: "!",
1270	TIMESTAMP: "@",
1271	W3C: "yy-mm-dd", // ISO 8601
1272
1273	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
1274		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
1275
1276	/* Format a date object into a string value.
1277	 * The format can be combinations of the following:
1278	 * d  - day of month (no leading zero)
1279	 * dd - day of month (two digit)
1280	 * o  - day of year (no leading zeros)
1281	 * oo - day of year (three digit)
1282	 * D  - day name short
1283	 * DD - day name long
1284	 * m  - month of year (no leading zero)
1285	 * mm - month of year (two digit)
1286	 * M  - month name short
1287	 * MM - month name long
1288	 * y  - year (two digit)
1289	 * yy - year (four digit)
1290	 * @ - Unix timestamp (ms since 01/01/1970)
1291	 * ! - Windows ticks (100ns since 01/01/0001)
1292	 * "..." - literal text
1293	 * '' - single quote
1294	 *
vendor: 11,157 bytes, lines 1295-1628
1295	 * @param  format string - the desired format of the date
1296	 * @param  date Date - the date value to format
1297	 * @param  settings Object - attributes include:
1298	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
1299	 *					dayNames		string[7] - names of the days from Sunday (optional)
1300	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
1301	 *					monthNames		string[12] - names of the months (optional)
1302	 * @return  string - the date in the above format
1303	 */
1304	formatDate: function (format, date, settings) {
1305		if (!date) {
1306			return "";
1307		}
1308
1309		var iFormat,
1310			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
1311			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
1312			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
1313			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
1314			// Check whether a format character is doubled
1315			lookAhead = function(match) {
1316				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
1317				if (matches) {
1318					iFormat++;
1319				}
1320				return matches;
1321			},
1322			// Format a number, with leading zero if necessary
1323			formatNumber = function(match, value, len) {
1324				var num = "" + value;
1325				if (lookAhead(match)) {
1326					while (num.length < len) {
1327						num = "0" + num;
1328					}
1329				}
1330				return num;
1331			},
1332			// Format a name, short or long as requested
1333			formatName = function(match, value, shortNames, longNames) {
1334				return (lookAhead(match) ? longNames[value] : shortNames[value]);
1335			},
1336			output = "",
1337			literal = false;
1338
1339		if (date) {
1340			for (iFormat = 0; iFormat < format.length; iFormat++) {
1341				if (literal) {
1342					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
1343						literal = false;
1344					} else {
1345						output += format.charAt(iFormat);
1346					}
1347				} else {
1348					switch (format.charAt(iFormat)) {
1349						case "d":
1350							output += formatNumber("d", date.getDate(), 2);
1351							break;
1352						case "D":
1353							output += formatName("D", date.getDay(), dayNamesShort, dayNames);
1354							break;
1355						case "o":
1356							output += formatNumber("o",
1357								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
1358							break;
1359						case "m":
1360							output += formatNumber("m", date.getMonth() + 1, 2);
1361							break;
1362						case "M":
1363							output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
1364							break;
1365						case "y":
1366							output += (lookAhead("y") ? date.getFullYear() :
1367								(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
1368							break;
1369						case "@":
1370							output += date.getTime();
1371							break;
1372						case "!":
1373							output += date.getTime() * 10000 + this._ticksTo1970;
1374							break;
1375						case "'":
1376							if (lookAhead("'")) {
1377								output += "'";
1378							} else {
1379								literal = true;
1380							}
1381							break;
1382						default:
1383							output += format.charAt(iFormat);
1384					}
1385				}
1386			}
1387		}
1388		return output;
1389	},
1390
1391	/* Extract all possible characters from the date format. */
1392	_possibleChars: function (format) {
1393		var iFormat,
1394			chars = "",
1395			literal = false,
1396			// Check whether a format character is doubled
1397			lookAhead = function(match) {
1398				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
1399				if (matches) {
1400					iFormat++;
1401				}
1402				return matches;
1403			};
1404
1405		for (iFormat = 0; iFormat < format.length; iFormat++) {
1406			if (literal) {
1407				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
1408					literal = false;
1409				} else {
1410					chars += format.charAt(iFormat);
1411				}
1412			} else {
1413				switch (format.charAt(iFormat)) {
1414					case "d": case "m": case "y": case "@":
1415						chars += "0123456789";
1416						break;
1417					case "D": case "M":
1418						return null; // Accept anything
1419					case "'":
1420						if (lookAhead("'")) {
1421							chars += "'";
1422						} else {
1423							literal = true;
1424						}
1425						break;
1426					default:
1427						chars += format.charAt(iFormat);
1428				}
1429			}
1430		}
1431		return chars;
1432	},
1433
1434	/* Get a setting value, defaulting if necessary. */
1435	_get: function(inst, name) {
1436		return inst.settings[name] !== undefined ?
1437			inst.settings[name] : this._defaults[name];
1438	},
1439
1440	/* Parse existing date and initialise date picker. */
1441	_setDateFromField: function(inst, noDefault) {
1442		if (inst.input.val() === inst.lastVal) {
1443			return;
1444		}
1445
1446		var dateFormat = this._get(inst, "dateFormat"),
1447			dates = inst.lastVal = inst.input ? inst.input.val() : null,
1448			defaultDate = this._getDefaultDate(inst),
1449			date = defaultDate,
1450			settings = this._getFormatConfig(inst);
1451
1452		try {
1453			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
1454		} catch (event) {
1455			dates = (noDefault ? "" : dates);
1456		}
1457		inst.selectedDay = date.getDate();
1458		inst.drawMonth = inst.selectedMonth = date.getMonth();
1459		inst.drawYear = inst.selectedYear = date.getFullYear();
1460		inst.currentDay = (dates ? date.getDate() : 0);
1461		inst.currentMonth = (dates ? date.getMonth() : 0);
1462		inst.currentYear = (dates ? date.getFullYear() : 0);
1463		this._adjustInstDate(inst);
1464	},
1465
1466	/* Retrieve the default date shown on opening. */
1467	_getDefaultDate: function(inst) {
1468		return this._restrictMinMax(inst,
1469			this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
1470	},
1471
1472	/* A date may be specified as an exact value or a relative one. */
1473	_determineDate: function(inst, date, defaultDate) {
1474		var offsetNumeric = function(offset) {
1475				var date = new Date();
1476				date.setDate(date.getDate() + offset);
1477				return date;
1478			},
1479			offsetString = function(offset) {
1480				try {
1481					return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
1482						offset, $.datepicker._getFormatConfig(inst));
1483				}
1484				catch (e) {
1485					// Ignore
1486				}
1487
1488				var date = (offset.toLowerCase().match(/^c/) ?
1489					$.datepicker._getDate(inst) : null) || new Date(),
1490					year = date.getFullYear(),
1491					month = date.getMonth(),
1492					day = date.getDate(),
1493					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
1494					matches = pattern.exec(offset);
1495
1496				while (matches) {
1497					switch (matches[2] || "d") {
1498						case "d" : case "D" :
1499							day += parseInt(matches[1],10); break;
1500						case "w" : case "W" :
1501							day += parseInt(matches[1],10) * 7; break;
1502						case "m" : case "M" :
1503							month += parseInt(matches[1],10);
1504							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
1505							break;
1506						case "y": case "Y" :
1507							year += parseInt(matches[1],10);
1508							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
1509							break;
1510					}
1511					matches = pattern.exec(offset);
1512				}
1513				return new Date(year, month, day);
1514			},
1515			newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
1516				(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
1517
1518		newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
1519		if (newDate) {
1520			newDate.setHours(0);
1521			newDate.setMinutes(0);
1522			newDate.setSeconds(0);
1523			newDate.setMilliseconds(0);
1524		}
1525		return this._daylightSavingAdjust(newDate);
1526	},
1527
1528	/* Handle switch to/from daylight saving.
1529	 * Hours may be non-zero on daylight saving cut-over:
1530	 * > 12 when midnight changeover, but then cannot generate
1531	 * midnight datetime, so jump to 1AM, otherwise reset.
1532	 * @param  date  (Date) the date to check
1533	 * @return  (Date) the corrected date
1534	 */
1535	_daylightSavingAdjust: function(date) {
1536		if (!date) {
1537			return null;
1538		}
1539		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
1540		return date;
1541	},
1542
1543	/* Set the date(s) directly. */
1544	_setDate: function(inst, date, noChange) {
1545		var clear = !date,
1546			origMonth = inst.selectedMonth,
1547			origYear = inst.selectedYear,
1548			newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
1549
1550		inst.selectedDay = inst.currentDay = newDate.getDate();
1551		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
1552		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
1553		if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
1554			this._notifyChange(inst);
1555		}
1556		this._adjustInstDate(inst);
1557		if (inst.input) {
1558			inst.input.val(clear ? "" : this._formatDate(inst));
1559		}
1560	},
1561
1562	/* Retrieve the date(s) directly. */
1563	_getDate: function(inst) {
1564		var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
1565			this._daylightSavingAdjust(new Date(
1566			inst.currentYear, inst.currentMonth, inst.currentDay)));
1567			return startDate;
1568	},
1569
1570	/* Attach the onxxx handlers.  These are declared statically so
1571	 * they work with static code transformers like Caja.
1572	 */
1573	_attachHandlers: function(inst) {
1574		var stepMonths = this._get(inst, "stepMonths"),
1575			id = "#" + inst.id.replace( /\\\\/g, "\\" );
1576		inst.dpDiv.find("[data-handler]").map(function () {
1577			var handler = {
1578				prev: function () {
1579					$.datepicker._adjustDate(id, -stepMonths, "M");
1580				},
1581				next: function () {
1582					$.datepicker._adjustDate(id, +stepMonths, "M");
1583				},
1584				hide: function () {
1585					$.datepicker._hideDatepicker();
1586				},
1587				today: function () {
1588					$.datepicker._gotoToday(id);
1589				},
1590				selectDay: function () {
1591					$.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
1592					return false;
1593				},
1594				selectMonth: function () {
1595					$.datepicker._selectMonthYear(id, this, "M");
1596					return false;
1597				},
1598				selectYear: function () {
1599					$.datepicker._selectMonthYear(id, this, "Y");
1600					return false;
1601				}
1602			};
1603			$(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
1604		});
1605	},
1606
1607	/* Generate the HTML for the current state of the date picker. */
1608	_generateHTML: function(inst) {
1609		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
1610			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
1611			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
1612			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
1613			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
1614			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
1615			tempDate = new Date(),
1616			today = this._daylightSavingAdjust(
1617				new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
1618			isRTL = this._get(inst, "isRTL"),
1619			showButtonPanel = this._get(inst, "showButtonPanel"),
1620			hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
1621			navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
1622			numMonths = this._getNumberOfMonths(inst),
1623			showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
1624			stepMonths = this._get(inst, "stepMonths"),
1625			isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
1626			currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
1627				new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
1628			minDate = this._getMinMaxDate(inst, "min"),
vendor: 9,139 bytes, lines 1629-1787
1629			maxDate = this._getMinMaxDate(inst, "max"),
1630			drawMonth = inst.drawMonth - showCurrentAtPos,
1631			drawYear = inst.drawYear;
1632
1633		if (drawMonth < 0) {
1634			drawMonth += 12;
1635			drawYear--;
1636		}
1637		if (maxDate) {
1638			maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
1639				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
1640			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
1641			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
1642				drawMonth--;
1643				if (drawMonth < 0) {
1644					drawMonth = 11;
1645					drawYear--;
1646				}
1647			}
1648		}
1649		inst.drawMonth = drawMonth;
1650		inst.drawYear = drawYear;
1651
1652		prevText = this._get(inst, "prevText");
1653		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
1654			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
1655			this._getFormatConfig(inst)));
1656
1657		prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
1658			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
1659			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
1660			(hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
1661
1662		nextText = this._get(inst, "nextText");
1663		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
1664			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
1665			this._getFormatConfig(inst)));
1666
1667		next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
1668			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
1669			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
1670			(hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
1671
1672		currentText = this._get(inst, "currentText");
1673		gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
1674		currentText = (!navigationAsDateFormat ? currentText :
1675			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
1676
1677		controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
1678			this._get(inst, "closeText") + "</button>" : "");
1679
1680		buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
1681			(this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
1682			">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
1683
1684		firstDay = parseInt(this._get(inst, "firstDay"),10);
1685		firstDay = (isNaN(firstDay) ? 0 : firstDay);
1686
1687		showWeek = this._get(inst, "showWeek");
1688		dayNames = this._get(inst, "dayNames");
1689		dayNamesMin = this._get(inst, "dayNamesMin");
1690		monthNames = this._get(inst, "monthNames");
1691		monthNamesShort = this._get(inst, "monthNamesShort");
1692		beforeShowDay = this._get(inst, "beforeShowDay");
1693		showOtherMonths = this._get(inst, "showOtherMonths");
1694		selectOtherMonths = this._get(inst, "selectOtherMonths");
1695		defaultDate = this._getDefaultDate(inst);
1696		html = "";
1697		dow;
1698		for (row = 0; row < numMonths[0]; row++) {
1699			group = "";
1700			this.maxRows = 4;
1701			for (col = 0; col < numMonths[1]; col++) {
1702				selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
1703				cornerClass = " ui-corner-all";
1704				calender = "";
1705				if (isMultiMonth) {
1706					calender += "<div class='ui-datepicker-group";
1707					if (numMonths[1] > 1) {
1708						switch (col) {
1709							case 0: calender += " ui-datepicker-group-first";
1710								cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
1711							case numMonths[1]-1: calender += " ui-datepicker-group-last";
1712								cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
1713							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
1714						}
1715					}
1716					calender += "'>";
1717				}
1718				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
1719					(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
1720					(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
1721					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
1722					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
1723					"</div><table class='ui-datepicker-calendar'><thead>" +
1724					"<tr>";
1725				thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
1726				for (dow = 0; dow < 7; dow++) { // days of the week
1727					day = (dow + firstDay) % 7;
1728					thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
1729						"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
1730				}
1731				calender += thead + "</tr></thead><tbody>";
1732				daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
1733				if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
1734					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
1735				}
1736				leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
1737				curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
1738				numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
1739				this.maxRows = numRows;
1740				printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
1741				for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
1742					calender += "<tr>";
1743					tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
1744						this._get(inst, "calculateWeek")(printDate) + "</td>");
1745					for (dow = 0; dow < 7; dow++) { // create date picker days
1746						daySettings = (beforeShowDay ?
1747							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
1748						otherMonth = (printDate.getMonth() !== drawMonth);
1749						unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
1750							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
1751						tbody += "<td class='" +
1752							((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
1753							(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
1754							((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
1755							(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
1756							// or defaultDate is current printedDate and defaultDate is selectedDate
1757							" " + this._dayOverClass : "") + // highlight selected day
1758							(unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
1759							(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
1760							(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
1761							(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
1762							((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
1763							(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
1764							(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
1765							(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
1766							(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
1767							(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
1768							(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
1769							"' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
1770						printDate.setDate(printDate.getDate() + 1);
1771						printDate = this._daylightSavingAdjust(printDate);
1772					}
1773					calender += tbody + "</tr>";
1774				}
1775				drawMonth++;
1776				if (drawMonth > 11) {
1777					drawMonth = 0;
1778					drawYear++;
1779				}
1780				calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
1781							((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
1782				group += calender;
1783			}
1784			html += group;
1785		}
1786		html += buttonPanel;
1787		inst._keyEvent = false;
vendor: 7,206 bytes, lines 1788-1977
1788		return html;
1789	},
1790
1791	/* Generate the month and year header. */
1792	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
1793			secondary, monthNames, monthNamesShort) {
1794
1795		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
1796			changeMonth = this._get(inst, "changeMonth"),
1797			changeYear = this._get(inst, "changeYear"),
1798			showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
1799			html = "<div class='ui-datepicker-title'>",
1800			monthHtml = "";
1801
1802		// month selection
1803		if (secondary || !changeMonth) {
1804			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
1805		} else {
1806			inMinYear = (minDate && minDate.getFullYear() === drawYear);
1807			inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
1808			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
1809			for ( month = 0; month < 12; month++) {
1810				if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
1811					monthHtml += "<option value='" + month + "'" +
1812						(month === drawMonth ? " selected='selected'" : "") +
1813						">" + monthNamesShort[month] + "</option>";
1814				}
1815			}
1816			monthHtml += "</select>";
1817		}
1818
1819		if (!showMonthAfterYear) {
1820			html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
1821		}
1822
1823		// year selection
1824		if ( !inst.yearshtml ) {
1825			inst.yearshtml = "";
1826			if (secondary || !changeYear) {
1827				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
1828			} else {
1829				// determine range of years to display
1830				years = this._get(inst, "yearRange").split(":");
1831				thisYear = new Date().getFullYear();
1832				determineYear = function(value) {
1833					var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
1834						(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
1835						parseInt(value, 10)));
1836					return (isNaN(year) ? thisYear : year);
1837				};
1838				year = determineYear(years[0]);
1839				endYear = Math.max(year, determineYear(years[1] || ""));
1840				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
1841				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
1842				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
1843				for (; year <= endYear; year++) {
1844					inst.yearshtml += "<option value='" + year + "'" +
1845						(year === drawYear ? " selected='selected'" : "") +
1846						">" + year + "</option>";
1847				}
1848				inst.yearshtml += "</select>";
1849
1850				html += inst.yearshtml;
1851				inst.yearshtml = null;
1852			}
1853		}
1854
1855		html += this._get(inst, "yearSuffix");
1856		if (showMonthAfterYear) {
1857			html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
1858		}
1859		html += "</div>"; // Close datepicker_header
1860		return html;
1861	},
1862
1863	/* Adjust one of the date sub-fields. */
1864	_adjustInstDate: function(inst, offset, period) {
1865		var year = inst.drawYear + (period === "Y" ? offset : 0),
1866			month = inst.drawMonth + (period === "M" ? offset : 0),
1867			day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
1868			date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
1869
1870		inst.selectedDay = date.getDate();
1871		inst.drawMonth = inst.selectedMonth = date.getMonth();
1872		inst.drawYear = inst.selectedYear = date.getFullYear();
1873		if (period === "M" || period === "Y") {
1874			this._notifyChange(inst);
1875		}
1876	},
1877
1878	/* Ensure a date is within any min/max bounds. */
1879	_restrictMinMax: function(inst, date) {
1880		var minDate = this._getMinMaxDate(inst, "min"),
1881			maxDate = this._getMinMaxDate(inst, "max"),
1882			newDate = (minDate && date < minDate ? minDate : date);
1883		return (maxDate && newDate > maxDate ? maxDate : newDate);
1884	},
1885
1886	/* Notify change of month/year. */
1887	_notifyChange: function(inst) {
1888		var onChange = this._get(inst, "onChangeMonthYear");
1889		if (onChange) {
1890			onChange.apply((inst.input ? inst.input[0] : null),
1891				[inst.selectedYear, inst.selectedMonth + 1, inst]);
1892		}
1893	},
1894
1895	/* Determine the number of months to show. */
1896	_getNumberOfMonths: function(inst) {
1897		var numMonths = this._get(inst, "numberOfMonths");
1898		return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
1899	},
1900
1901	/* Determine the current maximum date - ensure no time components are set. */
1902	_getMinMaxDate: function(inst, minMax) {
1903		return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
1904	},
1905
1906	/* Find the number of days in a given month. */
1907	_getDaysInMonth: function(year, month) {
1908		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
1909	},
1910
1911	/* Find the day of the week of the first of a month. */
1912	_getFirstDayOfMonth: function(year, month) {
1913		return new Date(year, month, 1).getDay();
1914	},
1915
1916	/* Determines if we should allow a "next/prev" month display change. */
1917	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
1918		var numMonths = this._getNumberOfMonths(inst),
1919			date = this._daylightSavingAdjust(new Date(curYear,
1920			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
1921
1922		if (offset < 0) {
1923			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
1924		}
1925		return this._isInRange(inst, date);
1926	},
1927
1928	/* Is the given date in the accepted range? */
1929	_isInRange: function(inst, date) {
1930		var yearSplit, currentYear,
1931			minDate = this._getMinMaxDate(inst, "min"),
1932			maxDate = this._getMinMaxDate(inst, "max"),
1933			minYear = null,
1934			maxYear = null,
1935			years = this._get(inst, "yearRange");
1936			if (years){
1937				yearSplit = years.split(":");
1938				currentYear = new Date().getFullYear();
1939				minYear = parseInt(yearSplit[0], 10);
1940				maxYear = parseInt(yearSplit[1], 10);
1941				if ( yearSplit[0].match(/[+\-].*/) ) {
1942					minYear += currentYear;
1943				}
1944				if ( yearSplit[1].match(/[+\-].*/) ) {
1945					maxYear += currentYear;
1946				}
1947			}
1948
1949		return ((!minDate || date.getTime() >= minDate.getTime()) &&
1950			(!maxDate || date.getTime() <= maxDate.getTime()) &&
1951			(!minYear || date.getFullYear() >= minYear) &&
1952			(!maxYear || date.getFullYear() <= maxYear));
1953	},
1954
1955	/* Provide the configuration settings for formatting/parsing. */
1956	_getFormatConfig: function(inst) {
1957		var shortYearCutoff = this._get(inst, "shortYearCutoff");
1958		shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
1959			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
1960		return {shortYearCutoff: shortYearCutoff,
1961			dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
1962			monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
1963	},
1964
1965	/* Format the given date for display. */
1966	_formatDate: function(inst, day, month, year) {
1967		if (!day) {
1968			inst.currentDay = inst.selectedDay;
1969			inst.currentMonth = inst.selectedMonth;
1970			inst.currentYear = inst.selectedYear;
1971		}
1972		var date = (day ? (typeof day === "object" ? day :
1973			this._daylightSavingAdjust(new Date(year, month, day))) :
1974			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
1975		return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
1976	}
1977});
vendor: 3,071 bytes, lines 1977-2057
1977 
1978/*
1979 * Bind hover events for datepicker elements.
1980 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
1981 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
1982 */
1983function datepicker_bindHover(dpDiv) {
1984	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
1985	return dpDiv.delegate(selector, "mouseout", function() {
1986			$(this).removeClass("ui-state-hover");
1987			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
1988				$(this).removeClass("ui-datepicker-prev-hover");
1989			}
1990			if (this.className.indexOf("ui-datepicker-next") !== -1) {
1991				$(this).removeClass("ui-datepicker-next-hover");
1992			}
1993		})
1994		.delegate( selector, "mouseover", datepicker_handleMouseover );
1995}
1996function datepicker_handleMouseover() {
1997	if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
1998		$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
1999		$(this).addClass("ui-state-hover");
2000		if (this.className.indexOf("ui-datepicker-prev") !== -1) {
2001			$(this).addClass("ui-datepicker-prev-hover");
2002		}
2003		if (this.className.indexOf("ui-datepicker-next") !== -1) {
2004			$(this).addClass("ui-datepicker-next-hover");
2005		}
2006	}
2007}
2008/* jQuery extend now ignores nulls! */
2009function datepicker_extendRemove(target, props) {
2010	$.extend(target, props);
2011	for (var name in props) {
2012		if (props[name] == null) {
2013			target[name] = props[name];
2014		}
2015	}
2016	return target;
2017}
2018/* Invoke the datepicker functionality.
2019   @param  options  string - a command, optionally followed by additional parameters or
2020					Object - settings for attaching new datepicker functionality
2021   @return  jQuery object */
2022$.fn.datepicker = function(options){
2023
2024	/* Verify an empty collection wasn't passed - Fixes #6976 */
2025	if ( !this.length ) {
2026		return this;
2027	}
2028
2029	/* Initialise the date picker. */
2030	if (!$.datepicker.initialized) {
2031		$(document).mousedown($.datepicker._checkExternalClick);
2032		$.datepicker.initialized = true;
2033	}
2034
2035	/* Append datepicker main container to body if not exist. */
2036	if ($("#"+$.datepicker._mainDivId).length === 0) {
2037		$("body").append($.datepicker.dpDiv);
2038	}
2039
2040	var otherArgs = Array.prototype.slice.call(arguments, 1);
2041	if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
2042		return $.datepicker["_" + options + "Datepicker"].
2043			apply($.datepicker, [this[0]].concat(otherArgs));
2044	}
2045	if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
2046		return $.datepicker["_" + options + "Datepicker"].
2047			apply($.datepicker, [this[0]].concat(otherArgs));
2048	}
2049	return this.each(function() {
2050		typeof options === "string" ?
2051			$.datepicker["_" + options + "Datepicker"].
2052				apply($.datepicker, [this].concat(otherArgs)) :
2053			$.datepicker._attachDatepicker(this, options);
2054	});
2055};
2056$.datepicker = new Datepicker(); // singleton instance
2057$.datepicker.initialized = false;
2058$.datepicker.uuid = new Date().getTime();
2059$.datepicker.version = "1.11.4";
2060var datepicker = $.datepicker;
2061
2062}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.