PageSourceSearch

https://www.doh.go.th/vendor/jquery-ui-1.12.1.offset.datepicker.min.js?ref=202602018

js doh.go.th collected 2026-09-24 09:46:26 UTC 85,022 bytes, 2,252 lines download raw bytes

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

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.