tb_core 1.2.6 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/libs/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  3. data/app/assets/libs/jquery-ui/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  4. data/app/assets/libs/jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  5. data/app/assets/libs/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  6. data/app/assets/libs/jquery-ui/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  7. data/app/assets/libs/jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  8. data/app/assets/libs/jquery-ui/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  9. data/app/assets/libs/jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  10. data/app/assets/libs/jquery-ui/images/{ui-icons_228ef1_256x240.png → ui-icons_2e83ff_256x240.png} +0 -0
  11. data/app/assets/libs/jquery-ui/images/ui-icons_454545_256x240.png +0 -0
  12. data/app/assets/libs/jquery-ui/images/ui-icons_888888_256x240.png +0 -0
  13. data/app/assets/libs/jquery-ui/images/{ui-icons_ef8c08_256x240.png → ui-icons_cd0a0a_256x240.png} +0 -0
  14. data/app/assets/libs/jquery-ui/jquery-ui.js +3486 -2
  15. data/app/assets/libs/jquery-ui/{jquery-ui.css.scss → jquery-ui.scss} +309 -77
  16. data/lib/spud_core/version.rb +1 -1
  17. metadata +14 -32
  18. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  19. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  20. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-bg_flat_55_ffffff_40x100.png +0 -0
  21. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  22. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  23. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png +0 -0
  24. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png +0 -0
  25. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png +0 -0
  26. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-icons_0073ea_256x240.png +0 -0
  27. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-icons_454545_256x240.png +0 -0
  28. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-icons_666666_256x240.png +0 -0
  29. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-icons_ff0084_256x240.png +0 -0
  30. data/app/assets/libs/jquery-ui-old/css/flick/images/ui-icons_ffffff_256x240.png +0 -0
  31. data/app/assets/libs/jquery-ui-old/css/flick/jquery-ui-1.9.1.custom.css +0 -297
  32. data/app/assets/libs/jquery-ui-old/css/flick/jquery-ui-1.9.1.custom.min.css +0 -5
  33. data/app/assets/libs/jquery-ui-old/js/jquery-ui-1.9.1.custom.js +0 -4870
  34. data/app/assets/libs/jquery-ui-old/js/jquery-ui-1.9.1.custom.min.js +0 -6
  35. data/app/assets/libs/jquery-ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  36. data/app/assets/libs/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  37. data/app/assets/libs/jquery-ui/images/ui-bg_flat_10_000000_40x100.png +0 -0
  38. data/app/assets/libs/jquery-ui/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  39. data/app/assets/libs/jquery-ui/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  40. data/app/assets/libs/jquery-ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  41. data/app/assets/libs/jquery-ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  42. data/app/assets/libs/jquery-ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  43. data/app/assets/libs/jquery-ui/images/ui-icons_ffd27a_256x240.png +0 -0
  44. data/app/assets/libs/jquery-ui/images/ui-icons_ffffff_256x240.png +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0995b70d53813ddd5e1ebbbdd6204d05bf578162
4
- data.tar.gz: 540e350accfc57eb8041a07cddc45b6e2c528f95
3
+ metadata.gz: 1b7fb2a20414e7e1f3c6231fc0d87d8884c770e0
4
+ data.tar.gz: 7abfcd98b5851a0d15b8a46b189c24e01e69f1b4
5
5
  SHA512:
