PageSourceSearch

https://www.mouzakipalace.com/app/themes/nelios-base/src/js/jquery…/1.13.0/ui/widgets/datepicker.js?ver=1.13.0

js mouzakipalace.com collected 2026-09-28 17:32:14 UTC 82,518 bytes, 2,240 lines download raw bytes

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

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.