spree_delivery_options 2.1.5 → 2.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2687fc3ca83448a1dbbe09f2d3f1b699c0ccf466
4
- data.tar.gz: 4da57adfa9deadb80c321ada0d0c4369c0bef9a5
3
+ metadata.gz: 9a9aa72d507a7004357cfccc966fe519a24b6998
4
+ data.tar.gz: 73b694b94bd0665d3363e58e7d03be0b3a21140e
5
5
  SHA512:
6
- metadata.gz: 3800bdad3b2642aa0136e29a7c90b1bb1687d2b46c3ba0440803b922d29d7093a84be3ba1f7204683c8cc34025f8f50401e255bb7ce5a7baba80a44ac27a5b76
7
- data.tar.gz: 0d82f9a28fef33050f4ae2227da85d646fd26d7b630e922aa0416748a7a5666644946642b917e516aaae836c1d6758915b91db1776e6b208f22484f9c9d64615
6
+ metadata.gz: 8169208d9eede00f9d63f99055e7814bd98d98eb21819ec177889bd9988987ba957c56e41b88965f79d242a83f62f546949ba407093a4977c5fc0b5a192d2560
7
+ data.tar.gz: 48a995653a6a5d06964134c8d5f7944dbcea9daac1c722c31a6714a2617e134171e066b1b30513b7389b6709a5c6944bc16cbacfcd95f6f125ecbeedcb91c99a
@@ -2,6 +2,10 @@ function SpreeDeliveryOptions() {
2
2
 
3
3
  var that = this;
4
4
 
5
+ this.initializeDatePicker = function() {
6
+ $('#order_delivery_date').datepicker({dateFormat: "dd/mm/yy"});
7
+ };
8
+
5
9
  this.initializeDeliveryTimeSelect = function() {
6
10
  this.update_delivery_time_options();
7
11
 
@@ -15,7 +19,8 @@ function SpreeDeliveryOptions() {
15
19
 
16
20
  if (delivery_time_options){
17
21
  weekdays = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
18
- day_index = new Date($('#order_delivery_date').val()).getDay();
22
+ var dateParts = $('#order_delivery_date').val().split('/')
23
+ day_index = new Date(dateParts[2], dateParts[1]-1, dateParts[0]).getDay();
19
24
  weekday = weekdays[day_index];
20
25
 
21
26
  day_options = delivery_time_options[weekday];
@@ -40,5 +45,6 @@ function SpreeDeliveryOptions() {
40
45
 
41
46
  $(document).ready(function() {
42
47
  var deliveryOptions = new SpreeDeliveryOptions();
48
+ deliveryOptions.initializeDatePicker();
43
49
  deliveryOptions.initializeDeliveryTimeSelect();
44
50
  });
@@ -0,0 +1,3498 @@
1
+ /*! jQuery UI - v1.10.4 - 2014-01-24
2
+ * http://jqueryui.com
3
+ * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.datepicker.js
4
+ * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5
+
6
+ (function( $, undefined ) {
7
+
8
+ var uuid = 0,
9
+ runiqueId = /^ui-id-\d+$/;
10
+
11
+ // $.ui might exist from components with no dependencies, e.g., $.ui.position
12
+ $.ui = $.ui || {};
13
+
14
+ $.extend( $.ui, {
15
+ version: "1.10.4",
16
+
17
+ keyCode: {
18
+ BACKSPACE: 8,
19
+ COMMA: 188,
20
+ DELETE: 46,
21
+ DOWN: 40,
22
+ END: 35,
23
+ ENTER: 13,
24
+ ESCAPE: 27,
25
+ HOME: 36,
26
+ LEFT: 37,
27
+ NUMPAD_ADD: 107,
28
+ NUMPAD_DECIMAL: 110,
29
+ NUMPAD_DIVIDE: 111,
30
+ NUMPAD_ENTER: 108,
31
+ NUMPAD_MULTIPLY: 106,
32
+ NUMPAD_SUBTRACT: 109,
33
+ PAGE_DOWN: 34,
34
+ PAGE_UP: 33,
35
+ PERIOD: 190,
36
+ RIGHT: 39,
37
+ SPACE: 32,
38
+ TAB: 9,
39
+ UP: 38
40
+ }
41
+ });
42
+
43
+ // plugins
44
+ $.fn.extend({
45
+ focus: (function( orig ) {
46
+ return function( delay, fn ) {
47
+ return typeof delay === "number" ?
48
+ this.each(function() {
49
+ var elem = this;
50
+ setTimeout(function() {
51
+ $( elem ).focus();
52
+ if ( fn ) {
53
+ fn.call( elem );
54
+ }
55
+ }, delay );
56
+ }) :
57
+ orig.apply( this, arguments );
58
+ };
59
+ })( $.fn.focus ),
60
+
61
+ scrollParent: function() {
62
+ var scrollParent;
63
+ if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
64
+ scrollParent = this.parents().filter(function() {
65
+ return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
66
+ }).eq(0);
67
+ } else {
68
+ scrollParent = this.parents().filter(function() {
69
+ return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
70
+ }).eq(0);
71
+ }
72
+
73
+ return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
74
+ },
75
+
76
+ zIndex: function( zIndex ) {
77
+ if ( zIndex !== undefined ) {
78
+ return this.css( "zIndex", zIndex );
79
+ }
80
+
81
+ if ( this.length ) {
82
+ var elem = $( this[ 0 ] ), position, value;
83
+ while ( elem.length && elem[ 0 ] !== document ) {
84
+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
85
+ // This makes behavior of this function consistent across browsers
86
+ // WebKit always returns auto if the element is positioned
87
+ position = elem.css( "position" );
88
+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
89
+ // IE returns 0 when zIndex is not specified
90
+ // other browsers return a string
91
+ // we ignore the case of nested elements with an explicit value of 0
92
+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
93
+ value = parseInt( elem.css( "zIndex" ), 10 );
94
+ if ( !isNaN( value ) && value !== 0 ) {
95
+ return value;
96
+ }
97
+ }
98
+ elem = elem.parent();
99
+ }
100
+ }
101
+
102
+ return 0;
103
+ },
104
+
105
+ uniqueId: function() {
106
+ return this.each(function() {
107
+ if ( !this.id ) {
108
+ this.id = "ui-id-" + (++uuid);
109
+ }
110
+ });
111
+ },
112
+
113
+ removeUniqueId: function() {
114
+ return this.each(function() {
115
+ if ( runiqueId.test( this.id ) ) {
116
+ $( this ).removeAttr( "id" );
117
+ }
118
+ });
119
+ }
120
+ });
121
+
122
+ // selectors
123
+ function focusable( element, isTabIndexNotNaN ) {
124
+ var map, mapName, img,
125
+ nodeName = element.nodeName.toLowerCase();
126
+ if ( "area" === nodeName ) {
127
+ map = element.parentNode;
128
+ mapName = map.name;
129
+ if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
130
+ return false;
131
+ }
132
+ img = $( "img[usemap=#" + mapName + "]" )[0];
133
+ return !!img && visible( img );
134
+ }
135
+ return ( /input|select|textarea|button|object/.test( nodeName ) ?
136
+ !element.disabled :
137
+ "a" === nodeName ?
138
+ element.href || isTabIndexNotNaN :
139
+ isTabIndexNotNaN) &&
140
+ // the element and all of its ancestors must be visible
141
+ visible( element );
142
+ }
143
+
144
+ function visible( element ) {
145
+ return $.expr.filters.visible( element ) &&
146
+ !$( element ).parents().addBack().filter(function() {
147
+ return $.css( this, "visibility" ) === "hidden";
148
+ }).length;
149
+ }
150
+
151
+ $.extend( $.expr[ ":" ], {
152
+ data: $.expr.createPseudo ?
153
+ $.expr.createPseudo(function( dataName ) {
154
+ return function( elem ) {
155
+ return !!$.data( elem, dataName );
156
+ };
157
+ }) :
158
+ // support: jQuery <1.8
159
+ function( elem, i, match ) {
160
+ return !!$.data( elem, match[ 3 ] );
161
+ },
162
+
163
+ focusable: function( element ) {
164
+ return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
165
+ },
166
+
167
+ tabbable: function( element ) {
168
+ var tabIndex = $.attr( element, "tabindex" ),
169
+ isTabIndexNaN = isNaN( tabIndex );
170
+ return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
171
+ }
172
+ });
173
+
174
+ // support: jQuery <1.8
175
+ if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
176
+ $.each( [ "Width", "Height" ], function( i, name ) {
177
+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
178
+ type = name.toLowerCase(),
179
+ orig = {
180
+ innerWidth: $.fn.innerWidth,
181
+ innerHeight: $.fn.innerHeight,
182
+ outerWidth: $.fn.outerWidth,
183
+ outerHeight: $.fn.outerHeight
184
+ };
185
+
186
+ function reduce( elem, size, border, margin ) {
187
+ $.each( side, function() {
188
+ size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
189
+ if ( border ) {
190
+ size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
191
+ }
192
+ if ( margin ) {
193
+ size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
194
+ }
195
+ });
196
+ return size;
197
+ }
198
+
199
+ $.fn[ "inner" + name ] = function( size ) {
200
+ if ( size === undefined ) {
201
+ return orig[ "inner" + name ].call( this );
202
+ }
203
+
204
+ return this.each(function() {
205
+ $( this ).css( type, reduce( this, size ) + "px" );
206
+ });
207
+ };
208
+
209
+ $.fn[ "outer" + name] = function( size, margin ) {
210
+ if ( typeof size !== "number" ) {
211
+ return orig[ "outer" + name ].call( this, size );
212
+ }
213
+
214
+ return this.each(function() {
215
+ $( this).css( type, reduce( this, size, true, margin ) + "px" );
216
+ });
217
+ };
218
+ });
219
+ }
220
+
221
+ // support: jQuery <1.8
222
+ if ( !$.fn.addBack ) {
223
+ $.fn.addBack = function( selector ) {
224
+ return this.add( selector == null ?
225
+ this.prevObject : this.prevObject.filter( selector )
226
+ );
227
+ };
228
+ }
229
+
230
+ // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
231
+ if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
232
+ $.fn.removeData = (function( removeData ) {
233
+ return function( key ) {
234
+ if ( arguments.length ) {
235
+ return removeData.call( this, $.camelCase( key ) );
236
+ } else {
237
+ return removeData.call( this );
238
+ }
239
+ };
240
+ })( $.fn.removeData );
241
+ }
242
+
243
+
244
+
245
+
246
+
247
+ // deprecated
248
+ $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
249
+
250
+ $.support.selectstart = "onselectstart" in document.createElement( "div" );
251
+ $.fn.extend({
252
+ disableSelection: function() {
253
+ return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
254
+ ".ui-disableSelection", function( event ) {
255
+ event.preventDefault();
256
+ });
257
+ },
258
+
259
+ enableSelection: function() {
260
+ return this.unbind( ".ui-disableSelection" );
261
+ }
262
+ });
263
+
264
+ $.extend( $.ui, {
265
+ // $.ui.plugin is deprecated. Use $.widget() extensions instead.
266
+ plugin: {
267
+ add: function( module, option, set ) {
268
+ var i,
269
+ proto = $.ui[ module ].prototype;
270
+ for ( i in set ) {
271
+ proto.plugins[ i ] = proto.plugins[ i ] || [];
272
+ proto.plugins[ i ].push( [ option, set[ i ] ] );
273
+ }
274
+ },
275
+ call: function( instance, name, args ) {
276
+ var i,
277
+ set = instance.plugins[ name ];
278
+ if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
279
+ return;
280
+ }
281
+
282
+ for ( i = 0; i < set.length; i++ ) {
283
+ if ( instance.options[ set[ i ][ 0 ] ] ) {
284
+ set[ i ][ 1 ].apply( instance.element, args );
285
+ }
286
+ }
287
+ }
288
+ },
289
+
290
+ // only used by resizable
291
+ hasScroll: function( el, a ) {
292
+
293
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
294
+ if ( $( el ).css( "overflow" ) === "hidden") {
295
+ return false;
296
+ }
297
+
298
+ var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
299
+ has = false;
300
+
301
+ if ( el[ scroll ] > 0 ) {
302
+ return true;
303
+ }
304
+
305
+ // TODO: determine which cases actually cause this to happen
306
+ // if the element doesn't have the scroll set, see if it's possible to
307
+ // set the scroll
308
+ el[ scroll ] = 1;
309
+ has = ( el[ scroll ] > 0 );
310
+ el[ scroll ] = 0;
311
+ return has;
312
+ }
313
+ });
314
+
315
+ })( jQuery );
316
+ (function( $, undefined ) {
317
+
318
+ var uuid = 0,
319
+ slice = Array.prototype.slice,
320
+ _cleanData = $.cleanData;
321
+ $.cleanData = function( elems ) {
322
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
323
+ try {
324
+ $( elem ).triggerHandler( "remove" );
325
+ // http://bugs.jquery.com/ticket/8235
326
+ } catch( e ) {}
327
+ }
328
+ _cleanData( elems );
329
+ };
330
+
331
+ $.widget = function( name, base, prototype ) {
332
+ var fullName, existingConstructor, constructor, basePrototype,
333
+ // proxiedPrototype allows the provided prototype to remain unmodified
334
+ // so that it can be used as a mixin for multiple widgets (#8876)
335
+ proxiedPrototype = {},
336
+ namespace = name.split( "." )[ 0 ];
337
+
338
+ name = name.split( "." )[ 1 ];
339
+ fullName = namespace + "-" + name;
340
+
341
+ if ( !prototype ) {
342
+ prototype = base;
343
+ base = $.Widget;
344
+ }
345
+
346
+ // create selector for plugin
347
+ $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
348
+ return !!$.data( elem, fullName );
349
+ };
350
+
351
+ $[ namespace ] = $[ namespace ] || {};
352
+ existingConstructor = $[ namespace ][ name ];
353
+ constructor = $[ namespace ][ name ] = function( options, element ) {
354
+ // allow instantiation without "new" keyword
355
+ if ( !this._createWidget ) {
356
+ return new constructor( options, element );
357
+ }
358
+
359
+ // allow instantiation without initializing for simple inheritance
360
+ // must use "new" keyword (the code above always passes args)
361
+ if ( arguments.length ) {
362
+ this._createWidget( options, element );
363
+ }
364
+ };
365
+ // extend with the existing constructor to carry over any static properties
366
+ $.extend( constructor, existingConstructor, {
367
+ version: prototype.version,
368
+ // copy the object used to create the prototype in case we need to
369
+ // redefine the widget later
370
+ _proto: $.extend( {}, prototype ),
371
+ // track widgets that inherit from this widget in case this widget is
372
+ // redefined after a widget inherits from it
373
+ _childConstructors: []
374
+ });
375
+
376
+ basePrototype = new base();
377
+ // we need to make the options hash a property directly on the new instance
378
+ // otherwise we'll modify the options hash on the prototype that we're
379
+ // inheriting from
380
+ basePrototype.options = $.widget.extend( {}, basePrototype.options );
381
+ $.each( prototype, function( prop, value ) {
382
+ if ( !$.isFunction( value ) ) {
383
+ proxiedPrototype[ prop ] = value;
384
+ return;
385
+ }
386
+ proxiedPrototype[ prop ] = (function() {
387
+ var _super = function() {
388
+ return base.prototype[ prop ].apply( this, arguments );
389
+ },
390
+ _superApply = function( args ) {
391
+ return base.prototype[ prop ].apply( this, args );
392
+ };
393
+ return function() {
394
+ var __super = this._super,
395
+ __superApply = this._superApply,
396
+ returnValue;
397
+
398
+ this._super = _super;
399
+ this._superApply = _superApply;
400
+
401
+ returnValue = value.apply( this, arguments );
402
+
403
+ this._super = __super;
404
+ this._superApply = __superApply;
405
+
406
+ return returnValue;
407
+ };
408
+ })();
409
+ });
410
+ constructor.prototype = $.widget.extend( basePrototype, {
411
+ // TODO: remove support for widgetEventPrefix
412
+ // always use the name + a colon as the prefix, e.g., draggable:start
413
+ // don't prefix for widgets that aren't DOM-based
414
+ widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
415
+ }, proxiedPrototype, {
416
+ constructor: constructor,
417
+ namespace: namespace,
418
+ widgetName: name,
419
+ widgetFullName: fullName
420
+ });
421
+
422
+ // If this widget is being redefined then we need to find all widgets that
423
+ // are inheriting from it and redefine all of them so that they inherit from
424
+ // the new version of this widget. We're essentially trying to replace one
425
+ // level in the prototype chain.
426
+ if ( existingConstructor ) {
427
+ $.each( existingConstructor._childConstructors, function( i, child ) {
428
+ var childPrototype = child.prototype;
429
+
430
+ // redefine the child widget using the same prototype that was
431
+ // originally used, but inherit from the new version of the base
432
+ $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
433
+ });
434
+ // remove the list of existing child constructors from the old constructor
435
+ // so the old child constructors can be garbage collected
436
+ delete existingConstructor._childConstructors;
437
+ } else {
438
+ base._childConstructors.push( constructor );
439
+ }
440
+
441
+ $.widget.bridge( name, constructor );
442
+ };
443
+
444
+ $.widget.extend = function( target ) {
445
+ var input = slice.call( arguments, 1 ),
446
+ inputIndex = 0,
447
+ inputLength = input.length,
448
+ key,
449
+ value;
450
+ for ( ; inputIndex < inputLength; inputIndex++ ) {
451
+ for ( key in input[ inputIndex ] ) {
452
+ value = input[ inputIndex ][ key ];
453
+ if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
454
+ // Clone objects
455
+ if ( $.isPlainObject( value ) ) {
456
+ target[ key ] = $.isPlainObject( target[ key ] ) ?
457
+ $.widget.extend( {}, target[ key ], value ) :
458
+ // Don't extend strings, arrays, etc. with objects
459
+ $.widget.extend( {}, value );
460
+ // Copy everything else by reference
461
+ } else {
462
+ target[ key ] = value;
463
+ }
464
+ }
465
+ }
466
+ }
467
+ return target;
468
+ };
469
+
470
+ $.widget.bridge = function( name, object ) {
471
+ var fullName = object.prototype.widgetFullName || name;
472
+ $.fn[ name ] = function( options ) {
473
+ var isMethodCall = typeof options === "string",
474
+ args = slice.call( arguments, 1 ),
475
+ returnValue = this;
476
+
477
+ // allow multiple hashes to be passed on init
478
+ options = !isMethodCall && args.length ?
479
+ $.widget.extend.apply( null, [ options ].concat(args) ) :
480
+ options;
481
+
482
+ if ( isMethodCall ) {
483
+ this.each(function() {
484
+ var methodValue,
485
+ instance = $.data( this, fullName );
486
+ if ( !instance ) {
487
+ return $.error( "cannot call methods on " + name + " prior to initialization; " +
488
+ "attempted to call method '" + options + "'" );
489
+ }
490
+ if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
491
+ return $.error( "no such method '" + options + "' for " + name + " widget instance" );
492
+ }
493
+ methodValue = instance[ options ].apply( instance, args );
494
+ if ( methodValue !== instance && methodValue !== undefined ) {
495
+ returnValue = methodValue && methodValue.jquery ?
496
+ returnValue.pushStack( methodValue.get() ) :
497
+ methodValue;
498
+ return false;
499
+ }
500
+ });
501
+ } else {
502
+ this.each(function() {
503
+ var instance = $.data( this, fullName );
504
+ if ( instance ) {
505
+ instance.option( options || {} )._init();
506
+ } else {
507
+ $.data( this, fullName, new object( options, this ) );
508
+ }
509
+ });
510
+ }
511
+
512
+ return returnValue;
513
+ };
514
+ };
515
+
516
+ $.Widget = function( /* options, element */ ) {};
517
+ $.Widget._childConstructors = [];
518
+
519
+ $.Widget.prototype = {
520
+ widgetName: "widget",
521
+ widgetEventPrefix: "",
522
+ defaultElement: "<div>",
523
+ options: {
524
+ disabled: false,
525
+
526
+ // callbacks
527
+ create: null
528
+ },
529
+ _createWidget: function( options, element ) {
530
+ element = $( element || this.defaultElement || this )[ 0 ];
531
+ this.element = $( element );
532
+ this.uuid = uuid++;
533
+ this.eventNamespace = "." + this.widgetName + this.uuid;
534
+ this.options = $.widget.extend( {},
535
+ this.options,
536
+ this._getCreateOptions(),
537
+ options );
538
+
539
+ this.bindings = $();
540
+ this.hoverable = $();
541
+ this.focusable = $();
542
+
543
+ if ( element !== this ) {
544
+ $.data( element, this.widgetFullName, this );
545
+ this._on( true, this.element, {
546
+ remove: function( event ) {
547
+ if ( event.target === element ) {
548
+ this.destroy();
549
+ }
550
+ }
551
+ });
552
+ this.document = $( element.style ?
553
+ // element within the document
554
+ element.ownerDocument :
555
+ // element is window or document
556
+ element.document || element );
557
+ this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
558
+ }
559
+
560
+ this._create();
561
+ this._trigger( "create", null, this._getCreateEventData() );
562
+ this._init();
563
+ },
564
+ _getCreateOptions: $.noop,
565
+ _getCreateEventData: $.noop,
566
+ _create: $.noop,
567
+ _init: $.noop,
568
+
569
+ destroy: function() {
570
+ this._destroy();
571
+ // we can probably remove the unbind calls in 2.0
572
+ // all event bindings should go through this._on()
573
+ this.element
574
+ .unbind( this.eventNamespace )
575
+ // 1.9 BC for #7810
576
+ // TODO remove dual storage
577
+ .removeData( this.widgetName )
578
+ .removeData( this.widgetFullName )
579
+ // support: jquery <1.6.3
580
+ // http://bugs.jquery.com/ticket/9413
581
+ .removeData( $.camelCase( this.widgetFullName ) );
582
+ this.widget()
583
+ .unbind( this.eventNamespace )
584
+ .removeAttr( "aria-disabled" )
585
+ .removeClass(
586
+ this.widgetFullName + "-disabled " +
587
+ "ui-state-disabled" );
588
+
589
+ // clean up events and states
590
+ this.bindings.unbind( this.eventNamespace );
591
+ this.hoverable.removeClass( "ui-state-hover" );
592
+ this.focusable.removeClass( "ui-state-focus" );
593
+ },
594
+ _destroy: $.noop,
595
+
596
+ widget: function() {
597
+ return this.element;
598
+ },
599
+
600
+ option: function( key, value ) {
601
+ var options = key,
602
+ parts,
603
+ curOption,
604
+ i;
605
+
606
+ if ( arguments.length === 0 ) {
607
+ // don't return a reference to the internal hash
608
+ return $.widget.extend( {}, this.options );
609
+ }
610
+
611
+ if ( typeof key === "string" ) {
612
+ // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
613
+ options = {};
614
+ parts = key.split( "." );
615
+ key = parts.shift();
616
+ if ( parts.length ) {
617
+ curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
618
+ for ( i = 0; i < parts.length - 1; i++ ) {
619
+ curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
620
+ curOption = curOption[ parts[ i ] ];
621
+ }
622
+ key = parts.pop();
623
+ if ( arguments.length === 1 ) {
624
+ return curOption[ key ] === undefined ? null : curOption[ key ];
625
+ }
626
+ curOption[ key ] = value;
627
+ } else {
628
+ if ( arguments.length === 1 ) {
629
+ return this.options[ key ] === undefined ? null : this.options[ key ];
630
+ }
631
+ options[ key ] = value;
632
+ }
633
+ }
634
+
635
+ this._setOptions( options );
636
+
637
+ return this;
638
+ },
639
+ _setOptions: function( options ) {
640
+ var key;
641
+
642
+ for ( key in options ) {
643
+ this._setOption( key, options[ key ] );
644
+ }
645
+
646
+ return this;
647
+ },
648
+ _setOption: function( key, value ) {
649
+ this.options[ key ] = value;
650
+
651
+ if ( key === "disabled" ) {
652
+ this.widget()
653
+ .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
654
+ .attr( "aria-disabled", value );
655
+ this.hoverable.removeClass( "ui-state-hover" );
656
+ this.focusable.removeClass( "ui-state-focus" );
657
+ }
658
+
659
+ return this;
660
+ },
661
+
662
+ enable: function() {
663
+ return this._setOption( "disabled", false );
664
+ },
665
+ disable: function() {
666
+ return this._setOption( "disabled", true );
667
+ },
668
+
669
+ _on: function( suppressDisabledCheck, element, handlers ) {
670
+ var delegateElement,
671
+ instance = this;
672
+
673
+ // no suppressDisabledCheck flag, shuffle arguments
674
+ if ( typeof suppressDisabledCheck !== "boolean" ) {
675
+ handlers = element;
676
+ element = suppressDisabledCheck;
677
+ suppressDisabledCheck = false;
678
+ }
679
+
680
+ // no element argument, shuffle and use this.element
681
+ if ( !handlers ) {
682
+ handlers = element;
683
+ element = this.element;
684
+ delegateElement = this.widget();
685
+ } else {
686
+ // accept selectors, DOM elements
687
+ element = delegateElement = $( element );
688
+ this.bindings = this.bindings.add( element );
689
+ }
690
+
691
+ $.each( handlers, function( event, handler ) {
692
+ function handlerProxy() {
693
+ // allow widgets to customize the disabled handling
694
+ // - disabled as an array instead of boolean
695
+ // - disabled class as method for disabling individual parts
696
+ if ( !suppressDisabledCheck &&
697
+ ( instance.options.disabled === true ||
698
+ $( this ).hasClass( "ui-state-disabled" ) ) ) {
699
+ return;
700
+ }
701
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
702
+ .apply( instance, arguments );
703
+ }
704
+
705
+ // copy the guid so direct unbinding works
706
+ if ( typeof handler !== "string" ) {
707
+ handlerProxy.guid = handler.guid =
708
+ handler.guid || handlerProxy.guid || $.guid++;
709
+ }
710
+
711
+ var match = event.match( /^(\w+)\s*(.*)$/ ),
712
+ eventName = match[1] + instance.eventNamespace,
713
+ selector = match[2];
714
+ if ( selector ) {
715
+ delegateElement.delegate( selector, eventName, handlerProxy );
716
+ } else {
717
+ element.bind( eventName, handlerProxy );
718
+ }
719
+ });
720
+ },
721
+
722
+ _off: function( element, eventName ) {
723
+ eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
724
+ element.unbind( eventName ).undelegate( eventName );
725
+ },
726
+
727
+ _delay: function( handler, delay ) {
728
+ function handlerProxy() {
729
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
730
+ .apply( instance, arguments );
731
+ }
732
+ var instance = this;
733
+ return setTimeout( handlerProxy, delay || 0 );
734
+ },
735
+
736
+ _hoverable: function( element ) {
737
+ this.hoverable = this.hoverable.add( element );
738
+ this._on( element, {
739
+ mouseenter: function( event ) {
740
+ $( event.currentTarget ).addClass( "ui-state-hover" );
741
+ },
742
+ mouseleave: function( event ) {
743
+ $( event.currentTarget ).removeClass( "ui-state-hover" );
744
+ }
745
+ });
746
+ },
747
+
748
+ _focusable: function( element ) {
749
+ this.focusable = this.focusable.add( element );
750
+ this._on( element, {
751
+ focusin: function( event ) {
752
+ $( event.currentTarget ).addClass( "ui-state-focus" );
753
+ },
754
+ focusout: function( event ) {
755
+ $( event.currentTarget ).removeClass( "ui-state-focus" );
756
+ }
757
+ });
758
+ },
759
+
760
+ _trigger: function( type, event, data ) {
761
+ var prop, orig,
762
+ callback = this.options[ type ];
763
+
764
+ data = data || {};
765
+ event = $.Event( event );
766
+ event.type = ( type === this.widgetEventPrefix ?
767
+ type :
768
+ this.widgetEventPrefix + type ).toLowerCase();
769
+ // the original event may come from any element
770
+ // so we need to reset the target on the new event
771
+ event.target = this.element[ 0 ];
772
+
773
+ // copy original event properties over to the new event
774
+ orig = event.originalEvent;
775
+ if ( orig ) {
776
+ for ( prop in orig ) {
777
+ if ( !( prop in event ) ) {
778
+ event[ prop ] = orig[ prop ];
779
+ }
780
+ }
781
+ }
782
+
783
+ this.element.trigger( event, data );
784
+ return !( $.isFunction( callback ) &&
785
+ callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
786
+ event.isDefaultPrevented() );
787
+ }
788
+ };
789
+
790
+ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
791
+ $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
792
+ if ( typeof options === "string" ) {
793
+ options = { effect: options };
794
+ }
795
+ var hasOptions,
796
+ effectName = !options ?
797
+ method :
798
+ options === true || typeof options === "number" ?
799
+ defaultEffect :
800
+ options.effect || defaultEffect;
801
+ options = options || {};
802
+ if ( typeof options === "number" ) {
803
+ options = { duration: options };
804
+ }
805
+ hasOptions = !$.isEmptyObject( options );
806
+ options.complete = callback;
807
+ if ( options.delay ) {
808
+ element.delay( options.delay );
809
+ }
810
+ if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
811
+ element[ method ]( options );
812
+ } else if ( effectName !== method && element[ effectName ] ) {
813
+ element[ effectName ]( options.duration, options.easing, callback );
814
+ } else {
815
+ element.queue(function( next ) {
816
+ $( this )[ method ]();
817
+ if ( callback ) {
818
+ callback.call( element[ 0 ] );
819
+ }
820
+ next();
821
+ });
822
+ }
823
+ };
824
+ });
825
+
826
+ })( jQuery );
827
+ (function( $, undefined ) {
828
+
829
+ var mouseHandled = false;
830
+ $( document ).mouseup( function() {
831
+ mouseHandled = false;
832
+ });
833
+
834
+ $.widget("ui.mouse", {
835
+ version: "1.10.4",
836
+ options: {
837
+ cancel: "input,textarea,button,select,option",
838
+ distance: 1,
839
+ delay: 0
840
+ },
841
+ _mouseInit: function() {
842
+ var that = this;
843
+
844
+ this.element
845
+ .bind("mousedown."+this.widgetName, function(event) {
846
+ return that._mouseDown(event);
847
+ })
848
+ .bind("click."+this.widgetName, function(event) {
849
+ if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
850
+ $.removeData(event.target, that.widgetName + ".preventClickEvent");
851
+ event.stopImmediatePropagation();
852
+ return false;
853
+ }
854
+ });
855
+
856
+ this.started = false;
857
+ },
858
+
859
+ // TODO: make sure destroying one instance of mouse doesn't mess with
860
+ // other instances of mouse
861
+ _mouseDestroy: function() {
862
+ this.element.unbind("."+this.widgetName);
863
+ if ( this._mouseMoveDelegate ) {
864
+ $(document)
865
+ .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
866
+ .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
867
+ }
868
+ },
869
+
870
+ _mouseDown: function(event) {
871
+ // don't let more than one widget handle mouseStart
872
+ if( mouseHandled ) { return; }
873
+
874
+ // we may have missed mouseup (out of window)
875
+ (this._mouseStarted && this._mouseUp(event));
876
+
877
+ this._mouseDownEvent = event;
878
+
879
+ var that = this,
880
+ btnIsLeft = (event.which === 1),
881
+ // event.target.nodeName works around a bug in IE 8 with
882
+ // disabled inputs (#7620)
883
+ elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
884
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
885
+ return true;
886
+ }
887
+
888
+ this.mouseDelayMet = !this.options.delay;
889
+ if (!this.mouseDelayMet) {
890
+ this._mouseDelayTimer = setTimeout(function() {
891
+ that.mouseDelayMet = true;
892
+ }, this.options.delay);
893
+ }
894
+
895
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
896
+ this._mouseStarted = (this._mouseStart(event) !== false);
897
+ if (!this._mouseStarted) {
898
+ event.preventDefault();
899
+ return true;
900
+ }
901
+ }
902
+
903
+ // Click event may never have fired (Gecko & Opera)
904
+ if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
905
+ $.removeData(event.target, this.widgetName + ".preventClickEvent");
906
+ }
907
+
908
+ // these delegates are required to keep context
909
+ this._mouseMoveDelegate = function(event) {
910
+ return that._mouseMove(event);
911
+ };
912
+ this._mouseUpDelegate = function(event) {
913
+ return that._mouseUp(event);
914
+ };
915
+ $(document)
916
+ .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
917
+ .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
918
+
919
+ event.preventDefault();
920
+
921
+ mouseHandled = true;
922
+ return true;
923
+ },
924
+
925
+ _mouseMove: function(event) {
926
+ // IE mouseup check - mouseup happened when mouse was out of window
927
+ if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
928
+ return this._mouseUp(event);
929
+ }
930
+
931
+ if (this._mouseStarted) {
932
+ this._mouseDrag(event);
933
+ return event.preventDefault();
934
+ }
935
+
936
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
937
+ this._mouseStarted =
938
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
939
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
940
+ }
941
+
942
+ return !this._mouseStarted;
943
+ },
944
+
945
+ _mouseUp: function(event) {
946
+ $(document)
947
+ .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
948
+ .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
949
+
950
+ if (this._mouseStarted) {
951
+ this._mouseStarted = false;
952
+
953
+ if (event.target === this._mouseDownEvent.target) {
954
+ $.data(event.target, this.widgetName + ".preventClickEvent", true);
955
+ }
956
+
957
+ this._mouseStop(event);
958
+ }
959
+
960
+ return false;
961
+ },
962
+
963
+ _mouseDistanceMet: function(event) {
964
+ return (Math.max(
965
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
966
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
967
+ ) >= this.options.distance
968
+ );
969
+ },
970
+
971
+ _mouseDelayMet: function(/* event */) {
972
+ return this.mouseDelayMet;
973
+ },
974
+
975
+ // These are placeholder methods, to be overriden by extending plugin
976
+ _mouseStart: function(/* event */) {},
977
+ _mouseDrag: function(/* event */) {},
978
+ _mouseStop: function(/* event */) {},
979
+ _mouseCapture: function(/* event */) { return true; }
980
+ });
981
+
982
+ })(jQuery);
983
+ (function( $, undefined ) {
984
+
985
+ $.ui = $.ui || {};
986
+
987
+ var cachedScrollbarWidth,
988
+ max = Math.max,
989
+ abs = Math.abs,
990
+ round = Math.round,
991
+ rhorizontal = /left|center|right/,
992
+ rvertical = /top|center|bottom/,
993
+ roffset = /[\+\-]\d+(\.[\d]+)?%?/,
994
+ rposition = /^\w+/,
995
+ rpercent = /%$/,
996
+ _position = $.fn.position;
997
+
998
+ function getOffsets( offsets, width, height ) {
999
+ return [
1000
+ parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1001
+ parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1002
+ ];
1003
+ }
1004
+
1005
+ function parseCss( element, property ) {
1006
+ return parseInt( $.css( element, property ), 10 ) || 0;
1007
+ }
1008
+
1009
+ function getDimensions( elem ) {
1010
+ var raw = elem[0];
1011
+ if ( raw.nodeType === 9 ) {
1012
+ return {
1013
+ width: elem.width(),
1014
+ height: elem.height(),
1015
+ offset: { top: 0, left: 0 }
1016
+ };
1017
+ }
1018
+ if ( $.isWindow( raw ) ) {
1019
+ return {
1020
+ width: elem.width(),
1021
+ height: elem.height(),
1022
+ offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1023
+ };
1024
+ }
1025
+ if ( raw.preventDefault ) {
1026
+ return {
1027
+ width: 0,
1028
+ height: 0,
1029
+ offset: { top: raw.pageY, left: raw.pageX }
1030
+ };
1031
+ }
1032
+ return {
1033
+ width: elem.outerWidth(),
1034
+ height: elem.outerHeight(),
1035
+ offset: elem.offset()
1036
+ };
1037
+ }
1038
+
1039
+ $.position = {
1040
+ scrollbarWidth: function() {
1041
+ if ( cachedScrollbarWidth !== undefined ) {
1042
+ return cachedScrollbarWidth;
1043
+ }
1044
+ var w1, w2,
1045
+ div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1046
+ innerDiv = div.children()[0];
1047
+
1048
+ $( "body" ).append( div );
1049
+ w1 = innerDiv.offsetWidth;
1050
+ div.css( "overflow", "scroll" );
1051
+
1052
+ w2 = innerDiv.offsetWidth;
1053
+
1054
+ if ( w1 === w2 ) {
1055
+ w2 = div[0].clientWidth;
1056
+ }
1057
+
1058
+ div.remove();
1059
+
1060
+ return (cachedScrollbarWidth = w1 - w2);
1061
+ },
1062
+ getScrollInfo: function( within ) {
1063
+ var overflowX = within.isWindow || within.isDocument ? "" :
1064
+ within.element.css( "overflow-x" ),
1065
+ overflowY = within.isWindow || within.isDocument ? "" :
1066
+ within.element.css( "overflow-y" ),
1067
+ hasOverflowX = overflowX === "scroll" ||
1068
+ ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1069
+ hasOverflowY = overflowY === "scroll" ||
1070
+ ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1071
+ return {
1072
+ width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1073
+ height: hasOverflowX ? $.position.scrollbarWidth() : 0
1074
+ };
1075
+ },
1076
+ getWithinInfo: function( element ) {
1077
+ var withinElement = $( element || window ),
1078
+ isWindow = $.isWindow( withinElement[0] ),
1079
+ isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1080
+ return {
1081
+ element: withinElement,
1082
+ isWindow: isWindow,
1083
+ isDocument: isDocument,
1084
+ offset: withinElement.offset() || { left: 0, top: 0 },
1085
+ scrollLeft: withinElement.scrollLeft(),
1086
+ scrollTop: withinElement.scrollTop(),
1087
+ width: isWindow ? withinElement.width() : withinElement.outerWidth(),
1088
+ height: isWindow ? withinElement.height() : withinElement.outerHeight()
1089
+ };
1090
+ }
1091
+ };
1092
+
1093
+ $.fn.position = function( options ) {
1094
+ if ( !options || !options.of ) {
1095
+ return _position.apply( this, arguments );
1096
+ }
1097
+
1098
+ // make a copy, we don't want to modify arguments
1099
+ options = $.extend( {}, options );
1100
+
1101
+ var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1102
+ target = $( options.of ),
1103
+ within = $.position.getWithinInfo( options.within ),
1104
+ scrollInfo = $.position.getScrollInfo( within ),
1105
+ collision = ( options.collision || "flip" ).split( " " ),
1106
+ offsets = {};
1107
+
1108
+ dimensions = getDimensions( target );
1109
+ if ( target[0].preventDefault ) {
1110
+ // force left top to allow flipping
1111
+ options.at = "left top";
1112
+ }
1113
+ targetWidth = dimensions.width;
1114
+ targetHeight = dimensions.height;
1115
+ targetOffset = dimensions.offset;
1116
+ // clone to reuse original targetOffset later
1117
+ basePosition = $.extend( {}, targetOffset );
1118
+
1119
+ // force my and at to have valid horizontal and vertical positions
1120
+ // if a value is missing or invalid, it will be converted to center
1121
+ $.each( [ "my", "at" ], function() {
1122
+ var pos = ( options[ this ] || "" ).split( " " ),
1123
+ horizontalOffset,
1124
+ verticalOffset;
1125
+
1126
+ if ( pos.length === 1) {
1127
+ pos = rhorizontal.test( pos[ 0 ] ) ?
1128
+ pos.concat( [ "center" ] ) :
1129
+ rvertical.test( pos[ 0 ] ) ?
1130
+ [ "center" ].concat( pos ) :
1131
+ [ "center", "center" ];
1132
+ }
1133
+ pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1134
+ pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1135
+
1136
+ // calculate offsets
1137
+ horizontalOffset = roffset.exec( pos[ 0 ] );
1138
+ verticalOffset = roffset.exec( pos[ 1 ] );
1139
+ offsets[ this ] = [
1140
+ horizontalOffset ? horizontalOffset[ 0 ] : 0,
1141
+ verticalOffset ? verticalOffset[ 0 ] : 0
1142
+ ];
1143
+
1144
+ // reduce to just the positions without the offsets
1145
+ options[ this ] = [
1146
+ rposition.exec( pos[ 0 ] )[ 0 ],
1147
+ rposition.exec( pos[ 1 ] )[ 0 ]
1148
+ ];
1149
+ });
1150
+
1151
+ // normalize collision option
1152
+ if ( collision.length === 1 ) {
1153
+ collision[ 1 ] = collision[ 0 ];
1154
+ }
1155
+
1156
+ if ( options.at[ 0 ] === "right" ) {
1157
+ basePosition.left += targetWidth;
1158
+ } else if ( options.at[ 0 ] === "center" ) {
1159
+ basePosition.left += targetWidth / 2;
1160
+ }
1161
+
1162
+ if ( options.at[ 1 ] === "bottom" ) {
1163
+ basePosition.top += targetHeight;
1164
+ } else if ( options.at[ 1 ] === "center" ) {
1165
+ basePosition.top += targetHeight / 2;
1166
+ }
1167
+
1168
+ atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1169
+ basePosition.left += atOffset[ 0 ];
1170
+ basePosition.top += atOffset[ 1 ];
1171
+
1172
+ return this.each(function() {
1173
+ var collisionPosition, using,
1174
+ elem = $( this ),
1175
+ elemWidth = elem.outerWidth(),
1176
+ elemHeight = elem.outerHeight(),
1177
+ marginLeft = parseCss( this, "marginLeft" ),
1178
+ marginTop = parseCss( this, "marginTop" ),
1179
+ collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1180
+ collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1181
+ position = $.extend( {}, basePosition ),
1182
+ myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1183
+
1184
+ if ( options.my[ 0 ] === "right" ) {
1185
+ position.left -= elemWidth;
1186
+ } else if ( options.my[ 0 ] === "center" ) {
1187
+ position.left -= elemWidth / 2;
1188
+ }
1189
+
1190
+ if ( options.my[ 1 ] === "bottom" ) {
1191
+ position.top -= elemHeight;
1192
+ } else if ( options.my[ 1 ] === "center" ) {
1193
+ position.top -= elemHeight / 2;
1194
+ }
1195
+
1196
+ position.left += myOffset[ 0 ];
1197
+ position.top += myOffset[ 1 ];
1198
+
1199
+ // if the browser doesn't support fractions, then round for consistent results
1200
+ if ( !$.support.offsetFractions ) {
1201
+ position.left = round( position.left );
1202
+ position.top = round( position.top );
1203
+ }
1204
+
1205
+ collisionPosition = {
1206
+ marginLeft: marginLeft,
1207
+ marginTop: marginTop
1208
+ };
1209
+
1210
+ $.each( [ "left", "top" ], function( i, dir ) {
1211
+ if ( $.ui.position[ collision[ i ] ] ) {
1212
+ $.ui.position[ collision[ i ] ][ dir ]( position, {
1213
+ targetWidth: targetWidth,
1214
+ targetHeight: targetHeight,
1215
+ elemWidth: elemWidth,
1216
+ elemHeight: elemHeight,
1217
+ collisionPosition: collisionPosition,
1218
+ collisionWidth: collisionWidth,
1219
+ collisionHeight: collisionHeight,
1220
+ offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1221
+ my: options.my,
1222
+ at: options.at,
1223
+ within: within,
1224
+ elem : elem
1225
+ });
1226
+ }
1227
+ });
1228
+
1229
+ if ( options.using ) {
1230
+ // adds feedback as second argument to using callback, if present
1231
+ using = function( props ) {
1232
+ var left = targetOffset.left - position.left,
1233
+ right = left + targetWidth - elemWidth,
1234
+ top = targetOffset.top - position.top,
1235
+ bottom = top + targetHeight - elemHeight,
1236
+ feedback = {
1237
+ target: {
1238
+ element: target,
1239
+ left: targetOffset.left,
1240
+ top: targetOffset.top,
1241
+ width: targetWidth,
1242
+ height: targetHeight
1243
+ },
1244
+ element: {
1245
+ element: elem,
1246
+ left: position.left,
1247
+ top: position.top,
1248
+ width: elemWidth,
1249
+ height: elemHeight
1250
+ },
1251
+ horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1252
+ vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1253
+ };
1254
+ if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1255
+ feedback.horizontal = "center";
1256
+ }
1257
+ if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1258
+ feedback.vertical = "middle";
1259
+ }
1260
+ if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1261
+ feedback.important = "horizontal";
1262
+ } else {
1263
+ feedback.important = "vertical";
1264
+ }
1265
+ options.using.call( this, props, feedback );
1266
+ };
1267
+ }
1268
+
1269
+ elem.offset( $.extend( position, { using: using } ) );
1270
+ });
1271
+ };
1272
+
1273
+ $.ui.position = {
1274
+ fit: {
1275
+ left: function( position, data ) {
1276
+ var within = data.within,
1277
+ withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1278
+ outerWidth = within.width,
1279
+ collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1280
+ overLeft = withinOffset - collisionPosLeft,
1281
+ overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1282
+ newOverRight;
1283
+
1284
+ // element is wider than within
1285
+ if ( data.collisionWidth > outerWidth ) {
1286
+ // element is initially over the left side of within
1287
+ if ( overLeft > 0 && overRight <= 0 ) {
1288
+ newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1289
+ position.left += overLeft - newOverRight;
1290
+ // element is initially over right side of within
1291
+ } else if ( overRight > 0 && overLeft <= 0 ) {
1292
+ position.left = withinOffset;
1293
+ // element is initially over both left and right sides of within
1294
+ } else {
1295
+ if ( overLeft > overRight ) {
1296
+ position.left = withinOffset + outerWidth - data.collisionWidth;
1297
+ } else {
1298
+ position.left = withinOffset;
1299
+ }
1300
+ }
1301
+ // too far left -> align with left edge
1302
+ } else if ( overLeft > 0 ) {
1303
+ position.left += overLeft;
1304
+ // too far right -> align with right edge
1305
+ } else if ( overRight > 0 ) {
1306
+ position.left -= overRight;
1307
+ // adjust based on position and margin
1308
+ } else {
1309
+ position.left = max( position.left - collisionPosLeft, position.left );
1310
+ }
1311
+ },
1312
+ top: function( position, data ) {
1313
+ var within = data.within,
1314
+ withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1315
+ outerHeight = data.within.height,
1316
+ collisionPosTop = position.top - data.collisionPosition.marginTop,
1317
+ overTop = withinOffset - collisionPosTop,
1318
+ overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1319
+ newOverBottom;
1320
+
1321
+ // element is taller than within
1322
+ if ( data.collisionHeight > outerHeight ) {
1323
+ // element is initially over the top of within
1324
+ if ( overTop > 0 && overBottom <= 0 ) {
1325
+ newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1326
+ position.top += overTop - newOverBottom;
1327
+ // element is initially over bottom of within
1328
+ } else if ( overBottom > 0 && overTop <= 0 ) {
1329
+ position.top = withinOffset;
1330
+ // element is initially over both top and bottom of within
1331
+ } else {
1332
+ if ( overTop > overBottom ) {
1333
+ position.top = withinOffset + outerHeight - data.collisionHeight;
1334
+ } else {
1335
+ position.top = withinOffset;
1336
+ }
1337
+ }
1338
+ // too far up -> align with top
1339
+ } else if ( overTop > 0 ) {
1340
+ position.top += overTop;
1341
+ // too far down -> align with bottom edge
1342
+ } else if ( overBottom > 0 ) {
1343
+ position.top -= overBottom;
1344
+ // adjust based on position and margin
1345
+ } else {
1346
+ position.top = max( position.top - collisionPosTop, position.top );
1347
+ }
1348
+ }
1349
+ },
1350
+ flip: {
1351
+ left: function( position, data ) {
1352
+ var within = data.within,
1353
+ withinOffset = within.offset.left + within.scrollLeft,
1354
+ outerWidth = within.width,
1355
+ offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1356
+ collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1357
+ overLeft = collisionPosLeft - offsetLeft,
1358
+ overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1359
+ myOffset = data.my[ 0 ] === "left" ?
1360
+ -data.elemWidth :
1361
+ data.my[ 0 ] === "right" ?
1362
+ data.elemWidth :
1363
+ 0,
1364
+ atOffset = data.at[ 0 ] === "left" ?
1365
+ data.targetWidth :
1366
+ data.at[ 0 ] === "right" ?
1367
+ -data.targetWidth :
1368
+ 0,
1369
+ offset = -2 * data.offset[ 0 ],
1370
+ newOverRight,
1371
+ newOverLeft;
1372
+
1373
+ if ( overLeft < 0 ) {
1374
+ newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1375
+ if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1376
+ position.left += myOffset + atOffset + offset;
1377
+ }
1378
+ }
1379
+ else if ( overRight > 0 ) {
1380
+ newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1381
+ if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1382
+ position.left += myOffset + atOffset + offset;
1383
+ }
1384
+ }
1385
+ },
1386
+ top: function( position, data ) {
1387
+ var within = data.within,
1388
+ withinOffset = within.offset.top + within.scrollTop,
1389
+ outerHeight = within.height,
1390
+ offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1391
+ collisionPosTop = position.top - data.collisionPosition.marginTop,
1392
+ overTop = collisionPosTop - offsetTop,
1393
+ overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1394
+ top = data.my[ 1 ] === "top",
1395
+ myOffset = top ?
1396
+ -data.elemHeight :
1397
+ data.my[ 1 ] === "bottom" ?
1398
+ data.elemHeight :
1399
+ 0,
1400
+ atOffset = data.at[ 1 ] === "top" ?
1401
+ data.targetHeight :
1402
+ data.at[ 1 ] === "bottom" ?
1403
+ -data.targetHeight :
1404
+ 0,
1405
+ offset = -2 * data.offset[ 1 ],
1406
+ newOverTop,
1407
+ newOverBottom;
1408
+ if ( overTop < 0 ) {
1409
+ newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1410
+ if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1411
+ position.top += myOffset + atOffset + offset;
1412
+ }
1413
+ }
1414
+ else if ( overBottom > 0 ) {
1415
+ newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1416
+ if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1417
+ position.top += myOffset + atOffset + offset;
1418
+ }
1419
+ }
1420
+ }
1421
+ },
1422
+ flipfit: {
1423
+ left: function() {
1424
+ $.ui.position.flip.left.apply( this, arguments );
1425
+ $.ui.position.fit.left.apply( this, arguments );
1426
+ },
1427
+ top: function() {
1428
+ $.ui.position.flip.top.apply( this, arguments );
1429
+ $.ui.position.fit.top.apply( this, arguments );
1430
+ }
1431
+ }
1432
+ };
1433
+
1434
+ // fraction support test
1435
+ (function () {
1436
+ var testElement, testElementParent, testElementStyle, offsetLeft, i,
1437
+ body = document.getElementsByTagName( "body" )[ 0 ],
1438
+ div = document.createElement( "div" );
1439
+
1440
+ //Create a "fake body" for testing based on method used in jQuery.support
1441
+ testElement = document.createElement( body ? "div" : "body" );
1442
+ testElementStyle = {
1443
+ visibility: "hidden",
1444
+ width: 0,
1445
+ height: 0,
1446
+ border: 0,
1447
+ margin: 0,
1448
+ background: "none"
1449
+ };
1450
+ if ( body ) {
1451
+ $.extend( testElementStyle, {
1452
+ position: "absolute",
1453
+ left: "-1000px",
1454
+ top: "-1000px"
1455
+ });
1456
+ }
1457
+ for ( i in testElementStyle ) {
1458
+ testElement.style[ i ] = testElementStyle[ i ];
1459
+ }
1460
+ testElement.appendChild( div );
1461
+ testElementParent = body || document.documentElement;
1462
+ testElementParent.insertBefore( testElement, testElementParent.firstChild );
1463
+
1464
+ div.style.cssText = "position: absolute; left: 10.7432222px;";
1465
+
1466
+ offsetLeft = $( div ).offset().left;
1467
+ $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
1468
+
1469
+ testElement.innerHTML = "";
1470
+ testElementParent.removeChild( testElement );
1471
+ })();
1472
+
1473
+ }( jQuery ) );
1474
+ (function( $, undefined ) {
1475
+
1476
+ $.extend($.ui, { datepicker: { version: "1.10.4" } });
1477
+
1478
+ var PROP_NAME = "datepicker",
1479
+ instActive;
1480
+
1481
+ /* Date picker manager.
1482
+ Use the singleton instance of this class, $.datepicker, to interact with the date picker.
1483
+ Settings for (groups of) date pickers are maintained in an instance object,
1484
+ allowing multiple different settings on the same page. */
1485
+
1486
+ function Datepicker() {
1487
+ this._curInst = null; // The current instance in use
1488
+ this._keyEvent = false; // If the last event was a key event
1489
+ this._disabledInputs = []; // List of date picker inputs that have been disabled
1490
+ this._datepickerShowing = false; // True if the popup picker is showing , false if not
1491
+ this._inDialog = false; // True if showing within a "dialog", false if not
1492
+ this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
1493
+ this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
1494
+ this._appendClass = "ui-datepicker-append"; // The name of the append marker class
1495
+ this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
1496
+ this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
1497
+ this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
1498
+ this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
1499
+ this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
1500
+ this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
1501
+ this.regional = []; // Available regional settings, indexed by language code
1502
+ this.regional[""] = { // Default regional settings
1503
+ closeText: "Done", // Display text for close link
1504
+ prevText: "Prev", // Display text for previous month link
1505
+ nextText: "Next", // Display text for next month link
1506
+ currentText: "Today", // Display text for current month link
1507
+ monthNames: ["January","February","March","April","May","June",
1508
+ "July","August","September","October","November","December"], // Names of months for drop-down and formatting
1509
+ monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
1510
+ dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
1511
+ dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
1512
+ dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
1513
+ weekHeader: "Wk", // Column header for week of the year
1514
+ dateFormat: "mm/dd/yy", // See format options on parseDate
1515
+ firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
1516
+ isRTL: false, // True if right-to-left language, false if left-to-right
1517
+ showMonthAfterYear: false, // True if the year select precedes month, false for month then year
1518
+ yearSuffix: "" // Additional text to append to the year in the month headers
1519
+ };
1520
+ this._defaults = { // Global defaults for all the date picker instances
1521
+ showOn: "focus", // "focus" for popup on focus,
1522
+ // "button" for trigger button, or "both" for either
1523
+ showAnim: "fadeIn", // Name of jQuery animation for popup
1524
+ showOptions: {}, // Options for enhanced animations
1525
+ defaultDate: null, // Used when field is blank: actual date,
1526
+ // +/-number for offset from today, null for today
1527
+ appendText: "", // Display text following the input box, e.g. showing the format
1528
+ buttonText: "...", // Text for trigger button
1529
+ buttonImage: "", // URL for trigger button image
1530
+ buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
1531
+ hideIfNoPrevNext: false, // True to hide next/previous month links
1532
+ // if not applicable, false to just disable them
1533
+ navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
1534
+ gotoCurrent: false, // True if today link goes back to current selection instead
1535
+ changeMonth: false, // True if month can be selected directly, false if only prev/next
1536
+ changeYear: false, // True if year can be selected directly, false if only prev/next
1537
+ yearRange: "c-10:c+10", // Range of years to display in drop-down,
1538
+ // either relative to today's year (-nn:+nn), relative to currently displayed year
1539
+ // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
1540
+ showOtherMonths: false, // True to show dates in other months, false to leave blank
1541
+ selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
1542
+ showWeek: false, // True to show week of the year, false to not show it
1543
+ calculateWeek: this.iso8601Week, // How to calculate the week of the year,
1544
+ // takes a Date and returns the number of the week for it
1545
+ shortYearCutoff: "+10", // Short year values < this are in the current century,
1546
+ // > this are in the previous century,
1547
+ // string value starting with "+" for current year + value
1548
+ minDate: null, // The earliest selectable date, or null for no limit
1549
+ maxDate: null, // The latest selectable date, or null for no limit
1550
+ duration: "fast", // Duration of display/closure
1551
+ beforeShowDay: null, // Function that takes a date and returns an array with
1552
+ // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
1553
+ // [2] = cell title (optional), e.g. $.datepicker.noWeekends
1554
+ beforeShow: null, // Function that takes an input field and
1555
+ // returns a set of custom settings for the date picker
1556
+ onSelect: null, // Define a callback function when a date is selected
1557
+ onChangeMonthYear: null, // Define a callback function when the month or year is changed
1558
+ onClose: null, // Define a callback function when the datepicker is closed
1559
+ numberOfMonths: 1, // Number of months to show at a time
1560
+ showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
1561
+ stepMonths: 1, // Number of months to step back/forward
1562
+ stepBigMonths: 12, // Number of months to step back/forward for the big links
1563
+ altField: "", // Selector for an alternate field to store selected dates into
1564
+ altFormat: "", // The date format to use for the alternate field
1565
+ constrainInput: true, // The input is constrained by the current date format
1566
+ showButtonPanel: false, // True to show button panel, false to not show it
1567
+ autoSize: false, // True to size the input for the date format, false to leave as is
1568
+ disabled: false // The initial disabled state
1569
+ };
1570
+ $.extend(this._defaults, this.regional[""]);
1571
+ this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
1572
+ }
1573
+
1574
+ $.extend(Datepicker.prototype, {
1575
+ /* Class name added to elements to indicate already configured with a date picker. */
1576
+ markerClassName: "hasDatepicker",
1577
+
1578
+ //Keep track of the maximum number of rows displayed (see #7043)
1579
+ maxRows: 4,
1580
+
1581
+ // TODO rename to "widget" when switching to widget factory
1582
+ _widgetDatepicker: function() {
1583
+ return this.dpDiv;
1584
+ },
1585
+
1586
+ /* Override the default settings for all instances of the date picker.
1587
+ * @param settings object - the new settings to use as defaults (anonymous object)
1588
+ * @return the manager object
1589
+ */
1590
+ setDefaults: function(settings) {
1591
+ extendRemove(this._defaults, settings || {});
1592
+ return this;
1593
+ },
1594
+
1595
+ /* Attach the date picker to a jQuery selection.
1596
+ * @param target element - the target input field or division or span
1597
+ * @param settings object - the new settings to use for this date picker instance (anonymous)
1598
+ */
1599
+ _attachDatepicker: function(target, settings) {
1600
+ var nodeName, inline, inst;
1601
+ nodeName = target.nodeName.toLowerCase();
1602
+ inline = (nodeName === "div" || nodeName === "span");
1603
+ if (!target.id) {
1604
+ this.uuid += 1;
1605
+ target.id = "dp" + this.uuid;
1606
+ }
1607
+ inst = this._newInst($(target), inline);
1608
+ inst.settings = $.extend({}, settings || {});
1609
+ if (nodeName === "input") {
1610
+ this._connectDatepicker(target, inst);
1611
+ } else if (inline) {
1612
+ this._inlineDatepicker(target, inst);
1613
+ }
1614
+ },
1615
+
1616
+ /* Create a new instance object. */
1617
+ _newInst: function(target, inline) {
1618
+ var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
1619
+ return {id: id, input: target, // associated target
1620
+ selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
1621
+ drawMonth: 0, drawYear: 0, // month being drawn
1622
+ inline: inline, // is datepicker inline or not
1623
+ dpDiv: (!inline ? this.dpDiv : // presentation div
1624
+ bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
1625
+ },
1626
+
1627
+ /* Attach the date picker to an input field. */
1628
+ _connectDatepicker: function(target, inst) {
1629
+ var input = $(target);
1630
+ inst.append = $([]);
1631
+ inst.trigger = $([]);
1632
+ if (input.hasClass(this.markerClassName)) {
1633
+ return;
1634
+ }
1635
+ this._attachments(input, inst);
1636
+ input.addClass(this.markerClassName).keydown(this._doKeyDown).
1637
+ keypress(this._doKeyPress).keyup(this._doKeyUp);
1638
+ this._autoSize(inst);
1639
+ $.data(target, PROP_NAME, inst);
1640
+ //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
1641
+ if( inst.settings.disabled ) {
1642
+ this._disableDatepicker( target );
1643
+ }
1644
+ },
1645
+
1646
+ /* Make attachments based on settings. */
1647
+ _attachments: function(input, inst) {
1648
+ var showOn, buttonText, buttonImage,
1649
+ appendText = this._get(inst, "appendText"),
1650
+ isRTL = this._get(inst, "isRTL");
1651
+
1652
+ if (inst.append) {
1653
+ inst.append.remove();
1654
+ }
1655
+ if (appendText) {
1656
+ inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
1657
+ input[isRTL ? "before" : "after"](inst.append);
1658
+ }
1659
+
1660
+ input.unbind("focus", this._showDatepicker);
1661
+
1662
+ if (inst.trigger) {
1663
+ inst.trigger.remove();
1664
+ }
1665
+
1666
+ showOn = this._get(inst, "showOn");
1667
+ if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
1668
+ input.focus(this._showDatepicker);
1669
+ }
1670
+ if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
1671
+ buttonText = this._get(inst, "buttonText");
1672
+ buttonImage = this._get(inst, "buttonImage");
1673
+ inst.trigger = $(this._get(inst, "buttonImageOnly") ?
1674
+ $("<img/>").addClass(this._triggerClass).
1675
+ attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
1676
+ $("<button type='button'></button>").addClass(this._triggerClass).
1677
+ html(!buttonImage ? buttonText : $("<img/>").attr(
1678
+ { src:buttonImage, alt:buttonText, title:buttonText })));
1679
+ input[isRTL ? "before" : "after"](inst.trigger);
1680
+ inst.trigger.click(function() {
1681
+ if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
1682
+ $.datepicker._hideDatepicker();
1683
+ } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
1684
+ $.datepicker._hideDatepicker();
1685
+ $.datepicker._showDatepicker(input[0]);
1686
+ } else {
1687
+ $.datepicker._showDatepicker(input[0]);
1688
+ }
1689
+ return false;
1690
+ });
1691
+ }
1692
+ },
1693
+
1694
+ /* Apply the maximum length for the date format. */
1695
+ _autoSize: function(inst) {
1696
+ if (this._get(inst, "autoSize") && !inst.inline) {
1697
+ var findMax, max, maxI, i,
1698
+ date = new Date(2009, 12 - 1, 20), // Ensure double digits
1699
+ dateFormat = this._get(inst, "dateFormat");
1700
+
1701
+ if (dateFormat.match(/[DM]/)) {
1702
+ findMax = function(names) {
1703
+ max = 0;
1704
+ maxI = 0;
1705
+ for (i = 0; i < names.length; i++) {
1706
+ if (names[i].length > max) {
1707
+ max = names[i].length;
1708
+ maxI = i;
1709
+ }
1710
+ }
1711
+ return maxI;
1712
+ };
1713
+ date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
1714
+ "monthNames" : "monthNamesShort"))));
1715
+ date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
1716
+ "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
1717
+ }
1718
+ inst.input.attr("size", this._formatDate(inst, date).length);
1719
+ }
1720
+ },
1721
+
1722
+ /* Attach an inline date picker to a div. */
1723
+ _inlineDatepicker: function(target, inst) {
1724
+ var divSpan = $(target);
1725
+ if (divSpan.hasClass(this.markerClassName)) {
1726
+ return;
1727
+ }
1728
+ divSpan.addClass(this.markerClassName).append(inst.dpDiv);
1729
+ $.data(target, PROP_NAME, inst);
1730
+ this._setDate(inst, this._getDefaultDate(inst), true);
1731
+ this._updateDatepicker(inst);
1732
+ this._updateAlternate(inst);
1733
+ //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
1734
+ if( inst.settings.disabled ) {
1735
+ this._disableDatepicker( target );
1736
+ }
1737
+ // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
1738
+ // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
1739
+ inst.dpDiv.css( "display", "block" );
1740
+ },
1741
+
1742
+ /* Pop-up the date picker in a "dialog" box.
1743
+ * @param input element - ignored
1744
+ * @param date string or Date - the initial date to display
1745
+ * @param onSelect function - the function to call when a date is selected
1746
+ * @param settings object - update the dialog date picker instance's settings (anonymous object)
1747
+ * @param pos int[2] - coordinates for the dialog's position within the screen or
1748
+ * event - with x/y coordinates or
1749
+ * leave empty for default (screen centre)
1750
+ * @return the manager object
1751
+ */
1752
+ _dialogDatepicker: function(input, date, onSelect, settings, pos) {
1753
+ var id, browserWidth, browserHeight, scrollX, scrollY,
1754
+ inst = this._dialogInst; // internal instance
1755
+
1756
+ if (!inst) {
1757
+ this.uuid += 1;
1758
+ id = "dp" + this.uuid;
1759
+ this._dialogInput = $("<input type='text' id='" + id +
1760
+ "' style='position: absolute; top: -100px; width: 0px;'/>");
1761
+ this._dialogInput.keydown(this._doKeyDown);
1762
+ $("body").append(this._dialogInput);
1763
+ inst = this._dialogInst = this._newInst(this._dialogInput, false);
1764
+ inst.settings = {};
1765
+ $.data(this._dialogInput[0], PROP_NAME, inst);
1766
+ }
1767
+ extendRemove(inst.settings, settings || {});
1768
+ date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
1769
+ this._dialogInput.val(date);
1770
+
1771
+ this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
1772
+ if (!this._pos) {
1773
+ browserWidth = document.documentElement.clientWidth;
1774
+ browserHeight = document.documentElement.clientHeight;
1775
+ scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
1776
+ scrollY = document.documentElement.scrollTop || document.body.scrollTop;
1777
+ this._pos = // should use actual width/height below
1778
+ [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
1779
+ }
1780
+
1781
+ // move input on screen for focus, but hidden behind dialog
1782
+ this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
1783
+ inst.settings.onSelect = onSelect;
1784
+ this._inDialog = true;
1785
+ this.dpDiv.addClass(this._dialogClass);
1786
+ this._showDatepicker(this._dialogInput[0]);
1787
+ if ($.blockUI) {
1788
+ $.blockUI(this.dpDiv);
1789
+ }
1790
+ $.data(this._dialogInput[0], PROP_NAME, inst);
1791
+ return this;
1792
+ },
1793
+
1794
+ /* Detach a datepicker from its control.
1795
+ * @param target element - the target input field or division or span
1796
+ */
1797
+ _destroyDatepicker: function(target) {
1798
+ var nodeName,
1799
+ $target = $(target),
1800
+ inst = $.data(target, PROP_NAME);
1801
+
1802
+ if (!$target.hasClass(this.markerClassName)) {
1803
+ return;
1804
+ }
1805
+
1806
+ nodeName = target.nodeName.toLowerCase();
1807
+ $.removeData(target, PROP_NAME);
1808
+ if (nodeName === "input") {
1809
+ inst.append.remove();
1810
+ inst.trigger.remove();
1811
+ $target.removeClass(this.markerClassName).
1812
+ unbind("focus", this._showDatepicker).
1813
+ unbind("keydown", this._doKeyDown).
1814
+ unbind("keypress", this._doKeyPress).
1815
+ unbind("keyup", this._doKeyUp);
1816
+ } else if (nodeName === "div" || nodeName === "span") {
1817
+ $target.removeClass(this.markerClassName).empty();
1818
+ }
1819
+ },
1820
+
1821
+ /* Enable the date picker to a jQuery selection.
1822
+ * @param target element - the target input field or division or span
1823
+ */
1824
+ _enableDatepicker: function(target) {
1825
+ var nodeName, inline,
1826
+ $target = $(target),
1827
+ inst = $.data(target, PROP_NAME);
1828
+
1829
+ if (!$target.hasClass(this.markerClassName)) {
1830
+ return;
1831
+ }
1832
+
1833
+ nodeName = target.nodeName.toLowerCase();
1834
+ if (nodeName === "input") {
1835
+ target.disabled = false;
1836
+ inst.trigger.filter("button").
1837
+ each(function() { this.disabled = false; }).end().
1838
+ filter("img").css({opacity: "1.0", cursor: ""});
1839
+ } else if (nodeName === "div" || nodeName === "span") {
1840
+ inline = $target.children("." + this._inlineClass);
1841
+ inline.children().removeClass("ui-state-disabled");
1842
+ inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
1843
+ prop("disabled", false);
1844
+ }
1845
+ this._disabledInputs = $.map(this._disabledInputs,
1846
+ function(value) { return (value === target ? null : value); }); // delete entry
1847
+ },
1848
+
1849
+ /* Disable the date picker to a jQuery selection.
1850
+ * @param target element - the target input field or division or span
1851
+ */
1852
+ _disableDatepicker: function(target) {
1853
+ var nodeName, inline,
1854
+ $target = $(target),
1855
+ inst = $.data(target, PROP_NAME);
1856
+
1857
+ if (!$target.hasClass(this.markerClassName)) {
1858
+ return;
1859
+ }
1860
+
1861
+ nodeName = target.nodeName.toLowerCase();
1862
+ if (nodeName === "input") {
1863
+ target.disabled = true;
1864
+ inst.trigger.filter("button").
1865
+ each(function() { this.disabled = true; }).end().
1866
+ filter("img").css({opacity: "0.5", cursor: "default"});
1867
+ } else if (nodeName === "div" || nodeName === "span") {
1868
+ inline = $target.children("." + this._inlineClass);
1869
+ inline.children().addClass("ui-state-disabled");
1870
+ inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
1871
+ prop("disabled", true);
1872
+ }
1873
+ this._disabledInputs = $.map(this._disabledInputs,
1874
+ function(value) { return (value === target ? null : value); }); // delete entry
1875
+ this._disabledInputs[this._disabledInputs.length] = target;
1876
+ },
1877
+
1878
+ /* Is the first field in a jQuery collection disabled as a datepicker?
1879
+ * @param target element - the target input field or division or span
1880
+ * @return boolean - true if disabled, false if enabled
1881
+ */
1882
+ _isDisabledDatepicker: function(target) {
1883
+ if (!target) {
1884
+ return false;
1885
+ }
1886
+ for (var i = 0; i < this._disabledInputs.length; i++) {
1887
+ if (this._disabledInputs[i] === target) {
1888
+ return true;
1889
+ }
1890
+ }
1891
+ return false;
1892
+ },
1893
+
1894
+ /* Retrieve the instance data for the target control.
1895
+ * @param target element - the target input field or division or span
1896
+ * @return object - the associated instance data
1897
+ * @throws error if a jQuery problem getting data
1898
+ */
1899
+ _getInst: function(target) {
1900
+ try {
1901
+ return $.data(target, PROP_NAME);
1902
+ }
1903
+ catch (err) {
1904
+ throw "Missing instance data for this datepicker";
1905
+ }
1906
+ },
1907
+
1908
+ /* Update or retrieve the settings for a date picker attached to an input field or division.
1909
+ * @param target element - the target input field or division or span
1910
+ * @param name object - the new settings to update or
1911
+ * string - the name of the setting to change or retrieve,
1912
+ * when retrieving also "all" for all instance settings or
1913
+ * "defaults" for all global defaults
1914
+ * @param value any - the new value for the setting
1915
+ * (omit if above is an object or to retrieve a value)
1916
+ */
1917
+ _optionDatepicker: function(target, name, value) {
1918
+ var settings, date, minDate, maxDate,
1919
+ inst = this._getInst(target);
1920
+
1921
+ if (arguments.length === 2 && typeof name === "string") {
1922
+ return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
1923
+ (inst ? (name === "all" ? $.extend({}, inst.settings) :
1924
+ this._get(inst, name)) : null));
1925
+ }
1926
+
1927
+ settings = name || {};
1928
+ if (typeof name === "string") {
1929
+ settings = {};
1930
+ settings[name] = value;
1931
+ }
1932
+
1933
+ if (inst) {
1934
+ if (this._curInst === inst) {
1935
+ this._hideDatepicker();
1936
+ }
1937
+
1938
+ date = this._getDateDatepicker(target, true);
1939
+ minDate = this._getMinMaxDate(inst, "min");
1940
+ maxDate = this._getMinMaxDate(inst, "max");
1941
+ extendRemove(inst.settings, settings);
1942
+ // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
1943
+ if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
1944
+ inst.settings.minDate = this._formatDate(inst, minDate);
1945
+ }
1946
+ if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
1947
+ inst.settings.maxDate = this._formatDate(inst, maxDate);
1948
+ }
1949
+ if ( "disabled" in settings ) {
1950
+ if ( settings.disabled ) {
1951
+ this._disableDatepicker(target);
1952
+ } else {
1953
+ this._enableDatepicker(target);
1954
+ }
1955
+ }
1956
+ this._attachments($(target), inst);
1957
+ this._autoSize(inst);
1958
+ this._setDate(inst, date);
1959
+ this._updateAlternate(inst);
1960
+ this._updateDatepicker(inst);
1961
+ }
1962
+ },
1963
+
1964
+ // change method deprecated
1965
+ _changeDatepicker: function(target, name, value) {
1966
+ this._optionDatepicker(target, name, value);
1967
+ },
1968
+
1969
+ /* Redraw the date picker attached to an input field or division.
1970
+ * @param target element - the target input field or division or span
1971
+ */
1972
+ _refreshDatepicker: function(target) {
1973
+ var inst = this._getInst(target);
1974
+ if (inst) {
1975
+ this._updateDatepicker(inst);
1976
+ }
1977
+ },
1978
+
1979
+ /* Set the dates for a jQuery selection.
1980
+ * @param target element - the target input field or division or span
1981
+ * @param date Date - the new date
1982
+ */
1983
+ _setDateDatepicker: function(target, date) {
1984
+ var inst = this._getInst(target);
1985
+ if (inst) {
1986
+ this._setDate(inst, date);
1987
+ this._updateDatepicker(inst);
1988
+ this._updateAlternate(inst);
1989
+ }
1990
+ },
1991
+
1992
+ /* Get the date(s) for the first entry in a jQuery selection.
1993
+ * @param target element - the target input field or division or span
1994
+ * @param noDefault boolean - true if no default date is to be used
1995
+ * @return Date - the current date
1996
+ */
1997
+ _getDateDatepicker: function(target, noDefault) {
1998
+ var inst = this._getInst(target);
1999
+ if (inst && !inst.inline) {
2000
+ this._setDateFromField(inst, noDefault);
2001
+ }
2002
+ return (inst ? this._getDate(inst) : null);
2003
+ },
2004
+
2005
+ /* Handle keystrokes. */
2006
+ _doKeyDown: function(event) {
2007
+ var onSelect, dateStr, sel,
2008
+ inst = $.datepicker._getInst(event.target),
2009
+ handled = true,
2010
+ isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
2011
+
2012
+ inst._keyEvent = true;
2013
+ if ($.datepicker._datepickerShowing) {
2014
+ switch (event.keyCode) {
2015
+ case 9: $.datepicker._hideDatepicker();
2016
+ handled = false;
2017
+ break; // hide on tab out
2018
+ case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
2019
+ $.datepicker._currentClass + ")", inst.dpDiv);
2020
+ if (sel[0]) {
2021
+ $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
2022
+ }
2023
+
2024
+ onSelect = $.datepicker._get(inst, "onSelect");
2025
+ if (onSelect) {
2026
+ dateStr = $.datepicker._formatDate(inst);
2027
+
2028
+ // trigger custom callback
2029
+ onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
2030
+ } else {
2031
+ $.datepicker._hideDatepicker();
2032
+ }
2033
+
2034
+ return false; // don't submit the form
2035
+ case 27: $.datepicker._hideDatepicker();
2036
+ break; // hide on escape
2037
+ case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
2038
+ -$.datepicker._get(inst, "stepBigMonths") :
2039
+ -$.datepicker._get(inst, "stepMonths")), "M");
2040
+ break; // previous month/year on page up/+ ctrl
2041
+ case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
2042
+ +$.datepicker._get(inst, "stepBigMonths") :
2043
+ +$.datepicker._get(inst, "stepMonths")), "M");
2044
+ break; // next month/year on page down/+ ctrl
2045
+ case 35: if (event.ctrlKey || event.metaKey) {
2046
+ $.datepicker._clearDate(event.target);
2047
+ }
2048
+ handled = event.ctrlKey || event.metaKey;
2049
+ break; // clear on ctrl or command +end
2050
+ case 36: if (event.ctrlKey || event.metaKey) {
2051
+ $.datepicker._gotoToday(event.target);
2052
+ }
2053
+ handled = event.ctrlKey || event.metaKey;
2054
+ break; // current on ctrl or command +home
2055
+ case 37: if (event.ctrlKey || event.metaKey) {
2056
+ $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
2057
+ }
2058
+ handled = event.ctrlKey || event.metaKey;
2059
+ // -1 day on ctrl or command +left
2060
+ if (event.originalEvent.altKey) {
2061
+ $.datepicker._adjustDate(event.target, (event.ctrlKey ?
2062
+ -$.datepicker._get(inst, "stepBigMonths") :
2063
+ -$.datepicker._get(inst, "stepMonths")), "M");
2064
+ }
2065
+ // next month/year on alt +left on Mac
2066
+ break;
2067
+ case 38: if (event.ctrlKey || event.metaKey) {
2068
+ $.datepicker._adjustDate(event.target, -7, "D");
2069
+ }
2070
+ handled = event.ctrlKey || event.metaKey;
2071
+ break; // -1 week on ctrl or command +up
2072
+ case 39: if (event.ctrlKey || event.metaKey) {
2073
+ $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
2074
+ }
2075
+ handled = event.ctrlKey || event.metaKey;
2076
+ // +1 day on ctrl or command +right
2077
+ if (event.originalEvent.altKey) {
2078
+ $.datepicker._adjustDate(event.target, (event.ctrlKey ?
2079
+ +$.datepicker._get(inst, "stepBigMonths") :
2080
+ +$.datepicker._get(inst, "stepMonths")), "M");
2081
+ }
2082
+ // next month/year on alt +right
2083
+ break;
2084
+ case 40: if (event.ctrlKey || event.metaKey) {
2085
+ $.datepicker._adjustDate(event.target, +7, "D");
2086
+ }
2087
+ handled = event.ctrlKey || event.metaKey;
2088
+ break; // +1 week on ctrl or command +down
2089
+ default: handled = false;
2090
+ }
2091
+ } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
2092
+ $.datepicker._showDatepicker(this);
2093
+ } else {
2094
+ handled = false;
2095
+ }
2096
+
2097
+ if (handled) {
2098
+ event.preventDefault();
2099
+ event.stopPropagation();
2100
+ }
2101
+ },
2102
+
2103
+ /* Filter entered characters - based on date format. */
2104
+ _doKeyPress: function(event) {
2105
+ var chars, chr,
2106
+ inst = $.datepicker._getInst(event.target);
2107
+
2108
+ if ($.datepicker._get(inst, "constrainInput")) {
2109
+ chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
2110
+ chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
2111
+ return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
2112
+ }
2113
+ },
2114
+
2115
+ /* Synchronise manual entry and field/alternate field. */
2116
+ _doKeyUp: function(event) {
2117
+ var date,
2118
+ inst = $.datepicker._getInst(event.target);
2119
+
2120
+ if (inst.input.val() !== inst.lastVal) {
2121
+ try {
2122
+ date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
2123
+ (inst.input ? inst.input.val() : null),
2124
+ $.datepicker._getFormatConfig(inst));
2125
+
2126
+ if (date) { // only if valid
2127
+ $.datepicker._setDateFromField(inst);
2128
+ $.datepicker._updateAlternate(inst);
2129
+ $.datepicker._updateDatepicker(inst);
2130
+ }
2131
+ }
2132
+ catch (err) {
2133
+ }
2134
+ }
2135
+ return true;
2136
+ },
2137
+
2138
+ /* Pop-up the date picker for a given input field.
2139
+ * If false returned from beforeShow event handler do not show.
2140
+ * @param input element - the input field attached to the date picker or
2141
+ * event - if triggered by focus
2142
+ */
2143
+ _showDatepicker: function(input) {
2144
+ input = input.target || input;
2145
+ if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
2146
+ input = $("input", input.parentNode)[0];
2147
+ }
2148
+
2149
+ if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
2150
+ return;
2151
+ }
2152
+
2153
+ var inst, beforeShow, beforeShowSettings, isFixed,
2154
+ offset, showAnim, duration;
2155
+
2156
+ inst = $.datepicker._getInst(input);
2157
+ if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
2158
+ $.datepicker._curInst.dpDiv.stop(true, true);
2159
+ if ( inst && $.datepicker._datepickerShowing ) {
2160
+ $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
2161
+ }
2162
+ }
2163
+
2164
+ beforeShow = $.datepicker._get(inst, "beforeShow");
2165
+ beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
2166
+ if(beforeShowSettings === false){
2167
+ return;
2168
+ }
2169
+ extendRemove(inst.settings, beforeShowSettings);
2170
+
2171
+ inst.lastVal = null;
2172
+ $.datepicker._lastInput = input;
2173
+ $.datepicker._setDateFromField(inst);
2174
+
2175
+ if ($.datepicker._inDialog) { // hide cursor
2176
+ input.value = "";
2177
+ }
2178
+ if (!$.datepicker._pos) { // position below input
2179
+ $.datepicker._pos = $.datepicker._findPos(input);
2180
+ $.datepicker._pos[1] += input.offsetHeight; // add the height
2181
+ }
2182
+
2183
+ isFixed = false;
2184
+ $(input).parents().each(function() {
2185
+ isFixed |= $(this).css("position") === "fixed";
2186
+ return !isFixed;
2187
+ });
2188
+
2189
+ offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
2190
+ $.datepicker._pos = null;
2191
+ //to avoid flashes on Firefox
2192
+ inst.dpDiv.empty();
2193
+ // determine sizing offscreen
2194
+ inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
2195
+ $.datepicker._updateDatepicker(inst);
2196
+ // fix width for dynamic number of date pickers
2197
+ // and adjust position before showing
2198
+ offset = $.datepicker._checkOffset(inst, offset, isFixed);
2199
+ inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
2200
+ "static" : (isFixed ? "fixed" : "absolute")), display: "none",
2201
+ left: offset.left + "px", top: offset.top + "px"});
2202
+
2203
+ if (!inst.inline) {
2204
+ showAnim = $.datepicker._get(inst, "showAnim");
2205
+ duration = $.datepicker._get(inst, "duration");
2206
+ inst.dpDiv.zIndex($(input).zIndex()+1);
2207
+ $.datepicker._datepickerShowing = true;
2208
+
2209
+ if ( $.effects && $.effects.effect[ showAnim ] ) {
2210
+ inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
2211
+ } else {
2212
+ inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
2213
+ }
2214
+
2215
+ if ( $.datepicker._shouldFocusInput( inst ) ) {
2216
+ inst.input.focus();
2217
+ }
2218
+
2219
+ $.datepicker._curInst = inst;
2220
+ }
2221
+ },
2222
+
2223
+ /* Generate the date picker content. */
2224
+ _updateDatepicker: function(inst) {
2225
+ this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
2226
+ instActive = inst; // for delegate hover events
2227
+ inst.dpDiv.empty().append(this._generateHTML(inst));
2228
+ this._attachHandlers(inst);
2229
+ inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
2230
+
2231
+ var origyearshtml,
2232
+ numMonths = this._getNumberOfMonths(inst),
2233
+ cols = numMonths[1],
2234
+ width = 17;
2235
+
2236
+ inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
2237
+ if (cols > 1) {
2238
+ inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
2239
+ }
2240
+ inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
2241
+ "Class"]("ui-datepicker-multi");
2242
+ inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
2243
+ "Class"]("ui-datepicker-rtl");
2244
+
2245
+ if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
2246
+ inst.input.focus();
2247
+ }
2248
+
2249
+ // deffered render of the years select (to avoid flashes on Firefox)
2250
+ if( inst.yearshtml ){
2251
+ origyearshtml = inst.yearshtml;
2252
+ setTimeout(function(){
2253
+ //assure that inst.yearshtml didn't change.
2254
+ if( origyearshtml === inst.yearshtml && inst.yearshtml ){
2255
+ inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
2256
+ }
2257
+ origyearshtml = inst.yearshtml = null;
2258
+ }, 0);
2259
+ }
2260
+ },
2261
+
2262
+ // #6694 - don't focus the input if it's already focused
2263
+ // this breaks the change event in IE
2264
+ // Support: IE and jQuery <1.9
2265
+ _shouldFocusInput: function( inst ) {
2266
+ return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
2267
+ },
2268
+
2269
+ /* Check positioning to remain on screen. */
2270
+ _checkOffset: function(inst, offset, isFixed) {
2271
+ var dpWidth = inst.dpDiv.outerWidth(),
2272
+ dpHeight = inst.dpDiv.outerHeight(),
2273
+ inputWidth = inst.input ? inst.input.outerWidth() : 0,
2274
+ inputHeight = inst.input ? inst.input.outerHeight() : 0,
2275
+ viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
2276
+ viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
2277
+
2278
+ offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
2279
+ offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
2280
+ offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
2281
+
2282
+ // now check if datepicker is showing outside window viewport - move to a better place if so.
2283
+ offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
2284
+ Math.abs(offset.left + dpWidth - viewWidth) : 0);
2285
+ offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
2286
+ Math.abs(dpHeight + inputHeight) : 0);
2287
+
2288
+ return offset;
2289
+ },
2290
+
2291
+ /* Find an object's position on the screen. */
2292
+ _findPos: function(obj) {
2293
+ var position,
2294
+ inst = this._getInst(obj),
2295
+ isRTL = this._get(inst, "isRTL");
2296
+
2297
+ while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
2298
+ obj = obj[isRTL ? "previousSibling" : "nextSibling"];
2299
+ }
2300
+
2301
+ position = $(obj).offset();
2302
+ return [position.left, position.top];
2303
+ },
2304
+
2305
+ /* Hide the date picker from view.
2306
+ * @param input element - the input field attached to the date picker
2307
+ */
2308
+ _hideDatepicker: function(input) {
2309
+ var showAnim, duration, postProcess, onClose,
2310
+ inst = this._curInst;
2311
+
2312
+ if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
2313
+ return;
2314
+ }
2315
+
2316
+ if (this._datepickerShowing) {
2317
+ showAnim = this._get(inst, "showAnim");
2318
+ duration = this._get(inst, "duration");
2319
+ postProcess = function() {
2320
+ $.datepicker._tidyDialog(inst);
2321
+ };
2322
+
2323
+ // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
2324
+ if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
2325
+ inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
2326
+ } else {
2327
+ inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
2328
+ (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
2329
+ }
2330
+
2331
+ if (!showAnim) {
2332
+ postProcess();
2333
+ }
2334
+ this._datepickerShowing = false;
2335
+
2336
+ onClose = this._get(inst, "onClose");
2337
+ if (onClose) {
2338
+ onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
2339
+ }
2340
+
2341
+ this._lastInput = null;
2342
+ if (this._inDialog) {
2343
+ this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
2344
+ if ($.blockUI) {
2345
+ $.unblockUI();
2346
+ $("body").append(this.dpDiv);
2347
+ }
2348
+ }
2349
+ this._inDialog = false;
2350
+ }
2351
+ },
2352
+
2353
+ /* Tidy up after a dialog display. */
2354
+ _tidyDialog: function(inst) {
2355
+ inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
2356
+ },
2357
+
2358
+ /* Close date picker if clicked elsewhere. */
2359
+ _checkExternalClick: function(event) {
2360
+ if (!$.datepicker._curInst) {
2361
+ return;
2362
+ }
2363
+
2364
+ var $target = $(event.target),
2365
+ inst = $.datepicker._getInst($target[0]);
2366
+
2367
+ if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
2368
+ $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
2369
+ !$target.hasClass($.datepicker.markerClassName) &&
2370
+ !$target.closest("." + $.datepicker._triggerClass).length &&
2371
+ $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
2372
+ ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
2373
+ $.datepicker._hideDatepicker();
2374
+ }
2375
+ },
2376
+
2377
+ /* Adjust one of the date sub-fields. */
2378
+ _adjustDate: function(id, offset, period) {
2379
+ var target = $(id),
2380
+ inst = this._getInst(target[0]);
2381
+
2382
+ if (this._isDisabledDatepicker(target[0])) {
2383
+ return;
2384
+ }
2385
+ this._adjustInstDate(inst, offset +
2386
+ (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
2387
+ period);
2388
+ this._updateDatepicker(inst);
2389
+ },
2390
+
2391
+ /* Action for current link. */
2392
+ _gotoToday: function(id) {
2393
+ var date,
2394
+ target = $(id),
2395
+ inst = this._getInst(target[0]);
2396
+
2397
+ if (this._get(inst, "gotoCurrent") && inst.currentDay) {
2398
+ inst.selectedDay = inst.currentDay;
2399
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth;
2400
+ inst.drawYear = inst.selectedYear = inst.currentYear;
2401
+ } else {
2402
+ date = new Date();
2403
+ inst.selectedDay = date.getDate();
2404
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
2405
+ inst.drawYear = inst.selectedYear = date.getFullYear();
2406
+ }
2407
+ this._notifyChange(inst);
2408
+ this._adjustDate(target);
2409
+ },
2410
+
2411
+ /* Action for selecting a new month/year. */
2412
+ _selectMonthYear: function(id, select, period) {
2413
+ var target = $(id),
2414
+ inst = this._getInst(target[0]);
2415
+
2416
+ inst["selected" + (period === "M" ? "Month" : "Year")] =
2417
+ inst["draw" + (period === "M" ? "Month" : "Year")] =
2418
+ parseInt(select.options[select.selectedIndex].value,10);
2419
+
2420
+ this._notifyChange(inst);
2421
+ this._adjustDate(target);
2422
+ },
2423
+
2424
+ /* Action for selecting a day. */
2425
+ _selectDay: function(id, month, year, td) {
2426
+ var inst,
2427
+ target = $(id);
2428
+
2429
+ if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
2430
+ return;
2431
+ }
2432
+
2433
+ inst = this._getInst(target[0]);
2434
+ inst.selectedDay = inst.currentDay = $("a", td).html();
2435
+ inst.selectedMonth = inst.currentMonth = month;
2436
+ inst.selectedYear = inst.currentYear = year;
2437
+ this._selectDate(id, this._formatDate(inst,
2438
+ inst.currentDay, inst.currentMonth, inst.currentYear));
2439
+ },
2440
+
2441
+ /* Erase the input field and hide the date picker. */
2442
+ _clearDate: function(id) {
2443
+ var target = $(id);
2444
+ this._selectDate(target, "");
2445
+ },
2446
+
2447
+ /* Update the input field with the selected date. */
2448
+ _selectDate: function(id, dateStr) {
2449
+ var onSelect,
2450
+ target = $(id),
2451
+ inst = this._getInst(target[0]);
2452
+
2453
+ dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
2454
+ if (inst.input) {
2455
+ inst.input.val(dateStr);
2456
+ }
2457
+ this._updateAlternate(inst);
2458
+
2459
+ onSelect = this._get(inst, "onSelect");
2460
+ if (onSelect) {
2461
+ onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
2462
+ } else if (inst.input) {
2463
+ inst.input.trigger("change"); // fire the change event
2464
+ }
2465
+
2466
+ if (inst.inline){
2467
+ this._updateDatepicker(inst);
2468
+ } else {
2469
+ this._hideDatepicker();
2470
+ this._lastInput = inst.input[0];
2471
+ if (typeof(inst.input[0]) !== "object") {
2472
+ inst.input.focus(); // restore focus
2473
+ }
2474
+ this._lastInput = null;
2475
+ }
2476
+ },
2477
+
2478
+ /* Update any alternate field to synchronise with the main field. */
2479
+ _updateAlternate: function(inst) {
2480
+ var altFormat, date, dateStr,
2481
+ altField = this._get(inst, "altField");
2482
+
2483
+ if (altField) { // update alternate field too
2484
+ altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
2485
+ date = this._getDate(inst);
2486
+ dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
2487
+ $(altField).each(function() { $(this).val(dateStr); });
2488
+ }
2489
+ },
2490
+
2491
+ /* Set as beforeShowDay function to prevent selection of weekends.
2492
+ * @param date Date - the date to customise
2493
+ * @return [boolean, string] - is this date selectable?, what is its CSS class?
2494
+ */
2495
+ noWeekends: function(date) {
2496
+ var day = date.getDay();
2497
+ return [(day > 0 && day < 6), ""];
2498
+ },
2499
+
2500
+ /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
2501
+ * @param date Date - the date to get the week for
2502
+ * @return number - the number of the week within the year that contains this date
2503
+ */
2504
+ iso8601Week: function(date) {
2505
+ var time,
2506
+ checkDate = new Date(date.getTime());
2507
+
2508
+ // Find Thursday of this week starting on Monday
2509
+ checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
2510
+
2511
+ time = checkDate.getTime();
2512
+ checkDate.setMonth(0); // Compare with Jan 1
2513
+ checkDate.setDate(1);
2514
+ return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
2515
+ },
2516
+
2517
+ /* Parse a string value into a date object.
2518
+ * See formatDate below for the possible formats.
2519
+ *
2520
+ * @param format string - the expected format of the date
2521
+ * @param value string - the date in the above format
2522
+ * @param settings Object - attributes include:
2523
+ * shortYearCutoff number - the cutoff year for determining the century (optional)
2524
+ * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
2525
+ * dayNames string[7] - names of the days from Sunday (optional)
2526
+ * monthNamesShort string[12] - abbreviated names of the months (optional)
2527
+ * monthNames string[12] - names of the months (optional)
2528
+ * @return Date - the extracted date value or null if value is blank
2529
+ */
2530
+ parseDate: function (format, value, settings) {
2531
+ if (format == null || value == null) {
2532
+ throw "Invalid arguments";
2533
+ }
2534
+
2535
+ value = (typeof value === "object" ? value.toString() : value + "");
2536
+ if (value === "") {
2537
+ return null;
2538
+ }
2539
+
2540
+ var iFormat, dim, extra,
2541
+ iValue = 0,
2542
+ shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
2543
+ shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
2544
+ new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
2545
+ dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
2546
+ dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
2547
+ monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
2548
+ monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
2549
+ year = -1,
2550
+ month = -1,
2551
+ day = -1,
2552
+ doy = -1,
2553
+ literal = false,
2554
+ date,
2555
+ // Check whether a format character is doubled
2556
+ lookAhead = function(match) {
2557
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
2558
+ if (matches) {
2559
+ iFormat++;
2560
+ }
2561
+ return matches;
2562
+ },
2563
+ // Extract a number from the string value
2564
+ getNumber = function(match) {
2565
+ var isDoubled = lookAhead(match),
2566
+ size = (match === "@" ? 14 : (match === "!" ? 20 :
2567
+ (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
2568
+ digits = new RegExp("^\\d{1," + size + "}"),
2569
+ num = value.substring(iValue).match(digits);
2570
+ if (!num) {
2571
+ throw "Missing number at position " + iValue;
2572
+ }
2573
+ iValue += num[0].length;
2574
+ return parseInt(num[0], 10);
2575
+ },
2576
+ // Extract a name from the string value and convert to an index
2577
+ getName = function(match, shortNames, longNames) {
2578
+ var index = -1,
2579
+ names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
2580
+ return [ [k, v] ];
2581
+ }).sort(function (a, b) {
2582
+ return -(a[1].length - b[1].length);
2583
+ });
2584
+
2585
+ $.each(names, function (i, pair) {
2586
+ var name = pair[1];
2587
+ if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
2588
+ index = pair[0];
2589
+ iValue += name.length;
2590
+ return false;
2591
+ }
2592
+ });
2593
+ if (index !== -1) {
2594
+ return index + 1;
2595
+ } else {
2596
+ throw "Unknown name at position " + iValue;
2597
+ }
2598
+ },
2599
+ // Confirm that a literal character matches the string value
2600
+ checkLiteral = function() {
2601
+ if (value.charAt(iValue) !== format.charAt(iFormat)) {
2602
+ throw "Unexpected literal at position " + iValue;
2603
+ }
2604
+ iValue++;
2605
+ };
2606
+
2607
+ for (iFormat = 0; iFormat < format.length; iFormat++) {
2608
+ if (literal) {
2609
+ if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
2610
+ literal = false;
2611
+ } else {
2612
+ checkLiteral();
2613
+ }
2614
+ } else {
2615
+ switch (format.charAt(iFormat)) {
2616
+ case "d":
2617
+ day = getNumber("d");
2618
+ break;
2619
+ case "D":
2620
+ getName("D", dayNamesShort, dayNames);
2621
+ break;
2622
+ case "o":
2623
+ doy = getNumber("o");
2624
+ break;
2625
+ case "m":
2626
+ month = getNumber("m");
2627
+ break;
2628
+ case "M":
2629
+ month = getName("M", monthNamesShort, monthNames);
2630
+ break;
2631
+ case "y":
2632
+ year = getNumber("y");
2633
+ break;
2634
+ case "@":
2635
+ date = new Date(getNumber("@"));
2636
+ year = date.getFullYear();
2637
+ month = date.getMonth() + 1;
2638
+ day = date.getDate();
2639
+ break;
2640
+ case "!":
2641
+ date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
2642
+ year = date.getFullYear();
2643
+ month = date.getMonth() + 1;
2644
+ day = date.getDate();
2645
+ break;
2646
+ case "'":
2647
+ if (lookAhead("'")){
2648
+ checkLiteral();
2649
+ } else {
2650
+ literal = true;
2651
+ }
2652
+ break;
2653
+ default:
2654
+ checkLiteral();
2655
+ }
2656
+ }
2657
+ }
2658
+
2659
+ if (iValue < value.length){
2660
+ extra = value.substr(iValue);
2661
+ if (!/^\s+/.test(extra)) {
2662
+ throw "Extra/unparsed characters found in date: " + extra;
2663
+ }
2664
+ }
2665
+
2666
+ if (year === -1) {
2667
+ year = new Date().getFullYear();
2668
+ } else if (year < 100) {
2669
+ year += new Date().getFullYear() - new Date().getFullYear() % 100 +
2670
+ (year <= shortYearCutoff ? 0 : -100);
2671
+ }
2672
+
2673
+ if (doy > -1) {
2674
+ month = 1;
2675
+ day = doy;
2676
+ do {
2677
+ dim = this._getDaysInMonth(year, month - 1);
2678
+ if (day <= dim) {
2679
+ break;
2680
+ }
2681
+ month++;
2682
+ day -= dim;
2683
+ } while (true);
2684
+ }
2685
+
2686
+ date = this._daylightSavingAdjust(new Date(year, month - 1, day));
2687
+ if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
2688
+ throw "Invalid date"; // E.g. 31/02/00
2689
+ }
2690
+ return date;
2691
+ },
2692
+
2693
+ /* Standard date formats. */
2694
+ ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
2695
+ COOKIE: "D, dd M yy",
2696
+ ISO_8601: "yy-mm-dd",
2697
+ RFC_822: "D, d M y",
2698
+ RFC_850: "DD, dd-M-y",
2699
+ RFC_1036: "D, d M y",
2700
+ RFC_1123: "D, d M yy",
2701
+ RFC_2822: "D, d M yy",
2702
+ RSS: "D, d M y", // RFC 822
2703
+ TICKS: "!",
2704
+ TIMESTAMP: "@",
2705
+ W3C: "yy-mm-dd", // ISO 8601
2706
+
2707
+ _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
2708
+ Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
2709
+
2710
+ /* Format a date object into a string value.
2711
+ * The format can be combinations of the following:
2712
+ * d - day of month (no leading zero)
2713
+ * dd - day of month (two digit)
2714
+ * o - day of year (no leading zeros)
2715
+ * oo - day of year (three digit)
2716
+ * D - day name short
2717
+ * DD - day name long
2718
+ * m - month of year (no leading zero)
2719
+ * mm - month of year (two digit)
2720
+ * M - month name short
2721
+ * MM - month name long
2722
+ * y - year (two digit)
2723
+ * yy - year (four digit)
2724
+ * @ - Unix timestamp (ms since 01/01/1970)
2725
+ * ! - Windows ticks (100ns since 01/01/0001)
2726
+ * "..." - literal text
2727
+ * '' - single quote
2728
+ *
2729
+ * @param format string - the desired format of the date
2730
+ * @param date Date - the date value to format
2731
+ * @param settings Object - attributes include:
2732
+ * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
2733
+ * dayNames string[7] - names of the days from Sunday (optional)
2734
+ * monthNamesShort string[12] - abbreviated names of the months (optional)
2735
+ * monthNames string[12] - names of the months (optional)
2736
+ * @return string - the date in the above format
2737
+ */
2738
+ formatDate: function (format, date, settings) {
2739
+ if (!date) {
2740
+ return "";
2741
+ }
2742
+
2743
+ var iFormat,
2744
+ dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
2745
+ dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
2746
+ monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
2747
+ monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
2748
+ // Check whether a format character is doubled
2749
+ lookAhead = function(match) {
2750
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
2751
+ if (matches) {
2752
+ iFormat++;
2753
+ }
2754
+ return matches;
2755
+ },
2756
+ // Format a number, with leading zero if necessary
2757
+ formatNumber = function(match, value, len) {
2758
+ var num = "" + value;
2759
+ if (lookAhead(match)) {
2760
+ while (num.length < len) {
2761
+ num = "0" + num;
2762
+ }
2763
+ }
2764
+ return num;
2765
+ },
2766
+ // Format a name, short or long as requested
2767
+ formatName = function(match, value, shortNames, longNames) {
2768
+ return (lookAhead(match) ? longNames[value] : shortNames[value]);
2769
+ },
2770
+ output = "",
2771
+ literal = false;
2772
+
2773
+ if (date) {
2774
+ for (iFormat = 0; iFormat < format.length; iFormat++) {
2775
+ if (literal) {
2776
+ if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
2777
+ literal = false;
2778
+ } else {
2779
+ output += format.charAt(iFormat);
2780
+ }
2781
+ } else {
2782
+ switch (format.charAt(iFormat)) {
2783
+ case "d":
2784
+ output += formatNumber("d", date.getDate(), 2);
2785
+ break;
2786
+ case "D":
2787
+ output += formatName("D", date.getDay(), dayNamesShort, dayNames);
2788
+ break;
2789
+ case "o":
2790
+ output += formatNumber("o",
2791
+ Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
2792
+ break;
2793
+ case "m":
2794
+ output += formatNumber("m", date.getMonth() + 1, 2);
2795
+ break;
2796
+ case "M":
2797
+ output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
2798
+ break;
2799
+ case "y":
2800
+ output += (lookAhead("y") ? date.getFullYear() :
2801
+ (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
2802
+ break;
2803
+ case "@":
2804
+ output += date.getTime();
2805
+ break;
2806
+ case "!":
2807
+ output += date.getTime() * 10000 + this._ticksTo1970;
2808
+ break;
2809
+ case "'":
2810
+ if (lookAhead("'")) {
2811
+ output += "'";
2812
+ } else {
2813
+ literal = true;
2814
+ }
2815
+ break;
2816
+ default:
2817
+ output += format.charAt(iFormat);
2818
+ }
2819
+ }
2820
+ }
2821
+ }
2822
+ return output;
2823
+ },
2824
+
2825
+ /* Extract all possible characters from the date format. */
2826
+ _possibleChars: function (format) {
2827
+ var iFormat,
2828
+ chars = "",
2829
+ literal = false,
2830
+ // Check whether a format character is doubled
2831
+ lookAhead = function(match) {
2832
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
2833
+ if (matches) {
2834
+ iFormat++;
2835
+ }
2836
+ return matches;
2837
+ };
2838
+
2839
+ for (iFormat = 0; iFormat < format.length; iFormat++) {
2840
+ if (literal) {
2841
+ if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
2842
+ literal = false;
2843
+ } else {
2844
+ chars += format.charAt(iFormat);
2845
+ }
2846
+ } else {
2847
+ switch (format.charAt(iFormat)) {
2848
+ case "d": case "m": case "y": case "@":
2849
+ chars += "0123456789";
2850
+ break;
2851
+ case "D": case "M":
2852
+ return null; // Accept anything
2853
+ case "'":
2854
+ if (lookAhead("'")) {
2855
+ chars += "'";
2856
+ } else {
2857
+ literal = true;
2858
+ }
2859
+ break;
2860
+ default:
2861
+ chars += format.charAt(iFormat);
2862
+ }
2863
+ }
2864
+ }
2865
+ return chars;
2866
+ },
2867
+
2868
+ /* Get a setting value, defaulting if necessary. */
2869
+ _get: function(inst, name) {
2870
+ return inst.settings[name] !== undefined ?
2871
+ inst.settings[name] : this._defaults[name];
2872
+ },
2873
+
2874
+ /* Parse existing date and initialise date picker. */
2875
+ _setDateFromField: function(inst, noDefault) {
2876
+ if (inst.input.val() === inst.lastVal) {
2877
+ return;
2878
+ }
2879
+
2880
+ var dateFormat = this._get(inst, "dateFormat"),
2881
+ dates = inst.lastVal = inst.input ? inst.input.val() : null,
2882
+ defaultDate = this._getDefaultDate(inst),
2883
+ date = defaultDate,
2884
+ settings = this._getFormatConfig(inst);
2885
+
2886
+ try {
2887
+ date = this.parseDate(dateFormat, dates, settings) || defaultDate;
2888
+ } catch (event) {
2889
+ dates = (noDefault ? "" : dates);
2890
+ }
2891
+ inst.selectedDay = date.getDate();
2892
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
2893
+ inst.drawYear = inst.selectedYear = date.getFullYear();
2894
+ inst.currentDay = (dates ? date.getDate() : 0);
2895
+ inst.currentMonth = (dates ? date.getMonth() : 0);
2896
+ inst.currentYear = (dates ? date.getFullYear() : 0);
2897
+ this._adjustInstDate(inst);
2898
+ },
2899
+
2900
+ /* Retrieve the default date shown on opening. */
2901
+ _getDefaultDate: function(inst) {
2902
+ return this._restrictMinMax(inst,
2903
+ this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
2904
+ },
2905
+
2906
+ /* A date may be specified as an exact value or a relative one. */
2907
+ _determineDate: function(inst, date, defaultDate) {
2908
+ var offsetNumeric = function(offset) {
2909
+ var date = new Date();
2910
+ date.setDate(date.getDate() + offset);
2911
+ return date;
2912
+ },
2913
+ offsetString = function(offset) {
2914
+ try {
2915
+ return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
2916
+ offset, $.datepicker._getFormatConfig(inst));
2917
+ }
2918
+ catch (e) {
2919
+ // Ignore
2920
+ }
2921
+
2922
+ var date = (offset.toLowerCase().match(/^c/) ?
2923
+ $.datepicker._getDate(inst) : null) || new Date(),
2924
+ year = date.getFullYear(),
2925
+ month = date.getMonth(),
2926
+ day = date.getDate(),
2927
+ pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
2928
+ matches = pattern.exec(offset);
2929
+
2930
+ while (matches) {
2931
+ switch (matches[2] || "d") {
2932
+ case "d" : case "D" :
2933
+ day += parseInt(matches[1],10); break;
2934
+ case "w" : case "W" :
2935
+ day += parseInt(matches[1],10) * 7; break;
2936
+ case "m" : case "M" :
2937
+ month += parseInt(matches[1],10);
2938
+ day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
2939
+ break;
2940
+ case "y": case "Y" :
2941
+ year += parseInt(matches[1],10);
2942
+ day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
2943
+ break;
2944
+ }
2945
+ matches = pattern.exec(offset);
2946
+ }
2947
+ return new Date(year, month, day);
2948
+ },
2949
+ newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
2950
+ (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
2951
+
2952
+ newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
2953
+ if (newDate) {
2954
+ newDate.setHours(0);
2955
+ newDate.setMinutes(0);
2956
+ newDate.setSeconds(0);
2957
+ newDate.setMilliseconds(0);
2958
+ }
2959
+ return this._daylightSavingAdjust(newDate);
2960
+ },
2961
+
2962
+ /* Handle switch to/from daylight saving.
2963
+ * Hours may be non-zero on daylight saving cut-over:
2964
+ * > 12 when midnight changeover, but then cannot generate
2965
+ * midnight datetime, so jump to 1AM, otherwise reset.
2966
+ * @param date (Date) the date to check
2967
+ * @return (Date) the corrected date
2968
+ */
2969
+ _daylightSavingAdjust: function(date) {
2970
+ if (!date) {
2971
+ return null;
2972
+ }
2973
+ date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
2974
+ return date;
2975
+ },
2976
+
2977
+ /* Set the date(s) directly. */
2978
+ _setDate: function(inst, date, noChange) {
2979
+ var clear = !date,
2980
+ origMonth = inst.selectedMonth,
2981
+ origYear = inst.selectedYear,
2982
+ newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
2983
+
2984
+ inst.selectedDay = inst.currentDay = newDate.getDate();
2985
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
2986
+ inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
2987
+ if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
2988
+ this._notifyChange(inst);
2989
+ }
2990
+ this._adjustInstDate(inst);
2991
+ if (inst.input) {
2992
+ inst.input.val(clear ? "" : this._formatDate(inst));
2993
+ }
2994
+ },
2995
+
2996
+ /* Retrieve the date(s) directly. */
2997
+ _getDate: function(inst) {
2998
+ var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
2999
+ this._daylightSavingAdjust(new Date(
3000
+ inst.currentYear, inst.currentMonth, inst.currentDay)));
3001
+ return startDate;
3002
+ },
3003
+
3004
+ /* Attach the onxxx handlers. These are declared statically so
3005
+ * they work with static code transformers like Caja.
3006
+ */
3007
+ _attachHandlers: function(inst) {
3008
+ var stepMonths = this._get(inst, "stepMonths"),
3009
+ id = "#" + inst.id.replace( /\\\\/g, "\\" );
3010
+ inst.dpDiv.find("[data-handler]").map(function () {
3011
+ var handler = {
3012
+ prev: function () {
3013
+ $.datepicker._adjustDate(id, -stepMonths, "M");
3014
+ },
3015
+ next: function () {
3016
+ $.datepicker._adjustDate(id, +stepMonths, "M");
3017
+ },
3018
+ hide: function () {
3019
+ $.datepicker._hideDatepicker();
3020
+ },
3021
+ today: function () {
3022
+ $.datepicker._gotoToday(id);
3023
+ },
3024
+ selectDay: function () {
3025
+ $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
3026
+ return false;
3027
+ },
3028
+ selectMonth: function () {
3029
+ $.datepicker._selectMonthYear(id, this, "M");
3030
+ return false;
3031
+ },
3032
+ selectYear: function () {
3033
+ $.datepicker._selectMonthYear(id, this, "Y");
3034
+ return false;
3035
+ }
3036
+ };
3037
+ $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
3038
+ });
3039
+ },
3040
+
3041
+ /* Generate the HTML for the current state of the date picker. */
3042
+ _generateHTML: function(inst) {
3043
+ var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
3044
+ controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
3045
+ monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
3046
+ selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
3047
+ cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
3048
+ printDate, dRow, tbody, daySettings, otherMonth, unselectable,
3049
+ tempDate = new Date(),
3050
+ today = this._daylightSavingAdjust(
3051
+ new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
3052
+ isRTL = this._get(inst, "isRTL"),
3053
+ showButtonPanel = this._get(inst, "showButtonPanel"),
3054
+ hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
3055
+ navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
3056
+ numMonths = this._getNumberOfMonths(inst),
3057
+ showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
3058
+ stepMonths = this._get(inst, "stepMonths"),
3059
+ isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
3060
+ currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
3061
+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
3062
+ minDate = this._getMinMaxDate(inst, "min"),
3063
+ maxDate = this._getMinMaxDate(inst, "max"),
3064
+ drawMonth = inst.drawMonth - showCurrentAtPos,
3065
+ drawYear = inst.drawYear;
3066
+
3067
+ if (drawMonth < 0) {
3068
+ drawMonth += 12;
3069
+ drawYear--;
3070
+ }
3071
+ if (maxDate) {
3072
+ maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
3073
+ maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
3074
+ maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
3075
+ while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
3076
+ drawMonth--;
3077
+ if (drawMonth < 0) {
3078
+ drawMonth = 11;
3079
+ drawYear--;
3080
+ }
3081
+ }
3082
+ }
3083
+ inst.drawMonth = drawMonth;
3084
+ inst.drawYear = drawYear;
3085
+
3086
+ prevText = this._get(inst, "prevText");
3087
+ prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
3088
+ this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
3089
+ this._getFormatConfig(inst)));
3090
+
3091
+ prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
3092
+ "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
3093
+ " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
3094
+ (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
3095
+
3096
+ nextText = this._get(inst, "nextText");
3097
+ nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
3098
+ this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
3099
+ this._getFormatConfig(inst)));
3100
+
3101
+ next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
3102
+ "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
3103
+ " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
3104
+ (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
3105
+
3106
+ currentText = this._get(inst, "currentText");
3107
+ gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
3108
+ currentText = (!navigationAsDateFormat ? currentText :
3109
+ this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
3110
+
3111
+ 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'>" +
3112
+ this._get(inst, "closeText") + "</button>" : "");
3113
+
3114
+ buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
3115
+ (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'" +
3116
+ ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
3117
+
3118
+ firstDay = parseInt(this._get(inst, "firstDay"),10);
3119
+ firstDay = (isNaN(firstDay) ? 0 : firstDay);
3120
+
3121
+ showWeek = this._get(inst, "showWeek");
3122
+ dayNames = this._get(inst, "dayNames");
3123
+ dayNamesMin = this._get(inst, "dayNamesMin");
3124
+ monthNames = this._get(inst, "monthNames");
3125
+ monthNamesShort = this._get(inst, "monthNamesShort");
3126
+ beforeShowDay = this._get(inst, "beforeShowDay");
3127
+ showOtherMonths = this._get(inst, "showOtherMonths");
3128
+ selectOtherMonths = this._get(inst, "selectOtherMonths");
3129
+ defaultDate = this._getDefaultDate(inst);
3130
+ html = "";
3131
+ dow;
3132
+ for (row = 0; row < numMonths[0]; row++) {
3133
+ group = "";
3134
+ this.maxRows = 4;
3135
+ for (col = 0; col < numMonths[1]; col++) {
3136
+ selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
3137
+ cornerClass = " ui-corner-all";
3138
+ calender = "";
3139
+ if (isMultiMonth) {
3140
+ calender += "<div class='ui-datepicker-group";
3141
+ if (numMonths[1] > 1) {
3142
+ switch (col) {
3143
+ case 0: calender += " ui-datepicker-group-first";
3144
+ cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
3145
+ case numMonths[1]-1: calender += " ui-datepicker-group-last";
3146
+ cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
3147
+ default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
3148
+ }
3149
+ }
3150
+ calender += "'>";
3151
+ }
3152
+ calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
3153
+ (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
3154
+ (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
3155
+ this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
3156
+ row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
3157
+ "</div><table class='ui-datepicker-calendar'><thead>" +
3158
+ "<tr>";
3159
+ thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
3160
+ for (dow = 0; dow < 7; dow++) { // days of the week
3161
+ day = (dow + firstDay) % 7;
3162
+ thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
3163
+ "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
3164
+ }
3165
+ calender += thead + "</tr></thead><tbody>";
3166
+ daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
3167
+ if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
3168
+ inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
3169
+ }
3170
+ leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
3171
+ curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
3172
+ numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
3173
+ this.maxRows = numRows;
3174
+ printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
3175
+ for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
3176
+ calender += "<tr>";
3177
+ tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
3178
+ this._get(inst, "calculateWeek")(printDate) + "</td>");
3179
+ for (dow = 0; dow < 7; dow++) { // create date picker days
3180
+ daySettings = (beforeShowDay ?
3181
+ beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
3182
+ otherMonth = (printDate.getMonth() !== drawMonth);
3183
+ unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
3184
+ (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
3185
+ tbody += "<td class='" +
3186
+ ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
3187
+ (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
3188
+ ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
3189
+ (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
3190
+ // or defaultDate is current printedDate and defaultDate is selectedDate
3191
+ " " + this._dayOverClass : "") + // highlight selected day
3192
+ (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days
3193
+ (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
3194
+ (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
3195
+ (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
3196
+ ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
3197
+ (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
3198
+ (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
3199
+ (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
3200
+ (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
3201
+ (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
3202
+ (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
3203
+ "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
3204
+ printDate.setDate(printDate.getDate() + 1);
3205
+ printDate = this._daylightSavingAdjust(printDate);
3206
+ }
3207
+ calender += tbody + "</tr>";
3208
+ }
3209
+ drawMonth++;
3210
+ if (drawMonth > 11) {
3211
+ drawMonth = 0;
3212
+ drawYear++;
3213
+ }
3214
+ calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
3215
+ ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
3216
+ group += calender;
3217
+ }
3218
+ html += group;
3219
+ }
3220
+ html += buttonPanel;
3221
+ inst._keyEvent = false;
3222
+ return html;
3223
+ },
3224
+
3225
+ /* Generate the month and year header. */
3226
+ _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
3227
+ secondary, monthNames, monthNamesShort) {
3228
+
3229
+ var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
3230
+ changeMonth = this._get(inst, "changeMonth"),
3231
+ changeYear = this._get(inst, "changeYear"),
3232
+ showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
3233
+ html = "<div class='ui-datepicker-title'>",
3234
+ monthHtml = "";
3235
+
3236
+ // month selection
3237
+ if (secondary || !changeMonth) {
3238
+ monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
3239
+ } else {
3240
+ inMinYear = (minDate && minDate.getFullYear() === drawYear);
3241
+ inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
3242
+ monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
3243
+ for ( month = 0; month < 12; month++) {
3244
+ if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
3245
+ monthHtml += "<option value='" + month + "'" +
3246
+ (month === drawMonth ? " selected='selected'" : "") +
3247
+ ">" + monthNamesShort[month] + "</option>";
3248
+ }
3249
+ }
3250
+ monthHtml += "</select>";
3251
+ }
3252
+
3253
+ if (!showMonthAfterYear) {
3254
+ html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
3255
+ }
3256
+
3257
+ // year selection
3258
+ if ( !inst.yearshtml ) {
3259
+ inst.yearshtml = "";
3260
+ if (secondary || !changeYear) {
3261
+ html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
3262
+ } else {
3263
+ // determine range of years to display
3264
+ years = this._get(inst, "yearRange").split(":");
3265
+ thisYear = new Date().getFullYear();
3266
+ determineYear = function(value) {
3267
+ var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
3268
+ (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
3269
+ parseInt(value, 10)));
3270
+ return (isNaN(year) ? thisYear : year);
3271
+ };
3272
+ year = determineYear(years[0]);
3273
+ endYear = Math.max(year, determineYear(years[1] || ""));
3274
+ year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
3275
+ endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
3276
+ inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
3277
+ for (; year <= endYear; year++) {
3278
+ inst.yearshtml += "<option value='" + year + "'" +
3279
+ (year === drawYear ? " selected='selected'" : "") +
3280
+ ">" + year + "</option>";
3281
+ }
3282
+ inst.yearshtml += "</select>";
3283
+
3284
+ html += inst.yearshtml;
3285
+ inst.yearshtml = null;
3286
+ }
3287
+ }
3288
+
3289
+ html += this._get(inst, "yearSuffix");
3290
+ if (showMonthAfterYear) {
3291
+ html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
3292
+ }
3293
+ html += "</div>"; // Close datepicker_header
3294
+ return html;
3295
+ },
3296
+
3297
+ /* Adjust one of the date sub-fields. */
3298
+ _adjustInstDate: function(inst, offset, period) {
3299
+ var year = inst.drawYear + (period === "Y" ? offset : 0),
3300
+ month = inst.drawMonth + (period === "M" ? offset : 0),
3301
+ day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
3302
+ date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
3303
+
3304
+ inst.selectedDay = date.getDate();
3305
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
3306
+ inst.drawYear = inst.selectedYear = date.getFullYear();
3307
+ if (period === "M" || period === "Y") {
3308
+ this._notifyChange(inst);
3309
+ }
3310
+ },
3311
+
3312
+ /* Ensure a date is within any min/max bounds. */
3313
+ _restrictMinMax: function(inst, date) {
3314
+ var minDate = this._getMinMaxDate(inst, "min"),
3315
+ maxDate = this._getMinMaxDate(inst, "max"),
3316
+ newDate = (minDate && date < minDate ? minDate : date);
3317
+ return (maxDate && newDate > maxDate ? maxDate : newDate);
3318
+ },
3319
+
3320
+ /* Notify change of month/year. */
3321
+ _notifyChange: function(inst) {
3322
+ var onChange = this._get(inst, "onChangeMonthYear");
3323
+ if (onChange) {
3324
+ onChange.apply((inst.input ? inst.input[0] : null),
3325
+ [inst.selectedYear, inst.selectedMonth + 1, inst]);
3326
+ }
3327
+ },
3328
+
3329
+ /* Determine the number of months to show. */
3330
+ _getNumberOfMonths: function(inst) {
3331
+ var numMonths = this._get(inst, "numberOfMonths");
3332
+ return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
3333
+ },
3334
+
3335
+ /* Determine the current maximum date - ensure no time components are set. */
3336
+ _getMinMaxDate: function(inst, minMax) {
3337
+ return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
3338
+ },
3339
+
3340
+ /* Find the number of days in a given month. */
3341
+ _getDaysInMonth: function(year, month) {
3342
+ return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
3343
+ },
3344
+
3345
+ /* Find the day of the week of the first of a month. */
3346
+ _getFirstDayOfMonth: function(year, month) {
3347
+ return new Date(year, month, 1).getDay();
3348
+ },
3349
+
3350
+ /* Determines if we should allow a "next/prev" month display change. */
3351
+ _canAdjustMonth: function(inst, offset, curYear, curMonth) {
3352
+ var numMonths = this._getNumberOfMonths(inst),
3353
+ date = this._daylightSavingAdjust(new Date(curYear,
3354
+ curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
3355
+
3356
+ if (offset < 0) {
3357
+ date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
3358
+ }
3359
+ return this._isInRange(inst, date);
3360
+ },
3361
+
3362
+ /* Is the given date in the accepted range? */
3363
+ _isInRange: function(inst, date) {
3364
+ var yearSplit, currentYear,
3365
+ minDate = this._getMinMaxDate(inst, "min"),
3366
+ maxDate = this._getMinMaxDate(inst, "max"),
3367
+ minYear = null,
3368
+ maxYear = null,
3369
+ years = this._get(inst, "yearRange");
3370
+ if (years){
3371
+ yearSplit = years.split(":");
3372
+ currentYear = new Date().getFullYear();
3373
+ minYear = parseInt(yearSplit[0], 10);
3374
+ maxYear = parseInt(yearSplit[1], 10);
3375
+ if ( yearSplit[0].match(/[+\-].*/) ) {
3376
+ minYear += currentYear;
3377
+ }
3378
+ if ( yearSplit[1].match(/[+\-].*/) ) {
3379
+ maxYear += currentYear;
3380
+ }
3381
+ }
3382
+
3383
+ return ((!minDate || date.getTime() >= minDate.getTime()) &&
3384
+ (!maxDate || date.getTime() <= maxDate.getTime()) &&
3385
+ (!minYear || date.getFullYear() >= minYear) &&
3386
+ (!maxYear || date.getFullYear() <= maxYear));
3387
+ },
3388
+
3389
+ /* Provide the configuration settings for formatting/parsing. */
3390
+ _getFormatConfig: function(inst) {
3391
+ var shortYearCutoff = this._get(inst, "shortYearCutoff");
3392
+ shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
3393
+ new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
3394
+ return {shortYearCutoff: shortYearCutoff,
3395
+ dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
3396
+ monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
3397
+ },
3398
+
3399
+ /* Format the given date for display. */
3400
+ _formatDate: function(inst, day, month, year) {
3401
+ if (!day) {
3402
+ inst.currentDay = inst.selectedDay;
3403
+ inst.currentMonth = inst.selectedMonth;
3404
+ inst.currentYear = inst.selectedYear;
3405
+ }
3406
+ var date = (day ? (typeof day === "object" ? day :
3407
+ this._daylightSavingAdjust(new Date(year, month, day))) :
3408
+ this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
3409
+ return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
3410
+ }
3411
+ });
3412
+
3413
+ /*
3414
+ * Bind hover events for datepicker elements.
3415
+ * Done via delegate so the binding only occurs once in the lifetime of the parent div.
3416
+ * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
3417
+ */
3418
+ function bindHover(dpDiv) {
3419
+ var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
3420
+ return dpDiv.delegate(selector, "mouseout", function() {
3421
+ $(this).removeClass("ui-state-hover");
3422
+ if (this.className.indexOf("ui-datepicker-prev") !== -1) {
3423
+ $(this).removeClass("ui-datepicker-prev-hover");
3424
+ }
3425
+ if (this.className.indexOf("ui-datepicker-next") !== -1) {
3426
+ $(this).removeClass("ui-datepicker-next-hover");
3427
+ }
3428
+ })
3429
+ .delegate(selector, "mouseover", function(){
3430
+ if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
3431
+ $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
3432
+ $(this).addClass("ui-state-hover");
3433
+ if (this.className.indexOf("ui-datepicker-prev") !== -1) {
3434
+ $(this).addClass("ui-datepicker-prev-hover");
3435
+ }
3436
+ if (this.className.indexOf("ui-datepicker-next") !== -1) {
3437
+ $(this).addClass("ui-datepicker-next-hover");
3438
+ }
3439
+ }
3440
+ });
3441
+ }
3442
+
3443
+ /* jQuery extend now ignores nulls! */
3444
+ function extendRemove(target, props) {
3445
+ $.extend(target, props);
3446
+ for (var name in props) {
3447
+ if (props[name] == null) {
3448
+ target[name] = props[name];
3449
+ }
3450
+ }
3451
+ return target;
3452
+ }
3453
+
3454
+ /* Invoke the datepicker functionality.
3455
+ @param options string - a command, optionally followed by additional parameters or
3456
+ Object - settings for attaching new datepicker functionality
3457
+ @return jQuery object */
3458
+ $.fn.datepicker = function(options){
3459
+
3460
+ /* Verify an empty collection wasn't passed - Fixes #6976 */
3461
+ if ( !this.length ) {
3462
+ return this;
3463
+ }
3464
+
3465
+ /* Initialise the date picker. */
3466
+ if (!$.datepicker.initialized) {
3467
+ $(document).mousedown($.datepicker._checkExternalClick);
3468
+ $.datepicker.initialized = true;
3469
+ }
3470
+
3471
+ /* Append datepicker main container to body if not exist. */
3472
+ if ($("#"+$.datepicker._mainDivId).length === 0) {
3473
+ $("body").append($.datepicker.dpDiv);
3474
+ }
3475
+
3476
+ var otherArgs = Array.prototype.slice.call(arguments, 1);
3477
+ if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
3478
+ return $.datepicker["_" + options + "Datepicker"].
3479
+ apply($.datepicker, [this[0]].concat(otherArgs));
3480
+ }
3481
+ if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
3482
+ return $.datepicker["_" + options + "Datepicker"].
3483
+ apply($.datepicker, [this[0]].concat(otherArgs));
3484
+ }
3485
+ return this.each(function() {
3486
+ typeof options === "string" ?
3487
+ $.datepicker["_" + options + "Datepicker"].
3488
+ apply($.datepicker, [this].concat(otherArgs)) :
3489
+ $.datepicker._attachDatepicker(this, options);
3490
+ });
3491
+ };
3492
+
3493
+ $.datepicker = new Datepicker(); // singleton instance
3494
+ $.datepicker.initialized = false;
3495
+ $.datepicker.uuid = new Date().getTime();
3496
+ $.datepicker.version = "1.10.4";
3497
+
3498
+ })(jQuery);