6
- metadata.gz: 4c82914ae0bc2d21cf85b6f56deebfbd7f5c12b8ac5c0030085fada42db0031ecb1a5e3f39b42fa38f3ab2f7ca491b26ad43ca7e4dde1cdb6d20ba0550f705ae
7
- data.tar.gz: 0cefa04341cd76b2d2c6aeafdeeebf422379e59bce09944e823a70749218a44e04bc2eb64bff1179cf314170fb8cfbeb2659a8651ead0c0cff74c4aca250d8c0
6
+ metadata.gz: 5b0a3a31e3129b89d02ea0b6b028f12fd2ad9d37f4a9bccebc9ffd19afc8db1d0ea81d403007875efea708912840727c5005a4b407356897780297b998e299f0
7
+ data.tar.gz: 2f49b1ae926d600e560287de6187bbf23c15e613af3c51bb7627ad564aa1caecc6a603e3ff542ef91a03856f49d0b9d83974bfdd3707efa78a5320b8f6518a70
@@ -1,6 +1,6 @@
1
- /*! jQuery UI - v1.11.1 - 2014-08-20
1
+ /*! jQuery UI - v1.11.1 - 2014-09-09
2
2
  * http://jqueryui.com
3
- * Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, sortable.js, autocomplete.js, menu.js
3
+ * Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, sortable.js, accordion.js, autocomplete.js, datepicker.js, menu.js, tabs.js
4
4
  * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5
5
 
6
6
  (function( factory ) {
@@ -4227,6 +4227,567 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, {
4227
4227
  });
4228
4228
 
4229
4229
 
4230
+ /*!
4231
+ * jQuery UI Accordion 1.11.1
4232
+ * http://jqueryui.com
4233
+ *
4234
+ * Copyright 2014 jQuery Foundation and other contributors
4235
+ * Released under the MIT license.
4236
+ * http://jquery.org/license
4237
+ *
4238
+ * http://api.jqueryui.com/accordion/
4239
+ */
4240
+
4241
+
4242
+ var accordion = $.widget( "ui.accordion", {
4243
+ version: "1.11.1",
4244
+ options: {
4245
+ active: 0,
4246
+ animate: {},
4247
+ collapsible: false,
4248
+ event: "click",
4249
+ header: "> li > :first-child,> :not(li):even",
4250
+ heightStyle: "auto",
4251
+ icons: {
4252
+ activeHeader: "ui-icon-triangle-1-s",
4253
+ header: "ui-icon-triangle-1-e"
4254
+ },
4255
+
4256
+ // callbacks
4257
+ activate: null,
4258
+ beforeActivate: null
4259
+ },
4260
+
4261
+ hideProps: {
4262
+ borderTopWidth: "hide",
4263
+ borderBottomWidth: "hide",
4264
+ paddingTop: "hide",
4265
+ paddingBottom: "hide",
4266
+ height: "hide"
4267
+ },
4268
+
4269
+ showProps: {
4270
+ borderTopWidth: "show",
4271
+ borderBottomWidth: "show",
4272
+ paddingTop: "show",
4273
+ paddingBottom: "show",
4274
+ height: "show"
4275
+ },
4276
+
4277
+ _create: function() {
4278
+ var options = this.options;
4279
+ this.prevShow = this.prevHide = $();
4280
+ this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
4281
+ // ARIA
4282
+ .attr( "role", "tablist" );
4283
+
4284
+ // don't allow collapsible: false and active: false / null
4285
+ if ( !options.collapsible && (options.active === false || options.active == null) ) {
4286
+ options.active = 0;
4287
+ }
4288
+
4289
+ this._processPanels();
4290
+ // handle negative values
4291
+ if ( options.active < 0 ) {
4292
+ options.active += this.headers.length;
4293
+ }
4294
+ this._refresh();
4295
+ },
4296
+
4297
+ _getCreateEventData: function() {
4298
+ return {
4299
+ header: this.active,
4300
+ panel: !this.active.length ? $() : this.active.next()
4301
+ };
4302
+ },
4303
+
4304
+ _createIcons: function() {
4305
+ var icons = this.options.icons;
4306
+ if ( icons ) {
4307
+ $( "<span>" )
4308
+ .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
4309
+ .prependTo( this.headers );
4310
+ this.active.children( ".ui-accordion-header-icon" )
4311
+ .removeClass( icons.header )
4312
+ .addClass( icons.activeHeader );
4313
+ this.headers.addClass( "ui-accordion-icons" );
4314
+ }
4315
+ },
4316
+
4317
+ _destroyIcons: function() {
4318
+ this.headers
4319
+ .removeClass( "ui-accordion-icons" )
4320
+ .children( ".ui-accordion-header-icon" )
4321
+ .remove();
4322
+ },
4323
+
4324
+ _destroy: function() {
4325
+ var contents;
4326
+
4327
+ // clean up main element
4328
+ this.element
4329
+ .removeClass( "ui-accordion ui-widget ui-helper-reset" )
4330
+ .removeAttr( "role" );
4331
+
4332
+ // clean up headers
4333
+ this.headers
4334
+ .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
4335
+ "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
4336
+ .removeAttr( "role" )
4337
+ .removeAttr( "aria-expanded" )
4338
+ .removeAttr( "aria-selected" )
4339
+ .removeAttr( "aria-controls" )
4340
+ .removeAttr( "tabIndex" )
4341
+ .removeUniqueId();
4342
+
4343
+ this._destroyIcons();
4344
+
4345
+ // clean up content panels
4346
+ contents = this.headers.next()
4347
+ .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
4348
+ "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
4349
+ .css( "display", "" )
4350
+ .removeAttr( "role" )
4351
+ .removeAttr( "aria-hidden" )
4352
+ .removeAttr( "aria-labelledby" )
4353
+ .removeUniqueId();
4354
+
4355
+ if ( this.options.heightStyle !== "content" ) {
4356
+ contents.css( "height", "" );
4357
+ }
4358
+ },
4359
+
4360
+ _setOption: function( key, value ) {
4361
+ if ( key === "active" ) {
4362
+ // _activate() will handle invalid values and update this.options
4363
+ this._activate( value );
4364
+ return;
4365
+ }
4366
+
4367
+ if ( key === "event" ) {
4368
+ if ( this.options.event ) {
4369
+ this._off( this.headers, this.options.event );
4370
+ }
4371
+ this._setupEvents( value );
4372
+ }
4373
+
4374
+ this._super( key, value );
4375
+
4376
+ // setting collapsible: false while collapsed; open first panel
4377
+ if ( key === "collapsible" && !value && this.options.active === false ) {
4378
+ this._activate( 0 );
4379
+ }
4380
+
4381
+ if ( key === "icons" ) {
4382
+ this._destroyIcons();
4383
+ if ( value ) {
4384
+ this._createIcons();
4385
+ }
4386
+ }
4387
+
4388
+ // #5332 - opacity doesn't cascade to positioned elements in IE
4389
+ // so we need to add the disabled class to the headers and panels
4390
+ if ( key === "disabled" ) {
4391
+ this.element
4392
+ .toggleClass( "ui-state-disabled", !!value )
4393
+ .attr( "aria-disabled", value );
4394
+ this.headers.add( this.headers.next() )
4395
+ .toggleClass( "ui-state-disabled", !!value );
4396
+ }
4397
+ },
4398
+
4399
+ _keydown: function( event ) {
4400
+ if ( event.altKey || event.ctrlKey ) {
4401
+ return;
4402
+ }
4403
+
4404
+ var keyCode = $.ui.keyCode,
4405
+ length = this.headers.length,
4406
+ currentIndex = this.headers.index( event.target ),
4407
+ toFocus = false;
4408
+
4409
+ switch ( event.keyCode ) {
4410
+ case keyCode.RIGHT:
4411
+ case keyCode.DOWN:
4412
+ toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4413
+ break;
4414
+ case keyCode.LEFT:
4415
+ case keyCode.UP:
4416
+ toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4417
+ break;
4418
+ case keyCode.SPACE:
4419
+ case keyCode.ENTER:
4420
+ this._eventHandler( event );
4421
+ break;
4422
+ case keyCode.HOME:
4423
+ toFocus = this.headers[ 0 ];
4424
+ break;
4425
+ case keyCode.END:
4426
+ toFocus = this.headers[ length - 1 ];
4427
+ break;
4428
+ }
4429
+
4430
+ if ( toFocus ) {
4431
+ $( event.target ).attr( "tabIndex", -1 );
4432
+ $( toFocus ).attr( "tabIndex", 0 );
4433
+ toFocus.focus();
4434
+ event.preventDefault();
4435
+ }
4436
+ },
4437
+
4438
+ _panelKeyDown: function( event ) {
4439
+ if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4440
+ $( event.currentTarget ).prev().focus();
4441
+ }
4442
+ },
4443
+
4444
+ refresh: function() {
4445
+ var options = this.options;
4446
+ this._processPanels();
4447
+
4448
+ // was collapsed or no panel
4449
+ if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
4450
+ options.active = false;
4451
+ this.active = $();
4452
+ // active false only when collapsible is true
4453
+ } else if ( options.active === false ) {
4454
+ this._activate( 0 );
4455
+ // was active, but active panel is gone
4456
+ } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4457
+ // all remaining panel are disabled
4458
+ if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
4459
+ options.active = false;
4460
+ this.active = $();
4461
+ // activate previous panel
4462
+ } else {
4463
+ this._activate( Math.max( 0, options.active - 1 ) );
4464
+ }
4465
+ // was active, active panel still exists
4466
+ } else {
4467
+ // make sure active index is correct
4468
+ options.active = this.headers.index( this.active );
4469
+ }
4470
+
4471
+ this._destroyIcons();
4472
+
4473
+ this._refresh();
4474
+ },
4475
+
4476
+ _processPanels: function() {
4477
+ this.headers = this.element.find( this.options.header )
4478
+ .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
4479
+
4480
+ this.headers.next()
4481
+ .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
4482
+ .filter( ":not(.ui-accordion-content-active)" )
4483
+ .hide();
4484
+ },
4485
+
4486
+ _refresh: function() {
4487
+ var maxHeight,
4488
+ options = this.options,
4489
+ heightStyle = options.heightStyle,
4490
+ parent = this.element.parent();
4491
+
4492
+ this.active = this._findActive( options.active )
4493
+ .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
4494
+ .removeClass( "ui-corner-all" );
4495
+ this.active.next()
4496
+ .addClass( "ui-accordion-content-active" )
4497
+ .show();
4498
+
4499
+ this.headers
4500
+ .attr( "role", "tab" )
4501
+ .each(function() {
4502
+ var header = $( this ),
4503
+ headerId = header.uniqueId().attr( "id" ),
4504
+ panel = header.next(),
4505
+ panelId = panel.uniqueId().attr( "id" );
4506
+ header.attr( "aria-controls", panelId );
4507
+ panel.attr( "aria-labelledby", headerId );
4508
+ })
4509
+ .next()
4510
+ .attr( "role", "tabpanel" );
4511
+
4512
+ this.headers
4513
+ .not( this.active )
4514
+ .attr({
4515
+ "aria-selected": "false",
4516
+ "aria-expanded": "false",
4517
+ tabIndex: -1
4518
+ })
4519
+ .next()
4520
+ .attr({
4521
+ "aria-hidden": "true"
4522
+ })
4523
+ .hide();
4524
+
4525
+ // make sure at least one header is in the tab order
4526
+ if ( !this.active.length ) {
4527
+ this.headers.eq( 0 ).attr( "tabIndex", 0 );
4528
+ } else {
4529
+ this.active.attr({
4530
+ "aria-selected": "true",
4531
+ "aria-expanded": "true",
4532
+ tabIndex: 0
4533
+ })
4534
+ .next()
4535
+ .attr({
4536
+ "aria-hidden": "false"
4537
+ });
4538
+ }
4539
+
4540
+ this._createIcons();
4541
+
4542
+ this._setupEvents( options.event );
4543
+
4544
+ if ( heightStyle === "fill" ) {
4545
+ maxHeight = parent.height();
4546
+ this.element.siblings( ":visible" ).each(function() {
4547
+ var elem = $( this ),
4548
+ position = elem.css( "position" );
4549
+
4550
+ if ( position === "absolute" || position === "fixed" ) {
4551
+ return;
4552
+ }
4553
+ maxHeight -= elem.outerHeight( true );
4554
+ });
4555
+
4556
+ this.headers.each(function() {
4557
+ maxHeight -= $( this ).outerHeight( true );
4558
+ });
4559
+
4560
+ this.headers.next()
4561
+ .each(function() {
4562
+ $( this ).height( Math.max( 0, maxHeight -
4563
+ $( this ).innerHeight() + $( this ).height() ) );
4564
+ })
4565
+ .css( "overflow", "auto" );
4566
+ } else if ( heightStyle === "auto" ) {
4567
+ maxHeight = 0;
4568
+ this.headers.next()
4569
+ .each(function() {
4570
+ maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4571
+ })
4572
+ .height( maxHeight );
4573
+ }
4574
+ },
4575
+
4576
+ _activate: function( index ) {
4577
+ var active = this._findActive( index )[ 0 ];
4578
+
4579
+ // trying to activate the already active panel
4580
+ if ( active === this.active[ 0 ] ) {
4581
+ return;
4582
+ }
4583
+
4584
+ // trying to collapse, simulate a click on the currently active header
4585
+ active = active || this.active[ 0 ];
4586
+
4587
+ this._eventHandler({
4588
+ target: active,
4589
+ currentTarget: active,
4590
+ preventDefault: $.noop
4591
+ });
4592
+ },
4593
+
4594
+ _findActive: function( selector ) {
4595
+ return typeof selector === "number" ? this.headers.eq( selector ) : $();
4596
+ },
4597
+
4598
+ _setupEvents: function( event ) {
4599
+ var events = {
4600
+ keydown: "_keydown"
4601
+ };
4602
+ if ( event ) {
4603
+ $.each( event.split( " " ), function( index, eventName ) {
4604
+ events[ eventName ] = "_eventHandler";
4605
+ });
4606
+ }
4607
+
4608
+ this._off( this.headers.add( this.headers.next() ) );
4609
+ this._on( this.headers, events );
4610
+ this._on( this.headers.next(), { keydown: "_panelKeyDown" });
4611
+ this._hoverable( this.headers );
4612
+ this._focusable( this.headers );
4613
+ },
4614
+
4615
+ _eventHandler: function( event ) {
4616
+ var options = this.options,
4617
+ active = this.active,
4618
+ clicked = $( event.currentTarget ),
4619
+ clickedIsActive = clicked[ 0 ] === active[ 0 ],
4620
+ collapsing = clickedIsActive && options.collapsible,
4621
+ toShow = collapsing ? $() : clicked.next(),
4622
+ toHide = active.next(),
4623
+ eventData = {
4624
+ oldHeader: active,
4625
+ oldPanel: toHide,
4626
+ newHeader: collapsing ? $() : clicked,
4627
+ newPanel: toShow
4628
+ };
4629
+
4630
+ event.preventDefault();
4631
+
4632
+ if (
4633
+ // click on active header, but not collapsible
4634
+ ( clickedIsActive && !options.collapsible ) ||
4635
+ // allow canceling activation
4636
+ ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4637
+ return;
4638
+ }
4639
+
4640
+ options.active = collapsing ? false : this.headers.index( clicked );
4641
+
4642
+ // when the call to ._toggle() comes after the class changes
4643
+ // it causes a very odd bug in IE 8 (see #6720)
4644
+ this.active = clickedIsActive ? $() : clicked;
4645
+ this._toggle( eventData );
4646
+
4647
+ // switch classes
4648
+ // corner classes on the previously active header stay after the animation
4649
+ active.removeClass( "ui-accordion-header-active ui-state-active" );
4650
+ if ( options.icons ) {
4651
+ active.children( ".ui-accordion-header-icon" )
4652
+ .removeClass( options.icons.activeHeader )
4653
+ .addClass( options.icons.header );
4654
+ }
4655
+
4656
+ if ( !clickedIsActive ) {
4657
+ clicked
4658
+ .removeClass( "ui-corner-all" )
4659
+ .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
4660
+ if ( options.icons ) {
4661
+ clicked.children( ".ui-accordion-header-icon" )
4662
+ .removeClass( options.icons.header )
4663
+ .addClass( options.icons.activeHeader );
4664
+ }
4665
+
4666
+ clicked
4667
+ .next()
4668
+ .addClass( "ui-accordion-content-active" );
4669
+ }
4670
+ },
4671
+
4672
+ _toggle: function( data ) {
4673
+ var toShow = data.newPanel,
4674
+ toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4675
+
4676
+ // handle activating a panel during the animation for another activation
4677
+ this.prevShow.add( this.prevHide ).stop( true, true );
4678
+ this.prevShow = toShow;
4679
+ this.prevHide = toHide;
4680
+
4681
+ if ( this.options.animate ) {
4682
+ this._animate( toShow, toHide, data );
4683
+ } else {
4684
+ toHide.hide();
4685
+ toShow.show();
4686
+ this._toggleComplete( data );
4687
+ }
4688
+
4689
+ toHide.attr({
4690
+ "aria-hidden": "true"
4691
+ });
4692
+ toHide.prev().attr( "aria-selected", "false" );
4693
+ // if we're switching panels, remove the old header from the tab order
4694
+ // if we're opening from collapsed state, remove the previous header from the tab order
4695
+ // if we're collapsing, then keep the collapsing header in the tab order
4696
+ if ( toShow.length && toHide.length ) {
4697
+ toHide.prev().attr({
4698
+ "tabIndex": -1,
4699
+ "aria-expanded": "false"
4700
+ });
4701
+ } else if ( toShow.length ) {
4702
+ this.headers.filter(function() {
4703
+ return $( this ).attr( "tabIndex" ) === 0;
4704
+ })
4705
+ .attr( "tabIndex", -1 );
4706
+ }
4707
+
4708
+ toShow
4709
+ .attr( "aria-hidden", "false" )
4710
+ .prev()
4711
+ .attr({
4712
+ "aria-selected": "true",
4713
+ tabIndex: 0,
4714
+ "aria-expanded": "true"
4715
+ });
4716
+ },
4717
+
4718
+ _animate: function( toShow, toHide, data ) {
4719
+ var total, easing, duration,
4720
+ that = this,
4721
+ adjust = 0,
4722
+ down = toShow.length &&
4723
+ ( !toHide.length || ( toShow.index() < toHide.index() ) ),
4724
+ animate = this.options.animate || {},
4725
+ options = down && animate.down || animate,
4726
+ complete = function() {
4727
+ that._toggleComplete( data );
4728
+ };
4729
+
4730
+ if ( typeof options === "number" ) {
4731
+ duration = options;
4732
+ }
4733
+ if ( typeof options === "string" ) {
4734
+ easing = options;
4735
+ }
4736
+ // fall back from options to animation in case of partial down settings
4737
+ easing = easing || options.easing || animate.easing;
4738
+ duration = duration || options.duration || animate.duration;
4739
+
4740
+ if ( !toHide.length ) {
4741
+ return toShow.animate( this.showProps, duration, easing, complete );
4742
+ }
4743
+ if ( !toShow.length ) {
4744
+ return toHide.animate( this.hideProps, duration, easing, complete );
4745
+ }
4746
+
4747
+ total = toShow.show().outerHeight();
4748
+ toHide.animate( this.hideProps, {
4749
+ duration: duration,
4750
+ easing: easing,
4751
+ step: function( now, fx ) {
4752
+ fx.now = Math.round( now );
4753
+ }
4754
+ });
4755
+ toShow
4756
+ .hide()
4757
+ .animate( this.showProps, {
4758
+ duration: duration,
4759
+ easing: easing,
4760
+ complete: complete,
4761
+ step: function( now, fx ) {
4762
+ fx.now = Math.round( now );
4763
+ if ( fx.prop !== "height" ) {
4764
+ adjust += fx.now;
4765
+ } else if ( that.options.heightStyle !== "content" ) {
4766
+ fx.now = Math.round( total - toHide.outerHeight() - adjust );
4767
+ adjust = 0;
4768
+ }
4769
+ }
4770
+ });
4771
+ },
4772
+
4773
+ _toggleComplete: function( data ) {
4774
+ var toHide = data.oldPanel;
4775
+
4776
+ toHide
4777
+ .removeClass( "ui-accordion-content-active" )
4778
+ .prev()
4779
+ .removeClass( "ui-corner-top" )
4780
+ .addClass( "ui-corner-all" );
4781
+
4782
+ // Work around for rendering bug in IE (#5421)
4783
+ if ( toHide.length ) {
4784
+ toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
4785
+ }
4786
+ this._trigger( "activate", null, data );
4787
+ }
4788
+ });
4789
+
4790
+
4230
4791
  /*!
4231
4792
  * jQuery UI Menu 1.11.1
4232
4793
  * http://jqueryui.com
@@ -5464,5 +6025,2928 @@ $.widget( "ui.autocomplete", $.ui.autocomplete, {
5464
6025
  var autocomplete = $.ui.autocomplete;
5465
6026
 
5466
6027
 
6028
+ /*!
6029
+ * jQuery UI Datepicker 1.11.1
6030
+ * http://jqueryui.com
6031
+ *
6032
+ * Copyright 2014 jQuery Foundation and other contributors
6033
+ * Released under the MIT license.
6034
+ * http://jquery.org/license
6035
+ *
6036
+ * http://api.jqueryui.com/datepicker/
6037
+ */
6038
+
6039
+
6040
+ $.extend($.ui, { datepicker: { version: "1.11.1" } });
6041
+
6042
+ var datepicker_instActive;
6043
+
6044
+ function datepicker_getZindex( elem ) {
6045
+ var position, value;
6046
+ while ( elem.length && elem[ 0 ] !== document ) {
6047
+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
6048
+ // This makes behavior of this function consistent across browsers
6049
+ // WebKit always returns auto if the element is positioned
6050
+ position = elem.css( "position" );
6051
+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
6052
+ // IE returns 0 when zIndex is not specified
6053
+ // other browsers return a string
6054
+ // we ignore the case of nested elements with an explicit value of 0
6055
+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
6056
+ value = parseInt( elem.css( "zIndex" ), 10 );
6057
+ if ( !isNaN( value ) && value !== 0 ) {
6058
+ return value;
6059
+ }
6060
+ }
6061
+ elem = elem.parent();
6062
+ }
6063
+
6064
+ return 0;
6065
+ }
6066
+ /* Date picker manager.
6067
+ Use the singleton instance of this class, $.datepicker, to interact with the date picker.
6068
+ Settings for (groups of) date pickers are maintained in an instance object,
6069
+ allowing multiple different settings on the same page. */
6070
+
6071
+ function Datepicker() {
6072
+ this._curInst = null; // The current instance in use
6073
+ this._keyEvent = false; // If the last event was a key event
6074
+ this._disabledInputs = []; // List of date picker inputs that have been disabled
6075
+ this._datepickerShowing = false; // True if the popup picker is showing , false if not
6076
+ this._inDialog = false; // True if showing within a "dialog", false if not
6077
+ this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
6078
+ this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
6079
+ this._appendClass = "ui-datepicker-append"; // The name of the append marker class
6080
+ this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
6081
+ this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
6082
+ this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
6083
+ this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
6084
+ this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
6085
+ this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
6086
+ this.regional = []; // Available regional settings, indexed by language code
6087
+ this.regional[""] = { // Default regional settings
6088
+ closeText: "Done", // Display text for close link
6089
+ prevText: "Prev", // Display text for previous month link
6090
+ nextText: "Next", // Display text for next month link
6091
+ currentText: "Today", // Display text for current month link
6092
+ monthNames: ["January","February","March","April","May","June",
6093
+ "July","August","September","October","November","December"], // Names of months for drop-down and formatting
6094
+ monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
6095
+ dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
6096
+ dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
6097
+ dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
6098
+ weekHeader: "Wk", // Column header for week of the year
6099
+ dateFormat: "mm/dd/yy", // See format options on parseDate
6100
+ firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
6101
+ isRTL: false, // True if right-to-left language, false if left-to-right
6102
+ showMonthAfterYear: false, // True if the year select precedes month, false for month then year
6103
+ yearSuffix: "" // Additional text to append to the year in the month headers
6104
+ };
6105
+ this._defaults = { // Global defaults for all the date picker instances
6106
+ showOn: "focus", // "focus" for popup on focus,
6107
+ // "button" for trigger button, or "both" for either
6108
+ showAnim: "fadeIn", // Name of jQuery animation for popup
6109
+ showOptions: {}, // Options for enhanced animations
6110
+ defaultDate: null, // Used when field is blank: actual date,
6111
+ // +/-number for offset from today, null for today
6112
+ appendText: "", // Display text following the input box, e.g. showing the format
6113
+ buttonText: "...", // Text for trigger button
6114
+ buttonImage: "", // URL for trigger button image
6115
+ buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
6116
+ hideIfNoPrevNext: false, // True to hide next/previous month links
6117
+ // if not applicable, false to just disable them
6118
+ navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
6119
+ gotoCurrent: false, // True if today link goes back to current selection instead
6120
+ changeMonth: false, // True if month can be selected directly, false if only prev/next
6121
+ changeYear: false, // True if year can be selected directly, false if only prev/next
6122
+ yearRange: "c-10:c+10", // Range of years to display in drop-down,
6123
+ // either relative to today's year (-nn:+nn), relative to currently displayed year
6124
+ // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
6125
+ showOtherMonths: false, // True to show dates in other months, false to leave blank
6126
+ selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
6127
+ showWeek: false, // True to show week of the year, false to not show it
6128
+ calculateWeek: this.iso8601Week, // How to calculate the week of the year,
6129
+ // takes a Date and returns the number of the week for it
6130
+ shortYearCutoff: "+10", // Short year values < this are in the current century,
6131
+ // > this are in the previous century,
6132
+ // string value starting with "+" for current year + value
6133
+ minDate: null, // The earliest selectable date, or null for no limit
6134
+ maxDate: null, // The latest selectable date, or null for no limit
6135
+ duration: "fast", // Duration of display/closure
6136
+ beforeShowDay: null, // Function that takes a date and returns an array with
6137
+ // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
6138
+ // [2] = cell title (optional), e.g. $.datepicker.noWeekends
6139
+ beforeShow: null, // Function that takes an input field and
6140
+ // returns a set of custom settings for the date picker
6141
+ onSelect: null, // Define a callback function when a date is selected
6142
+ onChangeMonthYear: null, // Define a callback function when the month or year is changed
6143
+ onClose: null, // Define a callback function when the datepicker is closed
6144
+ numberOfMonths: 1, // Number of months to show at a time
6145
+ showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
6146
+ stepMonths: 1, // Number of months to step back/forward
6147
+ stepBigMonths: 12, // Number of months to step back/forward for the big links
6148
+ altField: "", // Selector for an alternate field to store selected dates into
6149
+ altFormat: "", // The date format to use for the alternate field
6150
+ constrainInput: true, // The input is constrained by the current date format
6151
+ showButtonPanel: false, // True to show button panel, false to not show it
6152
+ autoSize: false, // True to size the input for the date format, false to leave as is
6153
+ disabled: false // The initial disabled state
6154
+ };
6155
+ $.extend(this._defaults, this.regional[""]);
6156
+ this.regional.en = $.extend( true, {}, this.regional[ "" ]);
6157
+ this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
6158
+ this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
6159
+ }
6160
+
6161
+ $.extend(Datepicker.prototype, {
6162
+ /* Class name added to elements to indicate already configured with a date picker. */
6163
+ markerClassName: "hasDatepicker",
6164
+
6165
+ //Keep track of the maximum number of rows displayed (see #7043)
6166
+ maxRows: 4,
6167
+
6168
+ // TODO rename to "widget" when switching to widget factory
6169
+ _widgetDatepicker: function() {
6170
+ return this.dpDiv;
6171
+ },
6172
+
6173
+ /* Override the default settings for all instances of the date picker.
6174
+ * @param settings object - the new settings to use as defaults (anonymous object)
6175
+ * @return the manager object
6176
+ */
6177
+ setDefaults: function(settings) {
6178
+ datepicker_extendRemove(this._defaults, settings || {});
6179
+ return this;
6180
+ },
6181
+
6182
+ /* Attach the date picker to a jQuery selection.
6183
+ * @param target element - the target input field or division or span
6184
+ * @param settings object - the new settings to use for this date picker instance (anonymous)
6185
+ */
6186
+ _attachDatepicker: function(target, settings) {
6187
+ var nodeName, inline, inst;
6188
+ nodeName = target.nodeName.toLowerCase();
6189
+ inline = (nodeName === "div" || nodeName === "span");
6190
+ if (!target.id) {
6191
+ this.uuid += 1;
6192
+ target.id = "dp" + this.uuid;
6193
+ }
6194
+ inst = this._newInst($(target), inline);
6195
+ inst.settings = $.extend({}, settings || {});
6196
+ if (nodeName === "input") {
6197
+ this._connectDatepicker(target, inst);
6198
+ } else if (inline) {
6199
+ this._inlineDatepicker(target, inst);
6200
+ }
6201
+ },
6202
+
6203
+ /* Create a new instance object. */
6204
+ _newInst: function(target, inline) {
6205
+ var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
6206
+ return {id: id, input: target, // associated target
6207
+ selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
6208
+ drawMonth: 0, drawYear: 0, // month being drawn
6209
+ inline: inline, // is datepicker inline or not
6210
+ dpDiv: (!inline ? this.dpDiv : // presentation div
6211
+ datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
6212
+ },
6213
+
6214
+ /* Attach the date picker to an input field. */
6215
+ _connectDatepicker: function(target, inst) {
6216
+ var input = $(target);
6217
+ inst.append = $([]);
6218
+ inst.trigger = $([]);
6219
+ if (input.hasClass(this.markerClassName)) {
6220
+ return;
6221
+ }
6222
+ this._attachments(input, inst);
6223
+ input.addClass(this.markerClassName).keydown(this._doKeyDown).
6224
+ keypress(this._doKeyPress).keyup(this._doKeyUp);
6225
+ this._autoSize(inst);
6226
+ $.data(target, "datepicker", inst);
6227
+ //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
6228
+ if( inst.settings.disabled ) {
6229
+ this._disableDatepicker( target );
6230
+ }
6231
+ },
6232
+
6233
+ /* Make attachments based on settings. */
6234
+ _attachments: function(input, inst) {
6235
+ var showOn, buttonText, buttonImage,
6236
+ appendText = this._get(inst, "appendText"),
6237
+ isRTL = this._get(inst, "isRTL");
6238
+
6239
+ if (inst.append) {
6240
+ inst.append.remove();
6241
+ }
6242
+ if (appendText) {
6243
+ inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
6244
+ input[isRTL ? "before" : "after"](inst.append);
6245
+ }
6246
+
6247
+ input.unbind("focus", this._showDatepicker);
6248
+
6249
+ if (inst.trigger) {
6250
+ inst.trigger.remove();
6251
+ }
6252
+
6253
+ showOn = this._get(inst, "showOn");
6254
+ if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
6255
+ input.focus(this._showDatepicker);
6256
+ }
6257
+ if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
6258
+ buttonText = this._get(inst, "buttonText");
6259
+ buttonImage = this._get(inst, "buttonImage");
6260
+ inst.trigger = $(this._get(inst, "buttonImageOnly") ?
6261
+ $("<img/>").addClass(this._triggerClass).
6262
+ attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
6263
+ $("<button type='button'></button>").addClass(this._triggerClass).
6264
+ html(!buttonImage ? buttonText : $("<img/>").attr(
6265
+ { src:buttonImage, alt:buttonText, title:buttonText })));
6266
+ input[isRTL ? "before" : "after"](inst.trigger);
6267
+ inst.trigger.click(function() {
6268
+ if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
6269
+ $.datepicker._hideDatepicker();
6270
+ } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
6271
+ $.datepicker._hideDatepicker();
6272
+ $.datepicker._showDatepicker(input[0]);
6273
+ } else {
6274
+ $.datepicker._showDatepicker(input[0]);
6275
+ }
6276
+ return false;
6277
+ });
6278
+ }
6279
+ },
6280
+
6281
+ /* Apply the maximum length for the date format. */
6282
+ _autoSize: function(inst) {
6283
+ if (this._get(inst, "autoSize") && !inst.inline) {
6284
+ var findMax, max, maxI, i,
6285
+ date = new Date(2009, 12 - 1, 20), // Ensure double digits
6286
+ dateFormat = this._get(inst, "dateFormat");
6287
+
6288
+ if (dateFormat.match(/[DM]/)) {
6289
+ findMax = function(names) {
6290
+ max = 0;
6291
+ maxI = 0;
6292
+ for (i = 0; i < names.length; i++) {
6293
+ if (names[i].length > max) {
6294
+ max = names[i].length;
6295
+ maxI = i;
6296
+ }
6297
+ }
6298
+ return maxI;
6299
+ };
6300
+ date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
6301
+ "monthNames" : "monthNamesShort"))));
6302
+ date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
6303
+ "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
6304
+ }
6305
+ inst.input.attr("size", this._formatDate(inst, date).length);
6306
+ }
6307
+ },
6308
+
6309
+ /* Attach an inline date picker to a div. */
6310
+ _inlineDatepicker: function(target, inst) {
6311
+ var divSpan = $(target);
6312
+ if (divSpan.hasClass(this.markerClassName)) {
6313
+ return;
6314
+ }
6315
+ divSpan.addClass(this.markerClassName).append(inst.dpDiv);
6316
+ $.data(target, "datepicker", inst);
6317
+ this._setDate(inst, this._getDefaultDate(inst), true);
6318
+ this._updateDatepicker(inst);
6319
+ this._updateAlternate(inst);
6320
+ //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
6321
+ if( inst.settings.disabled ) {
6322
+ this._disableDatepicker( target );
6323
+ }
6324
+ // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
6325
+ // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
6326
+ inst.dpDiv.css( "display", "block" );
6327
+ },
6328
+
6329
+ /* Pop-up the date picker in a "dialog" box.
6330
+ * @param input element - ignored
6331
+ * @param date string or Date - the initial date to display
6332
+ * @param onSelect function - the function to call when a date is selected
6333
+ * @param settings object - update the dialog date picker instance's settings (anonymous object)
6334
+ * @param pos int[2] - coordinates for the dialog's position within the screen or
6335
+ * event - with x/y coordinates or
6336
+ * leave empty for default (screen centre)
6337
+ * @return the manager object
6338
+ */
6339
+ _dialogDatepicker: function(input, date, onSelect, settings, pos) {
6340
+ var id, browserWidth, browserHeight, scrollX, scrollY,
6341
+ inst = this._dialogInst; // internal instance
6342
+
6343
+ if (!inst) {
6344
+ this.uuid += 1;
6345
+ id = "dp" + this.uuid;
6346
+ this._dialogInput = $("<input type='text' id='" + id +
6347
+ "' style='position: absolute; top: -100px; width: 0px;'/>");
6348
+ this._dialogInput.keydown(this._doKeyDown);
6349
+ $("body").append(this._dialogInput);
6350
+ inst = this._dialogInst = this._newInst(this._dialogInput, false);
6351
+ inst.settings = {};
6352
+ $.data(this._dialogInput[0], "datepicker", inst);
6353
+ }
6354
+ datepicker_extendRemove(inst.settings, settings || {});
6355
+ date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
6356
+ this._dialogInput.val(date);
6357
+
6358
+ this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
6359
+ if (!this._pos) {
6360
+ browserWidth = document.documentElement.clientWidth;
6361
+ browserHeight = document.documentElement.clientHeight;
6362
+ scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
6363
+ scrollY = document.documentElement.scrollTop || document.body.scrollTop;
6364
+ this._pos = // should use actual width/height below
6365
+ [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
6366
+ }
6367
+
6368
+ // move input on screen for focus, but hidden behind dialog
6369
+ this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
6370
+ inst.settings.onSelect = onSelect;
6371
+ this._inDialog = true;
6372
+ this.dpDiv.addClass(this._dialogClass);
6373
+ this._showDatepicker(this._dialogInput[0]);
6374
+ if ($.blockUI) {
6375
+ $.blockUI(this.dpDiv);
6376
+ }
6377
+ $.data(this._dialogInput[0], "datepicker", inst);
6378
+ return this;
6379
+ },
6380
+
6381
+ /* Detach a datepicker from its control.
6382
+ * @param target element - the target input field or division or span
6383
+ */
6384
+ _destroyDatepicker: function(target) {
6385
+ var nodeName,
6386
+ $target = $(target),
6387
+ inst = $.data(target, "datepicker");
6388
+
6389
+ if (!$target.hasClass(this.markerClassName)) {
6390
+ return;
6391
+ }
6392
+
6393
+ nodeName = target.nodeName.toLowerCase();
6394
+ $.removeData(target, "datepicker");
6395
+ if (nodeName === "input") {
6396
+ inst.append.remove();
6397
+ inst.trigger.remove();
6398
+ $target.removeClass(this.markerClassName).
6399
+ unbind("focus", this._showDatepicker).
6400
+ unbind("keydown", this._doKeyDown).
6401
+ unbind("keypress", this._doKeyPress).
6402
+ unbind("keyup", this._doKeyUp);
6403
+ } else if (nodeName === "div" || nodeName === "span") {
6404
+ $target.removeClass(this.markerClassName).empty();
6405
+ }
6406
+ },
6407
+
6408
+ /* Enable the date picker to a jQuery selection.
6409
+ * @param target element - the target input field or division or span
6410
+ */
6411
+ _enableDatepicker: function(target) {
6412
+ var nodeName, inline,
6413
+ $target = $(target),
6414
+ inst = $.data(target, "datepicker");
6415
+
6416
+ if (!$target.hasClass(this.markerClassName)) {
6417
+ return;
6418
+ }
6419
+
6420
+ nodeName = target.nodeName.toLowerCase();
6421
+ if (nodeName === "input") {
6422
+ target.disabled = false;
6423
+ inst.trigger.filter("button").
6424
+ each(function() { this.disabled = false; }).end().
6425
+ filter("img").css({opacity: "1.0", cursor: ""});
6426
+ } else if (nodeName === "div" || nodeName === "span") {
6427
+ inline = $target.children("." + this._inlineClass);
6428
+ inline.children().removeClass("ui-state-disabled");
6429
+ inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
6430
+ prop("disabled", false);
6431
+ }
6432
+ this._disabledInputs = $.map(this._disabledInputs,
6433
+ function(value) { return (value === target ? null : value); }); // delete entry
6434
+ },
6435
+
6436
+ /* Disable the date picker to a jQuery selection.
6437
+ * @param target element - the target input field or division or span
6438
+ */
6439
+ _disableDatepicker: function(target) {
6440
+ var nodeName, inline,
6441
+ $target = $(target),
6442
+ inst = $.data(target, "datepicker");
6443
+
6444
+ if (!$target.hasClass(this.markerClassName)) {
6445
+ return;
6446
+ }
6447
+
6448
+ nodeName = target.nodeName.toLowerCase();
6449
+ if (nodeName === "input") {
6450
+ target.disabled = true;
6451
+ inst.trigger.filter("button").
6452
+ each(function() { this.disabled = true; }).end().
6453
+ filter("img").css({opacity: "0.5", cursor: "default"});
6454
+ } else if (nodeName === "div" || nodeName === "span") {
6455
+ inline = $target.children("." + this._inlineClass);
6456
+ inline.children().addClass("ui-state-disabled");
6457
+ inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
6458
+ prop("disabled", true);
6459
+ }
6460
+ this._disabledInputs = $.map(this._disabledInputs,
6461
+ function(value) { return (value === target ? null : value); }); // delete entry
6462
+ this._disabledInputs[this._disabledInputs.length] = target;
6463
+ },
6464
+
6465
+ /* Is the first field in a jQuery collection disabled as a datepicker?
6466
+ * @param target element - the target input field or division or span
6467
+ * @return boolean - true if disabled, false if enabled
6468
+ */
6469
+ _isDisabledDatepicker: function(target) {
6470
+ if (!target) {
6471
+ return false;
6472
+ }
6473
+ for (var i = 0; i < this._disabledInputs.length; i++) {
6474
+ if (this._disabledInputs[i] === target) {
6475
+ return true;
6476
+ }
6477
+ }
6478
+ return false;
6479
+ },
6480
+
6481
+ /* Retrieve the instance data for the target control.
6482
+ * @param target element - the target input field or division or span
6483
+ * @return object - the associated instance data
6484
+ * @throws error if a jQuery problem getting data
6485
+ */
6486
+ _getInst: function(target) {
6487
+ try {
6488
+ return $.data(target, "datepicker");
6489
+ }
6490
+ catch (err) {
6491
+ throw "Missing instance data for this datepicker";
6492
+ }
6493
+ },
6494
+
6495
+ /* Update or retrieve the settings for a date picker attached to an input field or division.
6496
+ * @param target element - the target input field or division or span
6497
+ * @param name object - the new settings to update or
6498
+ * string - the name of the setting to change or retrieve,
6499
+ * when retrieving also "all" for all instance settings or
6500
+ * "defaults" for all global defaults
6501
+ * @param value any - the new value for the setting
6502
+ * (omit if above is an object or to retrieve a value)
6503
+ */
6504
+ _optionDatepicker: function(target, name, value) {
6505
+ var settings, date, minDate, maxDate,
6506
+ inst = this._getInst(target);
6507
+
6508
+ if (arguments.length === 2 && typeof name === "string") {
6509
+ return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
6510
+ (inst ? (name === "all" ? $.extend({}, inst.settings) :
6511
+ this._get(inst, name)) : null));
6512
+ }
6513
+
6514
+ settings = name || {};
6515
+ if (typeof name === "string") {
6516
+ settings = {};
6517
+ settings[name] = value;
6518
+ }
6519
+
6520
+ if (inst) {
6521
+ if (this._curInst === inst) {
6522
+ this._hideDatepicker();
6523
+ }
6524
+
6525
+ date = this._getDateDatepicker(target, true);
6526
+ minDate = this._getMinMaxDate(inst, "min");
6527
+ maxDate = this._getMinMaxDate(inst, "max");
6528
+ datepicker_extendRemove(inst.settings, settings);
6529
+ // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
6530
+ if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
6531
+ inst.settings.minDate = this._formatDate(inst, minDate);
6532
+ }
6533
+ if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
6534
+ inst.settings.maxDate = this._formatDate(inst, maxDate);
6535
+ }
6536
+ if ( "disabled" in settings ) {
6537
+ if ( settings.disabled ) {
6538
+ this._disableDatepicker(target);
6539
+ } else {
6540
+ this._enableDatepicker(target);
6541
+ }
6542
+ }
6543
+ this._attachments($(target), inst);
6544
+ this._autoSize(inst);
6545
+ this._setDate(inst, date);
6546
+ this._updateAlternate(inst);
6547
+ this._updateDatepicker(inst);
6548
+ }
6549
+ },
6550
+
6551
+ // change method deprecated
6552
+ _changeDatepicker: function(target, name, value) {
6553
+ this._optionDatepicker(target, name, value);
6554
+ },
6555
+
6556
+ /* Redraw the date picker attached to an input field or division.
6557
+ * @param target element - the target input field or division or span
6558
+ */
6559
+ _refreshDatepicker: function(target) {
6560
+ var inst = this._getInst(target);
6561
+ if (inst) {
6562
+ this._updateDatepicker(inst);
6563
+ }
6564
+ },
6565
+
6566
+ /* Set the dates for a jQuery selection.
6567
+ * @param target element - the target input field or division or span
6568
+ * @param date Date - the new date
6569
+ */
6570
+ _setDateDatepicker: function(target, date) {
6571
+ var inst = this._getInst(target);
6572
+ if (inst) {
6573
+ this._setDate(inst, date);
6574
+ this._updateDatepicker(inst);
6575
+ this._updateAlternate(inst);
6576
+ }
6577
+ },
6578
+
6579
+ /* Get the date(s) for the first entry in a jQuery selection.
6580
+ * @param target element - the target input field or division or span
6581
+ * @param noDefault boolean - true if no default date is to be used
6582
+ * @return Date - the current date
6583
+ */
6584
+ _getDateDatepicker: function(target, noDefault) {
6585
+ var inst = this._getInst(target);
6586
+ if (inst && !inst.inline) {
6587
+ this._setDateFromField(inst, noDefault);
6588
+ }
6589
+ return (inst ? this._getDate(inst) : null);
6590
+ },
6591
+
6592
+ /* Handle keystrokes. */
6593
+ _doKeyDown: function(event) {
6594
+ var onSelect, dateStr, sel,
6595
+ inst = $.datepicker._getInst(event.target),
6596
+ handled = true,
6597
+ isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
6598
+
6599
+ inst._keyEvent = true;
6600
+ if ($.datepicker._datepickerShowing) {
6601
+ switch (event.keyCode) {
6602
+ case 9: $.datepicker._hideDatepicker();
6603
+ handled = false;
6604
+ break; // hide on tab out
6605
+ case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
6606
+ $.datepicker._currentClass + ")", inst.dpDiv);
6607
+ if (sel[0]) {
6608
+ $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
6609
+ }
6610
+
6611
+ onSelect = $.datepicker._get(inst, "onSelect");
6612
+ if (onSelect) {
6613
+ dateStr = $.datepicker._formatDate(inst);
6614
+
6615
+ // trigger custom callback
6616
+ onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
6617
+ } else {
6618
+ $.datepicker._hideDatepicker();
6619
+ }
6620
+
6621
+ return false; // don't submit the form
6622
+ case 27: $.datepicker._hideDatepicker();
6623
+ break; // hide on escape
6624
+ case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
6625
+ -$.datepicker._get(inst, "stepBigMonths") :
6626
+ -$.datepicker._get(inst, "stepMonths")), "M");
6627
+ break; // previous month/year on page up/+ ctrl
6628
+ case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
6629
+ +$.datepicker._get(inst, "stepBigMonths") :
6630
+ +$.datepicker._get(inst, "stepMonths")), "M");
6631
+ break; // next month/year on page down/+ ctrl
6632
+ case 35: if (event.ctrlKey || event.metaKey) {
6633
+ $.datepicker._clearDate(event.target);
6634
+ }
6635
+ handled = event.ctrlKey || event.metaKey;
6636
+ break; // clear on ctrl or command +end
6637
+ case 36: if (event.ctrlKey || event.metaKey) {
6638
+ $.datepicker._gotoToday(event.target);
6639
+ }
6640
+ handled = event.ctrlKey || event.metaKey;
6641
+ break; // current on ctrl or command +home
6642
+ case 37: if (event.ctrlKey || event.metaKey) {
6643
+ $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
6644
+ }
6645
+ handled = event.ctrlKey || event.metaKey;
6646
+ // -1 day on ctrl or command +left
6647
+ if (event.originalEvent.altKey) {
6648
+ $.datepicker._adjustDate(event.target, (event.ctrlKey ?
6649
+ -$.datepicker._get(inst, "stepBigMonths") :
6650
+ -$.datepicker._get(inst, "stepMonths")), "M");
6651
+ }
6652
+ // next month/year on alt +left on Mac
6653
+ break;
6654
+ case 38: if (event.ctrlKey || event.metaKey) {
6655
+ $.datepicker._adjustDate(event.target, -7, "D");
6656
+ }
6657
+ handled = event.ctrlKey || event.metaKey;
6658
+ break; // -1 week on ctrl or command +up
6659
+ case 39: if (event.ctrlKey || event.metaKey) {
6660
+ $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
6661
+ }
6662
+ handled = event.ctrlKey || event.metaKey;
6663
+ // +1 day on ctrl or command +right
6664
+ if (event.originalEvent.altKey) {
6665
+ $.datepicker._adjustDate(event.target, (event.ctrlKey ?
6666
+ +$.datepicker._get(inst, "stepBigMonths") :
6667
+ +$.datepicker._get(inst, "stepMonths")), "M");
6668
+ }
6669
+ // next month/year on alt +right
6670
+ break;
6671
+ case 40: if (event.ctrlKey || event.metaKey) {
6672
+ $.datepicker._adjustDate(event.target, +7, "D");
6673
+ }
6674
+ handled = event.ctrlKey || event.metaKey;
6675
+ break; // +1 week on ctrl or command +down
6676
+ default: handled = false;
6677
+ }
6678
+ } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
6679
+ $.datepicker._showDatepicker(this);
6680
+ } else {
6681
+ handled = false;
6682
+ }
6683
+
6684
+ if (handled) {
6685
+ event.preventDefault();
6686
+ event.stopPropagation();
6687
+ }
6688
+ },
6689
+
6690
+ /* Filter entered characters - based on date format. */
6691
+ _doKeyPress: function(event) {
6692
+ var chars, chr,
6693
+ inst = $.datepicker._getInst(event.target);
6694
+
6695
+ if ($.datepicker._get(inst, "constrainInput")) {
6696
+ chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
6697
+ chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
6698
+ return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
6699
+ }
6700
+ },
6701
+
6702
+ /* Synchronise manual entry and field/alternate field. */
6703
+ _doKeyUp: function(event) {
6704
+ var date,
6705
+ inst = $.datepicker._getInst(event.target);
6706
+
6707
+ if (inst.input.val() !== inst.lastVal) {
6708
+ try {
6709
+ date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
6710
+ (inst.input ? inst.input.val() : null),
6711
+ $.datepicker._getFormatConfig(inst));
6712
+
6713
+ if (date) { // only if valid
6714
+ $.datepicker._setDateFromField(inst);
6715
+ $.datepicker._updateAlternate(inst);
6716
+ $.datepicker._updateDatepicker(inst);
6717
+ }
6718
+ }
6719
+ catch (err) {
6720
+ }
6721
+ }
6722
+ return true;
6723
+ },
6724
+
6725
+ /* Pop-up the date picker for a given input field.
6726
+ * If false returned from beforeShow event handler do not show.
6727
+ * @param input element - the input field attached to the date picker or
6728
+ * event - if triggered by focus
6729
+ */
6730
+ _showDatepicker: function(input) {
6731
+ input = input.target || input;
6732
+ if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
6733
+ input = $("input", input.parentNode)[0];
6734
+ }
6735
+
6736
+ if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
6737
+ return;
6738
+ }
6739
+
6740
+ var inst, beforeShow, beforeShowSettings, isFixed,
6741
+ offset, showAnim, duration;
6742
+
6743
+ inst = $.datepicker._getInst(input);
6744
+ if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
6745
+ $.datepicker._curInst.dpDiv.stop(true, true);
6746
+ if ( inst && $.datepicker._datepickerShowing ) {
6747
+ $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
6748
+ }
6749
+ }
6750
+
6751
+ beforeShow = $.datepicker._get(inst, "beforeShow");
6752
+ beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
6753
+ if(beforeShowSettings === false){
6754
+ return;
6755
+ }
6756
+ datepicker_extendRemove(inst.settings, beforeShowSettings);
6757
+
6758
+ inst.lastVal = null;
6759
+ $.datepicker._lastInput = input;
6760
+ $.datepicker._setDateFromField(inst);
6761
+
6762
+ if ($.datepicker._inDialog) { // hide cursor
6763
+ input.value = "";
6764
+ }
6765
+ if (!$.datepicker._pos) { // position below input
6766
+ $.datepicker._pos = $.datepicker._findPos(input);
6767
+ $.datepicker._pos[1] += input.offsetHeight; // add the height
6768
+ }
6769
+
6770
+ isFixed = false;
6771
+ $(input).parents().each(function() {
6772
+ isFixed |= $(this).css("position") === "fixed";
6773
+ return !isFixed;
6774
+ });
6775
+
6776
+ offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
6777
+ $.datepicker._pos = null;
6778
+ //to avoid flashes on Firefox
6779
+ inst.dpDiv.empty();
6780
+ // determine sizing offscreen
6781
+ inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
6782
+ $.datepicker._updateDatepicker(inst);
6783
+ // fix width for dynamic number of date pickers
6784
+ // and adjust position before showing
6785
+ offset = $.datepicker._checkOffset(inst, offset, isFixed);
6786
+ inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
6787
+ "static" : (isFixed ? "fixed" : "absolute")), display: "none",
6788
+ left: offset.left + "px", top: offset.top + "px"});
6789
+
6790
+ if (!inst.inline) {
6791
+ showAnim = $.datepicker._get(inst, "showAnim");
6792
+ duration = $.datepicker._get(inst, "duration");
6793
+ inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
6794
+ $.datepicker._datepickerShowing = true;
6795
+
6796
+ if ( $.effects && $.effects.effect[ showAnim ] ) {
6797
+ inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
6798
+ } else {
6799
+ inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
6800
+ }
6801
+
6802
+ if ( $.datepicker._shouldFocusInput( inst ) ) {
6803
+ inst.input.focus();
6804
+ }
6805
+
6806
+ $.datepicker._curInst = inst;
6807
+ }
6808
+ },
6809
+
6810
+ /* Generate the date picker content. */
6811
+ _updateDatepicker: function(inst) {
6812
+ this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
6813
+ datepicker_instActive = inst; // for delegate hover events
6814
+ inst.dpDiv.empty().append(this._generateHTML(inst));
6815
+ this._attachHandlers(inst);
6816
+
6817
+ var origyearshtml,
6818
+ numMonths = this._getNumberOfMonths(inst),
6819
+ cols = numMonths[1],
6820
+ width = 17,
6821
+ activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
6822
+
6823
+ if ( activeCell.length > 0 ) {
6824
+ datepicker_handleMouseover.apply( activeCell.get( 0 ) );
6825
+ }
6826
+
6827
+ inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
6828
+ if (cols > 1) {
6829
+ inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
6830
+ }
6831
+ inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
6832
+ "Class"]("ui-datepicker-multi");
6833
+ inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
6834
+ "Class"]("ui-datepicker-rtl");
6835
+
6836
+ if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
6837
+ inst.input.focus();
6838
+ }
6839
+
6840
+ // deffered render of the years select (to avoid flashes on Firefox)
6841
+ if( inst.yearshtml ){
6842
+ origyearshtml = inst.yearshtml;
6843
+ setTimeout(function(){
6844
+ //assure that inst.yearshtml didn't change.
6845
+ if( origyearshtml === inst.yearshtml && inst.yearshtml ){
6846
+ inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
6847
+ }
6848
+ origyearshtml = inst.yearshtml = null;
6849
+ }, 0);
6850
+ }
6851
+ },
6852
+
6853
+ // #6694 - don't focus the input if it's already focused
6854
+ // this breaks the change event in IE
6855
+ // Support: IE and jQuery <1.9
6856
+ _shouldFocusInput: function( inst ) {
6857
+ return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
6858
+ },
6859
+
6860
+ /* Check positioning to remain on screen. */
6861
+ _checkOffset: function(inst, offset, isFixed) {
6862
+ var dpWidth = inst.dpDiv.outerWidth(),
6863
+ dpHeight = inst.dpDiv.outerHeight(),
6864
+ inputWidth = inst.input ? inst.input.outerWidth() : 0,
6865
+ inputHeight = inst.input ? inst.input.outerHeight() : 0,
6866
+ viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
6867
+ viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
6868
+
6869
+ offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
6870
+ offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
6871
+ offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
6872
+
6873
+ // now check if datepicker is showing outside window viewport - move to a better place if so.
6874
+ offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
6875
+ Math.abs(offset.left + dpWidth - viewWidth) : 0);
6876
+ offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
6877
+ Math.abs(dpHeight + inputHeight) : 0);
6878
+
6879
+ return offset;
6880
+ },
6881
+
6882
+ /* Find an object's position on the screen. */
6883
+ _findPos: function(obj) {
6884
+ var position,
6885
+ inst = this._getInst(obj),
6886
+ isRTL = this._get(inst, "isRTL");
6887
+
6888
+ while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
6889
+ obj = obj[isRTL ? "previousSibling" : "nextSibling"];
6890
+ }
6891
+
6892
+ position = $(obj).offset();
6893
+ return [position.left, position.top];
6894
+ },
6895
+
6896
+ /* Hide the date picker from view.
6897
+ * @param input element - the input field attached to the date picker
6898
+ */
6899
+ _hideDatepicker: function(input) {
6900
+ var showAnim, duration, postProcess, onClose,
6901
+ inst = this._curInst;
6902
+
6903
+ if (!inst || (input && inst !== $.data(input, "datepicker"))) {
6904
+ return;
6905
+ }
6906
+
6907
+ if (this._datepickerShowing) {
6908
+ showAnim = this._get(inst, "showAnim");
6909
+ duration = this._get(inst, "duration");
6910
+ postProcess = function() {
6911
+ $.datepicker._tidyDialog(inst);
6912
+ };
6913
+
6914
+ // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
6915
+ if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
6916
+ inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
6917
+ } else {
6918
+ inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
6919
+ (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
6920
+ }
6921
+
6922
+ if (!showAnim) {
6923
+ postProcess();
6924
+ }
6925
+ this._datepickerShowing = false;
6926
+
6927
+ onClose = this._get(inst, "onClose");
6928
+ if (onClose) {
6929
+ onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
6930
+ }
6931
+
6932
+ this._lastInput = null;
6933
+ if (this._inDialog) {
6934
+ this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
6935
+ if ($.blockUI) {
6936
+ $.unblockUI();
6937
+ $("body").append(this.dpDiv);
6938
+ }
6939
+ }
6940
+ this._inDialog = false;
6941
+ }
6942
+ },
6943
+
6944
+ /* Tidy up after a dialog display. */
6945
+ _tidyDialog: function(inst) {
6946
+ inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
6947
+ },
6948
+
6949
+ /* Close date picker if clicked elsewhere. */
6950
+ _checkExternalClick: function(event) {
6951
+ if (!$.datepicker._curInst) {
6952
+ return;
6953
+ }
6954
+
6955
+ var $target = $(event.target),
6956
+ inst = $.datepicker._getInst($target[0]);
6957
+
6958
+ if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
6959
+ $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
6960
+ !$target.hasClass($.datepicker.markerClassName) &&
6961
+ !$target.closest("." + $.datepicker._triggerClass).length &&
6962
+ $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
6963
+ ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
6964
+ $.datepicker._hideDatepicker();
6965
+ }
6966
+ },
6967
+
6968
+ /* Adjust one of the date sub-fields. */
6969
+ _adjustDate: function(id, offset, period) {
6970
+ var target = $(id),
6971
+ inst = this._getInst(target[0]);
6972
+
6973
+ if (this._isDisabledDatepicker(target[0])) {
6974
+ return;
6975
+ }
6976
+ this._adjustInstDate(inst, offset +
6977
+ (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
6978
+ period);
6979
+ this._updateDatepicker(inst);
6980
+ },
6981
+
6982
+ /* Action for current link. */
6983
+ _gotoToday: function(id) {
6984
+ var date,
6985
+ target = $(id),
6986
+ inst = this._getInst(target[0]);
6987
+
6988
+ if (this._get(inst, "gotoCurrent") && inst.currentDay) {
6989
+ inst.selectedDay = inst.currentDay;
6990
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth;
6991
+ inst.drawYear = inst.selectedYear = inst.currentYear;
6992
+ } else {
6993
+ date = new Date();
6994
+ inst.selectedDay = date.getDate();
6995
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
6996
+ inst.drawYear = inst.selectedYear = date.getFullYear();
6997
+ }
6998
+ this._notifyChange(inst);
6999
+ this._adjustDate(target);
7000
+ },
7001
+
7002
+ /* Action for selecting a new month/year. */
7003
+ _selectMonthYear: function(id, select, period) {
7004
+ var target = $(id),
7005
+ inst = this._getInst(target[0]);
7006
+
7007
+ inst["selected" + (period === "M" ? "Month" : "Year")] =
7008
+ inst["draw" + (period === "M" ? "Month" : "Year")] =
7009
+ parseInt(select.options[select.selectedIndex].value,10);
7010
+
7011
+ this._notifyChange(inst);
7012
+ this._adjustDate(target);
7013
+ },
7014
+
7015
+ /* Action for selecting a day. */
7016
+ _selectDay: function(id, month, year, td) {
7017
+ var inst,
7018
+ target = $(id);
7019
+
7020
+ if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
7021
+ return;
7022
+ }
7023
+
7024
+ inst = this._getInst(target[0]);
7025
+ inst.selectedDay = inst.currentDay = $("a", td).html();
7026
+ inst.selectedMonth = inst.currentMonth = month;
7027
+ inst.selectedYear = inst.currentYear = year;
7028
+ this._selectDate(id, this._formatDate(inst,
7029
+ inst.currentDay, inst.currentMonth, inst.currentYear));
7030
+ },
7031
+
7032
+ /* Erase the input field and hide the date picker. */
7033
+ _clearDate: function(id) {
7034
+ var target = $(id);
7035
+ this._selectDate(target, "");
7036
+ },
7037
+
7038
+ /* Update the input field with the selected date. */
7039
+ _selectDate: function(id, dateStr) {
7040
+ var onSelect,
7041
+ target = $(id),
7042
+ inst = this._getInst(target[0]);
7043
+
7044
+ dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
7045
+ if (inst.input) {
7046
+ inst.input.val(dateStr);
7047
+ }
7048
+ this._updateAlternate(inst);
7049
+
7050
+ onSelect = this._get(inst, "onSelect");
7051
+ if (onSelect) {
7052
+ onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
7053
+ } else if (inst.input) {
7054
+ inst.input.trigger("change"); // fire the change event
7055
+ }
7056
+
7057
+ if (inst.inline){
7058
+ this._updateDatepicker(inst);
7059
+ } else {
7060
+ this._hideDatepicker();
7061
+ this._lastInput = inst.input[0];
7062
+ if (typeof(inst.input[0]) !== "object") {
7063
+ inst.input.focus(); // restore focus
7064
+ }
7065
+ this._lastInput = null;
7066
+ }
7067
+ },
7068
+
7069
+ /* Update any alternate field to synchronise with the main field. */
7070
+ _updateAlternate: function(inst) {
7071
+ var altFormat, date, dateStr,
7072
+ altField = this._get(inst, "altField");
7073
+
7074
+ if (altField) { // update alternate field too
7075
+ altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
7076
+ date = this._getDate(inst);
7077
+ dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
7078
+ $(altField).each(function() { $(this).val(dateStr); });
7079
+ }
7080
+ },
7081
+
7082
+ /* Set as beforeShowDay function to prevent selection of weekends.
7083
+ * @param date Date - the date to customise
7084
+ * @return [boolean, string] - is this date selectable?, what is its CSS class?
7085
+ */
7086
+ noWeekends: function(date) {
7087
+ var day = date.getDay();
7088
+ return [(day > 0 && day < 6), ""];
7089
+ },
7090
+
7091
+ /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
7092
+ * @param date Date - the date to get the week for
7093
+ * @return number - the number of the week within the year that contains this date
7094
+ */
7095
+ iso8601Week: function(date) {
7096
+ var time,
7097
+ checkDate = new Date(date.getTime());
7098
+
7099
+ // Find Thursday of this week starting on Monday
7100
+ checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
7101
+
7102
+ time = checkDate.getTime();
7103
+ checkDate.setMonth(0); // Compare with Jan 1
7104
+ checkDate.setDate(1);
7105
+ return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
7106
+ },
7107
+
7108
+ /* Parse a string value into a date object.
7109
+ * See formatDate below for the possible formats.
7110
+ *
7111
+ * @param format string - the expected format of the date
7112
+ * @param value string - the date in the above format
7113
+ * @param settings Object - attributes include:
7114
+ * shortYearCutoff number - the cutoff year for determining the century (optional)
7115
+ * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
7116
+ * dayNames string[7] - names of the days from Sunday (optional)
7117
+ * monthNamesShort string[12] - abbreviated names of the months (optional)
7118
+ * monthNames string[12] - names of the months (optional)
7119
+ * @return Date - the extracted date value or null if value is blank
7120
+ */
7121
+ parseDate: function (format, value, settings) {
7122
+ if (format == null || value == null) {
7123
+ throw "Invalid arguments";
7124
+ }
7125
+
7126
+ value = (typeof value === "object" ? value.toString() : value + "");
7127
+ if (value === "") {
7128
+ return null;
7129
+ }
7130
+
7131
+ var iFormat, dim, extra,
7132
+ iValue = 0,
7133
+ shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
7134
+ shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
7135
+ new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
7136
+ dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
7137
+ dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
7138
+ monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
7139
+ monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
7140
+ year = -1,
7141
+ month = -1,
7142
+ day = -1,
7143
+ doy = -1,
7144
+ literal = false,
7145
+ date,
7146
+ // Check whether a format character is doubled
7147
+ lookAhead = function(match) {
7148
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
7149
+ if (matches) {
7150
+ iFormat++;
7151
+ }
7152
+ return matches;
7153
+ },
7154
+ // Extract a number from the string value
7155
+ getNumber = function(match) {
7156
+ var isDoubled = lookAhead(match),
7157
+ size = (match === "@" ? 14 : (match === "!" ? 20 :
7158
+ (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
7159
+ minSize = (match === "y" ? size : 1),
7160
+ digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
7161
+ num = value.substring(iValue).match(digits);
7162
+ if (!num) {
7163
+ throw "Missing number at position " + iValue;
7164
+ }
7165
+ iValue += num[0].length;
7166
+ return parseInt(num[0], 10);
7167
+ },
7168
+ // Extract a name from the string value and convert to an index
7169
+ getName = function(match, shortNames, longNames) {
7170
+ var index = -1,
7171
+ names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
7172
+ return [ [k, v] ];
7173
+ }).sort(function (a, b) {
7174
+ return -(a[1].length - b[1].length);
7175
+ });
7176
+
7177
+ $.each(names, function (i, pair) {
7178
+ var name = pair[1];
7179
+ if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
7180
+ index = pair[0];
7181
+ iValue += name.length;
7182
+ return false;
7183
+ }
7184
+ });
7185
+ if (index !== -1) {
7186
+ return index + 1;
7187
+ } else {
7188
+ throw "Unknown name at position " + iValue;
7189
+ }
7190
+ },
7191
+ // Confirm that a literal character matches the string value
7192
+ checkLiteral = function() {
7193
+ if (value.charAt(iValue) !== format.charAt(iFormat)) {
7194
+ throw "Unexpected literal at position " + iValue;
7195
+ }
7196
+ iValue++;
7197
+ };
7198
+
7199
+ for (iFormat = 0; iFormat < format.length; iFormat++) {
7200
+ if (literal) {
7201
+ if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
7202
+ literal = false;
7203
+ } else {
7204
+ checkLiteral();
7205
+ }
7206
+ } else {
7207
+ switch (format.charAt(iFormat)) {
7208
+ case "d":
7209
+ day = getNumber("d");
7210
+ break;
7211
+ case "D":
7212
+ getName("D", dayNamesShort, dayNames);
7213
+ break;
7214
+ case "o":
7215
+ doy = getNumber("o");
7216
+ break;
7217
+ case "m":
7218
+ month = getNumber("m");
7219
+ break;
7220
+ case "M":
7221
+ month = getName("M", monthNamesShort, monthNames);
7222
+ break;
7223
+ case "y":
7224
+ year = getNumber("y");
7225
+ break;
7226
+ case "@":
7227
+ date = new Date(getNumber("@"));
7228
+ year = date.getFullYear();
7229
+ month = date.getMonth() + 1;
7230
+ day = date.getDate();
7231
+ break;
7232
+ case "!":
7233
+ date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
7234
+ year = date.getFullYear();
7235
+ month = date.getMonth() + 1;
7236
+ day = date.getDate();
7237
+ break;
7238
+ case "'":
7239
+ if (lookAhead("'")){
7240
+ checkLiteral();
7241
+ } else {
7242
+ literal = true;
7243
+ }
7244
+ break;
7245
+ default:
7246
+ checkLiteral();
7247
+ }
7248
+ }
7249
+ }
7250
+
7251
+ if (iValue < value.length){
7252
+ extra = value.substr(iValue);
7253
+ if (!/^\s+/.test(extra)) {
7254
+ throw "Extra/unparsed characters found in date: " + extra;
7255
+ }
7256
+ }
7257
+
7258
+ if (year === -1) {
7259
+ year = new Date().getFullYear();
7260
+ } else if (year < 100) {
7261
+ year += new Date().getFullYear() - new Date().getFullYear() % 100 +
7262
+ (year <= shortYearCutoff ? 0 : -100);
7263
+ }
7264
+
7265
+ if (doy > -1) {
7266
+ month = 1;
7267
+ day = doy;
7268
+ do {
7269
+ dim = this._getDaysInMonth(year, month - 1);
7270
+ if (day <= dim) {
7271
+ break;
7272
+ }
7273
+ month++;
7274
+ day -= dim;
7275
+ } while (true);
7276
+ }
7277
+
7278
+ date = this._daylightSavingAdjust(new Date(year, month - 1, day));
7279
+ if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
7280
+ throw "Invalid date"; // E.g. 31/02/00
7281
+ }
7282
+ return date;
7283
+ },
7284
+
7285
+ /* Standard date formats. */
7286
+ ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
7287
+ COOKIE: "D, dd M yy",
7288
+ ISO_8601: "yy-mm-dd",
7289
+ RFC_822: "D, d M y",
7290
+ RFC_850: "DD, dd-M-y",
7291
+ RFC_1036: "D, d M y",
7292
+ RFC_1123: "D, d M yy",
7293
+ RFC_2822: "D, d M yy",
7294
+ RSS: "D, d M y", // RFC 822
7295
+ TICKS: "!",
7296
+ TIMESTAMP: "@",
7297
+ W3C: "yy-mm-dd", // ISO 8601
7298
+
7299
+ _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
7300
+ Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
7301
+
7302
+ /* Format a date object into a string value.
7303
+ * The format can be combinations of the following:
7304
+ * d - day of month (no leading zero)
7305
+ * dd - day of month (two digit)
7306
+ * o - day of year (no leading zeros)
7307
+ * oo - day of year (three digit)
7308
+ * D - day name short
7309
+ * DD - day name long
7310
+ * m - month of year (no leading zero)
7311
+ * mm - month of year (two digit)
7312
+ * M - month name short
7313
+ * MM - month name long
7314
+ * y - year (two digit)
7315
+ * yy - year (four digit)
7316
+ * @ - Unix timestamp (ms since 01/01/1970)
7317
+ * ! - Windows ticks (100ns since 01/01/0001)
7318
+ * "..." - literal text
7319
+ * '' - single quote
7320
+ *
7321
+ * @param format string - the desired format of the date
7322
+ * @param date Date - the date value to format
7323
+ * @param settings Object - attributes include:
7324
+ * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
7325
+ * dayNames string[7] - names of the days from Sunday (optional)
7326
+ * monthNamesShort string[12] - abbreviated names of the months (optional)
7327
+ * monthNames string[12] - names of the months (optional)
7328
+ * @return string - the date in the above format
7329
+ */
7330
+ formatDate: function (format, date, settings) {
7331
+ if (!date) {
7332
+ return "";
7333
+ }
7334
+
7335
+ var iFormat,
7336
+ dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
7337
+ dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
7338
+ monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
7339
+ monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
7340
+ // Check whether a format character is doubled
7341
+ lookAhead = function(match) {
7342
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
7343
+ if (matches) {
7344
+ iFormat++;
7345
+ }
7346
+ return matches;
7347
+ },
7348
+ // Format a number, with leading zero if necessary
7349
+ formatNumber = function(match, value, len) {
7350
+ var num = "" + value;
7351
+ if (lookAhead(match)) {
7352
+ while (num.length < len) {
7353
+ num = "0" + num;
7354
+ }
7355
+ }
7356
+ return num;
7357
+ },
7358
+ // Format a name, short or long as requested
7359
+ formatName = function(match, value, shortNames, longNames) {
7360
+ return (lookAhead(match) ? longNames[value] : shortNames[value]);
7361
+ },
7362
+ output = "",
7363
+ literal = false;
7364
+
7365
+ if (date) {
7366
+ for (iFormat = 0; iFormat < format.length; iFormat++) {
7367
+ if (literal) {
7368
+ if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
7369
+ literal = false;
7370
+ } else {
7371
+ output += format.charAt(iFormat);
7372
+ }
7373
+ } else {
7374
+ switch (format.charAt(iFormat)) {
7375
+ case "d":
7376
+ output += formatNumber("d", date.getDate(), 2);
7377
+ break;
7378
+ case "D":
7379
+ output += formatName("D", date.getDay(), dayNamesShort, dayNames);
7380
+ break;
7381
+ case "o":
7382
+ output += formatNumber("o",
7383
+ Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
7384
+ break;
7385
+ case "m":
7386
+ output += formatNumber("m", date.getMonth() + 1, 2);
7387
+ break;
7388
+ case "M":
7389
+ output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
7390
+ break;
7391
+ case "y":
7392
+ output += (lookAhead("y") ? date.getFullYear() :
7393
+ (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
7394
+ break;
7395
+ case "@":
7396
+ output += date.getTime();
7397
+ break;
7398
+ case "!":
7399
+ output += date.getTime() * 10000 + this._ticksTo1970;
7400
+ break;
7401
+ case "'":
7402
+ if (lookAhead("'")) {
7403
+ output += "'";
7404
+ } else {
7405
+ literal = true;
7406
+ }
7407
+ break;
7408
+ default:
7409
+ output += format.charAt(iFormat);
7410
+ }
7411
+ }
7412
+ }
7413
+ }
7414
+ return output;
7415
+ },
7416
+
7417
+ /* Extract all possible characters from the date format. */
7418
+ _possibleChars: function (format) {
7419
+ var iFormat,
7420
+ chars = "",
7421
+ literal = false,
7422
+ // Check whether a format character is doubled
7423
+ lookAhead = function(match) {
7424
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
7425
+ if (matches) {
7426
+ iFormat++;
7427
+ }
7428
+ return matches;
7429
+ };
7430
+
7431
+ for (iFormat = 0; iFormat < format.length; iFormat++) {
7432
+ if (literal) {
7433
+ if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
7434
+ literal = false;
7435
+ } else {
7436
+ chars += format.charAt(iFormat);
7437
+ }
7438
+ } else {
7439
+ switch (format.charAt(iFormat)) {
7440
+ case "d": case "m": case "y": case "@":
7441
+ chars += "0123456789";
7442
+ break;
7443
+ case "D": case "M":
7444
+ return null; // Accept anything
7445
+ case "'":
7446
+ if (lookAhead("'")) {
7447
+ chars += "'";
7448
+ } else {
7449
+ literal = true;
7450
+ }
7451
+ break;
7452
+ default:
7453
+ chars += format.charAt(iFormat);
7454
+ }
7455
+ }
7456
+ }
7457
+ return chars;
7458
+ },
7459
+
7460
+ /* Get a setting value, defaulting if necessary. */
7461
+ _get: function(inst, name) {
7462
+ return inst.settings[name] !== undefined ?
7463
+ inst.settings[name] : this._defaults[name];
7464
+ },
7465
+
7466
+ /* Parse existing date and initialise date picker. */
7467
+ _setDateFromField: function(inst, noDefault) {
7468
+ if (inst.input.val() === inst.lastVal) {
7469
+ return;
7470
+ }
7471
+
7472
+ var dateFormat = this._get(inst, "dateFormat"),
7473
+ dates = inst.lastVal = inst.input ? inst.input.val() : null,
7474
+ defaultDate = this._getDefaultDate(inst),
7475
+ date = defaultDate,
7476
+ settings = this._getFormatConfig(inst);
7477
+
7478
+ try {
7479
+ date = this.parseDate(dateFormat, dates, settings) || defaultDate;
7480
+ } catch (event) {
7481
+ dates = (noDefault ? "" : dates);
7482
+ }
7483
+ inst.selectedDay = date.getDate();
7484
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
7485
+ inst.drawYear = inst.selectedYear = date.getFullYear();
7486
+ inst.currentDay = (dates ? date.getDate() : 0);
7487
+ inst.currentMonth = (dates ? date.getMonth() : 0);
7488
+ inst.currentYear = (dates ? date.getFullYear() : 0);
7489
+ this._adjustInstDate(inst);
7490
+ },
7491
+
7492
+ /* Retrieve the default date shown on opening. */
7493
+ _getDefaultDate: function(inst) {
7494
+ return this._restrictMinMax(inst,
7495
+ this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
7496
+ },
7497
+
7498
+ /* A date may be specified as an exact value or a relative one. */
7499
+ _determineDate: function(inst, date, defaultDate) {
7500
+ var offsetNumeric = function(offset) {
7501
+ var date = new Date();
7502
+ date.setDate(date.getDate() + offset);
7503
+ return date;
7504
+ },
7505
+ offsetString = function(offset) {
7506
+ try {
7507
+ return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
7508
+ offset, $.datepicker._getFormatConfig(inst));
7509
+ }
7510
+ catch (e) {
7511
+ // Ignore
7512
+ }
7513
+
7514
+ var date = (offset.toLowerCase().match(/^c/) ?
7515
+ $.datepicker._getDate(inst) : null) || new Date(),
7516
+ year = date.getFullYear(),
7517
+ month = date.getMonth(),
7518
+ day = date.getDate(),
7519
+ pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
7520
+ matches = pattern.exec(offset);
7521
+
7522
+ while (matches) {
7523
+ switch (matches[2] || "d") {
7524
+ case "d" : case "D" :
7525
+ day += parseInt(matches[1],10); break;
7526
+ case "w" : case "W" :
7527
+ day += parseInt(matches[1],10) * 7; break;
7528
+ case "m" : case "M" :
7529
+ month += parseInt(matches[1],10);
7530
+ day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
7531
+ break;
7532
+ case "y": case "Y" :
7533
+ year += parseInt(matches[1],10);
7534
+ day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
7535
+ break;
7536
+ }
7537
+ matches = pattern.exec(offset);
7538
+ }
7539
+ return new Date(year, month, day);
7540
+ },
7541
+ newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
7542
+ (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
7543
+
7544
+ newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
7545
+ if (newDate) {
7546
+ newDate.setHours(0);
7547
+ newDate.setMinutes(0);
7548
+ newDate.setSeconds(0);
7549
+ newDate.setMilliseconds(0);
7550
+ }
7551
+ return this._daylightSavingAdjust(newDate);
7552
+ },
7553
+
7554
+ /* Handle switch to/from daylight saving.
7555
+ * Hours may be non-zero on daylight saving cut-over:
7556
+ * > 12 when midnight changeover, but then cannot generate
7557
+ * midnight datetime, so jump to 1AM, otherwise reset.
7558
+ * @param date (Date) the date to check
7559
+ * @return (Date) the corrected date
7560
+ */
7561
+ _daylightSavingAdjust: function(date) {
7562
+ if (!date) {
7563
+ return null;
7564
+ }
7565
+ date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
7566
+ return date;
7567
+ },
7568
+
7569
+ /* Set the date(s) directly. */
7570
+ _setDate: function(inst, date, noChange) {
7571
+ var clear = !date,
7572
+ origMonth = inst.selectedMonth,
7573
+ origYear = inst.selectedYear,
7574
+ newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
7575
+
7576
+ inst.selectedDay = inst.currentDay = newDate.getDate();
7577
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
7578
+ inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
7579
+ if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
7580
+ this._notifyChange(inst);
7581
+ }
7582
+ this._adjustInstDate(inst);
7583
+ if (inst.input) {
7584
+ inst.input.val(clear ? "" : this._formatDate(inst));
7585
+ }
7586
+ },
7587
+
7588
+ /* Retrieve the date(s) directly. */
7589
+ _getDate: function(inst) {
7590
+ var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
7591
+ this._daylightSavingAdjust(new Date(
7592
+ inst.currentYear, inst.currentMonth, inst.currentDay)));
7593
+ return startDate;
7594
+ },
7595
+
7596
+ /* Attach the onxxx handlers. These are declared statically so
7597
+ * they work with static code transformers like Caja.
7598
+ */
7599
+ _attachHandlers: function(inst) {
7600
+ var stepMonths = this._get(inst, "stepMonths"),
7601
+ id = "#" + inst.id.replace( /\\\\/g, "\\" );
7602
+ inst.dpDiv.find("[data-handler]").map(function () {
7603
+ var handler = {
7604
+ prev: function () {
7605
+ $.datepicker._adjustDate(id, -stepMonths, "M");
7606
+ },
7607
+ next: function () {
7608
+ $.datepicker._adjustDate(id, +stepMonths, "M");
7609
+ },
7610
+ hide: function () {
7611
+ $.datepicker._hideDatepicker();
7612
+ },
7613
+ today: function () {
7614
+ $.datepicker._gotoToday(id);
7615
+ },
7616
+ selectDay: function () {
7617
+ $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
7618
+ return false;
7619
+ },
7620
+ selectMonth: function () {
7621
+ $.datepicker._selectMonthYear(id, this, "M");
7622
+ return false;
7623
+ },
7624
+ selectYear: function () {
7625
+ $.datepicker._selectMonthYear(id, this, "Y");
7626
+ return false;
7627
+ }
7628
+ };
7629
+ $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
7630
+ });
7631
+ },
7632
+
7633
+ /* Generate the HTML for the current state of the date picker. */
7634
+ _generateHTML: function(inst) {
7635
+ var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
7636
+ controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
7637
+ monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
7638
+ selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
7639
+ cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
7640
+ printDate, dRow, tbody, daySettings, otherMonth, unselectable,
7641
+ tempDate = new Date(),
7642
+ today = this._daylightSavingAdjust(
7643
+ new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
7644
+ isRTL = this._get(inst, "isRTL"),
7645
+ showButtonPanel = this._get(inst, "showButtonPanel"),
7646
+ hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
7647
+ navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
7648
+ numMonths = this._getNumberOfMonths(inst),
7649
+ showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
7650
+ stepMonths = this._get(inst, "stepMonths"),
7651
+ isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
7652
+ currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
7653
+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
7654
+ minDate = this._getMinMaxDate(inst, "min"),
7655
+ maxDate = this._getMinMaxDate(inst, "max"),
7656
+ drawMonth = inst.drawMonth - showCurrentAtPos,
7657
+ drawYear = inst.drawYear;
7658
+
7659
+ if (drawMonth < 0) {
7660
+ drawMonth += 12;
7661
+ drawYear--;
7662
+ }
7663
+ if (maxDate) {
7664
+ maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
7665
+ maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
7666
+ maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
7667
+ while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
7668
+ drawMonth--;
7669
+ if (drawMonth < 0) {
7670
+ drawMonth = 11;
7671
+ drawYear--;
7672
+ }
7673
+ }
7674
+ }
7675
+ inst.drawMonth = drawMonth;
7676
+ inst.drawYear = drawYear;
7677
+
7678
+ prevText = this._get(inst, "prevText");
7679
+ prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
7680
+ this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
7681
+ this._getFormatConfig(inst)));
7682
+
7683
+ prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
7684
+ "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
7685
+ " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
7686
+ (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>"));
7687
+
7688
+ nextText = this._get(inst, "nextText");
7689
+ nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
7690
+ this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
7691
+ this._getFormatConfig(inst)));
7692
+
7693
+ next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
7694
+ "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
7695
+ " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
7696
+ (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>"));
7697
+
7698
+ currentText = this._get(inst, "currentText");
7699
+ gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
7700
+ currentText = (!navigationAsDateFormat ? currentText :
7701
+ this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
7702
+
7703
+ 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'>" +
7704
+ this._get(inst, "closeText") + "</button>" : "");
7705
+
7706
+ buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
7707
+ (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'" +
7708
+ ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
7709
+
7710
+ firstDay = parseInt(this._get(inst, "firstDay"),10);
7711
+ firstDay = (isNaN(firstDay) ? 0 : firstDay);
7712
+
7713
+ showWeek = this._get(inst, "showWeek");
7714
+ dayNames = this._get(inst, "dayNames");
7715
+ dayNamesMin = this._get(inst, "dayNamesMin");
7716
+ monthNames = this._get(inst, "monthNames");
7717
+ monthNamesShort = this._get(inst, "monthNamesShort");
7718
+ beforeShowDay = this._get(inst, "beforeShowDay");
7719
+ showOtherMonths = this._get(inst, "showOtherMonths");
7720
+ selectOtherMonths = this._get(inst, "selectOtherMonths");
7721
+ defaultDate = this._getDefaultDate(inst);
7722
+ html = "";
7723
+ dow;
7724
+ for (row = 0; row < numMonths[0]; row++) {
7725
+ group = "";
7726
+ this.maxRows = 4;
7727
+ for (col = 0; col < numMonths[1]; col++) {
7728
+ selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
7729
+ cornerClass = " ui-corner-all";
7730
+ calender = "";
7731
+ if (isMultiMonth) {
7732
+ calender += "<div class='ui-datepicker-group";
7733
+ if (numMonths[1] > 1) {
7734
+ switch (col) {
7735
+ case 0: calender += " ui-datepicker-group-first";
7736
+ cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
7737
+ case numMonths[1]-1: calender += " ui-datepicker-group-last";
7738
+ cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
7739
+ default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
7740
+ }
7741
+ }
7742
+ calender += "'>";
7743
+ }
7744
+ calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
7745
+ (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
7746
+ (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
7747
+ this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
7748
+ row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
7749
+ "</div><table class='ui-datepicker-calendar'><thead>" +
7750
+ "<tr>";
7751
+ thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
7752
+ for (dow = 0; dow < 7; dow++) { // days of the week
7753
+ day = (dow + firstDay) % 7;
7754
+ thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
7755
+ "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
7756
+ }
7757
+ calender += thead + "</tr></thead><tbody>";
7758
+ daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
7759
+ if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
7760
+ inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
7761
+ }
7762
+ leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
7763
+ curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
7764
+ numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
7765
+ this.maxRows = numRows;
7766
+ printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
7767
+ for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
7768
+ calender += "<tr>";
7769
+ tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
7770
+ this._get(inst, "calculateWeek")(printDate) + "</td>");
7771
+ for (dow = 0; dow < 7; dow++) { // create date picker days
7772
+ daySettings = (beforeShowDay ?
7773
+ beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
7774
+ otherMonth = (printDate.getMonth() !== drawMonth);
7775
+ unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
7776
+ (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
7777
+ tbody += "<td class='" +
7778
+ ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
7779
+ (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
7780
+ ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
7781
+ (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
7782
+ // or defaultDate is current printedDate and defaultDate is selectedDate
7783
+ " " + this._dayOverClass : "") + // highlight selected day
7784
+ (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days
7785
+ (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
7786
+ (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
7787
+ (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
7788
+ ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
7789
+ (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
7790
+ (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
7791
+ (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
7792
+ (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
7793
+ (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
7794
+ (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
7795
+ "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
7796
+ printDate.setDate(printDate.getDate() + 1);
7797
+ printDate = this._daylightSavingAdjust(printDate);
7798
+ }
7799
+ calender += tbody + "</tr>";
7800
+ }
7801
+ drawMonth++;
7802
+ if (drawMonth > 11) {
7803
+ drawMonth = 0;
7804
+ drawYear++;
7805
+ }
7806
+ calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
7807
+ ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
7808
+ group += calender;
7809
+ }
7810
+ html += group;
7811
+ }
7812
+ html += buttonPanel;
7813
+ inst._keyEvent = false;
7814
+ return html;
7815
+ },
7816
+
7817
+ /* Generate the month and year header. */
7818
+ _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
7819
+ secondary, monthNames, monthNamesShort) {
7820
+
7821
+ var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
7822
+ changeMonth = this._get(inst, "changeMonth"),
7823
+ changeYear = this._get(inst, "changeYear"),
7824
+ showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
7825
+ html = "<div class='ui-datepicker-title'>",
7826
+ monthHtml = "";
7827
+
7828
+ // month selection
7829
+ if (secondary || !changeMonth) {
7830
+ monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
7831
+ } else {
7832
+ inMinYear = (minDate && minDate.getFullYear() === drawYear);
7833
+ inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
7834
+ monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
7835
+ for ( month = 0; month < 12; month++) {
7836
+ if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
7837
+ monthHtml += "<option value='" + month + "'" +
7838
+ (month === drawMonth ? " selected='selected'" : "") +
7839
+ ">" + monthNamesShort[month] + "</option>";
7840
+ }
7841
+ }
7842
+ monthHtml += "</select>";
7843
+ }
7844
+
7845
+ if (!showMonthAfterYear) {
7846
+ html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
7847
+ }
7848
+
7849
+ // year selection
7850
+ if ( !inst.yearshtml ) {
7851
+ inst.yearshtml = "";
7852
+ if (secondary || !changeYear) {
7853
+ html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
7854
+ } else {
7855
+ // determine range of years to display
7856
+ years = this._get(inst, "yearRange").split(":");
7857
+ thisYear = new Date().getFullYear();
7858
+ determineYear = function(value) {
7859
+ var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
7860
+ (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
7861
+ parseInt(value, 10)));
7862
+ return (isNaN(year) ? thisYear : year);
7863
+ };
7864
+ year = determineYear(years[0]);
7865
+ endYear = Math.max(year, determineYear(years[1] || ""));
7866
+ year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
7867
+ endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
7868
+ inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
7869
+ for (; year <= endYear; year++) {
7870
+ inst.yearshtml += "<option value='" + year + "'" +
7871
+ (year === drawYear ? " selected='selected'" : "") +
7872
+ ">" + year + "</option>";
7873
+ }
7874
+ inst.yearshtml += "</select>";
7875
+
7876
+ html += inst.yearshtml;
7877
+ inst.yearshtml = null;
7878
+ }
7879
+ }
7880
+
7881
+ html += this._get(inst, "yearSuffix");
7882
+ if (showMonthAfterYear) {
7883
+ html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
7884
+ }
7885
+ html += "</div>"; // Close datepicker_header
7886
+ return html;
7887
+ },
7888
+
7889
+ /* Adjust one of the date sub-fields. */
7890
+ _adjustInstDate: function(inst, offset, period) {
7891
+ var year = inst.drawYear + (period === "Y" ? offset : 0),
7892
+ month = inst.drawMonth + (period === "M" ? offset : 0),
7893
+ day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
7894
+ date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
7895
+
7896
+ inst.selectedDay = date.getDate();
7897
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
7898
+ inst.drawYear = inst.selectedYear = date.getFullYear();
7899
+ if (period === "M" || period === "Y") {
7900
+ this._notifyChange(inst);
7901
+ }
7902
+ },
7903
+
7904
+ /* Ensure a date is within any min/max bounds. */
7905
+ _restrictMinMax: function(inst, date) {
7906
+ var minDate = this._getMinMaxDate(inst, "min"),
7907
+ maxDate = this._getMinMaxDate(inst, "max"),
7908
+ newDate = (minDate && date < minDate ? minDate : date);
7909
+ return (maxDate && newDate > maxDate ? maxDate : newDate);
7910
+ },
7911
+
7912
+ /* Notify change of month/year. */
7913
+ _notifyChange: function(inst) {
7914
+ var onChange = this._get(inst, "onChangeMonthYear");
7915
+ if (onChange) {
7916
+ onChange.apply((inst.input ? inst.input[0] : null),
7917
+ [inst.selectedYear, inst.selectedMonth + 1, inst]);
7918
+ }
7919
+ },
7920
+
7921
+ /* Determine the number of months to show. */
7922
+ _getNumberOfMonths: function(inst) {
7923
+ var numMonths = this._get(inst, "numberOfMonths");
7924
+ return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
7925
+ },
7926
+
7927
+ /* Determine the current maximum date - ensure no time components are set. */
7928
+ _getMinMaxDate: function(inst, minMax) {
7929
+ return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
7930
+ },
7931
+
7932
+ /* Find the number of days in a given month. */
7933
+ _getDaysInMonth: function(year, month) {
7934
+ return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
7935
+ },
7936
+
7937
+ /* Find the day of the week of the first of a month. */
7938
+ _getFirstDayOfMonth: function(year, month) {
7939
+ return new Date(year, month, 1).getDay();
7940
+ },
7941
+
7942
+ /* Determines if we should allow a "next/prev" month display change. */
7943
+ _canAdjustMonth: function(inst, offset, curYear, curMonth) {
7944
+ var numMonths = this._getNumberOfMonths(inst),
7945
+ date = this._daylightSavingAdjust(new Date(curYear,
7946
+ curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
7947
+
7948
+ if (offset < 0) {
7949
+ date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
7950
+ }
7951
+ return this._isInRange(inst, date);
7952
+ },
7953
+
7954
+ /* Is the given date in the accepted range? */
7955
+ _isInRange: function(inst, date) {
7956
+ var yearSplit, currentYear,
7957
+ minDate = this._getMinMaxDate(inst, "min"),
7958
+ maxDate = this._getMinMaxDate(inst, "max"),
7959
+ minYear = null,
7960
+ maxYear = null,
7961
+ years = this._get(inst, "yearRange");
7962
+ if (years){
7963
+ yearSplit = years.split(":");
7964
+ currentYear = new Date().getFullYear();
7965
+ minYear = parseInt(yearSplit[0], 10);
7966
+ maxYear = parseInt(yearSplit[1], 10);
7967
+ if ( yearSplit[0].match(/[+\-].*/) ) {
7968
+ minYear += currentYear;
7969
+ }
7970
+ if ( yearSplit[1].match(/[+\-].*/) ) {
7971
+ maxYear += currentYear;
7972
+ }
7973
+ }
7974
+
7975
+ return ((!minDate || date.getTime() >= minDate.getTime()) &&
7976
+ (!maxDate || date.getTime() <= maxDate.getTime()) &&
7977
+ (!minYear || date.getFullYear() >= minYear) &&
7978
+ (!maxYear || date.getFullYear() <= maxYear));
7979
+ },
7980
+
7981
+ /* Provide the configuration settings for formatting/parsing. */
7982
+ _getFormatConfig: function(inst) {
7983
+ var shortYearCutoff = this._get(inst, "shortYearCutoff");
7984
+ shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
7985
+ new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
7986
+ return {shortYearCutoff: shortYearCutoff,
7987
+ dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
7988
+ monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
7989
+ },
7990
+
7991
+ /* Format the given date for display. */
7992
+ _formatDate: function(inst, day, month, year) {
7993
+ if (!day) {
7994
+ inst.currentDay = inst.selectedDay;
7995
+ inst.currentMonth = inst.selectedMonth;
7996
+ inst.currentYear = inst.selectedYear;
7997
+ }
7998
+ var date = (day ? (typeof day === "object" ? day :
7999
+ this._daylightSavingAdjust(new Date(year, month, day))) :
8000
+ this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8001
+ return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
8002
+ }
8003
+ });
8004
+
8005
+ /*
8006
+ * Bind hover events for datepicker elements.
8007
+ * Done via delegate so the binding only occurs once in the lifetime of the parent div.
8008
+ * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
8009
+ */
8010
+ function datepicker_bindHover(dpDiv) {
8011
+ var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
8012
+ return dpDiv.delegate(selector, "mouseout", function() {
8013
+ $(this).removeClass("ui-state-hover");
8014
+ if (this.className.indexOf("ui-datepicker-prev") !== -1) {
8015
+ $(this).removeClass("ui-datepicker-prev-hover");
8016
+ }
8017
+ if (this.className.indexOf("ui-datepicker-next") !== -1) {
8018
+ $(this).removeClass("ui-datepicker-next-hover");
8019
+ }
8020
+ })
8021
+ .delegate( selector, "mouseover", datepicker_handleMouseover );
8022
+ }
8023
+
8024
+ function datepicker_handleMouseover() {
8025
+ if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
8026
+ $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
8027
+ $(this).addClass("ui-state-hover");
8028
+ if (this.className.indexOf("ui-datepicker-prev") !== -1) {
8029
+ $(this).addClass("ui-datepicker-prev-hover");
8030
+ }
8031
+ if (this.className.indexOf("ui-datepicker-next") !== -1) {
8032
+ $(this).addClass("ui-datepicker-next-hover");
8033
+ }
8034
+ }
8035
+ }
8036
+
8037
+ /* jQuery extend now ignores nulls! */
8038
+ function datepicker_extendRemove(target, props) {
8039
+ $.extend(target, props);
8040
+ for (var name in props) {
8041
+ if (props[name] == null) {
8042
+ target[name] = props[name];
8043
+ }
8044
+ }
8045
+ return target;
8046
+ }
8047
+
8048
+ /* Invoke the datepicker functionality.
8049
+ @param options string - a command, optionally followed by additional parameters or
8050
+ Object - settings for attaching new datepicker functionality
8051
+ @return jQuery object */
8052
+ $.fn.datepicker = function(options){
8053
+
8054
+ /* Verify an empty collection wasn't passed - Fixes #6976 */
8055
+ if ( !this.length ) {
8056
+ return this;
8057
+ }
8058
+
8059
+ /* Initialise the date picker. */
8060
+ if (!$.datepicker.initialized) {
8061
+ $(document).mousedown($.datepicker._checkExternalClick);
8062
+ $.datepicker.initialized = true;
8063
+ }
8064
+
8065
+ /* Append datepicker main container to body if not exist. */
8066
+ if ($("#"+$.datepicker._mainDivId).length === 0) {
8067
+ $("body").append($.datepicker.dpDiv);
8068
+ }
8069
+
8070
+ var otherArgs = Array.prototype.slice.call(arguments, 1);
8071
+ if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
8072
+ return $.datepicker["_" + options + "Datepicker"].
8073
+ apply($.datepicker, [this[0]].concat(otherArgs));
8074
+ }
8075
+ if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
8076
+ return $.datepicker["_" + options + "Datepicker"].
8077
+ apply($.datepicker, [this[0]].concat(otherArgs));
8078
+ }
8079
+ return this.each(function() {
8080
+ typeof options === "string" ?
8081
+ $.datepicker["_" + options + "Datepicker"].
8082
+ apply($.datepicker, [this].concat(otherArgs)) :
8083
+ $.datepicker._attachDatepicker(this, options);
8084
+ });
8085
+ };
8086
+
8087
+ $.datepicker = new Datepicker(); // singleton instance
8088
+ $.datepicker.initialized = false;
8089
+ $.datepicker.uuid = new Date().getTime();
8090
+ $.datepicker.version = "1.11.1";
8091
+
8092
+ var datepicker = $.datepicker;
8093
+
8094
+
8095
+ /*!
8096
+ * jQuery UI Tabs 1.11.1
8097
+ * http://jqueryui.com
8098
+ *
8099
+ * Copyright 2014 jQuery Foundation and other contributors
8100
+ * Released under the MIT license.
8101
+ * http://jquery.org/license
8102
+ *
8103
+ * http://api.jqueryui.com/tabs/
8104
+ */
8105
+
8106
+
8107
+ var tabs = $.widget( "ui.tabs", {
8108
+ version: "1.11.1",
8109
+ delay: 300,
8110
+ options: {
8111
+ active: null,
8112
+ collapsible: false,
8113
+ event: "click",
8114
+ heightStyle: "content",
8115
+ hide: null,
8116
+ show: null,
8117
+
8118
+ // callbacks
8119
+ activate: null,
8120
+ beforeActivate: null,
8121
+ beforeLoad: null,
8122
+ load: null
8123
+ },
8124
+
8125
+ _isLocal: (function() {
8126
+ var rhash = /#.*$/;
8127
+
8128
+ return function( anchor ) {
8129
+ var anchorUrl, locationUrl;
8130
+
8131
+ // support: IE7
8132
+ // IE7 doesn't normalize the href property when set via script (#9317)
8133
+ anchor = anchor.cloneNode( false );
8134
+
8135
+ anchorUrl = anchor.href.replace( rhash, "" );
8136
+ locationUrl = location.href.replace( rhash, "" );
8137
+
8138
+ // decoding may throw an error if the URL isn't UTF-8 (#9518)
8139
+ try {
8140
+ anchorUrl = decodeURIComponent( anchorUrl );
8141
+ } catch ( error ) {}
8142
+ try {
8143
+ locationUrl = decodeURIComponent( locationUrl );
8144
+ } catch ( error ) {}
8145
+
8146
+ return anchor.hash.length > 1 && anchorUrl === locationUrl;
8147
+ };
8148
+ })(),
8149
+
8150
+ _create: function() {
8151
+ var that = this,
8152
+ options = this.options;
8153
+
8154
+ this.running = false;
8155
+
8156
+ this.element
8157
+ .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
8158
+ .toggleClass( "ui-tabs-collapsible", options.collapsible );
8159
+
8160
+ this._processTabs();
8161
+ options.active = this._initialActive();
8162
+
8163
+ // Take disabling tabs via class attribute from HTML
8164
+ // into account and update option properly.
8165
+ if ( $.isArray( options.disabled ) ) {
8166
+ options.disabled = $.unique( options.disabled.concat(
8167
+ $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
8168
+ return that.tabs.index( li );
8169
+ })
8170
+ ) ).sort();
8171
+ }
8172
+
8173
+ // check for length avoids error when initializing empty list
8174
+ if ( this.options.active !== false && this.anchors.length ) {
8175
+ this.active = this._findActive( options.active );
8176
+ } else {
8177
+ this.active = $();
8178
+ }
8179
+
8180
+ this._refresh();
8181
+
8182
+ if ( this.active.length ) {
8183
+ this.load( options.active );
8184
+ }
8185
+ },
8186
+
8187
+ _initialActive: function() {
8188
+ var active = this.options.active,
8189
+ collapsible = this.options.collapsible,
8190
+ locationHash = location.hash.substring( 1 );
8191
+
8192
+ if ( active === null ) {
8193
+ // check the fragment identifier in the URL
8194
+ if ( locationHash ) {
8195
+ this.tabs.each(function( i, tab ) {
8196
+ if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
8197
+ active = i;
8198
+ return false;
8199
+ }
8200
+ });
8201
+ }
8202
+
8203
+ // check for a tab marked active via a class
8204
+ if ( active === null ) {
8205
+ active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
8206
+ }
8207
+
8208
+ // no active tab, set to false
8209
+ if ( active === null || active === -1 ) {
8210
+ active = this.tabs.length ? 0 : false;
8211
+ }
8212
+ }
8213
+
8214
+ // handle numbers: negative, out of range
8215
+ if ( active !== false ) {
8216
+ active = this.tabs.index( this.tabs.eq( active ) );
8217
+ if ( active === -1 ) {
8218
+ active = collapsible ? false : 0;
8219
+ }
8220
+ }
8221
+
8222
+ // don't allow collapsible: false and active: false
8223
+ if ( !collapsible && active === false && this.anchors.length ) {
8224
+ active = 0;
8225
+ }
8226
+
8227
+ return active;
8228
+ },
8229
+
8230
+ _getCreateEventData: function() {
8231
+ return {
8232
+ tab: this.active,
8233
+ panel: !this.active.length ? $() : this._getPanelForTab( this.active )
8234
+ };
8235
+ },
8236
+
8237
+ _tabKeydown: function( event ) {
8238
+ var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
8239
+ selectedIndex = this.tabs.index( focusedTab ),
8240
+ goingForward = true;
8241
+
8242
+ if ( this._handlePageNav( event ) ) {
8243
+ return;
8244
+ }
8245
+
8246
+ switch ( event.keyCode ) {
8247
+ case $.ui.keyCode.RIGHT:
8248
+ case $.ui.keyCode.DOWN:
8249
+ selectedIndex++;
8250
+ break;
8251
+ case $.ui.keyCode.UP:
8252
+ case $.ui.keyCode.LEFT:
8253
+ goingForward = false;
8254
+ selectedIndex--;
8255
+ break;
8256
+ case $.ui.keyCode.END:
8257
+ selectedIndex = this.anchors.length - 1;
8258
+ break;
8259
+ case $.ui.keyCode.HOME:
8260
+ selectedIndex = 0;
8261
+ break;
8262
+ case $.ui.keyCode.SPACE:
8263
+ // Activate only, no collapsing
8264
+ event.preventDefault();
8265
+ clearTimeout( this.activating );
8266
+ this._activate( selectedIndex );
8267
+ return;
8268
+ case $.ui.keyCode.ENTER:
8269
+ // Toggle (cancel delayed activation, allow collapsing)
8270
+ event.preventDefault();
8271
+ clearTimeout( this.activating );
8272
+ // Determine if we should collapse or activate
8273
+ this._activate( selectedIndex === this.options.active ? false : selectedIndex );
8274
+ return;
8275
+ default:
8276
+ return;
8277
+ }
8278
+
8279
+ // Focus the appropriate tab, based on which key was pressed
8280
+ event.preventDefault();
8281
+ clearTimeout( this.activating );
8282
+ selectedIndex = this._focusNextTab( selectedIndex, goingForward );
8283
+
8284
+ // Navigating with control key will prevent automatic activation
8285
+ if ( !event.ctrlKey ) {
8286
+ // Update aria-selected immediately so that AT think the tab is already selected.
8287
+ // Otherwise AT may confuse the user by stating that they need to activate the tab,
8288
+ // but the tab will already be activated by the time the announcement finishes.
8289
+ focusedTab.attr( "aria-selected", "false" );
8290
+ this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
8291
+
8292
+ this.activating = this._delay(function() {
8293
+ this.option( "active", selectedIndex );
8294
+ }, this.delay );
8295
+ }
8296
+ },
8297
+
8298
+ _panelKeydown: function( event ) {
8299
+ if ( this._handlePageNav( event ) ) {
8300
+ return;
8301
+ }
8302
+
8303
+ // Ctrl+up moves focus to the current tab
8304
+ if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
8305
+ event.preventDefault();
8306
+ this.active.focus();
8307
+ }
8308
+ },
8309
+
8310
+ // Alt+page up/down moves focus to the previous/next tab (and activates)
8311
+ _handlePageNav: function( event ) {
8312
+ if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
8313
+ this._activate( this._focusNextTab( this.options.active - 1, false ) );
8314
+ return true;
8315
+ }
8316
+ if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
8317
+ this._activate( this._focusNextTab( this.options.active + 1, true ) );
8318
+ return true;
8319
+ }
8320
+ },
8321
+
8322
+ _findNextTab: function( index, goingForward ) {
8323
+ var lastTabIndex = this.tabs.length - 1;
8324
+
8325
+ function constrain() {
8326
+ if ( index > lastTabIndex ) {
8327
+ index = 0;
8328
+ }
8329
+ if ( index < 0 ) {
8330
+ index = lastTabIndex;
8331
+ }
8332
+ return index;
8333
+ }
8334
+
8335
+ while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
8336
+ index = goingForward ? index + 1 : index - 1;
8337
+ }
8338
+
8339
+ return index;
8340
+ },
8341
+
8342
+ _focusNextTab: function( index, goingForward ) {
8343
+ index = this._findNextTab( index, goingForward );
8344
+ this.tabs.eq( index ).focus();
8345
+ return index;
8346
+ },
8347
+
8348
+ _setOption: function( key, value ) {
8349
+ if ( key === "active" ) {
8350
+ // _activate() will handle invalid values and update this.options
8351
+ this._activate( value );
8352
+ return;
8353
+ }
8354
+
8355
+ if ( key === "disabled" ) {
8356
+ // don't use the widget factory's disabled handling
8357
+ this._setupDisabled( value );
8358
+ return;
8359
+ }
8360
+
8361
+ this._super( key, value);
8362
+
8363
+ if ( key === "collapsible" ) {
8364
+ this.element.toggleClass( "ui-tabs-collapsible", value );
8365
+ // Setting collapsible: false while collapsed; open first panel
8366
+ if ( !value && this.options.active === false ) {
8367
+ this._activate( 0 );
8368
+ }
8369
+ }
8370
+
8371
+ if ( key === "event" ) {
8372
+ this._setupEvents( value );
8373
+ }
8374
+
8375
+ if ( key === "heightStyle" ) {
8376
+ this._setupHeightStyle( value );
8377
+ }
8378
+ },
8379
+
8380
+ _sanitizeSelector: function( hash ) {
8381
+ return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
8382
+ },
8383
+
8384
+ refresh: function() {
8385
+ var options = this.options,
8386
+ lis = this.tablist.children( ":has(a[href])" );
8387
+
8388
+ // get disabled tabs from class attribute from HTML
8389
+ // this will get converted to a boolean if needed in _refresh()
8390
+ options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
8391
+ return lis.index( tab );
8392
+ });
8393
+
8394
+ this._processTabs();
8395
+
8396
+ // was collapsed or no tabs
8397
+ if ( options.active === false || !this.anchors.length ) {
8398
+ options.active = false;
8399
+ this.active = $();
8400
+ // was active, but active tab is gone
8401
+ } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
8402
+ // all remaining tabs are disabled
8403
+ if ( this.tabs.length === options.disabled.length ) {
8404
+ options.active = false;
8405
+ this.active = $();
8406
+ // activate previous tab
8407
+ } else {
8408
+ this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
8409
+ }
8410
+ // was active, active tab still exists
8411
+ } else {
8412
+ // make sure active index is correct
8413
+ options.active = this.tabs.index( this.active );
8414
+ }
8415
+
8416
+ this._refresh();
8417
+ },
8418
+
8419
+ _refresh: function() {
8420
+ this._setupDisabled( this.options.disabled );
8421
+ this._setupEvents( this.options.event );
8422
+ this._setupHeightStyle( this.options.heightStyle );
8423
+
8424
+ this.tabs.not( this.active ).attr({
8425
+ "aria-selected": "false",
8426
+ "aria-expanded": "false",
8427
+ tabIndex: -1
8428
+ });
8429
+ this.panels.not( this._getPanelForTab( this.active ) )
8430
+ .hide()
8431
+ .attr({
8432
+ "aria-hidden": "true"
8433
+ });
8434
+
8435
+ // Make sure one tab is in the tab order
8436
+ if ( !this.active.length ) {
8437
+ this.tabs.eq( 0 ).attr( "tabIndex", 0 );
8438
+ } else {
8439
+ this.active
8440
+ .addClass( "ui-tabs-active ui-state-active" )
8441
+ .attr({
8442
+ "aria-selected": "true",
8443
+ "aria-expanded": "true",
8444
+ tabIndex: 0
8445
+ });
8446
+ this._getPanelForTab( this.active )
8447
+ .show()
8448
+ .attr({
8449
+ "aria-hidden": "false"
8450
+ });
8451
+ }
8452
+ },
8453
+
8454
+ _processTabs: function() {
8455
+ var that = this;
8456
+
8457
+ this.tablist = this._getList()
8458
+ .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
8459
+ .attr( "role", "tablist" )
8460
+
8461
+ // Prevent users from focusing disabled tabs via click
8462
+ .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
8463
+ if ( $( this ).is( ".ui-state-disabled" ) ) {
8464
+ event.preventDefault();
8465
+ }
8466
+ })
8467
+
8468
+ // support: IE <9
8469
+ // Preventing the default action in mousedown doesn't prevent IE
8470
+ // from focusing the element, so if the anchor gets focused, blur.
8471
+ // We don't have to worry about focusing the previously focused
8472
+ // element since clicking on a non-focusable element should focus
8473
+ // the body anyway.
8474
+ .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
8475
+ if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
8476
+ this.blur();
8477
+ }
8478
+ });
8479
+
8480
+ this.tabs = this.tablist.find( "> li:has(a[href])" )
8481
+ .addClass( "ui-state-default ui-corner-top" )
8482
+ .attr({
8483
+ role: "tab",
8484
+ tabIndex: -1
8485
+ });
8486
+
8487
+ this.anchors = this.tabs.map(function() {
8488
+ return $( "a", this )[ 0 ];
8489
+ })
8490
+ .addClass( "ui-tabs-anchor" )
8491
+ .attr({
8492
+ role: "presentation",
8493
+ tabIndex: -1
8494
+ });
8495
+
8496
+ this.panels = $();
8497
+
8498
+ this.anchors.each(function( i, anchor ) {
8499
+ var selector, panel, panelId,
8500
+ anchorId = $( anchor ).uniqueId().attr( "id" ),
8501
+ tab = $( anchor ).closest( "li" ),
8502
+ originalAriaControls = tab.attr( "aria-controls" );
8503
+
8504
+ // inline tab
8505
+ if ( that._isLocal( anchor ) ) {
8506
+ selector = anchor.hash;
8507
+ panelId = selector.substring( 1 );
8508
+ panel = that.element.find( that._sanitizeSelector( selector ) );
8509
+ // remote tab
8510
+ } else {
8511
+ // If the tab doesn't already have aria-controls,
8512
+ // generate an id by using a throw-away element
8513
+ panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
8514
+ selector = "#" + panelId;
8515
+ panel = that.element.find( selector );
8516
+ if ( !panel.length ) {
8517
+ panel = that._createPanel( panelId );
8518
+ panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
8519
+ }
8520
+ panel.attr( "aria-live", "polite" );
8521
+ }
8522
+
8523
+ if ( panel.length) {
8524
+ that.panels = that.panels.add( panel );
8525
+ }
8526
+ if ( originalAriaControls ) {
8527
+ tab.data( "ui-tabs-aria-controls", originalAriaControls );
8528
+ }
8529
+ tab.attr({
8530
+ "aria-controls": panelId,
8531
+ "aria-labelledby": anchorId
8532
+ });
8533
+ panel.attr( "aria-labelledby", anchorId );
8534
+ });
8535
+
8536
+ this.panels
8537
+ .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
8538
+ .attr( "role", "tabpanel" );
8539
+ },
8540
+
8541
+ // allow overriding how to find the list for rare usage scenarios (#7715)
8542
+ _getList: function() {
8543
+ return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
8544
+ },
8545
+
8546
+ _createPanel: function( id ) {
8547
+ return $( "<div>" )
8548
+ .attr( "id", id )
8549
+ .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
8550
+ .data( "ui-tabs-destroy", true );
8551
+ },
8552
+
8553
+ _setupDisabled: function( disabled ) {
8554
+ if ( $.isArray( disabled ) ) {
8555
+ if ( !disabled.length ) {
8556
+ disabled = false;
8557
+ } else if ( disabled.length === this.anchors.length ) {
8558
+ disabled = true;
8559
+ }
8560
+ }
8561
+
8562
+ // disable tabs
8563
+ for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
8564
+ if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
8565
+ $( li )
8566
+ .addClass( "ui-state-disabled" )
8567
+ .attr( "aria-disabled", "true" );
8568
+ } else {
8569
+ $( li )
8570
+ .removeClass( "ui-state-disabled" )
8571
+ .removeAttr( "aria-disabled" );
8572
+ }
8573
+ }
8574
+
8575
+ this.options.disabled = disabled;
8576
+ },
8577
+
8578
+ _setupEvents: function( event ) {
8579
+ var events = {};
8580
+ if ( event ) {
8581
+ $.each( event.split(" "), function( index, eventName ) {
8582
+ events[ eventName ] = "_eventHandler";
8583
+ });
8584
+ }
8585
+
8586
+ this._off( this.anchors.add( this.tabs ).add( this.panels ) );
8587
+ // Always prevent the default action, even when disabled
8588
+ this._on( true, this.anchors, {
8589
+ click: function( event ) {
8590
+ event.preventDefault();
8591
+ }
8592
+ });
8593
+ this._on( this.anchors, events );
8594
+ this._on( this.tabs, { keydown: "_tabKeydown" } );
8595
+ this._on( this.panels, { keydown: "_panelKeydown" } );
8596
+
8597
+ this._focusable( this.tabs );
8598
+ this._hoverable( this.tabs );
8599
+ },
8600
+
8601
+ _setupHeightStyle: function( heightStyle ) {
8602
+ var maxHeight,
8603
+ parent = this.element.parent();
8604
+
8605
+ if ( heightStyle === "fill" ) {
8606
+ maxHeight = parent.height();
8607
+ maxHeight -= this.element.outerHeight() - this.element.height();
8608
+
8609
+ this.element.siblings( ":visible" ).each(function() {
8610
+ var elem = $( this ),
8611
+ position = elem.css( "position" );
8612
+
8613
+ if ( position === "absolute" || position === "fixed" ) {
8614
+ return;
8615
+ }
8616
+ maxHeight -= elem.outerHeight( true );
8617
+ });
8618
+
8619
+ this.element.children().not( this.panels ).each(function() {
8620
+ maxHeight -= $( this ).outerHeight( true );
8621
+ });
8622
+
8623
+ this.panels.each(function() {
8624
+ $( this ).height( Math.max( 0, maxHeight -
8625
+ $( this ).innerHeight() + $( this ).height() ) );
8626
+ })
8627
+ .css( "overflow", "auto" );
8628
+ } else if ( heightStyle === "auto" ) {
8629
+ maxHeight = 0;
8630
+ this.panels.each(function() {
8631
+ maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
8632
+ }).height( maxHeight );
8633
+ }
8634
+ },
8635
+
8636
+ _eventHandler: function( event ) {
8637
+ var options = this.options,
8638
+ active = this.active,
8639
+ anchor = $( event.currentTarget ),
8640
+ tab = anchor.closest( "li" ),
8641
+ clickedIsActive = tab[ 0 ] === active[ 0 ],
8642
+ collapsing = clickedIsActive && options.collapsible,
8643
+ toShow = collapsing ? $() : this._getPanelForTab( tab ),
8644
+ toHide = !active.length ? $() : this._getPanelForTab( active ),
8645
+ eventData = {
8646
+ oldTab: active,
8647
+ oldPanel: toHide,
8648
+ newTab: collapsing ? $() : tab,
8649
+ newPanel: toShow
8650
+ };
8651
+
8652
+ event.preventDefault();
8653
+
8654
+ if ( tab.hasClass( "ui-state-disabled" ) ||
8655
+ // tab is already loading
8656
+ tab.hasClass( "ui-tabs-loading" ) ||
8657
+ // can't switch durning an animation
8658
+ this.running ||
8659
+ // click on active header, but not collapsible
8660
+ ( clickedIsActive && !options.collapsible ) ||
8661
+ // allow canceling activation
8662
+ ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
8663
+ return;
8664
+ }
8665
+
8666
+ options.active = collapsing ? false : this.tabs.index( tab );
8667
+
8668
+ this.active = clickedIsActive ? $() : tab;
8669
+ if ( this.xhr ) {
8670
+ this.xhr.abort();
8671
+ }
8672
+
8673
+ if ( !toHide.length && !toShow.length ) {
8674
+ $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
8675
+ }
8676
+
8677
+ if ( toShow.length ) {
8678
+ this.load( this.tabs.index( tab ), event );
8679
+ }
8680
+ this._toggle( event, eventData );
8681
+ },
8682
+
8683
+ // handles show/hide for selecting tabs
8684
+ _toggle: function( event, eventData ) {
8685
+ var that = this,
8686
+ toShow = eventData.newPanel,
8687
+ toHide = eventData.oldPanel;
8688
+
8689
+ this.running = true;
8690
+
8691
+ function complete() {
8692
+ that.running = false;
8693
+ that._trigger( "activate", event, eventData );
8694
+ }
8695
+
8696
+ function show() {
8697
+ eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
8698
+
8699
+ if ( toShow.length && that.options.show ) {
8700
+ that._show( toShow, that.options.show, complete );
8701
+ } else {
8702
+ toShow.show();
8703
+ complete();
8704
+ }
8705
+ }
8706
+
8707
+ // start out by hiding, then showing, then completing
8708
+ if ( toHide.length && this.options.hide ) {
8709
+ this._hide( toHide, this.options.hide, function() {
8710
+ eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
8711
+ show();
8712
+ });
8713
+ } else {
8714
+ eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
8715
+ toHide.hide();
8716
+ show();
8717
+ }
8718
+
8719
+ toHide.attr( "aria-hidden", "true" );
8720
+ eventData.oldTab.attr({
8721
+ "aria-selected": "false",
8722
+ "aria-expanded": "false"
8723
+ });
8724
+ // If we're switching tabs, remove the old tab from the tab order.
8725
+ // If we're opening from collapsed state, remove the previous tab from the tab order.
8726
+ // If we're collapsing, then keep the collapsing tab in the tab order.
8727
+ if ( toShow.length && toHide.length ) {
8728
+ eventData.oldTab.attr( "tabIndex", -1 );
8729
+ } else if ( toShow.length ) {
8730
+ this.tabs.filter(function() {
8731
+ return $( this ).attr( "tabIndex" ) === 0;
8732
+ })
8733
+ .attr( "tabIndex", -1 );
8734
+ }
8735
+
8736
+ toShow.attr( "aria-hidden", "false" );
8737
+ eventData.newTab.attr({
8738
+ "aria-selected": "true",
8739
+ "aria-expanded": "true",
8740
+ tabIndex: 0
8741
+ });
8742
+ },
8743
+
8744
+ _activate: function( index ) {
8745
+ var anchor,
8746
+ active = this._findActive( index );
8747
+
8748
+ // trying to activate the already active panel
8749
+ if ( active[ 0 ] === this.active[ 0 ] ) {
8750
+ return;
8751
+ }
8752
+
8753
+ // trying to collapse, simulate a click on the current active header
8754
+ if ( !active.length ) {
8755
+ active = this.active;
8756
+ }
8757
+
8758
+ anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
8759
+ this._eventHandler({
8760
+ target: anchor,
8761
+ currentTarget: anchor,
8762
+ preventDefault: $.noop
8763
+ });
8764
+ },
8765
+
8766
+ _findActive: function( index ) {
8767
+ return index === false ? $() : this.tabs.eq( index );
8768
+ },
8769
+
8770
+ _getIndex: function( index ) {
8771
+ // meta-function to give users option to provide a href string instead of a numerical index.
8772
+ if ( typeof index === "string" ) {
8773
+ index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
8774
+ }
8775
+
8776
+ return index;
8777
+ },
8778
+
8779
+ _destroy: function() {
8780
+ if ( this.xhr ) {
8781
+ this.xhr.abort();
8782
+ }
8783
+
8784
+ this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
8785
+
8786
+ this.tablist
8787
+ .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
8788
+ .removeAttr( "role" );
8789
+
8790
+ this.anchors
8791
+ .removeClass( "ui-tabs-anchor" )
8792
+ .removeAttr( "role" )
8793
+ .removeAttr( "tabIndex" )
8794
+ .removeUniqueId();
8795
+
8796
+ this.tablist.unbind( this.eventNamespace );
8797
+
8798
+ this.tabs.add( this.panels ).each(function() {
8799
+ if ( $.data( this, "ui-tabs-destroy" ) ) {
8800
+ $( this ).remove();
8801
+ } else {
8802
+ $( this )
8803
+ .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
8804
+ "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
8805
+ .removeAttr( "tabIndex" )
8806
+ .removeAttr( "aria-live" )
8807
+ .removeAttr( "aria-busy" )
8808
+ .removeAttr( "aria-selected" )
8809
+ .removeAttr( "aria-labelledby" )
8810
+ .removeAttr( "aria-hidden" )
8811
+ .removeAttr( "aria-expanded" )
8812
+ .removeAttr( "role" );
8813
+ }
8814
+ });
8815
+
8816
+ this.tabs.each(function() {
8817
+ var li = $( this ),
8818
+ prev = li.data( "ui-tabs-aria-controls" );
8819
+ if ( prev ) {
8820
+ li
8821
+ .attr( "aria-controls", prev )
8822
+ .removeData( "ui-tabs-aria-controls" );
8823
+ } else {
8824
+ li.removeAttr( "aria-controls" );
8825
+ }
8826
+ });
8827
+
8828
+ this.panels.show();
8829
+
8830
+ if ( this.options.heightStyle !== "content" ) {
8831
+ this.panels.css( "height", "" );
8832
+ }
8833
+ },
8834
+
8835
+ enable: function( index ) {
8836
+ var disabled = this.options.disabled;
8837
+ if ( disabled === false ) {
8838
+ return;
8839
+ }
8840
+
8841
+ if ( index === undefined ) {
8842
+ disabled = false;
8843
+ } else {
8844
+ index = this._getIndex( index );
8845
+ if ( $.isArray( disabled ) ) {
8846
+ disabled = $.map( disabled, function( num ) {
8847
+ return num !== index ? num : null;
8848
+ });
8849
+ } else {
8850
+ disabled = $.map( this.tabs, function( li, num ) {
8851
+ return num !== index ? num : null;
8852
+ });
8853
+ }
8854
+ }
8855
+ this._setupDisabled( disabled );
8856
+ },
8857
+
8858
+ disable: function( index ) {
8859
+ var disabled = this.options.disabled;
8860
+ if ( disabled === true ) {
8861
+ return;
8862
+ }
8863
+
8864
+ if ( index === undefined ) {
8865
+ disabled = true;
8866
+ } else {
8867
+ index = this._getIndex( index );
8868
+ if ( $.inArray( index, disabled ) !== -1 ) {
8869
+ return;
8870
+ }
8871
+ if ( $.isArray( disabled ) ) {
8872
+ disabled = $.merge( [ index ], disabled ).sort();
8873
+ } else {
8874
+ disabled = [ index ];
8875
+ }
8876
+ }
8877
+ this._setupDisabled( disabled );
8878
+ },
8879
+
8880
+ load: function( index, event ) {
8881
+ index = this._getIndex( index );
8882
+ var that = this,
8883
+ tab = this.tabs.eq( index ),
8884
+ anchor = tab.find( ".ui-tabs-anchor" ),
8885
+ panel = this._getPanelForTab( tab ),
8886
+ eventData = {
8887
+ tab: tab,
8888
+ panel: panel
8889
+ };
8890
+
8891
+ // not remote
8892
+ if ( this._isLocal( anchor[ 0 ] ) ) {
8893
+ return;
8894
+ }
8895
+
8896
+ this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
8897
+
8898
+ // support: jQuery <1.8
8899
+ // jQuery <1.8 returns false if the request is canceled in beforeSend,
8900
+ // but as of 1.8, $.ajax() always returns a jqXHR object.
8901
+ if ( this.xhr && this.xhr.statusText !== "canceled" ) {
8902
+ tab.addClass( "ui-tabs-loading" );
8903
+ panel.attr( "aria-busy", "true" );
8904
+
8905
+ this.xhr
8906
+ .success(function( response ) {
8907
+ // support: jQuery <1.8
8908
+ // http://bugs.jquery.com/ticket/11778
8909
+ setTimeout(function() {
8910
+ panel.html( response );
8911
+ that._trigger( "load", event, eventData );
8912
+ }, 1 );
8913
+ })
8914
+ .complete(function( jqXHR, status ) {
8915
+ // support: jQuery <1.8
8916
+ // http://bugs.jquery.com/ticket/11778
8917
+ setTimeout(function() {
8918
+ if ( status === "abort" ) {
8919
+ that.panels.stop( false, true );
8920
+ }
8921
+
8922
+ tab.removeClass( "ui-tabs-loading" );
8923
+ panel.removeAttr( "aria-busy" );
8924
+
8925
+ if ( jqXHR === that.xhr ) {
8926
+ delete that.xhr;
8927
+ }
8928
+ }, 1 );
8929
+ });
8930
+ }
8931
+ },
8932
+
8933
+ _ajaxSettings: function( anchor, event, eventData ) {
8934
+ var that = this;
8935
+ return {
8936
+ url: anchor.attr( "href" ),
8937
+ beforeSend: function( jqXHR, settings ) {
8938
+ return that._trigger( "beforeLoad", event,
8939
+ $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
8940
+ }
8941
+ };
8942
+ },
8943
+
8944
+ _getPanelForTab: function( tab ) {
8945
+ var id = $( tab ).attr( "aria-controls" );
8946
+ return this.element.find( this._sanitizeSelector( "#" + id ) );
8947
+ }
8948
+ });
8949
+
8950
+
5467
8951
 
5468
8952
  }));