PageSourceSearch

https://salakhospitality.com/assets/js/jquery-ui.datepicker.js

js salakhospitality.com collected 2026-10-08 06:28:57 UTC 77,017 bytes, 2,050 lines download raw bytes

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

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.