]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.debug.browser/resources/js/jquery-ui.js
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.debug.browser / resources / js / jquery-ui.js
1 /*! jQuery UI - v1.11.2 - 2014-10-16
2 * http://jqueryui.com
3 * Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js
4 * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5
6 (function( factory ) {
7         if ( typeof define === "function" && define.amd ) {
8
9                 // AMD. Register as an anonymous module.
10                 define([ "jquery" ], factory );
11         } else {
12
13                 // Browser globals
14                 factory( jQuery );
15         }
16 }(function( $ ) {
17 /*!
18  * jQuery UI Core 1.11.2
19  * http://jqueryui.com
20  *
21  * Copyright 2014 jQuery Foundation and other contributors
22  * Released under the MIT license.
23  * http://jquery.org/license
24  *
25  * http://api.jqueryui.com/category/ui-core/
26  */
27
28
29 // $.ui might exist from components with no dependencies, e.g., $.ui.position
30 $.ui = $.ui || {};
31
32 $.extend( $.ui, {
33         version: "1.11.2",
34
35         keyCode: {
36                 BACKSPACE: 8,
37                 COMMA: 188,
38                 DELETE: 46,
39                 DOWN: 40,
40                 END: 35,
41                 ENTER: 13,
42                 ESCAPE: 27,
43                 HOME: 36,
44                 LEFT: 37,
45                 PAGE_DOWN: 34,
46                 PAGE_UP: 33,
47                 PERIOD: 190,
48                 RIGHT: 39,
49                 SPACE: 32,
50                 TAB: 9,
51                 UP: 38
52         }
53 });
54
55 // plugins
56 $.fn.extend({
57         scrollParent: function( includeHidden ) {
58                 var position = this.css( "position" ),
59                         excludeStaticParent = position === "absolute",
60                         overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
61                         scrollParent = this.parents().filter( function() {
62                                 var parent = $( this );
63                                 if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
64                                         return false;
65                                 }
66                                 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
67                         }).eq( 0 );
68
69                 return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
70         },
71
72         uniqueId: (function() {
73                 var uuid = 0;
74
75                 return function() {
76                         return this.each(function() {
77                                 if ( !this.id ) {
78                                         this.id = "ui-id-" + ( ++uuid );
79                                 }
80                         });
81                 };
82         })(),
83
84         removeUniqueId: function() {
85                 return this.each(function() {
86                         if ( /^ui-id-\d+$/.test( this.id ) ) {
87                                 $( this ).removeAttr( "id" );
88                         }
89                 });
90         }
91 });
92
93 // selectors
94 function focusable( element, isTabIndexNotNaN ) {
95         var map, mapName, img,
96                 nodeName = element.nodeName.toLowerCase();
97         if ( "area" === nodeName ) {
98                 map = element.parentNode;
99                 mapName = map.name;
100                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
101                         return false;
102                 }
103                 img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
104                 return !!img && visible( img );
105         }
106         return ( /input|select|textarea|button|object/.test( nodeName ) ?
107                 !element.disabled :
108                 "a" === nodeName ?
109                         element.href || isTabIndexNotNaN :
110                         isTabIndexNotNaN) &&
111                 // the element and all of its ancestors must be visible
112                 visible( element );
113 }
114
115 function visible( element ) {
116         return $.expr.filters.visible( element ) &&
117                 !$( element ).parents().addBack().filter(function() {
118                         return $.css( this, "visibility" ) === "hidden";
119                 }).length;
120 }
121
122 $.extend( $.expr[ ":" ], {
123         data: $.expr.createPseudo ?
124                 $.expr.createPseudo(function( dataName ) {
125                         return function( elem ) {
126                                 return !!$.data( elem, dataName );
127                         };
128                 }) :
129                 // support: jQuery <1.8
130                 function( elem, i, match ) {
131                         return !!$.data( elem, match[ 3 ] );
132                 },
133
134         focusable: function( element ) {
135                 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
136         },
137
138         tabbable: function( element ) {
139                 var tabIndex = $.attr( element, "tabindex" ),
140                         isTabIndexNaN = isNaN( tabIndex );
141                 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
142         }
143 });
144
145 // support: jQuery <1.8
146 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
147         $.each( [ "Width", "Height" ], function( i, name ) {
148                 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
149                         type = name.toLowerCase(),
150                         orig = {
151                                 innerWidth: $.fn.innerWidth,
152                                 innerHeight: $.fn.innerHeight,
153                                 outerWidth: $.fn.outerWidth,
154                                 outerHeight: $.fn.outerHeight
155                         };
156
157                 function reduce( elem, size, border, margin ) {
158                         $.each( side, function() {
159                                 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
160                                 if ( border ) {
161                                         size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
162                                 }
163                                 if ( margin ) {
164                                         size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
165                                 }
166                         });
167                         return size;
168                 }
169
170                 $.fn[ "inner" + name ] = function( size ) {
171                         if ( size === undefined ) {
172                                 return orig[ "inner" + name ].call( this );
173                         }
174
175                         return this.each(function() {
176                                 $( this ).css( type, reduce( this, size ) + "px" );
177                         });
178                 };
179
180                 $.fn[ "outer" + name] = function( size, margin ) {
181                         if ( typeof size !== "number" ) {
182                                 return orig[ "outer" + name ].call( this, size );
183                         }
184
185                         return this.each(function() {
186                                 $( this).css( type, reduce( this, size, true, margin ) + "px" );
187                         });
188                 };
189         });
190 }
191
192 // support: jQuery <1.8
193 if ( !$.fn.addBack ) {
194         $.fn.addBack = function( selector ) {
195                 return this.add( selector == null ?
196                         this.prevObject : this.prevObject.filter( selector )
197                 );
198         };
199 }
200
201 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
202 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
203         $.fn.removeData = (function( removeData ) {
204                 return function( key ) {
205                         if ( arguments.length ) {
206                                 return removeData.call( this, $.camelCase( key ) );
207                         } else {
208                                 return removeData.call( this );
209                         }
210                 };
211         })( $.fn.removeData );
212 }
213
214 // deprecated
215 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
216
217 $.fn.extend({
218         focus: (function( orig ) {
219                 return function( delay, fn ) {
220                         return typeof delay === "number" ?
221                                 this.each(function() {
222                                         var elem = this;
223                                         setTimeout(function() {
224                                                 $( elem ).focus();
225                                                 if ( fn ) {
226                                                         fn.call( elem );
227                                                 }
228                                         }, delay );
229                                 }) :
230                                 orig.apply( this, arguments );
231                 };
232         })( $.fn.focus ),
233
234         disableSelection: (function() {
235                 var eventType = "onselectstart" in document.createElement( "div" ) ?
236                         "selectstart" :
237                         "mousedown";
238
239                 return function() {
240                         return this.bind( eventType + ".ui-disableSelection", function( event ) {
241                                 event.preventDefault();
242                         });
243                 };
244         })(),
245
246         enableSelection: function() {
247                 return this.unbind( ".ui-disableSelection" );
248         },
249
250         zIndex: function( zIndex ) {
251                 if ( zIndex !== undefined ) {
252                         return this.css( "zIndex", zIndex );
253                 }
254
255                 if ( this.length ) {
256                         var elem = $( this[ 0 ] ), position, value;
257                         while ( elem.length && elem[ 0 ] !== document ) {
258                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
259                                 // This makes behavior of this function consistent across browsers
260                                 // WebKit always returns auto if the element is positioned
261                                 position = elem.css( "position" );
262                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
263                                         // IE returns 0 when zIndex is not specified
264                                         // other browsers return a string
265                                         // we ignore the case of nested elements with an explicit value of 0
266                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
267                                         value = parseInt( elem.css( "zIndex" ), 10 );
268                                         if ( !isNaN( value ) && value !== 0 ) {
269                                                 return value;
270                                         }
271                                 }
272                                 elem = elem.parent();
273                         }
274                 }
275
276                 return 0;
277         }
278 });
279
280 // $.ui.plugin is deprecated. Use $.widget() extensions instead.
281 $.ui.plugin = {
282         add: function( module, option, set ) {
283                 var i,
284                         proto = $.ui[ module ].prototype;
285                 for ( i in set ) {
286                         proto.plugins[ i ] = proto.plugins[ i ] || [];
287                         proto.plugins[ i ].push( [ option, set[ i ] ] );
288                 }
289         },
290         call: function( instance, name, args, allowDisconnected ) {
291                 var i,
292                         set = instance.plugins[ name ];
293
294                 if ( !set ) {
295                         return;
296                 }
297
298                 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
299                         return;
300                 }
301
302                 for ( i = 0; i < set.length; i++ ) {
303                         if ( instance.options[ set[ i ][ 0 ] ] ) {
304                                 set[ i ][ 1 ].apply( instance.element, args );
305                         }
306                 }
307         }
308 };
309
310
311 /*!
312  * jQuery UI Widget 1.11.2
313  * http://jqueryui.com
314  *
315  * Copyright 2014 jQuery Foundation and other contributors
316  * Released under the MIT license.
317  * http://jquery.org/license
318  *
319  * http://api.jqueryui.com/jQuery.widget/
320  */
321
322
323 var widget_uuid = 0,
324         widget_slice = Array.prototype.slice;
325
326 $.cleanData = (function( orig ) {
327         return function( elems ) {
328                 var events, elem, i;
329                 for ( i = 0; (elem = elems[i]) != null; i++ ) {
330                         try {
331
332                                 // Only trigger remove when necessary to save time
333                                 events = $._data( elem, "events" );
334                                 if ( events && events.remove ) {
335                                         $( elem ).triggerHandler( "remove" );
336                                 }
337
338                         // http://bugs.jquery.com/ticket/8235
339                         } catch ( e ) {}
340                 }
341                 orig( elems );
342         };
343 })( $.cleanData );
344
345 $.widget = function( name, base, prototype ) {
346         var fullName, existingConstructor, constructor, basePrototype,
347                 // proxiedPrototype allows the provided prototype to remain unmodified
348                 // so that it can be used as a mixin for multiple widgets (#8876)
349                 proxiedPrototype = {},
350                 namespace = name.split( "." )[ 0 ];
351
352         name = name.split( "." )[ 1 ];
353         fullName = namespace + "-" + name;
354
355         if ( !prototype ) {
356                 prototype = base;
357                 base = $.Widget;
358         }
359
360         // create selector for plugin
361         $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
362                 return !!$.data( elem, fullName );
363         };
364
365         $[ namespace ] = $[ namespace ] || {};
366         existingConstructor = $[ namespace ][ name ];
367         constructor = $[ namespace ][ name ] = function( options, element ) {
368                 // allow instantiation without "new" keyword
369                 if ( !this._createWidget ) {
370                         return new constructor( options, element );
371                 }
372
373                 // allow instantiation without initializing for simple inheritance
374                 // must use "new" keyword (the code above always passes args)
375                 if ( arguments.length ) {
376                         this._createWidget( options, element );
377                 }
378         };
379         // extend with the existing constructor to carry over any static properties
380         $.extend( constructor, existingConstructor, {
381                 version: prototype.version,
382                 // copy the object used to create the prototype in case we need to
383                 // redefine the widget later
384                 _proto: $.extend( {}, prototype ),
385                 // track widgets that inherit from this widget in case this widget is
386                 // redefined after a widget inherits from it
387                 _childConstructors: []
388         });
389
390         basePrototype = new base();
391         // we need to make the options hash a property directly on the new instance
392         // otherwise we'll modify the options hash on the prototype that we're
393         // inheriting from
394         basePrototype.options = $.widget.extend( {}, basePrototype.options );
395         $.each( prototype, function( prop, value ) {
396                 if ( !$.isFunction( value ) ) {
397                         proxiedPrototype[ prop ] = value;
398                         return;
399                 }
400                 proxiedPrototype[ prop ] = (function() {
401                         var _super = function() {
402                                         return base.prototype[ prop ].apply( this, arguments );
403                                 },
404                                 _superApply = function( args ) {
405                                         return base.prototype[ prop ].apply( this, args );
406                                 };
407                         return function() {
408                                 var __super = this._super,
409                                         __superApply = this._superApply,
410                                         returnValue;
411
412                                 this._super = _super;
413                                 this._superApply = _superApply;
414
415                                 returnValue = value.apply( this, arguments );
416
417                                 this._super = __super;
418                                 this._superApply = __superApply;
419
420                                 return returnValue;
421                         };
422                 })();
423         });
424         constructor.prototype = $.widget.extend( basePrototype, {
425                 // TODO: remove support for widgetEventPrefix
426                 // always use the name + a colon as the prefix, e.g., draggable:start
427                 // don't prefix for widgets that aren't DOM-based
428                 widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
429         }, proxiedPrototype, {
430                 constructor: constructor,
431                 namespace: namespace,
432                 widgetName: name,
433                 widgetFullName: fullName
434         });
435
436         // If this widget is being redefined then we need to find all widgets that
437         // are inheriting from it and redefine all of them so that they inherit from
438         // the new version of this widget. We're essentially trying to replace one
439         // level in the prototype chain.
440         if ( existingConstructor ) {
441                 $.each( existingConstructor._childConstructors, function( i, child ) {
442                         var childPrototype = child.prototype;
443
444                         // redefine the child widget using the same prototype that was
445                         // originally used, but inherit from the new version of the base
446                         $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
447                 });
448                 // remove the list of existing child constructors from the old constructor
449                 // so the old child constructors can be garbage collected
450                 delete existingConstructor._childConstructors;
451         } else {
452                 base._childConstructors.push( constructor );
453         }
454
455         $.widget.bridge( name, constructor );
456
457         return constructor;
458 };
459
460 $.widget.extend = function( target ) {
461         var input = widget_slice.call( arguments, 1 ),
462                 inputIndex = 0,
463                 inputLength = input.length,
464                 key,
465                 value;
466         for ( ; inputIndex < inputLength; inputIndex++ ) {
467                 for ( key in input[ inputIndex ] ) {
468                         value = input[ inputIndex ][ key ];
469                         if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
470                                 // Clone objects
471                                 if ( $.isPlainObject( value ) ) {
472                                         target[ key ] = $.isPlainObject( target[ key ] ) ?
473                                                 $.widget.extend( {}, target[ key ], value ) :
474                                                 // Don't extend strings, arrays, etc. with objects
475                                                 $.widget.extend( {}, value );
476                                 // Copy everything else by reference
477                                 } else {
478                                         target[ key ] = value;
479                                 }
480                         }
481                 }
482         }
483         return target;
484 };
485
486 $.widget.bridge = function( name, object ) {
487         var fullName = object.prototype.widgetFullName || name;
488         $.fn[ name ] = function( options ) {
489                 var isMethodCall = typeof options === "string",
490                         args = widget_slice.call( arguments, 1 ),
491                         returnValue = this;
492
493                 // allow multiple hashes to be passed on init
494                 options = !isMethodCall && args.length ?
495                         $.widget.extend.apply( null, [ options ].concat(args) ) :
496                         options;
497
498                 if ( isMethodCall ) {
499                         this.each(function() {
500                                 var methodValue,
501                                         instance = $.data( this, fullName );
502                                 if ( options === "instance" ) {
503                                         returnValue = instance;
504                                         return false;
505                                 }
506                                 if ( !instance ) {
507                                         return $.error( "cannot call methods on " + name + " prior to initialization; " +
508                                                 "attempted to call method '" + options + "'" );
509                                 }
510                                 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
511                                         return $.error( "no such method '" + options + "' for " + name + " widget instance" );
512                                 }
513                                 methodValue = instance[ options ].apply( instance, args );
514                                 if ( methodValue !== instance && methodValue !== undefined ) {
515                                         returnValue = methodValue && methodValue.jquery ?
516                                                 returnValue.pushStack( methodValue.get() ) :
517                                                 methodValue;
518                                         return false;
519                                 }
520                         });
521                 } else {
522                         this.each(function() {
523                                 var instance = $.data( this, fullName );
524                                 if ( instance ) {
525                                         instance.option( options || {} );
526                                         if ( instance._init ) {
527                                                 instance._init();
528                                         }
529                                 } else {
530                                         $.data( this, fullName, new object( options, this ) );
531                                 }
532                         });
533                 }
534
535                 return returnValue;
536         };
537 };
538
539 $.Widget = function( /* options, element */ ) {};
540 $.Widget._childConstructors = [];
541
542 $.Widget.prototype = {
543         widgetName: "widget",
544         widgetEventPrefix: "",
545         defaultElement: "<div>",
546         options: {
547                 disabled: false,
548
549                 // callbacks
550                 create: null
551         },
552         _createWidget: function( options, element ) {
553                 element = $( element || this.defaultElement || this )[ 0 ];
554                 this.element = $( element );
555                 this.uuid = widget_uuid++;
556                 this.eventNamespace = "." + this.widgetName + this.uuid;
557
558                 this.bindings = $();
559                 this.hoverable = $();
560                 this.focusable = $();
561
562                 if ( element !== this ) {
563                         $.data( element, this.widgetFullName, this );
564                         this._on( true, this.element, {
565                                 remove: function( event ) {
566                                         if ( event.target === element ) {
567                                                 this.destroy();
568                                         }
569                                 }
570                         });
571                         this.document = $( element.style ?
572                                 // element within the document
573                                 element.ownerDocument :
574                                 // element is window or document
575                                 element.document || element );
576                         this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
577                 }
578
579                 this.options = $.widget.extend( {},
580                         this.options,
581                         this._getCreateOptions(),
582                         options );
583
584                 this._create();
585                 this._trigger( "create", null, this._getCreateEventData() );
586                 this._init();
587         },
588         _getCreateOptions: $.noop,
589         _getCreateEventData: $.noop,
590         _create: $.noop,
591         _init: $.noop,
592
593         destroy: function() {
594                 this._destroy();
595                 // we can probably remove the unbind calls in 2.0
596                 // all event bindings should go through this._on()
597                 this.element
598                         .unbind( this.eventNamespace )
599                         .removeData( this.widgetFullName )
600                         // support: jquery <1.6.3
601                         // http://bugs.jquery.com/ticket/9413
602                         .removeData( $.camelCase( this.widgetFullName ) );
603                 this.widget()
604                         .unbind( this.eventNamespace )
605                         .removeAttr( "aria-disabled" )
606                         .removeClass(
607                                 this.widgetFullName + "-disabled " +
608                                 "ui-state-disabled" );
609
610                 // clean up events and states
611                 this.bindings.unbind( this.eventNamespace );
612                 this.hoverable.removeClass( "ui-state-hover" );
613                 this.focusable.removeClass( "ui-state-focus" );
614         },
615         _destroy: $.noop,
616
617         widget: function() {
618                 return this.element;
619         },
620
621         option: function( key, value ) {
622                 var options = key,
623                         parts,
624                         curOption,
625                         i;
626
627                 if ( arguments.length === 0 ) {
628                         // don't return a reference to the internal hash
629                         return $.widget.extend( {}, this.options );
630                 }
631
632                 if ( typeof key === "string" ) {
633                         // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
634                         options = {};
635                         parts = key.split( "." );
636                         key = parts.shift();
637                         if ( parts.length ) {
638                                 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
639                                 for ( i = 0; i < parts.length - 1; i++ ) {
640                                         curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
641                                         curOption = curOption[ parts[ i ] ];
642                                 }
643                                 key = parts.pop();
644                                 if ( arguments.length === 1 ) {
645                                         return curOption[ key ] === undefined ? null : curOption[ key ];
646                                 }
647                                 curOption[ key ] = value;
648                         } else {
649                                 if ( arguments.length === 1 ) {
650                                         return this.options[ key ] === undefined ? null : this.options[ key ];
651                                 }
652                                 options[ key ] = value;
653                         }
654                 }
655
656                 this._setOptions( options );
657
658                 return this;
659         },
660         _setOptions: function( options ) {
661                 var key;
662
663                 for ( key in options ) {
664                         this._setOption( key, options[ key ] );
665                 }
666
667                 return this;
668         },
669         _setOption: function( key, value ) {
670                 this.options[ key ] = value;
671
672                 if ( key === "disabled" ) {
673                         this.widget()
674                                 .toggleClass( this.widgetFullName + "-disabled", !!value );
675
676                         // If the widget is becoming disabled, then nothing is interactive
677                         if ( value ) {
678                                 this.hoverable.removeClass( "ui-state-hover" );
679                                 this.focusable.removeClass( "ui-state-focus" );
680                         }
681                 }
682
683                 return this;
684         },
685
686         enable: function() {
687                 return this._setOptions({ disabled: false });
688         },
689         disable: function() {
690                 return this._setOptions({ disabled: true });
691         },
692
693         _on: function( suppressDisabledCheck, element, handlers ) {
694                 var delegateElement,
695                         instance = this;
696
697                 // no suppressDisabledCheck flag, shuffle arguments
698                 if ( typeof suppressDisabledCheck !== "boolean" ) {
699                         handlers = element;
700                         element = suppressDisabledCheck;
701                         suppressDisabledCheck = false;
702                 }
703
704                 // no element argument, shuffle and use this.element
705                 if ( !handlers ) {
706                         handlers = element;
707                         element = this.element;
708                         delegateElement = this.widget();
709                 } else {
710                         element = delegateElement = $( element );
711                         this.bindings = this.bindings.add( element );
712                 }
713
714                 $.each( handlers, function( event, handler ) {
715                         function handlerProxy() {
716                                 // allow widgets to customize the disabled handling
717                                 // - disabled as an array instead of boolean
718                                 // - disabled class as method for disabling individual parts
719                                 if ( !suppressDisabledCheck &&
720                                                 ( instance.options.disabled === true ||
721                                                         $( this ).hasClass( "ui-state-disabled" ) ) ) {
722                                         return;
723                                 }
724                                 return ( typeof handler === "string" ? instance[ handler ] : handler )
725                                         .apply( instance, arguments );
726                         }
727
728                         // copy the guid so direct unbinding works
729                         if ( typeof handler !== "string" ) {
730                                 handlerProxy.guid = handler.guid =
731                                         handler.guid || handlerProxy.guid || $.guid++;
732                         }
733
734                         var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
735                                 eventName = match[1] + instance.eventNamespace,
736                                 selector = match[2];
737                         if ( selector ) {
738                                 delegateElement.delegate( selector, eventName, handlerProxy );
739                         } else {
740                                 element.bind( eventName, handlerProxy );
741                         }
742                 });
743         },
744
745         _off: function( element, eventName ) {
746                 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
747                         this.eventNamespace;
748                 element.unbind( eventName ).undelegate( eventName );
749
750                 // Clear the stack to avoid memory leaks (#10056)
751                 this.bindings = $( this.bindings.not( element ).get() );
752                 this.focusable = $( this.focusable.not( element ).get() );
753                 this.hoverable = $( this.hoverable.not( element ).get() );
754         },
755
756         _delay: function( handler, delay ) {
757                 function handlerProxy() {
758                         return ( typeof handler === "string" ? instance[ handler ] : handler )
759                                 .apply( instance, arguments );
760                 }
761                 var instance = this;
762                 return setTimeout( handlerProxy, delay || 0 );
763         },
764
765         _hoverable: function( element ) {
766                 this.hoverable = this.hoverable.add( element );
767                 this._on( element, {
768                         mouseenter: function( event ) {
769                                 $( event.currentTarget ).addClass( "ui-state-hover" );
770                         },
771                         mouseleave: function( event ) {
772                                 $( event.currentTarget ).removeClass( "ui-state-hover" );
773                         }
774                 });
775         },
776
777         _focusable: function( element ) {
778                 this.focusable = this.focusable.add( element );
779                 this._on( element, {
780                         focusin: function( event ) {
781                                 $( event.currentTarget ).addClass( "ui-state-focus" );
782                         },
783                         focusout: function( event ) {
784                                 $( event.currentTarget ).removeClass( "ui-state-focus" );
785                         }
786                 });
787         },
788
789         _trigger: function( type, event, data ) {
790                 var prop, orig,
791                         callback = this.options[ type ];
792
793                 data = data || {};
794                 event = $.Event( event );
795                 event.type = ( type === this.widgetEventPrefix ?
796                         type :
797                         this.widgetEventPrefix + type ).toLowerCase();
798                 // the original event may come from any element
799                 // so we need to reset the target on the new event
800                 event.target = this.element[ 0 ];
801
802                 // copy original event properties over to the new event
803                 orig = event.originalEvent;
804                 if ( orig ) {
805                         for ( prop in orig ) {
806                                 if ( !( prop in event ) ) {
807                                         event[ prop ] = orig[ prop ];
808                                 }
809                         }
810                 }
811
812                 this.element.trigger( event, data );
813                 return !( $.isFunction( callback ) &&
814                         callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
815                         event.isDefaultPrevented() );
816         }
817 };
818
819 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
820         $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
821                 if ( typeof options === "string" ) {
822                         options = { effect: options };
823                 }
824                 var hasOptions,
825                         effectName = !options ?
826                                 method :
827                                 options === true || typeof options === "number" ?
828                                         defaultEffect :
829                                         options.effect || defaultEffect;
830                 options = options || {};
831                 if ( typeof options === "number" ) {
832                         options = { duration: options };
833                 }
834                 hasOptions = !$.isEmptyObject( options );
835                 options.complete = callback;
836                 if ( options.delay ) {
837                         element.delay( options.delay );
838                 }
839                 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
840                         element[ method ]( options );
841                 } else if ( effectName !== method && element[ effectName ] ) {
842                         element[ effectName ]( options.duration, options.easing, callback );
843                 } else {
844                         element.queue(function( next ) {
845                                 $( this )[ method ]();
846                                 if ( callback ) {
847                                         callback.call( element[ 0 ] );
848                                 }
849                                 next();
850                         });
851                 }
852         };
853 });
854
855 var widget = $.widget;
856
857
858 /*!
859  * jQuery UI Mouse 1.11.2
860  * http://jqueryui.com
861  *
862  * Copyright 2014 jQuery Foundation and other contributors
863  * Released under the MIT license.
864  * http://jquery.org/license
865  *
866  * http://api.jqueryui.com/mouse/
867  */
868
869
870 var mouseHandled = false;
871 $( document ).mouseup( function() {
872         mouseHandled = false;
873 });
874
875 var mouse = $.widget("ui.mouse", {
876         version: "1.11.2",
877         options: {
878                 cancel: "input,textarea,button,select,option",
879                 distance: 1,
880                 delay: 0
881         },
882         _mouseInit: function() {
883                 var that = this;
884
885                 this.element
886                         .bind("mousedown." + this.widgetName, function(event) {
887                                 return that._mouseDown(event);
888                         })
889                         .bind("click." + this.widgetName, function(event) {
890                                 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
891                                         $.removeData(event.target, that.widgetName + ".preventClickEvent");
892                                         event.stopImmediatePropagation();
893                                         return false;
894                                 }
895                         });
896
897                 this.started = false;
898         },
899
900         // TODO: make sure destroying one instance of mouse doesn't mess with
901         // other instances of mouse
902         _mouseDestroy: function() {
903                 this.element.unbind("." + this.widgetName);
904                 if ( this._mouseMoveDelegate ) {
905                         this.document
906                                 .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
907                                 .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
908                 }
909         },
910
911         _mouseDown: function(event) {
912                 // don't let more than one widget handle mouseStart
913                 if ( mouseHandled ) {
914                         return;
915                 }
916
917                 this._mouseMoved = false;
918
919                 // we may have missed mouseup (out of window)
920                 (this._mouseStarted && this._mouseUp(event));
921
922                 this._mouseDownEvent = event;
923
924                 var that = this,
925                         btnIsLeft = (event.which === 1),
926                         // event.target.nodeName works around a bug in IE 8 with
927                         // disabled inputs (#7620)
928                         elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
929                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
930                         return true;
931                 }
932
933                 this.mouseDelayMet = !this.options.delay;
934                 if (!this.mouseDelayMet) {
935                         this._mouseDelayTimer = setTimeout(function() {
936                                 that.mouseDelayMet = true;
937                         }, this.options.delay);
938                 }
939
940                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
941                         this._mouseStarted = (this._mouseStart(event) !== false);
942                         if (!this._mouseStarted) {
943                                 event.preventDefault();
944                                 return true;
945                         }
946                 }
947
948                 // Click event may never have fired (Gecko & Opera)
949                 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
950                         $.removeData(event.target, this.widgetName + ".preventClickEvent");
951                 }
952
953                 // these delegates are required to keep context
954                 this._mouseMoveDelegate = function(event) {
955                         return that._mouseMove(event);
956                 };
957                 this._mouseUpDelegate = function(event) {
958                         return that._mouseUp(event);
959                 };
960
961                 this.document
962                         .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
963                         .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
964
965                 event.preventDefault();
966
967                 mouseHandled = true;
968                 return true;
969         },
970
971         _mouseMove: function(event) {
972                 // Only check for mouseups outside the document if you've moved inside the document
973                 // at least once. This prevents the firing of mouseup in the case of IE<9, which will
974                 // fire a mousemove event if content is placed under the cursor. See #7778
975                 // Support: IE <9
976                 if ( this._mouseMoved ) {
977                         // IE mouseup check - mouseup happened when mouse was out of window
978                         if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
979                                 return this._mouseUp(event);
980
981                         // Iframe mouseup check - mouseup occurred in another document
982                         } else if ( !event.which ) {
983                                 return this._mouseUp( event );
984                         }
985                 }
986
987                 if ( event.which || event.button ) {
988                         this._mouseMoved = true;
989                 }
990
991                 if (this._mouseStarted) {
992                         this._mouseDrag(event);
993                         return event.preventDefault();
994                 }
995
996                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
997                         this._mouseStarted =
998                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
999                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
1000                 }
1001
1002                 return !this._mouseStarted;
1003         },
1004
1005         _mouseUp: function(event) {
1006                 this.document
1007                         .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1008                         .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
1009
1010                 if (this._mouseStarted) {
1011                         this._mouseStarted = false;
1012
1013                         if (event.target === this._mouseDownEvent.target) {
1014                                 $.data(event.target, this.widgetName + ".preventClickEvent", true);
1015                         }
1016
1017                         this._mouseStop(event);
1018                 }
1019
1020                 mouseHandled = false;
1021                 return false;
1022         },
1023
1024         _mouseDistanceMet: function(event) {
1025                 return (Math.max(
1026                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
1027                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
1028                         ) >= this.options.distance
1029                 );
1030         },
1031
1032         _mouseDelayMet: function(/* event */) {
1033                 return this.mouseDelayMet;
1034         },
1035
1036         // These are placeholder methods, to be overriden by extending plugin
1037         _mouseStart: function(/* event */) {},
1038         _mouseDrag: function(/* event */) {},
1039         _mouseStop: function(/* event */) {},
1040         _mouseCapture: function(/* event */) { return true; }
1041 });
1042
1043
1044 /*!
1045  * jQuery UI Position 1.11.2
1046  * http://jqueryui.com
1047  *
1048  * Copyright 2014 jQuery Foundation and other contributors
1049  * Released under the MIT license.
1050  * http://jquery.org/license
1051  *
1052  * http://api.jqueryui.com/position/
1053  */
1054
1055 (function() {
1056
1057 $.ui = $.ui || {};
1058
1059 var cachedScrollbarWidth, supportsOffsetFractions,
1060         max = Math.max,
1061         abs = Math.abs,
1062         round = Math.round,
1063         rhorizontal = /left|center|right/,
1064         rvertical = /top|center|bottom/,
1065         roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1066         rposition = /^\w+/,
1067         rpercent = /%$/,
1068         _position = $.fn.position;
1069
1070 function getOffsets( offsets, width, height ) {
1071         return [
1072                 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1073                 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1074         ];
1075 }
1076
1077 function parseCss( element, property ) {
1078         return parseInt( $.css( element, property ), 10 ) || 0;
1079 }
1080
1081 function getDimensions( elem ) {
1082         var raw = elem[0];
1083         if ( raw.nodeType === 9 ) {
1084                 return {
1085                         width: elem.width(),
1086                         height: elem.height(),
1087                         offset: { top: 0, left: 0 }
1088                 };
1089         }
1090         if ( $.isWindow( raw ) ) {
1091                 return {
1092                         width: elem.width(),
1093                         height: elem.height(),
1094                         offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1095                 };
1096         }
1097         if ( raw.preventDefault ) {
1098                 return {
1099                         width: 0,
1100                         height: 0,
1101                         offset: { top: raw.pageY, left: raw.pageX }
1102                 };
1103         }
1104         return {
1105                 width: elem.outerWidth(),
1106                 height: elem.outerHeight(),
1107                 offset: elem.offset()
1108         };
1109 }
1110
1111 $.position = {
1112         scrollbarWidth: function() {
1113                 if ( cachedScrollbarWidth !== undefined ) {
1114                         return cachedScrollbarWidth;
1115                 }
1116                 var w1, w2,
1117                         div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1118                         innerDiv = div.children()[0];
1119
1120                 $( "body" ).append( div );
1121                 w1 = innerDiv.offsetWidth;
1122                 div.css( "overflow", "scroll" );
1123
1124                 w2 = innerDiv.offsetWidth;
1125
1126                 if ( w1 === w2 ) {
1127                         w2 = div[0].clientWidth;
1128                 }
1129
1130                 div.remove();
1131
1132                 return (cachedScrollbarWidth = w1 - w2);
1133         },
1134         getScrollInfo: function( within ) {
1135                 var overflowX = within.isWindow || within.isDocument ? "" :
1136                                 within.element.css( "overflow-x" ),
1137                         overflowY = within.isWindow || within.isDocument ? "" :
1138                                 within.element.css( "overflow-y" ),
1139                         hasOverflowX = overflowX === "scroll" ||
1140                                 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1141                         hasOverflowY = overflowY === "scroll" ||
1142                                 ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1143                 return {
1144                         width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1145                         height: hasOverflowX ? $.position.scrollbarWidth() : 0
1146                 };
1147         },
1148         getWithinInfo: function( element ) {
1149                 var withinElement = $( element || window ),
1150                         isWindow = $.isWindow( withinElement[0] ),
1151                         isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1152                 return {
1153                         element: withinElement,
1154                         isWindow: isWindow,
1155                         isDocument: isDocument,
1156                         offset: withinElement.offset() || { left: 0, top: 0 },
1157                         scrollLeft: withinElement.scrollLeft(),
1158                         scrollTop: withinElement.scrollTop(),
1159
1160                         // support: jQuery 1.6.x
1161                         // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
1162                         width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
1163                         height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
1164                 };
1165         }
1166 };
1167
1168 $.fn.position = function( options ) {
1169         if ( !options || !options.of ) {
1170                 return _position.apply( this, arguments );
1171         }
1172
1173         // make a copy, we don't want to modify arguments
1174         options = $.extend( {}, options );
1175
1176         var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1177                 target = $( options.of ),
1178                 within = $.position.getWithinInfo( options.within ),
1179                 scrollInfo = $.position.getScrollInfo( within ),
1180                 collision = ( options.collision || "flip" ).split( " " ),
1181                 offsets = {};
1182
1183         dimensions = getDimensions( target );
1184         if ( target[0].preventDefault ) {
1185                 // force left top to allow flipping
1186                 options.at = "left top";
1187         }
1188         targetWidth = dimensions.width;
1189         targetHeight = dimensions.height;
1190         targetOffset = dimensions.offset;
1191         // clone to reuse original targetOffset later
1192         basePosition = $.extend( {}, targetOffset );
1193
1194         // force my and at to have valid horizontal and vertical positions
1195         // if a value is missing or invalid, it will be converted to center
1196         $.each( [ "my", "at" ], function() {
1197                 var pos = ( options[ this ] || "" ).split( " " ),
1198                         horizontalOffset,
1199                         verticalOffset;
1200
1201                 if ( pos.length === 1) {
1202                         pos = rhorizontal.test( pos[ 0 ] ) ?
1203                                 pos.concat( [ "center" ] ) :
1204                                 rvertical.test( pos[ 0 ] ) ?
1205                                         [ "center" ].concat( pos ) :
1206                                         [ "center", "center" ];
1207                 }
1208                 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1209                 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1210
1211                 // calculate offsets
1212                 horizontalOffset = roffset.exec( pos[ 0 ] );
1213                 verticalOffset = roffset.exec( pos[ 1 ] );
1214                 offsets[ this ] = [
1215                         horizontalOffset ? horizontalOffset[ 0 ] : 0,
1216                         verticalOffset ? verticalOffset[ 0 ] : 0
1217                 ];
1218
1219                 // reduce to just the positions without the offsets
1220                 options[ this ] = [
1221                         rposition.exec( pos[ 0 ] )[ 0 ],
1222                         rposition.exec( pos[ 1 ] )[ 0 ]
1223                 ];
1224         });
1225
1226         // normalize collision option
1227         if ( collision.length === 1 ) {
1228                 collision[ 1 ] = collision[ 0 ];
1229         }
1230
1231         if ( options.at[ 0 ] === "right" ) {
1232                 basePosition.left += targetWidth;
1233         } else if ( options.at[ 0 ] === "center" ) {
1234                 basePosition.left += targetWidth / 2;
1235         }
1236
1237         if ( options.at[ 1 ] === "bottom" ) {
1238                 basePosition.top += targetHeight;
1239         } else if ( options.at[ 1 ] === "center" ) {
1240                 basePosition.top += targetHeight / 2;
1241         }
1242
1243         atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1244         basePosition.left += atOffset[ 0 ];
1245         basePosition.top += atOffset[ 1 ];
1246
1247         return this.each(function() {
1248                 var collisionPosition, using,
1249                         elem = $( this ),
1250                         elemWidth = elem.outerWidth(),
1251                         elemHeight = elem.outerHeight(),
1252                         marginLeft = parseCss( this, "marginLeft" ),
1253                         marginTop = parseCss( this, "marginTop" ),
1254                         collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1255                         collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1256                         position = $.extend( {}, basePosition ),
1257                         myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1258
1259                 if ( options.my[ 0 ] === "right" ) {
1260                         position.left -= elemWidth;
1261                 } else if ( options.my[ 0 ] === "center" ) {
1262                         position.left -= elemWidth / 2;
1263                 }
1264
1265                 if ( options.my[ 1 ] === "bottom" ) {
1266                         position.top -= elemHeight;
1267                 } else if ( options.my[ 1 ] === "center" ) {
1268                         position.top -= elemHeight / 2;
1269                 }
1270
1271                 position.left += myOffset[ 0 ];
1272                 position.top += myOffset[ 1 ];
1273
1274                 // if the browser doesn't support fractions, then round for consistent results
1275                 if ( !supportsOffsetFractions ) {
1276                         position.left = round( position.left );
1277                         position.top = round( position.top );
1278                 }
1279
1280                 collisionPosition = {
1281                         marginLeft: marginLeft,
1282                         marginTop: marginTop
1283                 };
1284
1285                 $.each( [ "left", "top" ], function( i, dir ) {
1286                         if ( $.ui.position[ collision[ i ] ] ) {
1287                                 $.ui.position[ collision[ i ] ][ dir ]( position, {
1288                                         targetWidth: targetWidth,
1289                                         targetHeight: targetHeight,
1290                                         elemWidth: elemWidth,
1291                                         elemHeight: elemHeight,
1292                                         collisionPosition: collisionPosition,
1293                                         collisionWidth: collisionWidth,
1294                                         collisionHeight: collisionHeight,
1295                                         offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1296                                         my: options.my,
1297                                         at: options.at,
1298                                         within: within,
1299                                         elem: elem
1300                                 });
1301                         }
1302                 });
1303
1304                 if ( options.using ) {
1305                         // adds feedback as second argument to using callback, if present
1306                         using = function( props ) {
1307                                 var left = targetOffset.left - position.left,
1308                                         right = left + targetWidth - elemWidth,
1309                                         top = targetOffset.top - position.top,
1310                                         bottom = top + targetHeight - elemHeight,
1311                                         feedback = {
1312                                                 target: {
1313                                                         element: target,
1314                                                         left: targetOffset.left,
1315                                                         top: targetOffset.top,
1316                                                         width: targetWidth,
1317                                                         height: targetHeight
1318                                                 },
1319                                                 element: {
1320                                                         element: elem,
1321                                                         left: position.left,
1322                                                         top: position.top,
1323                                                         width: elemWidth,
1324                                                         height: elemHeight
1325                                                 },
1326                                                 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1327                                                 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1328                                         };
1329                                 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1330                                         feedback.horizontal = "center";
1331                                 }
1332                                 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1333                                         feedback.vertical = "middle";
1334                                 }
1335                                 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1336                                         feedback.important = "horizontal";
1337                                 } else {
1338                                         feedback.important = "vertical";
1339                                 }
1340                                 options.using.call( this, props, feedback );
1341                         };
1342                 }
1343
1344                 elem.offset( $.extend( position, { using: using } ) );
1345         });
1346 };
1347
1348 $.ui.position = {
1349         fit: {
1350                 left: function( position, data ) {
1351                         var within = data.within,
1352                                 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1353                                 outerWidth = within.width,
1354                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1355                                 overLeft = withinOffset - collisionPosLeft,
1356                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1357                                 newOverRight;
1358
1359                         // element is wider than within
1360                         if ( data.collisionWidth > outerWidth ) {
1361                                 // element is initially over the left side of within
1362                                 if ( overLeft > 0 && overRight <= 0 ) {
1363                                         newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1364                                         position.left += overLeft - newOverRight;
1365                                 // element is initially over right side of within
1366                                 } else if ( overRight > 0 && overLeft <= 0 ) {
1367                                         position.left = withinOffset;
1368                                 // element is initially over both left and right sides of within
1369                                 } else {
1370                                         if ( overLeft > overRight ) {
1371                                                 position.left = withinOffset + outerWidth - data.collisionWidth;
1372                                         } else {
1373                                                 position.left = withinOffset;
1374                                         }
1375                                 }
1376                         // too far left -> align with left edge
1377                         } else if ( overLeft > 0 ) {
1378                                 position.left += overLeft;
1379                         // too far right -> align with right edge
1380                         } else if ( overRight > 0 ) {
1381                                 position.left -= overRight;
1382                         // adjust based on position and margin
1383                         } else {
1384                                 position.left = max( position.left - collisionPosLeft, position.left );
1385                         }
1386                 },
1387                 top: function( position, data ) {
1388                         var within = data.within,
1389                                 withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1390                                 outerHeight = data.within.height,
1391                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1392                                 overTop = withinOffset - collisionPosTop,
1393                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1394                                 newOverBottom;
1395
1396                         // element is taller than within
1397                         if ( data.collisionHeight > outerHeight ) {
1398                                 // element is initially over the top of within
1399                                 if ( overTop > 0 && overBottom <= 0 ) {
1400                                         newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1401                                         position.top += overTop - newOverBottom;
1402                                 // element is initially over bottom of within
1403                                 } else if ( overBottom > 0 && overTop <= 0 ) {
1404                                         position.top = withinOffset;
1405                                 // element is initially over both top and bottom of within
1406                                 } else {
1407                                         if ( overTop > overBottom ) {
1408                                                 position.top = withinOffset + outerHeight - data.collisionHeight;
1409                                         } else {
1410                                                 position.top = withinOffset;
1411                                         }
1412                                 }
1413                         // too far up -> align with top
1414                         } else if ( overTop > 0 ) {
1415                                 position.top += overTop;
1416                         // too far down -> align with bottom edge
1417                         } else if ( overBottom > 0 ) {
1418                                 position.top -= overBottom;
1419                         // adjust based on position and margin
1420                         } else {
1421                                 position.top = max( position.top - collisionPosTop, position.top );
1422                         }
1423                 }
1424         },
1425         flip: {
1426                 left: function( position, data ) {
1427                         var within = data.within,
1428                                 withinOffset = within.offset.left + within.scrollLeft,
1429                                 outerWidth = within.width,
1430                                 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1431                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1432                                 overLeft = collisionPosLeft - offsetLeft,
1433                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1434                                 myOffset = data.my[ 0 ] === "left" ?
1435                                         -data.elemWidth :
1436                                         data.my[ 0 ] === "right" ?
1437                                                 data.elemWidth :
1438                                                 0,
1439                                 atOffset = data.at[ 0 ] === "left" ?
1440                                         data.targetWidth :
1441                                         data.at[ 0 ] === "right" ?
1442                                                 -data.targetWidth :
1443                                                 0,
1444                                 offset = -2 * data.offset[ 0 ],
1445                                 newOverRight,
1446                                 newOverLeft;
1447
1448                         if ( overLeft < 0 ) {
1449                                 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1450                                 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1451                                         position.left += myOffset + atOffset + offset;
1452                                 }
1453                         } else if ( overRight > 0 ) {
1454                                 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1455                                 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1456                                         position.left += myOffset + atOffset + offset;
1457                                 }
1458                         }
1459                 },
1460                 top: function( position, data ) {
1461                         var within = data.within,
1462                                 withinOffset = within.offset.top + within.scrollTop,
1463                                 outerHeight = within.height,
1464                                 offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1465                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1466                                 overTop = collisionPosTop - offsetTop,
1467                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1468                                 top = data.my[ 1 ] === "top",
1469                                 myOffset = top ?
1470                                         -data.elemHeight :
1471                                         data.my[ 1 ] === "bottom" ?
1472                                                 data.elemHeight :
1473                                                 0,
1474                                 atOffset = data.at[ 1 ] === "top" ?
1475                                         data.targetHeight :
1476                                         data.at[ 1 ] === "bottom" ?
1477                                                 -data.targetHeight :
1478                                                 0,
1479                                 offset = -2 * data.offset[ 1 ],
1480                                 newOverTop,
1481                                 newOverBottom;
1482                         if ( overTop < 0 ) {
1483                                 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1484                                 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1485                                         position.top += myOffset + atOffset + offset;
1486                                 }
1487                         } else if ( overBottom > 0 ) {
1488                                 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1489                                 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1490                                         position.top += myOffset + atOffset + offset;
1491                                 }
1492                         }
1493                 }
1494         },
1495         flipfit: {
1496                 left: function() {
1497                         $.ui.position.flip.left.apply( this, arguments );
1498                         $.ui.position.fit.left.apply( this, arguments );
1499                 },
1500                 top: function() {
1501                         $.ui.position.flip.top.apply( this, arguments );
1502                         $.ui.position.fit.top.apply( this, arguments );
1503                 }
1504         }
1505 };
1506
1507 // fraction support test
1508 (function() {
1509         var testElement, testElementParent, testElementStyle, offsetLeft, i,
1510                 body = document.getElementsByTagName( "body" )[ 0 ],
1511                 div = document.createElement( "div" );
1512
1513         //Create a "fake body" for testing based on method used in jQuery.support
1514         testElement = document.createElement( body ? "div" : "body" );
1515         testElementStyle = {
1516                 visibility: "hidden",
1517                 width: 0,
1518                 height: 0,
1519                 border: 0,
1520                 margin: 0,
1521                 background: "none"
1522         };
1523         if ( body ) {
1524                 $.extend( testElementStyle, {
1525                         position: "absolute",
1526                         left: "-1000px",
1527                         top: "-1000px"
1528                 });
1529         }
1530         for ( i in testElementStyle ) {
1531                 testElement.style[ i ] = testElementStyle[ i ];
1532         }
1533         testElement.appendChild( div );
1534         testElementParent = body || document.documentElement;
1535         testElementParent.insertBefore( testElement, testElementParent.firstChild );
1536
1537         div.style.cssText = "position: absolute; left: 10.7432222px;";
1538
1539         offsetLeft = $( div ).offset().left;
1540         supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1541
1542         testElement.innerHTML = "";
1543         testElementParent.removeChild( testElement );
1544 })();
1545
1546 })();
1547
1548 var position = $.ui.position;
1549
1550
1551 /*!
1552  * jQuery UI Accordion 1.11.2
1553  * http://jqueryui.com
1554  *
1555  * Copyright 2014 jQuery Foundation and other contributors
1556  * Released under the MIT license.
1557  * http://jquery.org/license
1558  *
1559  * http://api.jqueryui.com/accordion/
1560  */
1561
1562
1563 var accordion = $.widget( "ui.accordion", {
1564         version: "1.11.2",
1565         options: {
1566                 active: 0,
1567                 animate: {},
1568                 collapsible: false,
1569                 event: "click",
1570                 header: "> li > :first-child,> :not(li):even",
1571                 heightStyle: "auto",
1572                 icons: {
1573                         activeHeader: "ui-icon-triangle-1-s",
1574                         header: "ui-icon-triangle-1-e"
1575                 },
1576
1577                 // callbacks
1578                 activate: null,
1579                 beforeActivate: null
1580         },
1581
1582         hideProps: {
1583                 borderTopWidth: "hide",
1584                 borderBottomWidth: "hide",
1585                 paddingTop: "hide",
1586                 paddingBottom: "hide",
1587                 height: "hide"
1588         },
1589
1590         showProps: {
1591                 borderTopWidth: "show",
1592                 borderBottomWidth: "show",
1593                 paddingTop: "show",
1594                 paddingBottom: "show",
1595                 height: "show"
1596         },
1597
1598         _create: function() {
1599                 var options = this.options;
1600                 this.prevShow = this.prevHide = $();
1601                 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
1602                         // ARIA
1603                         .attr( "role", "tablist" );
1604
1605                 // don't allow collapsible: false and active: false / null
1606                 if ( !options.collapsible && (options.active === false || options.active == null) ) {
1607                         options.active = 0;
1608                 }
1609
1610                 this._processPanels();
1611                 // handle negative values
1612                 if ( options.active < 0 ) {
1613                         options.active += this.headers.length;
1614                 }
1615                 this._refresh();
1616         },
1617
1618         _getCreateEventData: function() {
1619                 return {
1620                         header: this.active,
1621                         panel: !this.active.length ? $() : this.active.next()
1622                 };
1623         },
1624
1625         _createIcons: function() {
1626                 var icons = this.options.icons;
1627                 if ( icons ) {
1628                         $( "<span>" )
1629                                 .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
1630                                 .prependTo( this.headers );
1631                         this.active.children( ".ui-accordion-header-icon" )
1632                                 .removeClass( icons.header )
1633                                 .addClass( icons.activeHeader );
1634                         this.headers.addClass( "ui-accordion-icons" );
1635                 }
1636         },
1637
1638         _destroyIcons: function() {
1639                 this.headers
1640                         .removeClass( "ui-accordion-icons" )
1641                         .children( ".ui-accordion-header-icon" )
1642                                 .remove();
1643         },
1644
1645         _destroy: function() {
1646                 var contents;
1647
1648                 // clean up main element
1649                 this.element
1650                         .removeClass( "ui-accordion ui-widget ui-helper-reset" )
1651                         .removeAttr( "role" );
1652
1653                 // clean up headers
1654                 this.headers
1655                         .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
1656                                 "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
1657                         .removeAttr( "role" )
1658                         .removeAttr( "aria-expanded" )
1659                         .removeAttr( "aria-selected" )
1660                         .removeAttr( "aria-controls" )
1661                         .removeAttr( "tabIndex" )
1662                         .removeUniqueId();
1663
1664                 this._destroyIcons();
1665
1666                 // clean up content panels
1667                 contents = this.headers.next()
1668                         .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
1669                                 "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
1670                         .css( "display", "" )
1671                         .removeAttr( "role" )
1672                         .removeAttr( "aria-hidden" )
1673                         .removeAttr( "aria-labelledby" )
1674                         .removeUniqueId();
1675
1676                 if ( this.options.heightStyle !== "content" ) {
1677                         contents.css( "height", "" );
1678                 }
1679         },
1680
1681         _setOption: function( key, value ) {
1682                 if ( key === "active" ) {
1683                         // _activate() will handle invalid values and update this.options
1684                         this._activate( value );
1685                         return;
1686                 }
1687
1688                 if ( key === "event" ) {
1689                         if ( this.options.event ) {
1690                                 this._off( this.headers, this.options.event );
1691                         }
1692                         this._setupEvents( value );
1693                 }
1694
1695                 this._super( key, value );
1696
1697                 // setting collapsible: false while collapsed; open first panel
1698                 if ( key === "collapsible" && !value && this.options.active === false ) {
1699                         this._activate( 0 );
1700                 }
1701
1702                 if ( key === "icons" ) {
1703                         this._destroyIcons();
1704                         if ( value ) {
1705                                 this._createIcons();
1706                         }
1707                 }
1708
1709                 // #5332 - opacity doesn't cascade to positioned elements in IE
1710                 // so we need to add the disabled class to the headers and panels
1711                 if ( key === "disabled" ) {
1712                         this.element
1713                                 .toggleClass( "ui-state-disabled", !!value )
1714                                 .attr( "aria-disabled", value );
1715                         this.headers.add( this.headers.next() )
1716                                 .toggleClass( "ui-state-disabled", !!value );
1717                 }
1718         },
1719
1720         _keydown: function( event ) {
1721                 if ( event.altKey || event.ctrlKey ) {
1722                         return;
1723                 }
1724
1725                 var keyCode = $.ui.keyCode,
1726                         length = this.headers.length,
1727                         currentIndex = this.headers.index( event.target ),
1728                         toFocus = false;
1729
1730                 switch ( event.keyCode ) {
1731                         case keyCode.RIGHT:
1732                         case keyCode.DOWN:
1733                                 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
1734                                 break;
1735                         case keyCode.LEFT:
1736                         case keyCode.UP:
1737                                 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
1738                                 break;
1739                         case keyCode.SPACE:
1740                         case keyCode.ENTER:
1741                                 this._eventHandler( event );
1742                                 break;
1743                         case keyCode.HOME:
1744                                 toFocus = this.headers[ 0 ];
1745                                 break;
1746                         case keyCode.END:
1747                                 toFocus = this.headers[ length - 1 ];
1748                                 break;
1749                 }
1750
1751                 if ( toFocus ) {
1752                         $( event.target ).attr( "tabIndex", -1 );
1753                         $( toFocus ).attr( "tabIndex", 0 );
1754                         toFocus.focus();
1755                         event.preventDefault();
1756                 }
1757         },
1758
1759         _panelKeyDown: function( event ) {
1760                 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
1761                         $( event.currentTarget ).prev().focus();
1762                 }
1763         },
1764
1765         refresh: function() {
1766                 var options = this.options;
1767                 this._processPanels();
1768
1769                 // was collapsed or no panel
1770                 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
1771                         options.active = false;
1772                         this.active = $();
1773                 // active false only when collapsible is true
1774                 } else if ( options.active === false ) {
1775                         this._activate( 0 );
1776                 // was active, but active panel is gone
1777                 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
1778                         // all remaining panel are disabled
1779                         if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
1780                                 options.active = false;
1781                                 this.active = $();
1782                         // activate previous panel
1783                         } else {
1784                                 this._activate( Math.max( 0, options.active - 1 ) );
1785                         }
1786                 // was active, active panel still exists
1787                 } else {
1788                         // make sure active index is correct
1789                         options.active = this.headers.index( this.active );
1790                 }
1791
1792                 this._destroyIcons();
1793
1794                 this._refresh();
1795         },
1796
1797         _processPanels: function() {
1798                 var prevHeaders = this.headers,
1799                         prevPanels = this.panels;
1800
1801                 this.headers = this.element.find( this.options.header )
1802                         .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
1803
1804                 this.panels = this.headers.next()
1805                         .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
1806                         .filter( ":not(.ui-accordion-content-active)" )
1807                         .hide();
1808
1809                 // Avoid memory leaks (#10056)
1810                 if ( prevPanels ) {
1811                         this._off( prevHeaders.not( this.headers ) );
1812                         this._off( prevPanels.not( this.panels ) );
1813                 }
1814         },
1815
1816         _refresh: function() {
1817                 var maxHeight,
1818                         options = this.options,
1819                         heightStyle = options.heightStyle,
1820                         parent = this.element.parent();
1821
1822                 this.active = this._findActive( options.active )
1823                         .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
1824                         .removeClass( "ui-corner-all" );
1825                 this.active.next()
1826                         .addClass( "ui-accordion-content-active" )
1827                         .show();
1828
1829                 this.headers
1830                         .attr( "role", "tab" )
1831                         .each(function() {
1832                                 var header = $( this ),
1833                                         headerId = header.uniqueId().attr( "id" ),
1834                                         panel = header.next(),
1835                                         panelId = panel.uniqueId().attr( "id" );
1836                                 header.attr( "aria-controls", panelId );
1837                                 panel.attr( "aria-labelledby", headerId );
1838                         })
1839                         .next()
1840                                 .attr( "role", "tabpanel" );
1841
1842                 this.headers
1843                         .not( this.active )
1844                         .attr({
1845                                 "aria-selected": "false",
1846                                 "aria-expanded": "false",
1847                                 tabIndex: -1
1848                         })
1849                         .next()
1850                                 .attr({
1851                                         "aria-hidden": "true"
1852                                 })
1853                                 .hide();
1854
1855                 // make sure at least one header is in the tab order
1856                 if ( !this.active.length ) {
1857                         this.headers.eq( 0 ).attr( "tabIndex", 0 );
1858                 } else {
1859                         this.active.attr({
1860                                 "aria-selected": "true",
1861                                 "aria-expanded": "true",
1862                                 tabIndex: 0
1863                         })
1864                         .next()
1865                                 .attr({
1866                                         "aria-hidden": "false"
1867                                 });
1868                 }
1869
1870                 this._createIcons();
1871
1872                 this._setupEvents( options.event );
1873
1874                 if ( heightStyle === "fill" ) {
1875                         maxHeight = parent.height();
1876                         this.element.siblings( ":visible" ).each(function() {
1877                                 var elem = $( this ),
1878                                         position = elem.css( "position" );
1879
1880                                 if ( position === "absolute" || position === "fixed" ) {
1881                                         return;
1882                                 }
1883                                 maxHeight -= elem.outerHeight( true );
1884                         });
1885
1886                         this.headers.each(function() {
1887                                 maxHeight -= $( this ).outerHeight( true );
1888                         });
1889
1890                         this.headers.next()
1891                                 .each(function() {
1892                                         $( this ).height( Math.max( 0, maxHeight -
1893                                                 $( this ).innerHeight() + $( this ).height() ) );
1894                                 })
1895                                 .css( "overflow", "auto" );
1896                 } else if ( heightStyle === "auto" ) {
1897                         maxHeight = 0;
1898                         this.headers.next()
1899                                 .each(function() {
1900                                         maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
1901                                 })
1902                                 .height( maxHeight );
1903                 }
1904         },
1905
1906         _activate: function( index ) {
1907                 var active = this._findActive( index )[ 0 ];
1908
1909                 // trying to activate the already active panel
1910                 if ( active === this.active[ 0 ] ) {
1911                         return;
1912                 }
1913
1914                 // trying to collapse, simulate a click on the currently active header
1915                 active = active || this.active[ 0 ];
1916
1917                 this._eventHandler({
1918                         target: active,
1919                         currentTarget: active,
1920                         preventDefault: $.noop
1921                 });
1922         },
1923
1924         _findActive: function( selector ) {
1925                 return typeof selector === "number" ? this.headers.eq( selector ) : $();
1926         },
1927
1928         _setupEvents: function( event ) {
1929                 var events = {
1930                         keydown: "_keydown"
1931                 };
1932                 if ( event ) {
1933                         $.each( event.split( " " ), function( index, eventName ) {
1934                                 events[ eventName ] = "_eventHandler";
1935                         });
1936                 }
1937
1938                 this._off( this.headers.add( this.headers.next() ) );
1939                 this._on( this.headers, events );
1940                 this._on( this.headers.next(), { keydown: "_panelKeyDown" });
1941                 this._hoverable( this.headers );
1942                 this._focusable( this.headers );
1943         },
1944
1945         _eventHandler: function( event ) {
1946                 var options = this.options,
1947                         active = this.active,
1948                         clicked = $( event.currentTarget ),
1949                         clickedIsActive = clicked[ 0 ] === active[ 0 ],
1950                         collapsing = clickedIsActive && options.collapsible,
1951                         toShow = collapsing ? $() : clicked.next(),
1952                         toHide = active.next(),
1953                         eventData = {
1954                                 oldHeader: active,
1955                                 oldPanel: toHide,
1956                                 newHeader: collapsing ? $() : clicked,
1957                                 newPanel: toShow
1958                         };
1959
1960                 event.preventDefault();
1961
1962                 if (
1963                                 // click on active header, but not collapsible
1964                                 ( clickedIsActive && !options.collapsible ) ||
1965                                 // allow canceling activation
1966                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
1967                         return;
1968                 }
1969
1970                 options.active = collapsing ? false : this.headers.index( clicked );
1971
1972                 // when the call to ._toggle() comes after the class changes
1973                 // it causes a very odd bug in IE 8 (see #6720)
1974                 this.active = clickedIsActive ? $() : clicked;
1975                 this._toggle( eventData );
1976
1977                 // switch classes
1978                 // corner classes on the previously active header stay after the animation
1979                 active.removeClass( "ui-accordion-header-active ui-state-active" );
1980                 if ( options.icons ) {
1981                         active.children( ".ui-accordion-header-icon" )
1982                                 .removeClass( options.icons.activeHeader )
1983                                 .addClass( options.icons.header );
1984                 }
1985
1986                 if ( !clickedIsActive ) {
1987                         clicked
1988                                 .removeClass( "ui-corner-all" )
1989                                 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
1990                         if ( options.icons ) {
1991                                 clicked.children( ".ui-accordion-header-icon" )
1992                                         .removeClass( options.icons.header )
1993                                         .addClass( options.icons.activeHeader );
1994                         }
1995
1996                         clicked
1997                                 .next()
1998                                 .addClass( "ui-accordion-content-active" );
1999                 }
2000         },
2001
2002         _toggle: function( data ) {
2003                 var toShow = data.newPanel,
2004                         toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
2005
2006                 // handle activating a panel during the animation for another activation
2007                 this.prevShow.add( this.prevHide ).stop( true, true );
2008                 this.prevShow = toShow;
2009                 this.prevHide = toHide;
2010
2011                 if ( this.options.animate ) {
2012                         this._animate( toShow, toHide, data );
2013                 } else {
2014                         toHide.hide();
2015                         toShow.show();
2016                         this._toggleComplete( data );
2017                 }
2018
2019                 toHide.attr({
2020                         "aria-hidden": "true"
2021                 });
2022                 toHide.prev().attr( "aria-selected", "false" );
2023                 // if we're switching panels, remove the old header from the tab order
2024                 // if we're opening from collapsed state, remove the previous header from the tab order
2025                 // if we're collapsing, then keep the collapsing header in the tab order
2026                 if ( toShow.length && toHide.length ) {
2027                         toHide.prev().attr({
2028                                 "tabIndex": -1,
2029                                 "aria-expanded": "false"
2030                         });
2031                 } else if ( toShow.length ) {
2032                         this.headers.filter(function() {
2033                                 return $( this ).attr( "tabIndex" ) === 0;
2034                         })
2035                         .attr( "tabIndex", -1 );
2036                 }
2037
2038                 toShow
2039                         .attr( "aria-hidden", "false" )
2040                         .prev()
2041                                 .attr({
2042                                         "aria-selected": "true",
2043                                         tabIndex: 0,
2044                                         "aria-expanded": "true"
2045                                 });
2046         },
2047
2048         _animate: function( toShow, toHide, data ) {
2049                 var total, easing, duration,
2050                         that = this,
2051                         adjust = 0,
2052                         down = toShow.length &&
2053                                 ( !toHide.length || ( toShow.index() < toHide.index() ) ),
2054                         animate = this.options.animate || {},
2055                         options = down && animate.down || animate,
2056                         complete = function() {
2057                                 that._toggleComplete( data );
2058                         };
2059
2060                 if ( typeof options === "number" ) {
2061                         duration = options;
2062                 }
2063                 if ( typeof options === "string" ) {
2064                         easing = options;
2065                 }
2066                 // fall back from options to animation in case of partial down settings
2067                 easing = easing || options.easing || animate.easing;
2068                 duration = duration || options.duration || animate.duration;
2069
2070                 if ( !toHide.length ) {
2071                         return toShow.animate( this.showProps, duration, easing, complete );
2072                 }
2073                 if ( !toShow.length ) {
2074                         return toHide.animate( this.hideProps, duration, easing, complete );
2075                 }
2076
2077                 total = toShow.show().outerHeight();
2078                 toHide.animate( this.hideProps, {
2079                         duration: duration,
2080                         easing: easing,
2081                         step: function( now, fx ) {
2082                                 fx.now = Math.round( now );
2083                         }
2084                 });
2085                 toShow
2086                         .hide()
2087                         .animate( this.showProps, {
2088                                 duration: duration,
2089                                 easing: easing,
2090                                 complete: complete,
2091                                 step: function( now, fx ) {
2092                                         fx.now = Math.round( now );
2093                                         if ( fx.prop !== "height" ) {
2094                                                 adjust += fx.now;
2095                                         } else if ( that.options.heightStyle !== "content" ) {
2096                                                 fx.now = Math.round( total - toHide.outerHeight() - adjust );
2097                                                 adjust = 0;
2098                                         }
2099                                 }
2100                         });
2101         },
2102
2103         _toggleComplete: function( data ) {
2104                 var toHide = data.oldPanel;
2105
2106                 toHide
2107                         .removeClass( "ui-accordion-content-active" )
2108                         .prev()
2109                                 .removeClass( "ui-corner-top" )
2110                                 .addClass( "ui-corner-all" );
2111
2112                 // Work around for rendering bug in IE (#5421)
2113                 if ( toHide.length ) {
2114                         toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
2115                 }
2116                 this._trigger( "activate", null, data );
2117         }
2118 });
2119
2120
2121 /*!
2122  * jQuery UI Menu 1.11.2
2123  * http://jqueryui.com
2124  *
2125  * Copyright 2014 jQuery Foundation and other contributors
2126  * Released under the MIT license.
2127  * http://jquery.org/license
2128  *
2129  * http://api.jqueryui.com/menu/
2130  */
2131
2132
2133 var menu = $.widget( "ui.menu", {
2134         version: "1.11.2",
2135         defaultElement: "<ul>",
2136         delay: 300,
2137         options: {
2138                 icons: {
2139                         submenu: "ui-icon-carat-1-e"
2140                 },
2141                 items: "> *",
2142                 menus: "ul",
2143                 position: {
2144                         my: "left-1 top",
2145                         at: "right top"
2146                 },
2147                 role: "menu",
2148
2149                 // callbacks
2150                 blur: null,
2151                 focus: null,
2152                 select: null
2153         },
2154
2155         _create: function() {
2156                 this.activeMenu = this.element;
2157
2158                 // Flag used to prevent firing of the click handler
2159                 // as the event bubbles up through nested menus
2160                 this.mouseHandled = false;
2161                 this.element
2162                         .uniqueId()
2163                         .addClass( "ui-menu ui-widget ui-widget-content" )
2164                         .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
2165                         .attr({
2166                                 role: this.options.role,
2167                                 tabIndex: 0
2168                         });
2169
2170                 if ( this.options.disabled ) {
2171                         this.element
2172                                 .addClass( "ui-state-disabled" )
2173                                 .attr( "aria-disabled", "true" );
2174                 }
2175
2176                 this._on({
2177                         // Prevent focus from sticking to links inside menu after clicking
2178                         // them (focus should always stay on UL during navigation).
2179                         "mousedown .ui-menu-item": function( event ) {
2180                                 event.preventDefault();
2181                         },
2182                         "click .ui-menu-item": function( event ) {
2183                                 var target = $( event.target );
2184                                 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
2185                                         this.select( event );
2186
2187                                         // Only set the mouseHandled flag if the event will bubble, see #9469.
2188                                         if ( !event.isPropagationStopped() ) {
2189                                                 this.mouseHandled = true;
2190                                         }
2191
2192                                         // Open submenu on click
2193                                         if ( target.has( ".ui-menu" ).length ) {
2194                                                 this.expand( event );
2195                                         } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
2196
2197                                                 // Redirect focus to the menu
2198                                                 this.element.trigger( "focus", [ true ] );
2199
2200                                                 // If the active item is on the top level, let it stay active.
2201                                                 // Otherwise, blur the active item since it is no longer visible.
2202                                                 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
2203                                                         clearTimeout( this.timer );
2204                                                 }
2205                                         }
2206                                 }
2207                         },
2208                         "mouseenter .ui-menu-item": function( event ) {
2209                                 // Ignore mouse events while typeahead is active, see #10458.
2210                                 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
2211                                 // is over an item in the menu
2212                                 if ( this.previousFilter ) {
2213                                         return;
2214                                 }
2215                                 var target = $( event.currentTarget );
2216                                 // Remove ui-state-active class from siblings of the newly focused menu item
2217                                 // to avoid a jump caused by adjacent elements both having a class with a border
2218                                 target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
2219                                 this.focus( event, target );
2220                         },
2221                         mouseleave: "collapseAll",
2222                         "mouseleave .ui-menu": "collapseAll",
2223                         focus: function( event, keepActiveItem ) {
2224                                 // If there's already an active item, keep it active
2225                                 // If not, activate the first item
2226                                 var item = this.active || this.element.find( this.options.items ).eq( 0 );
2227
2228                                 if ( !keepActiveItem ) {
2229                                         this.focus( event, item );
2230                                 }
2231                         },
2232                         blur: function( event ) {
2233                                 this._delay(function() {
2234                                         if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
2235                                                 this.collapseAll( event );
2236                                         }
2237                                 });
2238                         },
2239                         keydown: "_keydown"
2240                 });
2241
2242                 this.refresh();
2243
2244                 // Clicks outside of a menu collapse any open menus
2245                 this._on( this.document, {
2246                         click: function( event ) {
2247                                 if ( this._closeOnDocumentClick( event ) ) {
2248                                         this.collapseAll( event );
2249                                 }
2250
2251                                 // Reset the mouseHandled flag
2252                                 this.mouseHandled = false;
2253                         }
2254                 });
2255         },
2256
2257         _destroy: function() {
2258                 // Destroy (sub)menus
2259                 this.element
2260                         .removeAttr( "aria-activedescendant" )
2261                         .find( ".ui-menu" ).addBack()
2262                                 .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
2263                                 .removeAttr( "role" )
2264                                 .removeAttr( "tabIndex" )
2265                                 .removeAttr( "aria-labelledby" )
2266                                 .removeAttr( "aria-expanded" )
2267                                 .removeAttr( "aria-hidden" )
2268                                 .removeAttr( "aria-disabled" )
2269                                 .removeUniqueId()
2270                                 .show();
2271
2272                 // Destroy menu items
2273                 this.element.find( ".ui-menu-item" )
2274                         .removeClass( "ui-menu-item" )
2275                         .removeAttr( "role" )
2276                         .removeAttr( "aria-disabled" )
2277                         .removeUniqueId()
2278                         .removeClass( "ui-state-hover" )
2279                         .removeAttr( "tabIndex" )
2280                         .removeAttr( "role" )
2281                         .removeAttr( "aria-haspopup" )
2282                         .children().each( function() {
2283                                 var elem = $( this );
2284                                 if ( elem.data( "ui-menu-submenu-carat" ) ) {
2285                                         elem.remove();
2286                                 }
2287                         });
2288
2289                 // Destroy menu dividers
2290                 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
2291         },
2292
2293         _keydown: function( event ) {
2294                 var match, prev, character, skip,
2295                         preventDefault = true;
2296
2297                 switch ( event.keyCode ) {
2298                 case $.ui.keyCode.PAGE_UP:
2299                         this.previousPage( event );
2300                         break;
2301                 case $.ui.keyCode.PAGE_DOWN:
2302                         this.nextPage( event );
2303                         break;
2304                 case $.ui.keyCode.HOME:
2305                         this._move( "first", "first", event );
2306                         break;
2307                 case $.ui.keyCode.END:
2308                         this._move( "last", "last", event );
2309                         break;
2310                 case $.ui.keyCode.UP:
2311                         this.previous( event );
2312                         break;
2313                 case $.ui.keyCode.DOWN:
2314                         this.next( event );
2315                         break;
2316                 case $.ui.keyCode.LEFT:
2317                         this.collapse( event );
2318                         break;
2319                 case $.ui.keyCode.RIGHT:
2320                         if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
2321                                 this.expand( event );
2322                         }
2323                         break;
2324                 case $.ui.keyCode.ENTER:
2325                 case $.ui.keyCode.SPACE:
2326                         this._activate( event );
2327                         break;
2328                 case $.ui.keyCode.ESCAPE:
2329                         this.collapse( event );
2330                         break;
2331                 default:
2332                         preventDefault = false;
2333                         prev = this.previousFilter || "";
2334                         character = String.fromCharCode( event.keyCode );
2335                         skip = false;
2336
2337                         clearTimeout( this.filterTimer );
2338
2339                         if ( character === prev ) {
2340                                 skip = true;
2341                         } else {
2342                                 character = prev + character;
2343                         }
2344
2345                         match = this._filterMenuItems( character );
2346                         match = skip && match.index( this.active.next() ) !== -1 ?
2347                                 this.active.nextAll( ".ui-menu-item" ) :
2348                                 match;
2349
2350                         // If no matches on the current filter, reset to the last character pressed
2351                         // to move down the menu to the first item that starts with that character
2352                         if ( !match.length ) {
2353                                 character = String.fromCharCode( event.keyCode );
2354                                 match = this._filterMenuItems( character );
2355                         }
2356
2357                         if ( match.length ) {
2358                                 this.focus( event, match );
2359                                 this.previousFilter = character;
2360                                 this.filterTimer = this._delay(function() {
2361                                         delete this.previousFilter;
2362                                 }, 1000 );
2363                         } else {
2364                                 delete this.previousFilter;
2365                         }
2366                 }
2367
2368                 if ( preventDefault ) {
2369                         event.preventDefault();
2370                 }
2371         },
2372
2373         _activate: function( event ) {
2374                 if ( !this.active.is( ".ui-state-disabled" ) ) {
2375                         if ( this.active.is( "[aria-haspopup='true']" ) ) {
2376                                 this.expand( event );
2377                         } else {
2378                                 this.select( event );
2379                         }
2380                 }
2381         },
2382
2383         refresh: function() {
2384                 var menus, items,
2385                         that = this,
2386                         icon = this.options.icons.submenu,
2387                         submenus = this.element.find( this.options.menus );
2388
2389                 this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
2390
2391                 // Initialize nested menus
2392                 submenus.filter( ":not(.ui-menu)" )
2393                         .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
2394                         .hide()
2395                         .attr({
2396                                 role: this.options.role,
2397                                 "aria-hidden": "true",
2398                                 "aria-expanded": "false"
2399                         })
2400                         .each(function() {
2401                                 var menu = $( this ),
2402                                         item = menu.parent(),
2403                                         submenuCarat = $( "<span>" )
2404                                                 .addClass( "ui-menu-icon ui-icon " + icon )
2405                                                 .data( "ui-menu-submenu-carat", true );
2406
2407                                 item
2408                                         .attr( "aria-haspopup", "true" )
2409                                         .prepend( submenuCarat );
2410                                 menu.attr( "aria-labelledby", item.attr( "id" ) );
2411                         });
2412
2413                 menus = submenus.add( this.element );
2414                 items = menus.find( this.options.items );
2415
2416                 // Initialize menu-items containing spaces and/or dashes only as dividers
2417                 items.not( ".ui-menu-item" ).each(function() {
2418                         var item = $( this );
2419                         if ( that._isDivider( item ) ) {
2420                                 item.addClass( "ui-widget-content ui-menu-divider" );
2421                         }
2422                 });
2423
2424                 // Don't refresh list items that are already adapted
2425                 items.not( ".ui-menu-item, .ui-menu-divider" )
2426                         .addClass( "ui-menu-item" )
2427                         .uniqueId()
2428                         .attr({
2429                                 tabIndex: -1,
2430                                 role: this._itemRole()
2431                         });
2432
2433                 // Add aria-disabled attribute to any disabled menu item
2434                 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
2435
2436                 // If the active item has been removed, blur the menu
2437                 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
2438                         this.blur();
2439                 }
2440         },
2441
2442         _itemRole: function() {
2443                 return {
2444                         menu: "menuitem",
2445                         listbox: "option"
2446                 }[ this.options.role ];
2447         },
2448
2449         _setOption: function( key, value ) {
2450                 if ( key === "icons" ) {
2451                         this.element.find( ".ui-menu-icon" )
2452                                 .removeClass( this.options.icons.submenu )
2453                                 .addClass( value.submenu );
2454                 }
2455                 if ( key === "disabled" ) {
2456                         this.element
2457                                 .toggleClass( "ui-state-disabled", !!value )
2458                                 .attr( "aria-disabled", value );
2459                 }
2460                 this._super( key, value );
2461         },
2462
2463         focus: function( event, item ) {
2464                 var nested, focused;
2465                 this.blur( event, event && event.type === "focus" );
2466
2467                 this._scrollIntoView( item );
2468
2469                 this.active = item.first();
2470                 focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
2471                 // Only update aria-activedescendant if there's a role
2472                 // otherwise we assume focus is managed elsewhere
2473                 if ( this.options.role ) {
2474                         this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
2475                 }
2476
2477                 // Highlight active parent menu item, if any
2478                 this.active
2479                         .parent()
2480                         .closest( ".ui-menu-item" )
2481                         .addClass( "ui-state-active" );
2482
2483                 if ( event && event.type === "keydown" ) {
2484                         this._close();
2485                 } else {
2486                         this.timer = this._delay(function() {
2487                                 this._close();
2488                         }, this.delay );
2489                 }
2490
2491                 nested = item.children( ".ui-menu" );
2492                 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
2493                         this._startOpening(nested);
2494                 }
2495                 this.activeMenu = item.parent();
2496
2497                 this._trigger( "focus", event, { item: item } );
2498         },
2499
2500         _scrollIntoView: function( item ) {
2501                 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
2502                 if ( this._hasScroll() ) {
2503                         borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
2504                         paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
2505                         offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
2506                         scroll = this.activeMenu.scrollTop();
2507                         elementHeight = this.activeMenu.height();
2508                         itemHeight = item.outerHeight();
2509
2510                         if ( offset < 0 ) {
2511                                 this.activeMenu.scrollTop( scroll + offset );
2512                         } else if ( offset + itemHeight > elementHeight ) {
2513                                 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
2514                         }
2515                 }
2516         },
2517
2518         blur: function( event, fromFocus ) {
2519                 if ( !fromFocus ) {
2520                         clearTimeout( this.timer );
2521                 }
2522
2523                 if ( !this.active ) {
2524                         return;
2525                 }
2526
2527                 this.active.removeClass( "ui-state-focus" );
2528                 this.active = null;
2529
2530                 this._trigger( "blur", event, { item: this.active } );
2531         },
2532
2533         _startOpening: function( submenu ) {
2534                 clearTimeout( this.timer );
2535
2536                 // Don't open if already open fixes a Firefox bug that caused a .5 pixel
2537                 // shift in the submenu position when mousing over the carat icon
2538                 if ( submenu.attr( "aria-hidden" ) !== "true" ) {
2539                         return;
2540                 }
2541
2542                 this.timer = this._delay(function() {
2543                         this._close();
2544                         this._open( submenu );
2545                 }, this.delay );
2546         },
2547
2548         _open: function( submenu ) {
2549                 var position = $.extend({
2550                         of: this.active
2551                 }, this.options.position );
2552
2553                 clearTimeout( this.timer );
2554                 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
2555                         .hide()
2556                         .attr( "aria-hidden", "true" );
2557
2558                 submenu
2559                         .show()
2560                         .removeAttr( "aria-hidden" )
2561                         .attr( "aria-expanded", "true" )
2562                         .position( position );
2563         },
2564
2565         collapseAll: function( event, all ) {
2566                 clearTimeout( this.timer );
2567                 this.timer = this._delay(function() {
2568                         // If we were passed an event, look for the submenu that contains the event
2569                         var currentMenu = all ? this.element :
2570                                 $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
2571
2572                         // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
2573                         if ( !currentMenu.length ) {
2574                                 currentMenu = this.element;
2575                         }
2576
2577                         this._close( currentMenu );
2578
2579                         this.blur( event );
2580                         this.activeMenu = currentMenu;
2581                 }, this.delay );
2582         },
2583
2584         // With no arguments, closes the currently active menu - if nothing is active
2585         // it closes all menus.  If passed an argument, it will search for menus BELOW
2586         _close: function( startMenu ) {
2587                 if ( !startMenu ) {
2588                         startMenu = this.active ? this.active.parent() : this.element;
2589                 }
2590
2591                 startMenu
2592                         .find( ".ui-menu" )
2593                                 .hide()
2594                                 .attr( "aria-hidden", "true" )
2595                                 .attr( "aria-expanded", "false" )
2596                         .end()
2597                         .find( ".ui-state-active" ).not( ".ui-state-focus" )
2598                                 .removeClass( "ui-state-active" );
2599         },
2600
2601         _closeOnDocumentClick: function( event ) {
2602                 return !$( event.target ).closest( ".ui-menu" ).length;
2603         },
2604
2605         _isDivider: function( item ) {
2606
2607                 // Match hyphen, em dash, en dash
2608                 return !/[^\-\u2014\u2013\s]/.test( item.text() );
2609         },
2610
2611         collapse: function( event ) {
2612                 var newItem = this.active &&
2613                         this.active.parent().closest( ".ui-menu-item", this.element );
2614                 if ( newItem && newItem.length ) {
2615                         this._close();
2616                         this.focus( event, newItem );
2617                 }
2618         },
2619
2620         expand: function( event ) {
2621                 var newItem = this.active &&
2622                         this.active
2623                                 .children( ".ui-menu " )
2624                                 .find( this.options.items )
2625                                 .first();
2626
2627                 if ( newItem && newItem.length ) {
2628                         this._open( newItem.parent() );
2629
2630                         // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
2631                         this._delay(function() {
2632                                 this.focus( event, newItem );
2633                         });
2634                 }
2635         },
2636
2637         next: function( event ) {
2638                 this._move( "next", "first", event );
2639         },
2640
2641         previous: function( event ) {
2642                 this._move( "prev", "last", event );
2643         },
2644
2645         isFirstItem: function() {
2646                 return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
2647         },
2648
2649         isLastItem: function() {
2650                 return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
2651         },
2652
2653         _move: function( direction, filter, event ) {
2654                 var next;
2655                 if ( this.active ) {
2656                         if ( direction === "first" || direction === "last" ) {
2657                                 next = this.active
2658                                         [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
2659                                         .eq( -1 );
2660                         } else {
2661                                 next = this.active
2662                                         [ direction + "All" ]( ".ui-menu-item" )
2663                                         .eq( 0 );
2664                         }
2665                 }
2666                 if ( !next || !next.length || !this.active ) {
2667                         next = this.activeMenu.find( this.options.items )[ filter ]();
2668                 }
2669
2670                 this.focus( event, next );
2671         },
2672
2673         nextPage: function( event ) {
2674                 var item, base, height;
2675
2676                 if ( !this.active ) {
2677                         this.next( event );
2678                         return;
2679                 }
2680                 if ( this.isLastItem() ) {
2681                         return;
2682                 }
2683                 if ( this._hasScroll() ) {
2684                         base = this.active.offset().top;
2685                         height = this.element.height();
2686                         this.active.nextAll( ".ui-menu-item" ).each(function() {
2687                                 item = $( this );
2688                                 return item.offset().top - base - height < 0;
2689                         });
2690
2691                         this.focus( event, item );
2692                 } else {
2693                         this.focus( event, this.activeMenu.find( this.options.items )
2694                                 [ !this.active ? "first" : "last" ]() );
2695                 }
2696         },
2697
2698         previousPage: function( event ) {
2699                 var item, base, height;
2700                 if ( !this.active ) {
2701                         this.next( event );
2702                         return;
2703                 }
2704                 if ( this.isFirstItem() ) {
2705                         return;
2706                 }
2707                 if ( this._hasScroll() ) {
2708                         base = this.active.offset().top;
2709                         height = this.element.height();
2710                         this.active.prevAll( ".ui-menu-item" ).each(function() {
2711                                 item = $( this );
2712                                 return item.offset().top - base + height > 0;
2713                         });
2714
2715                         this.focus( event, item );
2716                 } else {
2717                         this.focus( event, this.activeMenu.find( this.options.items ).first() );
2718                 }
2719         },
2720
2721         _hasScroll: function() {
2722                 return this.element.outerHeight() < this.element.prop( "scrollHeight" );
2723         },
2724
2725         select: function( event ) {
2726                 // TODO: It should never be possible to not have an active item at this
2727                 // point, but the tests don't trigger mouseenter before click.
2728                 this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
2729                 var ui = { item: this.active };
2730                 if ( !this.active.has( ".ui-menu" ).length ) {
2731                         this.collapseAll( event, true );
2732                 }
2733                 this._trigger( "select", event, ui );
2734         },
2735
2736         _filterMenuItems: function(character) {
2737                 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
2738                         regex = new RegExp( "^" + escapedCharacter, "i" );
2739
2740                 return this.activeMenu
2741                         .find( this.options.items )
2742
2743                         // Only match on items, not dividers or other content (#10571)
2744                         .filter( ".ui-menu-item" )
2745                         .filter(function() {
2746                                 return regex.test( $.trim( $( this ).text() ) );
2747                         });
2748         }
2749 });
2750
2751
2752 /*!
2753  * jQuery UI Autocomplete 1.11.2
2754  * http://jqueryui.com
2755  *
2756  * Copyright 2014 jQuery Foundation and other contributors
2757  * Released under the MIT license.
2758  * http://jquery.org/license
2759  *
2760  * http://api.jqueryui.com/autocomplete/
2761  */
2762
2763
2764 $.widget( "ui.autocomplete", {
2765         version: "1.11.2",
2766         defaultElement: "<input>",
2767         options: {
2768                 appendTo: null,
2769                 autoFocus: false,
2770                 delay: 300,
2771                 minLength: 1,
2772                 position: {
2773                         my: "left top",
2774                         at: "left bottom",
2775                         collision: "none"
2776                 },
2777                 source: null,
2778
2779                 // callbacks
2780                 change: null,
2781                 close: null,
2782                 focus: null,
2783                 open: null,
2784                 response: null,
2785                 search: null,
2786                 select: null
2787         },
2788
2789         requestIndex: 0,
2790         pending: 0,
2791
2792         _create: function() {
2793                 // Some browsers only repeat keydown events, not keypress events,
2794                 // so we use the suppressKeyPress flag to determine if we've already
2795                 // handled the keydown event. #7269
2796                 // Unfortunately the code for & in keypress is the same as the up arrow,
2797                 // so we use the suppressKeyPressRepeat flag to avoid handling keypress
2798                 // events when we know the keydown event was used to modify the
2799                 // search term. #7799
2800                 var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
2801                         nodeName = this.element[ 0 ].nodeName.toLowerCase(),
2802                         isTextarea = nodeName === "textarea",
2803                         isInput = nodeName === "input";
2804
2805                 this.isMultiLine =
2806                         // Textareas are always multi-line
2807                         isTextarea ? true :
2808                         // Inputs are always single-line, even if inside a contentEditable element
2809                         // IE also treats inputs as contentEditable
2810                         isInput ? false :
2811                         // All other element types are determined by whether or not they're contentEditable
2812                         this.element.prop( "isContentEditable" );
2813
2814                 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
2815                 this.isNewMenu = true;
2816
2817                 this.element
2818                         .addClass( "ui-autocomplete-input" )
2819                         .attr( "autocomplete", "off" );
2820
2821                 this._on( this.element, {
2822                         keydown: function( event ) {
2823                                 if ( this.element.prop( "readOnly" ) ) {
2824                                         suppressKeyPress = true;
2825                                         suppressInput = true;
2826                                         suppressKeyPressRepeat = true;
2827                                         return;
2828                                 }
2829
2830                                 suppressKeyPress = false;
2831                                 suppressInput = false;
2832                                 suppressKeyPressRepeat = false;
2833                                 var keyCode = $.ui.keyCode;
2834                                 switch ( event.keyCode ) {
2835                                 case keyCode.PAGE_UP:
2836                                         suppressKeyPress = true;
2837                                         this._move( "previousPage", event );
2838                                         break;
2839                                 case keyCode.PAGE_DOWN:
2840                                         suppressKeyPress = true;
2841                                         this._move( "nextPage", event );
2842                                         break;
2843                                 case keyCode.UP:
2844                                         suppressKeyPress = true;
2845                                         this._keyEvent( "previous", event );
2846                                         break;
2847                                 case keyCode.DOWN:
2848                                         suppressKeyPress = true;
2849                                         this._keyEvent( "next", event );
2850                                         break;
2851                                 case keyCode.ENTER:
2852                                         // when menu is open and has focus
2853                                         if ( this.menu.active ) {
2854                                                 // #6055 - Opera still allows the keypress to occur
2855                                                 // which causes forms to submit
2856                                                 suppressKeyPress = true;
2857                                                 event.preventDefault();
2858                                                 this.menu.select( event );
2859                                         }
2860                                         break;
2861                                 case keyCode.TAB:
2862                                         if ( this.menu.active ) {
2863                                                 this.menu.select( event );
2864                                         }
2865                                         break;
2866                                 case keyCode.ESCAPE:
2867                                         if ( this.menu.element.is( ":visible" ) ) {
2868                                                 if ( !this.isMultiLine ) {
2869                                                         this._value( this.term );
2870                                                 }
2871                                                 this.close( event );
2872                                                 // Different browsers have different default behavior for escape
2873                                                 // Single press can mean undo or clear
2874                                                 // Double press in IE means clear the whole form
2875                                                 event.preventDefault();
2876                                         }
2877                                         break;
2878                                 default:
2879                                         suppressKeyPressRepeat = true;
2880                                         // search timeout should be triggered before the input value is changed
2881                                         this._searchTimeout( event );
2882                                         break;
2883                                 }
2884                         },
2885                         keypress: function( event ) {
2886                                 if ( suppressKeyPress ) {
2887                                         suppressKeyPress = false;
2888                                         if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
2889                                                 event.preventDefault();
2890                                         }
2891                                         return;
2892                                 }
2893                                 if ( suppressKeyPressRepeat ) {
2894                                         return;
2895                                 }
2896
2897                                 // replicate some key handlers to allow them to repeat in Firefox and Opera
2898                                 var keyCode = $.ui.keyCode;
2899                                 switch ( event.keyCode ) {
2900                                 case keyCode.PAGE_UP:
2901                                         this._move( "previousPage", event );
2902                                         break;
2903                                 case keyCode.PAGE_DOWN:
2904                                         this._move( "nextPage", event );
2905                                         break;
2906                                 case keyCode.UP:
2907                                         this._keyEvent( "previous", event );
2908                                         break;
2909                                 case keyCode.DOWN:
2910                                         this._keyEvent( "next", event );
2911                                         break;
2912                                 }
2913                         },
2914                         input: function( event ) {
2915                                 if ( suppressInput ) {
2916                                         suppressInput = false;
2917                                         event.preventDefault();
2918                                         return;
2919                                 }
2920                                 this._searchTimeout( event );
2921                         },
2922                         focus: function() {
2923                                 this.selectedItem = null;
2924                                 this.previous = this._value();
2925                         },
2926                         blur: function( event ) {
2927                                 if ( this.cancelBlur ) {
2928                                         delete this.cancelBlur;
2929                                         return;
2930                                 }
2931
2932                                 clearTimeout( this.searching );
2933                                 this.close( event );
2934                                 this._change( event );
2935                         }
2936                 });
2937
2938                 this._initSource();
2939                 this.menu = $( "<ul>" )
2940                         .addClass( "ui-autocomplete ui-front" )
2941                         .appendTo( this._appendTo() )
2942                         .menu({
2943                                 // disable ARIA support, the live region takes care of that
2944                                 role: null
2945                         })
2946                         .hide()
2947                         .menu( "instance" );
2948
2949                 this._on( this.menu.element, {
2950                         mousedown: function( event ) {
2951                                 // prevent moving focus out of the text field
2952                                 event.preventDefault();
2953
2954                                 // IE doesn't prevent moving focus even with event.preventDefault()
2955                                 // so we set a flag to know when we should ignore the blur event
2956                                 this.cancelBlur = true;
2957                                 this._delay(function() {
2958                                         delete this.cancelBlur;
2959                                 });
2960
2961                                 // clicking on the scrollbar causes focus to shift to the body
2962                                 // but we can't detect a mouseup or a click immediately afterward
2963                                 // so we have to track the next mousedown and close the menu if
2964                                 // the user clicks somewhere outside of the autocomplete
2965                                 var menuElement = this.menu.element[ 0 ];
2966                                 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
2967                                         this._delay(function() {
2968                                                 var that = this;
2969                                                 this.document.one( "mousedown", function( event ) {
2970                                                         if ( event.target !== that.element[ 0 ] &&
2971                                                                         event.target !== menuElement &&
2972                                                                         !$.contains( menuElement, event.target ) ) {
2973                                                                 that.close();
2974                                                         }
2975                                                 });
2976                                         });
2977                                 }
2978                         },
2979                         menufocus: function( event, ui ) {
2980                                 var label, item;
2981                                 // support: Firefox
2982                                 // Prevent accidental activation of menu items in Firefox (#7024 #9118)
2983                                 if ( this.isNewMenu ) {
2984                                         this.isNewMenu = false;
2985                                         if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
2986                                                 this.menu.blur();
2987
2988                                                 this.document.one( "mousemove", function() {
2989                                                         $( event.target ).trigger( event.originalEvent );
2990                                                 });
2991
2992                                                 return;
2993                                         }
2994                                 }
2995
2996                                 item = ui.item.data( "ui-autocomplete-item" );
2997                                 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
2998                                         // use value to match what will end up in the input, if it was a key event
2999                                         if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
3000                                                 this._value( item.value );
3001                                         }
3002                                 }
3003
3004                                 // Announce the value in the liveRegion
3005                                 label = ui.item.attr( "aria-label" ) || item.value;
3006                                 if ( label && $.trim( label ).length ) {
3007                                         this.liveRegion.children().hide();
3008                                         $( "<div>" ).text( label ).appendTo( this.liveRegion );
3009                                 }
3010                         },
3011                         menuselect: function( event, ui ) {
3012                                 var item = ui.item.data( "ui-autocomplete-item" ),
3013                                         previous = this.previous;
3014
3015                                 // only trigger when focus was lost (click on menu)
3016                                 if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
3017                                         this.element.focus();
3018                                         this.previous = previous;
3019                                         // #6109 - IE triggers two focus events and the second
3020                                         // is asynchronous, so we need to reset the previous
3021                                         // term synchronously and asynchronously :-(
3022                                         this._delay(function() {
3023                                                 this.previous = previous;
3024                                                 this.selectedItem = item;
3025                                         });
3026                                 }
3027
3028                                 if ( false !== this._trigger( "select", event, { item: item } ) ) {
3029                                         this._value( item.value );
3030                                 }
3031                                 // reset the term after the select event
3032                                 // this allows custom select handling to work properly
3033                                 this.term = this._value();
3034
3035                                 this.close( event );
3036                                 this.selectedItem = item;
3037                         }
3038                 });
3039
3040                 this.liveRegion = $( "<span>", {
3041                                 role: "status",
3042                                 "aria-live": "assertive",
3043                                 "aria-relevant": "additions"
3044                         })
3045                         .addClass( "ui-helper-hidden-accessible" )
3046                         .appendTo( this.document[ 0 ].body );
3047
3048                 // turning off autocomplete prevents the browser from remembering the
3049                 // value when navigating through history, so we re-enable autocomplete
3050                 // if the page is unloaded before the widget is destroyed. #7790
3051                 this._on( this.window, {
3052                         beforeunload: function() {
3053                                 this.element.removeAttr( "autocomplete" );
3054                         }
3055                 });
3056         },
3057
3058         _destroy: function() {
3059                 clearTimeout( this.searching );
3060                 this.element
3061                         .removeClass( "ui-autocomplete-input" )
3062                         .removeAttr( "autocomplete" );
3063                 this.menu.element.remove();
3064                 this.liveRegion.remove();
3065         },
3066
3067         _setOption: function( key, value ) {
3068                 this._super( key, value );
3069                 if ( key === "source" ) {
3070                         this._initSource();
3071                 }
3072                 if ( key === "appendTo" ) {
3073                         this.menu.element.appendTo( this._appendTo() );
3074                 }
3075                 if ( key === "disabled" && value && this.xhr ) {
3076                         this.xhr.abort();
3077                 }
3078         },
3079
3080         _appendTo: function() {
3081                 var element = this.options.appendTo;
3082
3083                 if ( element ) {
3084                         element = element.jquery || element.nodeType ?
3085                                 $( element ) :
3086                                 this.document.find( element ).eq( 0 );
3087                 }
3088
3089                 if ( !element || !element[ 0 ] ) {
3090                         element = this.element.closest( ".ui-front" );
3091                 }
3092
3093                 if ( !element.length ) {
3094                         element = this.document[ 0 ].body;
3095                 }
3096
3097                 return element;
3098         },
3099
3100         _initSource: function() {
3101                 var array, url,
3102                         that = this;
3103                 if ( $.isArray( this.options.source ) ) {
3104                         array = this.options.source;
3105                         this.source = function( request, response ) {
3106                                 response( $.ui.autocomplete.filter( array, request.term ) );
3107                         };
3108                 } else if ( typeof this.options.source === "string" ) {
3109                         url = this.options.source;
3110                         this.source = function( request, response ) {
3111                                 if ( that.xhr ) {
3112                                         that.xhr.abort();
3113                                 }
3114                                 that.xhr = $.ajax({
3115                                         url: url,
3116                                         data: request,
3117                                         dataType: "json",
3118                                         success: function( data ) {
3119                                                 response( data );
3120                                         },
3121                                         error: function() {
3122                                                 response([]);
3123                                         }
3124                                 });
3125                         };
3126                 } else {
3127                         this.source = this.options.source;
3128                 }
3129         },
3130
3131         _searchTimeout: function( event ) {
3132                 clearTimeout( this.searching );
3133                 this.searching = this._delay(function() {
3134
3135                         // Search if the value has changed, or if the user retypes the same value (see #7434)
3136                         var equalValues = this.term === this._value(),
3137                                 menuVisible = this.menu.element.is( ":visible" ),
3138                                 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
3139
3140                         if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
3141                                 this.selectedItem = null;
3142                                 this.search( null, event );
3143                         }
3144                 }, this.options.delay );
3145         },
3146
3147         search: function( value, event ) {
3148                 value = value != null ? value : this._value();
3149
3150                 // always save the actual value, not the one passed as an argument
3151                 this.term = this._value();
3152
3153                 if ( value.length < this.options.minLength ) {
3154                         return this.close( event );
3155                 }
3156
3157                 if ( this._trigger( "search", event ) === false ) {
3158                         return;
3159                 }
3160
3161                 return this._search( value );
3162         },
3163
3164         _search: function( value ) {
3165                 this.pending++;
3166                 this.element.addClass( "ui-autocomplete-loading" );
3167                 this.cancelSearch = false;
3168
3169                 this.source( { term: value }, this._response() );
3170         },
3171
3172         _response: function() {
3173                 var index = ++this.requestIndex;
3174
3175                 return $.proxy(function( content ) {
3176                         if ( index === this.requestIndex ) {
3177                                 this.__response( content );
3178                         }
3179
3180                         this.pending--;
3181                         if ( !this.pending ) {
3182                                 this.element.removeClass( "ui-autocomplete-loading" );
3183                         }
3184                 }, this );
3185         },
3186
3187         __response: function( content ) {
3188                 if ( content ) {
3189                         content = this._normalize( content );
3190                 }
3191                 this._trigger( "response", null, { content: content } );
3192                 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
3193                         this._suggest( content );
3194                         this._trigger( "open" );
3195                 } else {
3196                         // use ._close() instead of .close() so we don't cancel future searches
3197                         this._close();
3198                 }
3199         },
3200
3201         close: function( event ) {
3202                 this.cancelSearch = true;
3203                 this._close( event );
3204         },
3205
3206         _close: function( event ) {
3207                 if ( this.menu.element.is( ":visible" ) ) {
3208                         this.menu.element.hide();
3209                         this.menu.blur();
3210                         this.isNewMenu = true;
3211                         this._trigger( "close", event );
3212                 }
3213         },
3214
3215         _change: function( event ) {
3216                 if ( this.previous !== this._value() ) {
3217                         this._trigger( "change", event, { item: this.selectedItem } );
3218                 }
3219         },
3220
3221         _normalize: function( items ) {
3222                 // assume all items have the right format when the first item is complete
3223                 if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
3224                         return items;
3225                 }
3226                 return $.map( items, function( item ) {
3227                         if ( typeof item === "string" ) {
3228                                 return {
3229                                         label: item,
3230                                         value: item
3231                                 };
3232                         }
3233                         return $.extend( {}, item, {
3234                                 label: item.label || item.value,
3235                                 value: item.value || item.label
3236                         });
3237                 });
3238         },
3239
3240         _suggest: function( items ) {
3241                 var ul = this.menu.element.empty();
3242                 this._renderMenu( ul, items );
3243                 this.isNewMenu = true;
3244                 this.menu.refresh();
3245
3246                 // size and position menu
3247                 ul.show();
3248                 this._resizeMenu();
3249                 ul.position( $.extend({
3250                         of: this.element
3251                 }, this.options.position ) );
3252
3253                 if ( this.options.autoFocus ) {
3254                         this.menu.next();
3255                 }
3256         },
3257
3258         _resizeMenu: function() {
3259                 var ul = this.menu.element;
3260                 ul.outerWidth( Math.max(
3261                         // Firefox wraps long text (possibly a rounding bug)
3262                         // so we add 1px to avoid the wrapping (#7513)
3263                         ul.width( "" ).outerWidth() + 1,
3264                         this.element.outerWidth()
3265                 ) );
3266         },
3267
3268         _renderMenu: function( ul, items ) {
3269                 var that = this;
3270                 $.each( items, function( index, item ) {
3271                         that._renderItemData( ul, item );
3272                 });
3273         },
3274
3275         _renderItemData: function( ul, item ) {
3276                 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
3277         },
3278
3279         _renderItem: function( ul, item ) {
3280                 return $( "<li>" ).text( item.label ).appendTo( ul );
3281         },
3282
3283         _move: function( direction, event ) {
3284                 if ( !this.menu.element.is( ":visible" ) ) {
3285                         this.search( null, event );
3286                         return;
3287                 }
3288                 if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
3289                                 this.menu.isLastItem() && /^next/.test( direction ) ) {
3290
3291                         if ( !this.isMultiLine ) {
3292                                 this._value( this.term );
3293                         }
3294
3295                         this.menu.blur();
3296                         return;
3297                 }
3298                 this.menu[ direction ]( event );
3299         },
3300
3301         widget: function() {
3302                 return this.menu.element;
3303         },
3304
3305         _value: function() {
3306                 return this.valueMethod.apply( this.element, arguments );
3307         },
3308
3309         _keyEvent: function( keyEvent, event ) {
3310                 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
3311                         this._move( keyEvent, event );
3312
3313                         // prevents moving cursor to beginning/end of the text field in some browsers
3314                         event.preventDefault();
3315                 }
3316         }
3317 });
3318
3319 $.extend( $.ui.autocomplete, {
3320         escapeRegex: function( value ) {
3321                 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
3322         },
3323         filter: function( array, term ) {
3324                 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
3325                 return $.grep( array, function( value ) {
3326                         return matcher.test( value.label || value.value || value );
3327                 });
3328         }
3329 });
3330
3331 // live region extension, adding a `messages` option
3332 // NOTE: This is an experimental API. We are still investigating
3333 // a full solution for string manipulation and internationalization.
3334 $.widget( "ui.autocomplete", $.ui.autocomplete, {
3335         options: {
3336                 messages: {
3337                         noResults: "No search results.",
3338                         results: function( amount ) {
3339                                 return amount + ( amount > 1 ? " results are" : " result is" ) +
3340                                         " available, use up and down arrow keys to navigate.";
3341                         }
3342                 }
3343         },
3344
3345         __response: function( content ) {
3346                 var message;
3347                 this._superApply( arguments );
3348                 if ( this.options.disabled || this.cancelSearch ) {
3349                         return;
3350                 }
3351                 if ( content && content.length ) {
3352                         message = this.options.messages.results( content.length );
3353                 } else {
3354                         message = this.options.messages.noResults;
3355                 }
3356                 this.liveRegion.children().hide();
3357                 $( "<div>" ).text( message ).appendTo( this.liveRegion );
3358         }
3359 });
3360
3361 var autocomplete = $.ui.autocomplete;
3362
3363
3364 /*!
3365  * jQuery UI Button 1.11.2
3366  * http://jqueryui.com
3367  *
3368  * Copyright 2014 jQuery Foundation and other contributors
3369  * Released under the MIT license.
3370  * http://jquery.org/license
3371  *
3372  * http://api.jqueryui.com/button/
3373  */
3374
3375
3376 var lastActive,
3377         baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
3378         typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
3379         formResetHandler = function() {
3380                 var form = $( this );
3381                 setTimeout(function() {
3382                         form.find( ":ui-button" ).button( "refresh" );
3383                 }, 1 );
3384         },
3385         radioGroup = function( radio ) {
3386                 var name = radio.name,
3387                         form = radio.form,
3388                         radios = $( [] );
3389                 if ( name ) {
3390                         name = name.replace( /'/g, "\\'" );
3391                         if ( form ) {
3392                                 radios = $( form ).find( "[name='" + name + "'][type=radio]" );
3393                         } else {
3394                                 radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
3395                                         .filter(function() {
3396                                                 return !this.form;
3397                                         });
3398                         }
3399                 }
3400                 return radios;
3401         };
3402
3403 $.widget( "ui.button", {
3404         version: "1.11.2",
3405         defaultElement: "<button>",
3406         options: {
3407                 disabled: null,
3408                 text: true,
3409                 label: null,
3410                 icons: {
3411                         primary: null,
3412                         secondary: null
3413                 }
3414         },
3415         _create: function() {
3416                 this.element.closest( "form" )
3417                         .unbind( "reset" + this.eventNamespace )
3418                         .bind( "reset" + this.eventNamespace, formResetHandler );
3419
3420                 if ( typeof this.options.disabled !== "boolean" ) {
3421                         this.options.disabled = !!this.element.prop( "disabled" );
3422                 } else {
3423                         this.element.prop( "disabled", this.options.disabled );
3424                 }
3425
3426                 this._determineButtonType();
3427                 this.hasTitle = !!this.buttonElement.attr( "title" );
3428
3429                 var that = this,
3430                         options = this.options,
3431                         toggleButton = this.type === "checkbox" || this.type === "radio",
3432                         activeClass = !toggleButton ? "ui-state-active" : "";
3433
3434                 if ( options.label === null ) {
3435                         options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
3436                 }
3437
3438                 this._hoverable( this.buttonElement );
3439
3440                 this.buttonElement
3441                         .addClass( baseClasses )
3442                         .attr( "role", "button" )
3443                         .bind( "mouseenter" + this.eventNamespace, function() {
3444                                 if ( options.disabled ) {
3445                                         return;
3446                                 }
3447                                 if ( this === lastActive ) {
3448                                         $( this ).addClass( "ui-state-active" );
3449                                 }
3450                         })
3451                         .bind( "mouseleave" + this.eventNamespace, function() {
3452                                 if ( options.disabled ) {
3453                                         return;
3454                                 }
3455                                 $( this ).removeClass( activeClass );
3456                         })
3457                         .bind( "click" + this.eventNamespace, function( event ) {
3458                                 if ( options.disabled ) {
3459                                         event.preventDefault();
3460                                         event.stopImmediatePropagation();
3461                                 }
3462                         });
3463
3464                 // Can't use _focusable() because the element that receives focus
3465                 // and the element that gets the ui-state-focus class are different
3466                 this._on({
3467                         focus: function() {
3468                                 this.buttonElement.addClass( "ui-state-focus" );
3469                         },
3470                         blur: function() {
3471                                 this.buttonElement.removeClass( "ui-state-focus" );
3472                         }
3473                 });
3474
3475                 if ( toggleButton ) {
3476                         this.element.bind( "change" + this.eventNamespace, function() {
3477                                 that.refresh();
3478                         });
3479                 }
3480
3481                 if ( this.type === "checkbox" ) {
3482                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
3483                                 if ( options.disabled ) {
3484                                         return false;
3485                                 }
3486                         });
3487                 } else if ( this.type === "radio" ) {
3488                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
3489                                 if ( options.disabled ) {
3490                                         return false;
3491                                 }
3492                                 $( this ).addClass( "ui-state-active" );
3493                                 that.buttonElement.attr( "aria-pressed", "true" );
3494
3495                                 var radio = that.element[ 0 ];
3496                                 radioGroup( radio )
3497                                         .not( radio )
3498                                         .map(function() {
3499                                                 return $( this ).button( "widget" )[ 0 ];
3500                                         })
3501                                         .removeClass( "ui-state-active" )
3502                                         .attr( "aria-pressed", "false" );
3503                         });
3504                 } else {
3505                         this.buttonElement
3506                                 .bind( "mousedown" + this.eventNamespace, function() {
3507                                         if ( options.disabled ) {
3508                                                 return false;
3509                                         }
3510                                         $( this ).addClass( "ui-state-active" );
3511                                         lastActive = this;
3512                                         that.document.one( "mouseup", function() {
3513                                                 lastActive = null;
3514                                         });
3515                                 })
3516                                 .bind( "mouseup" + this.eventNamespace, function() {
3517                                         if ( options.disabled ) {
3518                                                 return false;
3519                                         }
3520                                         $( this ).removeClass( "ui-state-active" );
3521                                 })
3522                                 .bind( "keydown" + this.eventNamespace, function(event) {
3523                                         if ( options.disabled ) {
3524                                                 return false;
3525                                         }
3526                                         if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
3527                                                 $( this ).addClass( "ui-state-active" );
3528                                         }
3529                                 })
3530                                 // see #8559, we bind to blur here in case the button element loses
3531                                 // focus between keydown and keyup, it would be left in an "active" state
3532                                 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
3533                                         $( this ).removeClass( "ui-state-active" );
3534                                 });
3535
3536                         if ( this.buttonElement.is("a") ) {
3537                                 this.buttonElement.keyup(function(event) {
3538                                         if ( event.keyCode === $.ui.keyCode.SPACE ) {
3539                                                 // TODO pass through original event correctly (just as 2nd argument doesn't work)
3540                                                 $( this ).click();
3541                                         }
3542                                 });
3543                         }
3544                 }
3545
3546                 this._setOption( "disabled", options.disabled );
3547                 this._resetButton();
3548         },
3549
3550         _determineButtonType: function() {
3551                 var ancestor, labelSelector, checked;
3552
3553                 if ( this.element.is("[type=checkbox]") ) {
3554                         this.type = "checkbox";
3555                 } else if ( this.element.is("[type=radio]") ) {
3556                         this.type = "radio";
3557                 } else if ( this.element.is("input") ) {
3558                         this.type = "input";
3559                 } else {
3560                         this.type = "button";
3561                 }
3562
3563                 if ( this.type === "checkbox" || this.type === "radio" ) {
3564                         // we don't search against the document in case the element
3565                         // is disconnected from the DOM
3566                         ancestor = this.element.parents().last();
3567                         labelSelector = "label[for='" + this.element.attr("id") + "']";
3568                         this.buttonElement = ancestor.find( labelSelector );
3569                         if ( !this.buttonElement.length ) {
3570                                 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
3571                                 this.buttonElement = ancestor.filter( labelSelector );
3572                                 if ( !this.buttonElement.length ) {
3573                                         this.buttonElement = ancestor.find( labelSelector );
3574                                 }
3575                         }
3576                         this.element.addClass( "ui-helper-hidden-accessible" );
3577
3578                         checked = this.element.is( ":checked" );
3579                         if ( checked ) {
3580                                 this.buttonElement.addClass( "ui-state-active" );
3581                         }
3582                         this.buttonElement.prop( "aria-pressed", checked );
3583                 } else {
3584                         this.buttonElement = this.element;
3585                 }
3586         },
3587
3588         widget: function() {
3589                 return this.buttonElement;
3590         },
3591
3592         _destroy: function() {
3593                 this.element
3594                         .removeClass( "ui-helper-hidden-accessible" );
3595                 this.buttonElement
3596                         .removeClass( baseClasses + " ui-state-active " + typeClasses )
3597                         .removeAttr( "role" )
3598                         .removeAttr( "aria-pressed" )
3599                         .html( this.buttonElement.find(".ui-button-text").html() );
3600
3601                 if ( !this.hasTitle ) {
3602                         this.buttonElement.removeAttr( "title" );
3603                 }
3604         },
3605
3606         _setOption: function( key, value ) {
3607                 this._super( key, value );
3608                 if ( key === "disabled" ) {
3609                         this.widget().toggleClass( "ui-state-disabled", !!value );
3610                         this.element.prop( "disabled", !!value );
3611                         if ( value ) {
3612                                 if ( this.type === "checkbox" || this.type === "radio" ) {
3613                                         this.buttonElement.removeClass( "ui-state-focus" );
3614                                 } else {
3615                                         this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
3616                                 }
3617                         }
3618                         return;
3619                 }
3620                 this._resetButton();
3621         },
3622
3623         refresh: function() {
3624                 //See #8237 & #8828
3625                 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
3626
3627                 if ( isDisabled !== this.options.disabled ) {
3628                         this._setOption( "disabled", isDisabled );
3629                 }
3630                 if ( this.type === "radio" ) {
3631                         radioGroup( this.element[0] ).each(function() {
3632                                 if ( $( this ).is( ":checked" ) ) {
3633                                         $( this ).button( "widget" )
3634                                                 .addClass( "ui-state-active" )
3635                                                 .attr( "aria-pressed", "true" );
3636                                 } else {
3637                                         $( this ).button( "widget" )
3638                                                 .removeClass( "ui-state-active" )
3639                                                 .attr( "aria-pressed", "false" );
3640                                 }
3641                         });
3642                 } else if ( this.type === "checkbox" ) {
3643                         if ( this.element.is( ":checked" ) ) {
3644                                 this.buttonElement
3645                                         .addClass( "ui-state-active" )
3646                                         .attr( "aria-pressed", "true" );
3647                         } else {
3648                                 this.buttonElement
3649                                         .removeClass( "ui-state-active" )
3650                                         .attr( "aria-pressed", "false" );
3651                         }
3652                 }
3653         },
3654
3655         _resetButton: function() {
3656                 if ( this.type === "input" ) {
3657                         if ( this.options.label ) {
3658                                 this.element.val( this.options.label );
3659                         }
3660                         return;
3661                 }
3662                 var buttonElement = this.buttonElement.removeClass( typeClasses ),
3663                         buttonText = $( "<span></span>", this.document[0] )
3664                                 .addClass( "ui-button-text" )
3665                                 .html( this.options.label )
3666                                 .appendTo( buttonElement.empty() )
3667                                 .text(),
3668                         icons = this.options.icons,
3669                         multipleIcons = icons.primary && icons.secondary,
3670                         buttonClasses = [];
3671
3672                 if ( icons.primary || icons.secondary ) {
3673                         if ( this.options.text ) {
3674                                 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
3675                         }
3676
3677                         if ( icons.primary ) {
3678                                 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
3679                         }
3680
3681                         if ( icons.secondary ) {
3682                                 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
3683                         }
3684
3685                         if ( !this.options.text ) {
3686                                 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
3687
3688                                 if ( !this.hasTitle ) {
3689                                         buttonElement.attr( "title", $.trim( buttonText ) );
3690                                 }
3691                         }
3692                 } else {
3693                         buttonClasses.push( "ui-button-text-only" );
3694                 }
3695                 buttonElement.addClass( buttonClasses.join( " " ) );
3696         }
3697 });
3698
3699 $.widget( "ui.buttonset", {
3700         version: "1.11.2",
3701         options: {
3702                 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
3703         },
3704
3705         _create: function() {
3706                 this.element.addClass( "ui-buttonset" );
3707         },
3708
3709         _init: function() {
3710                 this.refresh();
3711         },
3712
3713         _setOption: function( key, value ) {
3714                 if ( key === "disabled" ) {
3715                         this.buttons.button( "option", key, value );
3716                 }
3717
3718                 this._super( key, value );
3719         },
3720
3721         refresh: function() {
3722                 var rtl = this.element.css( "direction" ) === "rtl",
3723                         allButtons = this.element.find( this.options.items ),
3724                         existingButtons = allButtons.filter( ":ui-button" );
3725
3726                 // Initialize new buttons
3727                 allButtons.not( ":ui-button" ).button();
3728
3729                 // Refresh existing buttons
3730                 existingButtons.button( "refresh" );
3731
3732                 this.buttons = allButtons
3733                         .map(function() {
3734                                 return $( this ).button( "widget" )[ 0 ];
3735                         })
3736                                 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
3737                                 .filter( ":first" )
3738                                         .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
3739                                 .end()
3740                                 .filter( ":last" )
3741                                         .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
3742                                 .end()
3743                         .end();
3744         },
3745
3746         _destroy: function() {
3747                 this.element.removeClass( "ui-buttonset" );
3748                 this.buttons
3749                         .map(function() {
3750                                 return $( this ).button( "widget" )[ 0 ];
3751                         })
3752                                 .removeClass( "ui-corner-left ui-corner-right" )
3753                         .end()
3754                         .button( "destroy" );
3755         }
3756 });
3757
3758 var button = $.ui.button;
3759
3760
3761 /*!
3762  * jQuery UI Datepicker 1.11.2
3763  * http://jqueryui.com
3764  *
3765  * Copyright 2014 jQuery Foundation and other contributors
3766  * Released under the MIT license.
3767  * http://jquery.org/license
3768  *
3769  * http://api.jqueryui.com/datepicker/
3770  */
3771
3772
3773 $.extend($.ui, { datepicker: { version: "1.11.2" } });
3774
3775 var datepicker_instActive;
3776
3777 function datepicker_getZindex( elem ) {
3778         var position, value;
3779         while ( elem.length && elem[ 0 ] !== document ) {
3780                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
3781                 // This makes behavior of this function consistent across browsers
3782                 // WebKit always returns auto if the element is positioned
3783                 position = elem.css( "position" );
3784                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
3785                         // IE returns 0 when zIndex is not specified
3786                         // other browsers return a string
3787                         // we ignore the case of nested elements with an explicit value of 0
3788                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
3789                         value = parseInt( elem.css( "zIndex" ), 10 );
3790                         if ( !isNaN( value ) && value !== 0 ) {
3791                                 return value;
3792                         }
3793                 }
3794                 elem = elem.parent();
3795         }
3796
3797         return 0;
3798 }
3799 /* Date picker manager.
3800    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
3801    Settings for (groups of) date pickers are maintained in an instance object,
3802    allowing multiple different settings on the same page. */
3803
3804 function Datepicker() {
3805         this._curInst = null; // The current instance in use
3806         this._keyEvent = false; // If the last event was a key event
3807         this._disabledInputs = []; // List of date picker inputs that have been disabled
3808         this._datepickerShowing = false; // True if the popup picker is showing , false if not
3809         this._inDialog = false; // True if showing within a "dialog", false if not
3810         this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
3811         this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
3812         this._appendClass = "ui-datepicker-append"; // The name of the append marker class
3813         this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
3814         this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
3815         this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
3816         this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
3817         this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
3818         this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
3819         this.regional = []; // Available regional settings, indexed by language code
3820         this.regional[""] = { // Default regional settings
3821                 closeText: "Done", // Display text for close link
3822                 prevText: "Prev", // Display text for previous month link
3823                 nextText: "Next", // Display text for next month link
3824                 currentText: "Today", // Display text for current month link
3825                 monthNames: ["January","February","March","April","May","June",
3826                         "July","August","September","October","November","December"], // Names of months for drop-down and formatting
3827                 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
3828                 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
3829                 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
3830                 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
3831                 weekHeader: "Wk", // Column header for week of the year
3832                 dateFormat: "mm/dd/yy", // See format options on parseDate
3833                 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
3834                 isRTL: false, // True if right-to-left language, false if left-to-right
3835                 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
3836                 yearSuffix: "" // Additional text to append to the year in the month headers
3837         };
3838         this._defaults = { // Global defaults for all the date picker instances
3839                 showOn: "focus", // "focus" for popup on focus,
3840                         // "button" for trigger button, or "both" for either
3841                 showAnim: "fadeIn", // Name of jQuery animation for popup
3842                 showOptions: {}, // Options for enhanced animations
3843                 defaultDate: null, // Used when field is blank: actual date,
3844                         // +/-number for offset from today, null for today
3845                 appendText: "", // Display text following the input box, e.g. showing the format
3846                 buttonText: "...", // Text for trigger button
3847                 buttonImage: "", // URL for trigger button image
3848                 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
3849                 hideIfNoPrevNext: false, // True to hide next/previous month links
3850                         // if not applicable, false to just disable them
3851                 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
3852                 gotoCurrent: false, // True if today link goes back to current selection instead
3853                 changeMonth: false, // True if month can be selected directly, false if only prev/next
3854                 changeYear: false, // True if year can be selected directly, false if only prev/next
3855                 yearRange: "c-10:c+10", // Range of years to display in drop-down,
3856                         // either relative to today's year (-nn:+nn), relative to currently displayed year
3857                         // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
3858                 showOtherMonths: false, // True to show dates in other months, false to leave blank
3859                 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
3860                 showWeek: false, // True to show week of the year, false to not show it
3861                 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
3862                         // takes a Date and returns the number of the week for it
3863                 shortYearCutoff: "+10", // Short year values < this are in the current century,
3864                         // > this are in the previous century,
3865                         // string value starting with "+" for current year + value
3866                 minDate: null, // The earliest selectable date, or null for no limit
3867                 maxDate: null, // The latest selectable date, or null for no limit
3868                 duration: "fast", // Duration of display/closure
3869                 beforeShowDay: null, // Function that takes a date and returns an array with
3870                         // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
3871                         // [2] = cell title (optional), e.g. $.datepicker.noWeekends
3872                 beforeShow: null, // Function that takes an input field and
3873                         // returns a set of custom settings for the date picker
3874                 onSelect: null, // Define a callback function when a date is selected
3875                 onChangeMonthYear: null, // Define a callback function when the month or year is changed
3876                 onClose: null, // Define a callback function when the datepicker is closed
3877                 numberOfMonths: 1, // Number of months to show at a time
3878                 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
3879                 stepMonths: 1, // Number of months to step back/forward
3880                 stepBigMonths: 12, // Number of months to step back/forward for the big links
3881                 altField: "", // Selector for an alternate field to store selected dates into
3882                 altFormat: "", // The date format to use for the alternate field
3883                 constrainInput: true, // The input is constrained by the current date format
3884                 showButtonPanel: false, // True to show button panel, false to not show it
3885                 autoSize: false, // True to size the input for the date format, false to leave as is
3886                 disabled: false // The initial disabled state
3887         };
3888         $.extend(this._defaults, this.regional[""]);
3889         this.regional.en = $.extend( true, {}, this.regional[ "" ]);
3890         this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
3891         this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
3892 }
3893
3894 $.extend(Datepicker.prototype, {
3895         /* Class name added to elements to indicate already configured with a date picker. */
3896         markerClassName: "hasDatepicker",
3897
3898         //Keep track of the maximum number of rows displayed (see #7043)
3899         maxRows: 4,
3900
3901         // TODO rename to "widget" when switching to widget factory
3902         _widgetDatepicker: function() {
3903                 return this.dpDiv;
3904         },
3905
3906         /* Override the default settings for all instances of the date picker.
3907          * @param  settings  object - the new settings to use as defaults (anonymous object)
3908          * @return the manager object
3909          */
3910         setDefaults: function(settings) {
3911                 datepicker_extendRemove(this._defaults, settings || {});
3912                 return this;
3913         },
3914
3915         /* Attach the date picker to a jQuery selection.
3916          * @param  target       element - the target input field or division or span
3917          * @param  settings  object - the new settings to use for this date picker instance (anonymous)
3918          */
3919         _attachDatepicker: function(target, settings) {
3920                 var nodeName, inline, inst;
3921                 nodeName = target.nodeName.toLowerCase();
3922                 inline = (nodeName === "div" || nodeName === "span");
3923                 if (!target.id) {
3924                         this.uuid += 1;
3925                         target.id = "dp" + this.uuid;
3926                 }
3927                 inst = this._newInst($(target), inline);
3928                 inst.settings = $.extend({}, settings || {});
3929                 if (nodeName === "input") {
3930                         this._connectDatepicker(target, inst);
3931                 } else if (inline) {
3932                         this._inlineDatepicker(target, inst);
3933                 }
3934         },
3935
3936         /* Create a new instance object. */
3937         _newInst: function(target, inline) {
3938                 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
3939                 return {id: id, input: target, // associated target
3940                         selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
3941                         drawMonth: 0, drawYear: 0, // month being drawn
3942                         inline: inline, // is datepicker inline or not
3943                         dpDiv: (!inline ? this.dpDiv : // presentation div
3944                         datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
3945         },
3946
3947         /* Attach the date picker to an input field. */
3948         _connectDatepicker: function(target, inst) {
3949                 var input = $(target);
3950                 inst.append = $([]);
3951                 inst.trigger = $([]);
3952                 if (input.hasClass(this.markerClassName)) {
3953                         return;
3954                 }
3955                 this._attachments(input, inst);
3956                 input.addClass(this.markerClassName).keydown(this._doKeyDown).
3957                         keypress(this._doKeyPress).keyup(this._doKeyUp);
3958                 this._autoSize(inst);
3959                 $.data(target, "datepicker", inst);
3960                 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
3961                 if( inst.settings.disabled ) {
3962                         this._disableDatepicker( target );
3963                 }
3964         },
3965
3966         /* Make attachments based on settings. */
3967         _attachments: function(input, inst) {
3968                 var showOn, buttonText, buttonImage,
3969                         appendText = this._get(inst, "appendText"),
3970                         isRTL = this._get(inst, "isRTL");
3971
3972                 if (inst.append) {
3973                         inst.append.remove();
3974                 }
3975                 if (appendText) {
3976                         inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
3977                         input[isRTL ? "before" : "after"](inst.append);
3978                 }
3979
3980                 input.unbind("focus", this._showDatepicker);
3981
3982                 if (inst.trigger) {
3983                         inst.trigger.remove();
3984                 }
3985
3986                 showOn = this._get(inst, "showOn");
3987                 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
3988                         input.focus(this._showDatepicker);
3989                 }
3990                 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
3991                         buttonText = this._get(inst, "buttonText");
3992                         buttonImage = this._get(inst, "buttonImage");
3993                         inst.trigger = $(this._get(inst, "buttonImageOnly") ?
3994                                 $("<img/>").addClass(this._triggerClass).
3995                                         attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
3996                                 $("<button type='button'></button>").addClass(this._triggerClass).
3997                                         html(!buttonImage ? buttonText : $("<img/>").attr(
3998                                         { src:buttonImage, alt:buttonText, title:buttonText })));
3999                         input[isRTL ? "before" : "after"](inst.trigger);
4000                         inst.trigger.click(function() {
4001                                 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
4002                                         $.datepicker._hideDatepicker();
4003                                 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
4004                                         $.datepicker._hideDatepicker();
4005                                         $.datepicker._showDatepicker(input[0]);
4006                                 } else {
4007                                         $.datepicker._showDatepicker(input[0]);
4008                                 }
4009                                 return false;
4010                         });
4011                 }
4012         },
4013
4014         /* Apply the maximum length for the date format. */
4015         _autoSize: function(inst) {
4016                 if (this._get(inst, "autoSize") && !inst.inline) {
4017                         var findMax, max, maxI, i,
4018                                 date = new Date(2009, 12 - 1, 20), // Ensure double digits
4019                                 dateFormat = this._get(inst, "dateFormat");
4020
4021                         if (dateFormat.match(/[DM]/)) {
4022                                 findMax = function(names) {
4023                                         max = 0;
4024                                         maxI = 0;
4025                                         for (i = 0; i < names.length; i++) {
4026                                                 if (names[i].length > max) {
4027                                                         max = names[i].length;
4028                                                         maxI = i;
4029                                                 }
4030                                         }
4031                                         return maxI;
4032                                 };
4033                                 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
4034                                         "monthNames" : "monthNamesShort"))));
4035                                 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
4036                                         "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
4037                         }
4038                         inst.input.attr("size", this._formatDate(inst, date).length);
4039                 }
4040         },
4041
4042         /* Attach an inline date picker to a div. */
4043         _inlineDatepicker: function(target, inst) {
4044                 var divSpan = $(target);
4045                 if (divSpan.hasClass(this.markerClassName)) {
4046                         return;
4047                 }
4048                 divSpan.addClass(this.markerClassName).append(inst.dpDiv);
4049                 $.data(target, "datepicker", inst);
4050                 this._setDate(inst, this._getDefaultDate(inst), true);
4051                 this._updateDatepicker(inst);
4052                 this._updateAlternate(inst);
4053                 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
4054                 if( inst.settings.disabled ) {
4055                         this._disableDatepicker( target );
4056                 }
4057                 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
4058                 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
4059                 inst.dpDiv.css( "display", "block" );
4060         },
4061
4062         /* Pop-up the date picker in a "dialog" box.
4063          * @param  input element - ignored
4064          * @param  date string or Date - the initial date to display
4065          * @param  onSelect  function - the function to call when a date is selected
4066          * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
4067          * @param  pos int[2] - coordinates for the dialog's position within the screen or
4068          *                                      event - with x/y coordinates or
4069          *                                      leave empty for default (screen centre)
4070          * @return the manager object
4071          */
4072         _dialogDatepicker: function(input, date, onSelect, settings, pos) {
4073                 var id, browserWidth, browserHeight, scrollX, scrollY,
4074                         inst = this._dialogInst; // internal instance
4075
4076                 if (!inst) {
4077                         this.uuid += 1;
4078                         id = "dp" + this.uuid;
4079                         this._dialogInput = $("<input type='text' id='" + id +
4080                                 "' style='position: absolute; top: -100px; width: 0px;'/>");
4081                         this._dialogInput.keydown(this._doKeyDown);
4082                         $("body").append(this._dialogInput);
4083                         inst = this._dialogInst = this._newInst(this._dialogInput, false);
4084                         inst.settings = {};
4085                         $.data(this._dialogInput[0], "datepicker", inst);
4086                 }
4087                 datepicker_extendRemove(inst.settings, settings || {});
4088                 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
4089                 this._dialogInput.val(date);
4090
4091                 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
4092                 if (!this._pos) {
4093                         browserWidth = document.documentElement.clientWidth;
4094                         browserHeight = document.documentElement.clientHeight;
4095                         scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
4096                         scrollY = document.documentElement.scrollTop || document.body.scrollTop;
4097                         this._pos = // should use actual width/height below
4098                                 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
4099                 }
4100
4101                 // move input on screen for focus, but hidden behind dialog
4102                 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
4103                 inst.settings.onSelect = onSelect;
4104                 this._inDialog = true;
4105                 this.dpDiv.addClass(this._dialogClass);
4106                 this._showDatepicker(this._dialogInput[0]);
4107                 if ($.blockUI) {
4108                         $.blockUI(this.dpDiv);
4109                 }
4110                 $.data(this._dialogInput[0], "datepicker", inst);
4111                 return this;
4112         },
4113
4114         /* Detach a datepicker from its control.
4115          * @param  target       element - the target input field or division or span
4116          */
4117         _destroyDatepicker: function(target) {
4118                 var nodeName,
4119                         $target = $(target),
4120                         inst = $.data(target, "datepicker");
4121
4122                 if (!$target.hasClass(this.markerClassName)) {
4123                         return;
4124                 }
4125
4126                 nodeName = target.nodeName.toLowerCase();
4127                 $.removeData(target, "datepicker");
4128                 if (nodeName === "input") {
4129                         inst.append.remove();
4130                         inst.trigger.remove();
4131                         $target.removeClass(this.markerClassName).
4132                                 unbind("focus", this._showDatepicker).
4133                                 unbind("keydown", this._doKeyDown).
4134                                 unbind("keypress", this._doKeyPress).
4135                                 unbind("keyup", this._doKeyUp);
4136                 } else if (nodeName === "div" || nodeName === "span") {
4137                         $target.removeClass(this.markerClassName).empty();
4138                 }
4139         },
4140
4141         /* Enable the date picker to a jQuery selection.
4142          * @param  target       element - the target input field or division or span
4143          */
4144         _enableDatepicker: function(target) {
4145                 var nodeName, inline,
4146                         $target = $(target),
4147                         inst = $.data(target, "datepicker");
4148
4149                 if (!$target.hasClass(this.markerClassName)) {
4150                         return;
4151                 }
4152
4153                 nodeName = target.nodeName.toLowerCase();
4154                 if (nodeName === "input") {
4155                         target.disabled = false;
4156                         inst.trigger.filter("button").
4157                                 each(function() { this.disabled = false; }).end().
4158                                 filter("img").css({opacity: "1.0", cursor: ""});
4159                 } else if (nodeName === "div" || nodeName === "span") {
4160                         inline = $target.children("." + this._inlineClass);
4161                         inline.children().removeClass("ui-state-disabled");
4162                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4163                                 prop("disabled", false);
4164                 }
4165                 this._disabledInputs = $.map(this._disabledInputs,
4166                         function(value) { return (value === target ? null : value); }); // delete entry
4167         },
4168
4169         /* Disable the date picker to a jQuery selection.
4170          * @param  target       element - the target input field or division or span
4171          */
4172         _disableDatepicker: function(target) {
4173                 var nodeName, inline,
4174                         $target = $(target),
4175                         inst = $.data(target, "datepicker");
4176
4177                 if (!$target.hasClass(this.markerClassName)) {
4178                         return;
4179                 }
4180
4181                 nodeName = target.nodeName.toLowerCase();
4182                 if (nodeName === "input") {
4183                         target.disabled = true;
4184                         inst.trigger.filter("button").
4185                                 each(function() { this.disabled = true; }).end().
4186                                 filter("img").css({opacity: "0.5", cursor: "default"});
4187                 } else if (nodeName === "div" || nodeName === "span") {
4188                         inline = $target.children("." + this._inlineClass);
4189                         inline.children().addClass("ui-state-disabled");
4190                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4191                                 prop("disabled", true);
4192                 }
4193                 this._disabledInputs = $.map(this._disabledInputs,
4194                         function(value) { return (value === target ? null : value); }); // delete entry
4195                 this._disabledInputs[this._disabledInputs.length] = target;
4196         },
4197
4198         /* Is the first field in a jQuery collection disabled as a datepicker?
4199          * @param  target       element - the target input field or division or span
4200          * @return boolean - true if disabled, false if enabled
4201          */
4202         _isDisabledDatepicker: function(target) {
4203                 if (!target) {
4204                         return false;
4205                 }
4206                 for (var i = 0; i < this._disabledInputs.length; i++) {
4207                         if (this._disabledInputs[i] === target) {
4208                                 return true;
4209                         }
4210                 }
4211                 return false;
4212         },
4213
4214         /* Retrieve the instance data for the target control.
4215          * @param  target  element - the target input field or division or span
4216          * @return  object - the associated instance data
4217          * @throws  error if a jQuery problem getting data
4218          */
4219         _getInst: function(target) {
4220                 try {
4221                         return $.data(target, "datepicker");
4222                 }
4223                 catch (err) {
4224                         throw "Missing instance data for this datepicker";
4225                 }
4226         },
4227
4228         /* Update or retrieve the settings for a date picker attached to an input field or division.
4229          * @param  target  element - the target input field or division or span
4230          * @param  name object - the new settings to update or
4231          *                              string - the name of the setting to change or retrieve,
4232          *                              when retrieving also "all" for all instance settings or
4233          *                              "defaults" for all global defaults
4234          * @param  value   any - the new value for the setting
4235          *                              (omit if above is an object or to retrieve a value)
4236          */
4237         _optionDatepicker: function(target, name, value) {
4238                 var settings, date, minDate, maxDate,
4239                         inst = this._getInst(target);
4240
4241                 if (arguments.length === 2 && typeof name === "string") {
4242                         return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
4243                                 (inst ? (name === "all" ? $.extend({}, inst.settings) :
4244                                 this._get(inst, name)) : null));
4245                 }
4246
4247                 settings = name || {};
4248                 if (typeof name === "string") {
4249                         settings = {};
4250                         settings[name] = value;
4251                 }
4252
4253                 if (inst) {
4254                         if (this._curInst === inst) {
4255                                 this._hideDatepicker();
4256                         }
4257
4258                         date = this._getDateDatepicker(target, true);
4259                         minDate = this._getMinMaxDate(inst, "min");
4260                         maxDate = this._getMinMaxDate(inst, "max");
4261                         datepicker_extendRemove(inst.settings, settings);
4262                         // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
4263                         if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
4264                                 inst.settings.minDate = this._formatDate(inst, minDate);
4265                         }
4266                         if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
4267                                 inst.settings.maxDate = this._formatDate(inst, maxDate);
4268                         }
4269                         if ( "disabled" in settings ) {
4270                                 if ( settings.disabled ) {
4271                                         this._disableDatepicker(target);
4272                                 } else {
4273                                         this._enableDatepicker(target);
4274                                 }
4275                         }
4276                         this._attachments($(target), inst);
4277                         this._autoSize(inst);
4278                         this._setDate(inst, date);
4279                         this._updateAlternate(inst);
4280                         this._updateDatepicker(inst);
4281                 }
4282         },
4283
4284         // change method deprecated
4285         _changeDatepicker: function(target, name, value) {
4286                 this._optionDatepicker(target, name, value);
4287         },
4288
4289         /* Redraw the date picker attached to an input field or division.
4290          * @param  target  element - the target input field or division or span
4291          */
4292         _refreshDatepicker: function(target) {
4293                 var inst = this._getInst(target);
4294                 if (inst) {
4295                         this._updateDatepicker(inst);
4296                 }
4297         },
4298
4299         /* Set the dates for a jQuery selection.
4300          * @param  target element - the target input field or division or span
4301          * @param  date Date - the new date
4302          */
4303         _setDateDatepicker: function(target, date) {
4304                 var inst = this._getInst(target);
4305                 if (inst) {
4306                         this._setDate(inst, date);
4307                         this._updateDatepicker(inst);
4308                         this._updateAlternate(inst);
4309                 }
4310         },
4311
4312         /* Get the date(s) for the first entry in a jQuery selection.
4313          * @param  target element - the target input field or division or span
4314          * @param  noDefault boolean - true if no default date is to be used
4315          * @return Date - the current date
4316          */
4317         _getDateDatepicker: function(target, noDefault) {
4318                 var inst = this._getInst(target);
4319                 if (inst && !inst.inline) {
4320                         this._setDateFromField(inst, noDefault);
4321                 }
4322                 return (inst ? this._getDate(inst) : null);
4323         },
4324
4325         /* Handle keystrokes. */
4326         _doKeyDown: function(event) {
4327                 var onSelect, dateStr, sel,
4328                         inst = $.datepicker._getInst(event.target),
4329                         handled = true,
4330                         isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
4331
4332                 inst._keyEvent = true;
4333                 if ($.datepicker._datepickerShowing) {
4334                         switch (event.keyCode) {
4335                                 case 9: $.datepicker._hideDatepicker();
4336                                                 handled = false;
4337                                                 break; // hide on tab out
4338                                 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
4339                                                                         $.datepicker._currentClass + ")", inst.dpDiv);
4340                                                 if (sel[0]) {
4341                                                         $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
4342                                                 }
4343
4344                                                 onSelect = $.datepicker._get(inst, "onSelect");
4345                                                 if (onSelect) {
4346                                                         dateStr = $.datepicker._formatDate(inst);
4347
4348                                                         // trigger custom callback
4349                                                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
4350                                                 } else {
4351                                                         $.datepicker._hideDatepicker();
4352                                                 }
4353
4354                                                 return false; // don't submit the form
4355                                 case 27: $.datepicker._hideDatepicker();
4356                                                 break; // hide on escape
4357                                 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4358                                                         -$.datepicker._get(inst, "stepBigMonths") :
4359                                                         -$.datepicker._get(inst, "stepMonths")), "M");
4360                                                 break; // previous month/year on page up/+ ctrl
4361                                 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4362                                                         +$.datepicker._get(inst, "stepBigMonths") :
4363                                                         +$.datepicker._get(inst, "stepMonths")), "M");
4364                                                 break; // next month/year on page down/+ ctrl
4365                                 case 35: if (event.ctrlKey || event.metaKey) {
4366                                                         $.datepicker._clearDate(event.target);
4367                                                 }
4368                                                 handled = event.ctrlKey || event.metaKey;
4369                                                 break; // clear on ctrl or command +end
4370                                 case 36: if (event.ctrlKey || event.metaKey) {
4371                                                         $.datepicker._gotoToday(event.target);
4372                                                 }
4373                                                 handled = event.ctrlKey || event.metaKey;
4374                                                 break; // current on ctrl or command +home
4375                                 case 37: if (event.ctrlKey || event.metaKey) {
4376                                                         $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
4377                                                 }
4378                                                 handled = event.ctrlKey || event.metaKey;
4379                                                 // -1 day on ctrl or command +left
4380                                                 if (event.originalEvent.altKey) {
4381                                                         $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4382                                                                 -$.datepicker._get(inst, "stepBigMonths") :
4383                                                                 -$.datepicker._get(inst, "stepMonths")), "M");
4384                                                 }
4385                                                 // next month/year on alt +left on Mac
4386                                                 break;
4387                                 case 38: if (event.ctrlKey || event.metaKey) {
4388                                                         $.datepicker._adjustDate(event.target, -7, "D");
4389                                                 }
4390                                                 handled = event.ctrlKey || event.metaKey;
4391                                                 break; // -1 week on ctrl or command +up
4392                                 case 39: if (event.ctrlKey || event.metaKey) {
4393                                                         $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
4394                                                 }
4395                                                 handled = event.ctrlKey || event.metaKey;
4396                                                 // +1 day on ctrl or command +right
4397                                                 if (event.originalEvent.altKey) {
4398                                                         $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4399                                                                 +$.datepicker._get(inst, "stepBigMonths") :
4400                                                                 +$.datepicker._get(inst, "stepMonths")), "M");
4401                                                 }
4402                                                 // next month/year on alt +right
4403                                                 break;
4404                                 case 40: if (event.ctrlKey || event.metaKey) {
4405                                                         $.datepicker._adjustDate(event.target, +7, "D");
4406                                                 }
4407                                                 handled = event.ctrlKey || event.metaKey;
4408                                                 break; // +1 week on ctrl or command +down
4409                                 default: handled = false;
4410                         }
4411                 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
4412                         $.datepicker._showDatepicker(this);
4413                 } else {
4414                         handled = false;
4415                 }
4416
4417                 if (handled) {
4418                         event.preventDefault();
4419                         event.stopPropagation();
4420                 }
4421         },
4422
4423         /* Filter entered characters - based on date format. */
4424         _doKeyPress: function(event) {
4425                 var chars, chr,
4426                         inst = $.datepicker._getInst(event.target);
4427
4428                 if ($.datepicker._get(inst, "constrainInput")) {
4429                         chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
4430                         chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
4431                         return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
4432                 }
4433         },
4434
4435         /* Synchronise manual entry and field/alternate field. */
4436         _doKeyUp: function(event) {
4437                 var date,
4438                         inst = $.datepicker._getInst(event.target);
4439
4440                 if (inst.input.val() !== inst.lastVal) {
4441                         try {
4442                                 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
4443                                         (inst.input ? inst.input.val() : null),
4444                                         $.datepicker._getFormatConfig(inst));
4445
4446                                 if (date) { // only if valid
4447                                         $.datepicker._setDateFromField(inst);
4448                                         $.datepicker._updateAlternate(inst);
4449                                         $.datepicker._updateDatepicker(inst);
4450                                 }
4451                         }
4452                         catch (err) {
4453                         }
4454                 }
4455                 return true;
4456         },
4457
4458         /* Pop-up the date picker for a given input field.
4459          * If false returned from beforeShow event handler do not show.
4460          * @param  input  element - the input field attached to the date picker or
4461          *                                      event - if triggered by focus
4462          */
4463         _showDatepicker: function(input) {
4464                 input = input.target || input;
4465                 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
4466                         input = $("input", input.parentNode)[0];
4467                 }
4468
4469                 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
4470                         return;
4471                 }
4472
4473                 var inst, beforeShow, beforeShowSettings, isFixed,
4474                         offset, showAnim, duration;
4475
4476                 inst = $.datepicker._getInst(input);
4477                 if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
4478                         $.datepicker._curInst.dpDiv.stop(true, true);
4479                         if ( inst && $.datepicker._datepickerShowing ) {
4480                                 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
4481                         }
4482                 }
4483
4484                 beforeShow = $.datepicker._get(inst, "beforeShow");
4485                 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
4486                 if(beforeShowSettings === false){
4487                         return;
4488                 }
4489                 datepicker_extendRemove(inst.settings, beforeShowSettings);
4490
4491                 inst.lastVal = null;
4492                 $.datepicker._lastInput = input;
4493                 $.datepicker._setDateFromField(inst);
4494
4495                 if ($.datepicker._inDialog) { // hide cursor
4496                         input.value = "";
4497                 }
4498                 if (!$.datepicker._pos) { // position below input
4499                         $.datepicker._pos = $.datepicker._findPos(input);
4500                         $.datepicker._pos[1] += input.offsetHeight; // add the height
4501                 }
4502
4503                 isFixed = false;
4504                 $(input).parents().each(function() {
4505                         isFixed |= $(this).css("position") === "fixed";
4506                         return !isFixed;
4507                 });
4508
4509                 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
4510                 $.datepicker._pos = null;
4511                 //to avoid flashes on Firefox
4512                 inst.dpDiv.empty();
4513                 // determine sizing offscreen
4514                 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
4515                 $.datepicker._updateDatepicker(inst);
4516                 // fix width for dynamic number of date pickers
4517                 // and adjust position before showing
4518                 offset = $.datepicker._checkOffset(inst, offset, isFixed);
4519                 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
4520                         "static" : (isFixed ? "fixed" : "absolute")), display: "none",
4521                         left: offset.left + "px", top: offset.top + "px"});
4522
4523                 if (!inst.inline) {
4524                         showAnim = $.datepicker._get(inst, "showAnim");
4525                         duration = $.datepicker._get(inst, "duration");
4526                         inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
4527                         $.datepicker._datepickerShowing = true;
4528
4529                         if ( $.effects && $.effects.effect[ showAnim ] ) {
4530                                 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
4531                         } else {
4532                                 inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
4533                         }
4534
4535                         if ( $.datepicker._shouldFocusInput( inst ) ) {
4536                                 inst.input.focus();
4537                         }
4538
4539                         $.datepicker._curInst = inst;
4540                 }
4541         },
4542
4543         /* Generate the date picker content. */
4544         _updateDatepicker: function(inst) {
4545                 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
4546                 datepicker_instActive = inst; // for delegate hover events
4547                 inst.dpDiv.empty().append(this._generateHTML(inst));
4548                 this._attachHandlers(inst);
4549
4550                 var origyearshtml,
4551                         numMonths = this._getNumberOfMonths(inst),
4552                         cols = numMonths[1],
4553                         width = 17,
4554                         activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
4555
4556                 if ( activeCell.length > 0 ) {
4557                         datepicker_handleMouseover.apply( activeCell.get( 0 ) );
4558                 }
4559
4560                 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
4561                 if (cols > 1) {
4562                         inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
4563                 }
4564                 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
4565                         "Class"]("ui-datepicker-multi");
4566                 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
4567                         "Class"]("ui-datepicker-rtl");
4568
4569                 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
4570                         inst.input.focus();
4571                 }
4572
4573                 // deffered render of the years select (to avoid flashes on Firefox)
4574                 if( inst.yearshtml ){
4575                         origyearshtml = inst.yearshtml;
4576                         setTimeout(function(){
4577                                 //assure that inst.yearshtml didn't change.
4578                                 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
4579                                         inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
4580                                 }
4581                                 origyearshtml = inst.yearshtml = null;
4582                         }, 0);
4583                 }
4584         },
4585
4586         // #6694 - don't focus the input if it's already focused
4587         // this breaks the change event in IE
4588         // Support: IE and jQuery <1.9
4589         _shouldFocusInput: function( inst ) {
4590                 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
4591         },
4592
4593         /* Check positioning to remain on screen. */
4594         _checkOffset: function(inst, offset, isFixed) {
4595                 var dpWidth = inst.dpDiv.outerWidth(),
4596                         dpHeight = inst.dpDiv.outerHeight(),
4597                         inputWidth = inst.input ? inst.input.outerWidth() : 0,
4598                         inputHeight = inst.input ? inst.input.outerHeight() : 0,
4599                         viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
4600                         viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
4601
4602                 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
4603                 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
4604                 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
4605
4606                 // now check if datepicker is showing outside window viewport - move to a better place if so.
4607                 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
4608                         Math.abs(offset.left + dpWidth - viewWidth) : 0);
4609                 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
4610                         Math.abs(dpHeight + inputHeight) : 0);
4611
4612                 return offset;
4613         },
4614
4615         /* Find an object's position on the screen. */
4616         _findPos: function(obj) {
4617                 var position,
4618                         inst = this._getInst(obj),
4619                         isRTL = this._get(inst, "isRTL");
4620
4621                 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
4622                         obj = obj[isRTL ? "previousSibling" : "nextSibling"];
4623                 }
4624
4625                 position = $(obj).offset();
4626                 return [position.left, position.top];
4627         },
4628
4629         /* Hide the date picker from view.
4630          * @param  input  element - the input field attached to the date picker
4631          */
4632         _hideDatepicker: function(input) {
4633                 var showAnim, duration, postProcess, onClose,
4634                         inst = this._curInst;
4635
4636                 if (!inst || (input && inst !== $.data(input, "datepicker"))) {
4637                         return;
4638                 }
4639
4640                 if (this._datepickerShowing) {
4641                         showAnim = this._get(inst, "showAnim");
4642                         duration = this._get(inst, "duration");
4643                         postProcess = function() {
4644                                 $.datepicker._tidyDialog(inst);
4645                         };
4646
4647                         // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
4648                         if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
4649                                 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
4650                         } else {
4651                                 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
4652                                         (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
4653                         }
4654
4655                         if (!showAnim) {
4656                                 postProcess();
4657                         }
4658                         this._datepickerShowing = false;
4659
4660                         onClose = this._get(inst, "onClose");
4661                         if (onClose) {
4662                                 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
4663                         }
4664
4665                         this._lastInput = null;
4666                         if (this._inDialog) {
4667                                 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
4668                                 if ($.blockUI) {
4669                                         $.unblockUI();
4670                                         $("body").append(this.dpDiv);
4671                                 }
4672                         }
4673                         this._inDialog = false;
4674                 }
4675         },
4676
4677         /* Tidy up after a dialog display. */
4678         _tidyDialog: function(inst) {
4679                 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
4680         },
4681
4682         /* Close date picker if clicked elsewhere. */
4683         _checkExternalClick: function(event) {
4684                 if (!$.datepicker._curInst) {
4685                         return;
4686                 }
4687
4688                 var $target = $(event.target),
4689                         inst = $.datepicker._getInst($target[0]);
4690
4691                 if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
4692                                 $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
4693                                 !$target.hasClass($.datepicker.markerClassName) &&
4694                                 !$target.closest("." + $.datepicker._triggerClass).length &&
4695                                 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
4696                         ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
4697                                 $.datepicker._hideDatepicker();
4698                 }
4699         },
4700
4701         /* Adjust one of the date sub-fields. */
4702         _adjustDate: function(id, offset, period) {
4703                 var target = $(id),
4704                         inst = this._getInst(target[0]);
4705
4706                 if (this._isDisabledDatepicker(target[0])) {
4707                         return;
4708                 }
4709                 this._adjustInstDate(inst, offset +
4710                         (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
4711                         period);
4712                 this._updateDatepicker(inst);
4713         },
4714
4715         /* Action for current link. */
4716         _gotoToday: function(id) {
4717                 var date,
4718                         target = $(id),
4719                         inst = this._getInst(target[0]);
4720
4721                 if (this._get(inst, "gotoCurrent") && inst.currentDay) {
4722                         inst.selectedDay = inst.currentDay;
4723                         inst.drawMonth = inst.selectedMonth = inst.currentMonth;
4724                         inst.drawYear = inst.selectedYear = inst.currentYear;
4725                 } else {
4726                         date = new Date();
4727                         inst.selectedDay = date.getDate();
4728                         inst.drawMonth = inst.selectedMonth = date.getMonth();
4729                         inst.drawYear = inst.selectedYear = date.getFullYear();
4730                 }
4731                 this._notifyChange(inst);
4732                 this._adjustDate(target);
4733         },
4734
4735         /* Action for selecting a new month/year. */
4736         _selectMonthYear: function(id, select, period) {
4737                 var target = $(id),
4738                         inst = this._getInst(target[0]);
4739
4740                 inst["selected" + (period === "M" ? "Month" : "Year")] =
4741                 inst["draw" + (period === "M" ? "Month" : "Year")] =
4742                         parseInt(select.options[select.selectedIndex].value,10);
4743
4744                 this._notifyChange(inst);
4745                 this._adjustDate(target);
4746         },
4747
4748         /* Action for selecting a day. */
4749         _selectDay: function(id, month, year, td) {
4750                 var inst,
4751                         target = $(id);
4752
4753                 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
4754                         return;
4755                 }
4756
4757                 inst = this._getInst(target[0]);
4758                 inst.selectedDay = inst.currentDay = $("a", td).html();
4759                 inst.selectedMonth = inst.currentMonth = month;
4760                 inst.selectedYear = inst.currentYear = year;
4761                 this._selectDate(id, this._formatDate(inst,
4762                         inst.currentDay, inst.currentMonth, inst.currentYear));
4763         },
4764
4765         /* Erase the input field and hide the date picker. */
4766         _clearDate: function(id) {
4767                 var target = $(id);
4768                 this._selectDate(target, "");
4769         },
4770
4771         /* Update the input field with the selected date. */
4772         _selectDate: function(id, dateStr) {
4773                 var onSelect,
4774                         target = $(id),
4775                         inst = this._getInst(target[0]);
4776
4777                 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
4778                 if (inst.input) {
4779                         inst.input.val(dateStr);
4780                 }
4781                 this._updateAlternate(inst);
4782
4783                 onSelect = this._get(inst, "onSelect");
4784                 if (onSelect) {
4785                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
4786                 } else if (inst.input) {
4787                         inst.input.trigger("change"); // fire the change event
4788                 }
4789
4790                 if (inst.inline){
4791                         this._updateDatepicker(inst);
4792                 } else {
4793                         this._hideDatepicker();
4794                         this._lastInput = inst.input[0];
4795                         if (typeof(inst.input[0]) !== "object") {
4796                                 inst.input.focus(); // restore focus
4797                         }
4798                         this._lastInput = null;
4799                 }
4800         },
4801
4802         /* Update any alternate field to synchronise with the main field. */
4803         _updateAlternate: function(inst) {
4804                 var altFormat, date, dateStr,
4805                         altField = this._get(inst, "altField");
4806
4807                 if (altField) { // update alternate field too
4808                         altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
4809                         date = this._getDate(inst);
4810                         dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
4811                         $(altField).each(function() { $(this).val(dateStr); });
4812                 }
4813         },
4814
4815         /* Set as beforeShowDay function to prevent selection of weekends.
4816          * @param  date  Date - the date to customise
4817          * @return [boolean, string] - is this date selectable?, what is its CSS class?
4818          */
4819         noWeekends: function(date) {
4820                 var day = date.getDay();
4821                 return [(day > 0 && day < 6), ""];
4822         },
4823
4824         /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
4825          * @param  date  Date - the date to get the week for
4826          * @return  number - the number of the week within the year that contains this date
4827          */
4828         iso8601Week: function(date) {
4829                 var time,
4830                         checkDate = new Date(date.getTime());
4831
4832                 // Find Thursday of this week starting on Monday
4833                 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
4834
4835                 time = checkDate.getTime();
4836                 checkDate.setMonth(0); // Compare with Jan 1
4837                 checkDate.setDate(1);
4838                 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
4839         },
4840
4841         /* Parse a string value into a date object.
4842          * See formatDate below for the possible formats.
4843          *
4844          * @param  format string - the expected format of the date
4845          * @param  value string - the date in the above format
4846          * @param  settings Object - attributes include:
4847          *                                      shortYearCutoff  number - the cutoff year for determining the century (optional)
4848          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
4849          *                                      dayNames                string[7] - names of the days from Sunday (optional)
4850          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
4851          *                                      monthNames              string[12] - names of the months (optional)
4852          * @return  Date - the extracted date value or null if value is blank
4853          */
4854         parseDate: function (format, value, settings) {
4855                 if (format == null || value == null) {
4856                         throw "Invalid arguments";
4857                 }
4858
4859                 value = (typeof value === "object" ? value.toString() : value + "");
4860                 if (value === "") {
4861                         return null;
4862                 }
4863
4864                 var iFormat, dim, extra,
4865                         iValue = 0,
4866                         shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
4867                         shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
4868                                 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
4869                         dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
4870                         dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
4871                         monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
4872                         monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
4873                         year = -1,
4874                         month = -1,
4875                         day = -1,
4876                         doy = -1,
4877                         literal = false,
4878                         date,
4879                         // Check whether a format character is doubled
4880                         lookAhead = function(match) {
4881                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
4882                                 if (matches) {
4883                                         iFormat++;
4884                                 }
4885                                 return matches;
4886                         },
4887                         // Extract a number from the string value
4888                         getNumber = function(match) {
4889                                 var isDoubled = lookAhead(match),
4890                                         size = (match === "@" ? 14 : (match === "!" ? 20 :
4891                                         (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
4892                                         minSize = (match === "y" ? size : 1),
4893                                         digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
4894                                         num = value.substring(iValue).match(digits);
4895                                 if (!num) {
4896                                         throw "Missing number at position " + iValue;
4897                                 }
4898                                 iValue += num[0].length;
4899                                 return parseInt(num[0], 10);
4900                         },
4901                         // Extract a name from the string value and convert to an index
4902                         getName = function(match, shortNames, longNames) {
4903                                 var index = -1,
4904                                         names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
4905                                                 return [ [k, v] ];
4906                                         }).sort(function (a, b) {
4907                                                 return -(a[1].length - b[1].length);
4908                                         });
4909
4910                                 $.each(names, function (i, pair) {
4911                                         var name = pair[1];
4912                                         if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
4913                                                 index = pair[0];
4914                                                 iValue += name.length;
4915                                                 return false;
4916                                         }
4917                                 });
4918                                 if (index !== -1) {
4919                                         return index + 1;
4920                                 } else {
4921                                         throw "Unknown name at position " + iValue;
4922                                 }
4923                         },
4924                         // Confirm that a literal character matches the string value
4925                         checkLiteral = function() {
4926                                 if (value.charAt(iValue) !== format.charAt(iFormat)) {
4927                                         throw "Unexpected literal at position " + iValue;
4928                                 }
4929                                 iValue++;
4930                         };
4931
4932                 for (iFormat = 0; iFormat < format.length; iFormat++) {
4933                         if (literal) {
4934                                 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
4935                                         literal = false;
4936                                 } else {
4937                                         checkLiteral();
4938                                 }
4939                         } else {
4940                                 switch (format.charAt(iFormat)) {
4941                                         case "d":
4942                                                 day = getNumber("d");
4943                                                 break;
4944                                         case "D":
4945                                                 getName("D", dayNamesShort, dayNames);
4946                                                 break;
4947                                         case "o":
4948                                                 doy = getNumber("o");
4949                                                 break;
4950                                         case "m":
4951                                                 month = getNumber("m");
4952                                                 break;
4953                                         case "M":
4954                                                 month = getName("M", monthNamesShort, monthNames);
4955                                                 break;
4956                                         case "y":
4957                                                 year = getNumber("y");
4958                                                 break;
4959                                         case "@":
4960                                                 date = new Date(getNumber("@"));
4961                                                 year = date.getFullYear();
4962                                                 month = date.getMonth() + 1;
4963                                                 day = date.getDate();
4964                                                 break;
4965                                         case "!":
4966                                                 date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
4967                                                 year = date.getFullYear();
4968                                                 month = date.getMonth() + 1;
4969                                                 day = date.getDate();
4970                                                 break;
4971                                         case "'":
4972                                                 if (lookAhead("'")){
4973                                                         checkLiteral();
4974                                                 } else {
4975                                                         literal = true;
4976                                                 }
4977                                                 break;
4978                                         default:
4979                                                 checkLiteral();
4980                                 }
4981                         }
4982                 }
4983
4984                 if (iValue < value.length){
4985                         extra = value.substr(iValue);
4986                         if (!/^\s+/.test(extra)) {
4987                                 throw "Extra/unparsed characters found in date: " + extra;
4988                         }
4989                 }
4990
4991                 if (year === -1) {
4992                         year = new Date().getFullYear();
4993                 } else if (year < 100) {
4994                         year += new Date().getFullYear() - new Date().getFullYear() % 100 +
4995                                 (year <= shortYearCutoff ? 0 : -100);
4996                 }
4997
4998                 if (doy > -1) {
4999                         month = 1;
5000                         day = doy;
5001                         do {
5002                                 dim = this._getDaysInMonth(year, month - 1);
5003                                 if (day <= dim) {
5004                                         break;
5005                                 }
5006                                 month++;
5007                                 day -= dim;
5008                         } while (true);
5009                 }
5010
5011                 date = this._daylightSavingAdjust(new Date(year, month - 1, day));
5012                 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
5013                         throw "Invalid date"; // E.g. 31/02/00
5014                 }
5015                 return date;
5016         },
5017
5018         /* Standard date formats. */
5019         ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
5020         COOKIE: "D, dd M yy",
5021         ISO_8601: "yy-mm-dd",
5022         RFC_822: "D, d M y",
5023         RFC_850: "DD, dd-M-y",
5024         RFC_1036: "D, d M y",
5025         RFC_1123: "D, d M yy",
5026         RFC_2822: "D, d M yy",
5027         RSS: "D, d M y", // RFC 822
5028         TICKS: "!",
5029         TIMESTAMP: "@",
5030         W3C: "yy-mm-dd", // ISO 8601
5031
5032         _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
5033                 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
5034
5035         /* Format a date object into a string value.
5036          * The format can be combinations of the following:
5037          * d  - day of month (no leading zero)
5038          * dd - day of month (two digit)
5039          * o  - day of year (no leading zeros)
5040          * oo - day of year (three digit)
5041          * D  - day name short
5042          * DD - day name long
5043          * m  - month of year (no leading zero)
5044          * mm - month of year (two digit)
5045          * M  - month name short
5046          * MM - month name long
5047          * y  - year (two digit)
5048          * yy - year (four digit)
5049          * @ - Unix timestamp (ms since 01/01/1970)
5050          * ! - Windows ticks (100ns since 01/01/0001)
5051          * "..." - literal text
5052          * '' - single quote
5053          *
5054          * @param  format string - the desired format of the date
5055          * @param  date Date - the date value to format
5056          * @param  settings Object - attributes include:
5057          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
5058          *                                      dayNames                string[7] - names of the days from Sunday (optional)
5059          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
5060          *                                      monthNames              string[12] - names of the months (optional)
5061          * @return  string - the date in the above format
5062          */
5063         formatDate: function (format, date, settings) {
5064                 if (!date) {
5065                         return "";
5066                 }
5067
5068                 var iFormat,
5069                         dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
5070                         dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
5071                         monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
5072                         monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
5073                         // Check whether a format character is doubled
5074                         lookAhead = function(match) {
5075                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5076                                 if (matches) {
5077                                         iFormat++;
5078                                 }
5079                                 return matches;
5080                         },
5081                         // Format a number, with leading zero if necessary
5082                         formatNumber = function(match, value, len) {
5083                                 var num = "" + value;
5084                                 if (lookAhead(match)) {
5085                                         while (num.length < len) {
5086                                                 num = "0" + num;
5087                                         }
5088                                 }
5089                                 return num;
5090                         },
5091                         // Format a name, short or long as requested
5092                         formatName = function(match, value, shortNames, longNames) {
5093                                 return (lookAhead(match) ? longNames[value] : shortNames[value]);
5094                         },
5095                         output = "",
5096                         literal = false;
5097
5098                 if (date) {
5099                         for (iFormat = 0; iFormat < format.length; iFormat++) {
5100                                 if (literal) {
5101                                         if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5102                                                 literal = false;
5103                                         } else {
5104                                                 output += format.charAt(iFormat);
5105                                         }
5106                                 } else {
5107                                         switch (format.charAt(iFormat)) {
5108                                                 case "d":
5109                                                         output += formatNumber("d", date.getDate(), 2);
5110                                                         break;
5111                                                 case "D":
5112                                                         output += formatName("D", date.getDay(), dayNamesShort, dayNames);
5113                                                         break;
5114                                                 case "o":
5115                                                         output += formatNumber("o",
5116                                                                 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
5117                                                         break;
5118                                                 case "m":
5119                                                         output += formatNumber("m", date.getMonth() + 1, 2);
5120                                                         break;
5121                                                 case "M":
5122                                                         output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
5123                                                         break;
5124                                                 case "y":
5125                                                         output += (lookAhead("y") ? date.getFullYear() :
5126                                                                 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
5127                                                         break;
5128                                                 case "@":
5129                                                         output += date.getTime();
5130                                                         break;
5131                                                 case "!":
5132                                                         output += date.getTime() * 10000 + this._ticksTo1970;
5133                                                         break;
5134                                                 case "'":
5135                                                         if (lookAhead("'")) {
5136                                                                 output += "'";
5137                                                         } else {
5138                                                                 literal = true;
5139                                                         }
5140                                                         break;
5141                                                 default:
5142                                                         output += format.charAt(iFormat);
5143                                         }
5144                                 }
5145                         }
5146                 }
5147                 return output;
5148         },
5149
5150         /* Extract all possible characters from the date format. */
5151         _possibleChars: function (format) {
5152                 var iFormat,
5153                         chars = "",
5154                         literal = false,
5155                         // Check whether a format character is doubled
5156                         lookAhead = function(match) {
5157                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5158                                 if (matches) {
5159                                         iFormat++;
5160                                 }
5161                                 return matches;
5162                         };
5163
5164                 for (iFormat = 0; iFormat < format.length; iFormat++) {
5165                         if (literal) {
5166                                 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5167                                         literal = false;
5168                                 } else {
5169                                         chars += format.charAt(iFormat);
5170                                 }
5171                         } else {
5172                                 switch (format.charAt(iFormat)) {
5173                                         case "d": case "m": case "y": case "@":
5174                                                 chars += "0123456789";
5175                                                 break;
5176                                         case "D": case "M":
5177                                                 return null; // Accept anything
5178                                         case "'":
5179                                                 if (lookAhead("'")) {
5180                                                         chars += "'";
5181                                                 } else {
5182                                                         literal = true;
5183                                                 }
5184                                                 break;
5185                                         default:
5186                                                 chars += format.charAt(iFormat);
5187                                 }
5188                         }
5189                 }
5190                 return chars;
5191         },
5192
5193         /* Get a setting value, defaulting if necessary. */
5194         _get: function(inst, name) {
5195                 return inst.settings[name] !== undefined ?
5196                         inst.settings[name] : this._defaults[name];
5197         },
5198
5199         /* Parse existing date and initialise date picker. */
5200         _setDateFromField: function(inst, noDefault) {
5201                 if (inst.input.val() === inst.lastVal) {
5202                         return;
5203                 }
5204
5205                 var dateFormat = this._get(inst, "dateFormat"),
5206                         dates = inst.lastVal = inst.input ? inst.input.val() : null,
5207                         defaultDate = this._getDefaultDate(inst),
5208                         date = defaultDate,
5209                         settings = this._getFormatConfig(inst);
5210
5211                 try {
5212                         date = this.parseDate(dateFormat, dates, settings) || defaultDate;
5213                 } catch (event) {
5214                         dates = (noDefault ? "" : dates);
5215                 }
5216                 inst.selectedDay = date.getDate();
5217                 inst.drawMonth = inst.selectedMonth = date.getMonth();
5218                 inst.drawYear = inst.selectedYear = date.getFullYear();
5219                 inst.currentDay = (dates ? date.getDate() : 0);
5220                 inst.currentMonth = (dates ? date.getMonth() : 0);
5221                 inst.currentYear = (dates ? date.getFullYear() : 0);
5222                 this._adjustInstDate(inst);
5223         },
5224
5225         /* Retrieve the default date shown on opening. */
5226         _getDefaultDate: function(inst) {
5227                 return this._restrictMinMax(inst,
5228                         this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
5229         },
5230
5231         /* A date may be specified as an exact value or a relative one. */
5232         _determineDate: function(inst, date, defaultDate) {
5233                 var offsetNumeric = function(offset) {
5234                                 var date = new Date();
5235                                 date.setDate(date.getDate() + offset);
5236                                 return date;
5237                         },
5238                         offsetString = function(offset) {
5239                                 try {
5240                                         return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
5241                                                 offset, $.datepicker._getFormatConfig(inst));
5242                                 }
5243                                 catch (e) {
5244                                         // Ignore
5245                                 }
5246
5247                                 var date = (offset.toLowerCase().match(/^c/) ?
5248                                         $.datepicker._getDate(inst) : null) || new Date(),
5249                                         year = date.getFullYear(),
5250                                         month = date.getMonth(),
5251                                         day = date.getDate(),
5252                                         pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
5253                                         matches = pattern.exec(offset);
5254
5255                                 while (matches) {
5256                                         switch (matches[2] || "d") {
5257                                                 case "d" : case "D" :
5258                                                         day += parseInt(matches[1],10); break;
5259                                                 case "w" : case "W" :
5260                                                         day += parseInt(matches[1],10) * 7; break;
5261                                                 case "m" : case "M" :
5262                                                         month += parseInt(matches[1],10);
5263                                                         day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5264                                                         break;
5265                                                 case "y": case "Y" :
5266                                                         year += parseInt(matches[1],10);
5267                                                         day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5268                                                         break;
5269                                         }
5270                                         matches = pattern.exec(offset);
5271                                 }
5272                                 return new Date(year, month, day);
5273                         },
5274                         newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
5275                                 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
5276
5277                 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
5278                 if (newDate) {
5279                         newDate.setHours(0);
5280                         newDate.setMinutes(0);
5281                         newDate.setSeconds(0);
5282                         newDate.setMilliseconds(0);
5283                 }
5284                 return this._daylightSavingAdjust(newDate);
5285         },
5286
5287         /* Handle switch to/from daylight saving.
5288          * Hours may be non-zero on daylight saving cut-over:
5289          * > 12 when midnight changeover, but then cannot generate
5290          * midnight datetime, so jump to 1AM, otherwise reset.
5291          * @param  date  (Date) the date to check
5292          * @return  (Date) the corrected date
5293          */
5294         _daylightSavingAdjust: function(date) {
5295                 if (!date) {
5296                         return null;
5297                 }
5298                 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
5299                 return date;
5300         },
5301
5302         /* Set the date(s) directly. */
5303         _setDate: function(inst, date, noChange) {
5304                 var clear = !date,
5305                         origMonth = inst.selectedMonth,
5306                         origYear = inst.selectedYear,
5307                         newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
5308
5309                 inst.selectedDay = inst.currentDay = newDate.getDate();
5310                 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
5311                 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
5312                 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
5313                         this._notifyChange(inst);
5314                 }
5315                 this._adjustInstDate(inst);
5316                 if (inst.input) {
5317                         inst.input.val(clear ? "" : this._formatDate(inst));
5318                 }
5319         },
5320
5321         /* Retrieve the date(s) directly. */
5322         _getDate: function(inst) {
5323                 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
5324                         this._daylightSavingAdjust(new Date(
5325                         inst.currentYear, inst.currentMonth, inst.currentDay)));
5326                         return startDate;
5327         },
5328
5329         /* Attach the onxxx handlers.  These are declared statically so
5330          * they work with static code transformers like Caja.
5331          */
5332         _attachHandlers: function(inst) {
5333                 var stepMonths = this._get(inst, "stepMonths"),
5334                         id = "#" + inst.id.replace( /\\\\/g, "\\" );
5335                 inst.dpDiv.find("[data-handler]").map(function () {
5336                         var handler = {
5337                                 prev: function () {
5338                                         $.datepicker._adjustDate(id, -stepMonths, "M");
5339                                 },
5340                                 next: function () {
5341                                         $.datepicker._adjustDate(id, +stepMonths, "M");
5342                                 },
5343                                 hide: function () {
5344                                         $.datepicker._hideDatepicker();
5345                                 },
5346                                 today: function () {
5347                                         $.datepicker._gotoToday(id);
5348                                 },
5349                                 selectDay: function () {
5350                                         $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
5351                                         return false;
5352                                 },
5353                                 selectMonth: function () {
5354                                         $.datepicker._selectMonthYear(id, this, "M");
5355                                         return false;
5356                                 },
5357                                 selectYear: function () {
5358                                         $.datepicker._selectMonthYear(id, this, "Y");
5359                                         return false;
5360                                 }
5361                         };
5362                         $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
5363                 });
5364         },
5365
5366         /* Generate the HTML for the current state of the date picker. */
5367         _generateHTML: function(inst) {
5368                 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
5369                         controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
5370                         monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
5371                         selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
5372                         cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
5373                         printDate, dRow, tbody, daySettings, otherMonth, unselectable,
5374                         tempDate = new Date(),
5375                         today = this._daylightSavingAdjust(
5376                                 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
5377                         isRTL = this._get(inst, "isRTL"),
5378                         showButtonPanel = this._get(inst, "showButtonPanel"),
5379                         hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
5380                         navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
5381                         numMonths = this._getNumberOfMonths(inst),
5382                         showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
5383                         stepMonths = this._get(inst, "stepMonths"),
5384                         isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
5385                         currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
5386                                 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
5387                         minDate = this._getMinMaxDate(inst, "min"),
5388                         maxDate = this._getMinMaxDate(inst, "max"),
5389                         drawMonth = inst.drawMonth - showCurrentAtPos,
5390                         drawYear = inst.drawYear;
5391
5392                 if (drawMonth < 0) {
5393                         drawMonth += 12;
5394                         drawYear--;
5395                 }
5396                 if (maxDate) {
5397                         maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
5398                                 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
5399                         maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
5400                         while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
5401                                 drawMonth--;
5402                                 if (drawMonth < 0) {
5403                                         drawMonth = 11;
5404                                         drawYear--;
5405                                 }
5406                         }
5407                 }
5408                 inst.drawMonth = drawMonth;
5409                 inst.drawYear = drawYear;
5410
5411                 prevText = this._get(inst, "prevText");
5412                 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
5413                         this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
5414                         this._getFormatConfig(inst)));
5415
5416                 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
5417                         "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
5418                         " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
5419                         (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>"));
5420
5421                 nextText = this._get(inst, "nextText");
5422                 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
5423                         this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
5424                         this._getFormatConfig(inst)));
5425
5426                 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
5427                         "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
5428                         " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
5429                         (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>"));
5430
5431                 currentText = this._get(inst, "currentText");
5432                 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
5433                 currentText = (!navigationAsDateFormat ? currentText :
5434                         this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
5435
5436                 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'>" +
5437                         this._get(inst, "closeText") + "</button>" : "");
5438
5439                 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
5440                         (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'" +
5441                         ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
5442
5443                 firstDay = parseInt(this._get(inst, "firstDay"),10);
5444                 firstDay = (isNaN(firstDay) ? 0 : firstDay);
5445
5446                 showWeek = this._get(inst, "showWeek");
5447                 dayNames = this._get(inst, "dayNames");
5448                 dayNamesMin = this._get(inst, "dayNamesMin");
5449                 monthNames = this._get(inst, "monthNames");
5450                 monthNamesShort = this._get(inst, "monthNamesShort");
5451                 beforeShowDay = this._get(inst, "beforeShowDay");
5452                 showOtherMonths = this._get(inst, "showOtherMonths");
5453                 selectOtherMonths = this._get(inst, "selectOtherMonths");
5454                 defaultDate = this._getDefaultDate(inst);
5455                 html = "";
5456                 dow;
5457                 for (row = 0; row < numMonths[0]; row++) {
5458                         group = "";
5459                         this.maxRows = 4;
5460                         for (col = 0; col < numMonths[1]; col++) {
5461                                 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
5462                                 cornerClass = " ui-corner-all";
5463                                 calender = "";
5464                                 if (isMultiMonth) {
5465                                         calender += "<div class='ui-datepicker-group";
5466                                         if (numMonths[1] > 1) {
5467                                                 switch (col) {
5468                                                         case 0: calender += " ui-datepicker-group-first";
5469                                                                 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
5470                                                         case numMonths[1]-1: calender += " ui-datepicker-group-last";
5471                                                                 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
5472                                                         default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
5473                                                 }
5474                                         }
5475                                         calender += "'>";
5476                                 }
5477                                 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
5478                                         (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
5479                                         (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
5480                                         this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
5481                                         row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
5482                                         "</div><table class='ui-datepicker-calendar'><thead>" +
5483                                         "<tr>";
5484                                 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
5485                                 for (dow = 0; dow < 7; dow++) { // days of the week
5486                                         day = (dow + firstDay) % 7;
5487                                         thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
5488                                                 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
5489                                 }
5490                                 calender += thead + "</tr></thead><tbody>";
5491                                 daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
5492                                 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
5493                                         inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
5494                                 }
5495                                 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
5496                                 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
5497                                 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
5498                                 this.maxRows = numRows;
5499                                 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
5500                                 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
5501                                         calender += "<tr>";
5502                                         tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
5503                                                 this._get(inst, "calculateWeek")(printDate) + "</td>");
5504                                         for (dow = 0; dow < 7; dow++) { // create date picker days
5505                                                 daySettings = (beforeShowDay ?
5506                                                         beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
5507                                                 otherMonth = (printDate.getMonth() !== drawMonth);
5508                                                 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
5509                                                         (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
5510                                                 tbody += "<td class='" +
5511                                                         ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
5512                                                         (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
5513                                                         ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
5514                                                         (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
5515                                                         // or defaultDate is current printedDate and defaultDate is selectedDate
5516                                                         " " + this._dayOverClass : "") + // highlight selected day
5517                                                         (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
5518                                                         (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
5519                                                         (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
5520                                                         (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
5521                                                         ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
5522                                                         (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
5523                                                         (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
5524                                                         (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
5525                                                         (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
5526                                                         (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
5527                                                         (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
5528                                                         "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
5529                                                 printDate.setDate(printDate.getDate() + 1);
5530                                                 printDate = this._daylightSavingAdjust(printDate);
5531                                         }
5532                                         calender += tbody + "</tr>";
5533                                 }
5534                                 drawMonth++;
5535                                 if (drawMonth > 11) {
5536                                         drawMonth = 0;
5537                                         drawYear++;
5538                                 }
5539                                 calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
5540                                                         ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
5541                                 group += calender;
5542                         }
5543                         html += group;
5544                 }
5545                 html += buttonPanel;
5546                 inst._keyEvent = false;
5547                 return html;
5548         },
5549
5550         /* Generate the month and year header. */
5551         _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
5552                         secondary, monthNames, monthNamesShort) {
5553
5554                 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
5555                         changeMonth = this._get(inst, "changeMonth"),
5556                         changeYear = this._get(inst, "changeYear"),
5557                         showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
5558                         html = "<div class='ui-datepicker-title'>",
5559                         monthHtml = "";
5560
5561                 // month selection
5562                 if (secondary || !changeMonth) {
5563                         monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
5564                 } else {
5565                         inMinYear = (minDate && minDate.getFullYear() === drawYear);
5566                         inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
5567                         monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
5568                         for ( month = 0; month < 12; month++) {
5569                                 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
5570                                         monthHtml += "<option value='" + month + "'" +
5571                                                 (month === drawMonth ? " selected='selected'" : "") +
5572                                                 ">" + monthNamesShort[month] + "</option>";
5573                                 }
5574                         }
5575                         monthHtml += "</select>";
5576                 }
5577
5578                 if (!showMonthAfterYear) {
5579                         html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
5580                 }
5581
5582                 // year selection
5583                 if ( !inst.yearshtml ) {
5584                         inst.yearshtml = "";
5585                         if (secondary || !changeYear) {
5586                                 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
5587                         } else {
5588                                 // determine range of years to display
5589                                 years = this._get(inst, "yearRange").split(":");
5590                                 thisYear = new Date().getFullYear();
5591                                 determineYear = function(value) {
5592                                         var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
5593                                                 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
5594                                                 parseInt(value, 10)));
5595                                         return (isNaN(year) ? thisYear : year);
5596                                 };
5597                                 year = determineYear(years[0]);
5598                                 endYear = Math.max(year, determineYear(years[1] || ""));
5599                                 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
5600                                 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
5601                                 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
5602                                 for (; year <= endYear; year++) {
5603                                         inst.yearshtml += "<option value='" + year + "'" +
5604                                                 (year === drawYear ? " selected='selected'" : "") +
5605                                                 ">" + year + "</option>";
5606                                 }
5607                                 inst.yearshtml += "</select>";
5608
5609                                 html += inst.yearshtml;
5610                                 inst.yearshtml = null;
5611                         }
5612                 }
5613
5614                 html += this._get(inst, "yearSuffix");
5615                 if (showMonthAfterYear) {
5616                         html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
5617                 }
5618                 html += "</div>"; // Close datepicker_header
5619                 return html;
5620         },
5621
5622         /* Adjust one of the date sub-fields. */
5623         _adjustInstDate: function(inst, offset, period) {
5624                 var year = inst.drawYear + (period === "Y" ? offset : 0),
5625                         month = inst.drawMonth + (period === "M" ? offset : 0),
5626                         day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
5627                         date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
5628
5629                 inst.selectedDay = date.getDate();
5630                 inst.drawMonth = inst.selectedMonth = date.getMonth();
5631                 inst.drawYear = inst.selectedYear = date.getFullYear();
5632                 if (period === "M" || period === "Y") {
5633                         this._notifyChange(inst);
5634                 }
5635         },
5636
5637         /* Ensure a date is within any min/max bounds. */
5638         _restrictMinMax: function(inst, date) {
5639                 var minDate = this._getMinMaxDate(inst, "min"),
5640                         maxDate = this._getMinMaxDate(inst, "max"),
5641                         newDate = (minDate && date < minDate ? minDate : date);
5642                 return (maxDate && newDate > maxDate ? maxDate : newDate);
5643         },
5644
5645         /* Notify change of month/year. */
5646         _notifyChange: function(inst) {
5647                 var onChange = this._get(inst, "onChangeMonthYear");
5648                 if (onChange) {
5649                         onChange.apply((inst.input ? inst.input[0] : null),
5650                                 [inst.selectedYear, inst.selectedMonth + 1, inst]);
5651                 }
5652         },
5653
5654         /* Determine the number of months to show. */
5655         _getNumberOfMonths: function(inst) {
5656                 var numMonths = this._get(inst, "numberOfMonths");
5657                 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
5658         },
5659
5660         /* Determine the current maximum date - ensure no time components are set. */
5661         _getMinMaxDate: function(inst, minMax) {
5662                 return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
5663         },
5664
5665         /* Find the number of days in a given month. */
5666         _getDaysInMonth: function(year, month) {
5667                 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
5668         },
5669
5670         /* Find the day of the week of the first of a month. */
5671         _getFirstDayOfMonth: function(year, month) {
5672                 return new Date(year, month, 1).getDay();
5673         },
5674
5675         /* Determines if we should allow a "next/prev" month display change. */
5676         _canAdjustMonth: function(inst, offset, curYear, curMonth) {
5677                 var numMonths = this._getNumberOfMonths(inst),
5678                         date = this._daylightSavingAdjust(new Date(curYear,
5679                         curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
5680
5681                 if (offset < 0) {
5682                         date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
5683                 }
5684                 return this._isInRange(inst, date);
5685         },
5686
5687         /* Is the given date in the accepted range? */
5688         _isInRange: function(inst, date) {
5689                 var yearSplit, currentYear,
5690                         minDate = this._getMinMaxDate(inst, "min"),
5691                         maxDate = this._getMinMaxDate(inst, "max"),
5692                         minYear = null,
5693                         maxYear = null,
5694                         years = this._get(inst, "yearRange");
5695                         if (years){
5696                                 yearSplit = years.split(":");
5697                                 currentYear = new Date().getFullYear();
5698                                 minYear = parseInt(yearSplit[0], 10);
5699                                 maxYear = parseInt(yearSplit[1], 10);
5700                                 if ( yearSplit[0].match(/[+\-].*/) ) {
5701                                         minYear += currentYear;
5702                                 }
5703                                 if ( yearSplit[1].match(/[+\-].*/) ) {
5704                                         maxYear += currentYear;
5705                                 }
5706                         }
5707
5708                 return ((!minDate || date.getTime() >= minDate.getTime()) &&
5709                         (!maxDate || date.getTime() <= maxDate.getTime()) &&
5710                         (!minYear || date.getFullYear() >= minYear) &&
5711                         (!maxYear || date.getFullYear() <= maxYear));
5712         },
5713
5714         /* Provide the configuration settings for formatting/parsing. */
5715         _getFormatConfig: function(inst) {
5716                 var shortYearCutoff = this._get(inst, "shortYearCutoff");
5717                 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
5718                         new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
5719                 return {shortYearCutoff: shortYearCutoff,
5720                         dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
5721                         monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
5722         },
5723
5724         /* Format the given date for display. */
5725         _formatDate: function(inst, day, month, year) {
5726                 if (!day) {
5727                         inst.currentDay = inst.selectedDay;
5728                         inst.currentMonth = inst.selectedMonth;
5729                         inst.currentYear = inst.selectedYear;
5730                 }
5731                 var date = (day ? (typeof day === "object" ? day :
5732                         this._daylightSavingAdjust(new Date(year, month, day))) :
5733                         this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
5734                 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
5735         }
5736 });
5737
5738 /*
5739  * Bind hover events for datepicker elements.
5740  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
5741  * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
5742  */
5743 function datepicker_bindHover(dpDiv) {
5744         var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
5745         return dpDiv.delegate(selector, "mouseout", function() {
5746                         $(this).removeClass("ui-state-hover");
5747                         if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5748                                 $(this).removeClass("ui-datepicker-prev-hover");
5749                         }
5750                         if (this.className.indexOf("ui-datepicker-next") !== -1) {
5751                                 $(this).removeClass("ui-datepicker-next-hover");
5752                         }
5753                 })
5754                 .delegate( selector, "mouseover", datepicker_handleMouseover );
5755 }
5756
5757 function datepicker_handleMouseover() {
5758         if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
5759                 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
5760                 $(this).addClass("ui-state-hover");
5761                 if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5762                         $(this).addClass("ui-datepicker-prev-hover");
5763                 }
5764                 if (this.className.indexOf("ui-datepicker-next") !== -1) {
5765                         $(this).addClass("ui-datepicker-next-hover");
5766                 }
5767         }
5768 }
5769
5770 /* jQuery extend now ignores nulls! */
5771 function datepicker_extendRemove(target, props) {
5772         $.extend(target, props);
5773         for (var name in props) {
5774                 if (props[name] == null) {
5775                         target[name] = props[name];
5776                 }
5777         }
5778         return target;
5779 }
5780
5781 /* Invoke the datepicker functionality.
5782    @param  options  string - a command, optionally followed by additional parameters or
5783                                         Object - settings for attaching new datepicker functionality
5784    @return  jQuery object */
5785 $.fn.datepicker = function(options){
5786
5787         /* Verify an empty collection wasn't passed - Fixes #6976 */
5788         if ( !this.length ) {
5789                 return this;
5790         }
5791
5792         /* Initialise the date picker. */
5793         if (!$.datepicker.initialized) {
5794                 $(document).mousedown($.datepicker._checkExternalClick);
5795                 $.datepicker.initialized = true;
5796         }
5797
5798         /* Append datepicker main container to body if not exist. */
5799         if ($("#"+$.datepicker._mainDivId).length === 0) {
5800                 $("body").append($.datepicker.dpDiv);
5801         }
5802
5803         var otherArgs = Array.prototype.slice.call(arguments, 1);
5804         if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
5805                 return $.datepicker["_" + options + "Datepicker"].
5806                         apply($.datepicker, [this[0]].concat(otherArgs));
5807         }
5808         if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
5809                 return $.datepicker["_" + options + "Datepicker"].
5810                         apply($.datepicker, [this[0]].concat(otherArgs));
5811         }
5812         return this.each(function() {
5813                 typeof options === "string" ?
5814                         $.datepicker["_" + options + "Datepicker"].
5815                                 apply($.datepicker, [this].concat(otherArgs)) :
5816                         $.datepicker._attachDatepicker(this, options);
5817         });
5818 };
5819
5820 $.datepicker = new Datepicker(); // singleton instance
5821 $.datepicker.initialized = false;
5822 $.datepicker.uuid = new Date().getTime();
5823 $.datepicker.version = "1.11.2";
5824
5825 var datepicker = $.datepicker;
5826
5827
5828 /*!
5829  * jQuery UI Draggable 1.11.2
5830  * http://jqueryui.com
5831  *
5832  * Copyright 2014 jQuery Foundation and other contributors
5833  * Released under the MIT license.
5834  * http://jquery.org/license
5835  *
5836  * http://api.jqueryui.com/draggable/
5837  */
5838
5839
5840 $.widget("ui.draggable", $.ui.mouse, {
5841         version: "1.11.2",
5842         widgetEventPrefix: "drag",
5843         options: {
5844                 addClasses: true,
5845                 appendTo: "parent",
5846                 axis: false,
5847                 connectToSortable: false,
5848                 containment: false,
5849                 cursor: "auto",
5850                 cursorAt: false,
5851                 grid: false,
5852                 handle: false,
5853                 helper: "original",
5854                 iframeFix: false,
5855                 opacity: false,
5856                 refreshPositions: false,
5857                 revert: false,
5858                 revertDuration: 500,
5859                 scope: "default",
5860                 scroll: true,
5861                 scrollSensitivity: 20,
5862                 scrollSpeed: 20,
5863                 snap: false,
5864                 snapMode: "both",
5865                 snapTolerance: 20,
5866                 stack: false,
5867                 zIndex: false,
5868
5869                 // callbacks
5870                 drag: null,
5871                 start: null,
5872                 stop: null
5873         },
5874         _create: function() {
5875
5876                 if ( this.options.helper === "original" ) {
5877                         this._setPositionRelative();
5878                 }
5879                 if (this.options.addClasses){
5880                         this.element.addClass("ui-draggable");
5881                 }
5882                 if (this.options.disabled){
5883                         this.element.addClass("ui-draggable-disabled");
5884                 }
5885                 this._setHandleClassName();
5886
5887                 this._mouseInit();
5888         },
5889
5890         _setOption: function( key, value ) {
5891                 this._super( key, value );
5892                 if ( key === "handle" ) {
5893                         this._removeHandleClassName();
5894                         this._setHandleClassName();
5895                 }
5896         },
5897
5898         _destroy: function() {
5899                 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
5900                         this.destroyOnClear = true;
5901                         return;
5902                 }
5903                 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
5904                 this._removeHandleClassName();
5905                 this._mouseDestroy();
5906         },
5907
5908         _mouseCapture: function(event) {
5909                 var o = this.options;
5910
5911                 this._blurActiveElement( event );
5912
5913                 // among others, prevent a drag on a resizable-handle
5914                 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
5915                         return false;
5916                 }
5917
5918                 //Quit if we're not on a valid handle
5919                 this.handle = this._getHandle(event);
5920                 if (!this.handle) {
5921                         return false;
5922                 }
5923
5924                 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
5925
5926                 return true;
5927
5928         },
5929
5930         _blockFrames: function( selector ) {
5931                 this.iframeBlocks = this.document.find( selector ).map(function() {
5932                         var iframe = $( this );
5933
5934                         return $( "<div>" )
5935                                 .css( "position", "absolute" )
5936                                 .appendTo( iframe.parent() )
5937                                 .outerWidth( iframe.outerWidth() )
5938                                 .outerHeight( iframe.outerHeight() )
5939                                 .offset( iframe.offset() )[ 0 ];
5940                 });
5941         },
5942
5943         _unblockFrames: function() {
5944                 if ( this.iframeBlocks ) {
5945                         this.iframeBlocks.remove();
5946                         delete this.iframeBlocks;
5947                 }
5948         },
5949
5950         _blurActiveElement: function( event ) {
5951                 var document = this.document[ 0 ];
5952
5953                 // Only need to blur if the event occurred on the draggable itself, see #10527
5954                 if ( !this.handleElement.is( event.target ) ) {
5955                         return;
5956                 }
5957
5958                 // support: IE9
5959                 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
5960                 try {
5961
5962                         // Support: IE9, IE10
5963                         // If the <body> is blurred, IE will switch windows, see #9520
5964                         if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
5965
5966                                 // Blur any element that currently has focus, see #4261
5967                                 $( document.activeElement ).blur();
5968                         }
5969                 } catch ( error ) {}
5970         },
5971
5972         _mouseStart: function(event) {
5973
5974                 var o = this.options;
5975
5976                 //Create and append the visible helper
5977                 this.helper = this._createHelper(event);
5978
5979                 this.helper.addClass("ui-draggable-dragging");
5980
5981                 //Cache the helper size
5982                 this._cacheHelperProportions();
5983
5984                 //If ddmanager is used for droppables, set the global draggable
5985                 if ($.ui.ddmanager) {
5986                         $.ui.ddmanager.current = this;
5987                 }
5988
5989                 /*
5990                  * - Position generation -
5991                  * This block generates everything position related - it's the core of draggables.
5992                  */
5993
5994                 //Cache the margins of the original element
5995                 this._cacheMargins();
5996
5997                 //Store the helper's css position
5998                 this.cssPosition = this.helper.css( "position" );
5999                 this.scrollParent = this.helper.scrollParent( true );
6000                 this.offsetParent = this.helper.offsetParent();
6001                 this.hasFixedAncestor = this.helper.parents().filter(function() {
6002                                 return $( this ).css( "position" ) === "fixed";
6003                         }).length > 0;
6004
6005                 //The element's absolute position on the page minus margins
6006                 this.positionAbs = this.element.offset();
6007                 this._refreshOffsets( event );
6008
6009                 //Generate the original position
6010                 this.originalPosition = this.position = this._generatePosition( event, false );
6011                 this.originalPageX = event.pageX;
6012                 this.originalPageY = event.pageY;
6013
6014                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
6015                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
6016
6017                 //Set a containment if given in the options
6018                 this._setContainment();
6019
6020                 //Trigger event + callbacks
6021                 if (this._trigger("start", event) === false) {
6022                         this._clear();
6023                         return false;
6024                 }
6025
6026                 //Recache the helper size
6027                 this._cacheHelperProportions();
6028
6029                 //Prepare the droppable offsets
6030                 if ($.ui.ddmanager && !o.dropBehaviour) {
6031                         $.ui.ddmanager.prepareOffsets(this, event);
6032                 }
6033
6034                 // Reset helper's right/bottom css if they're set and set explicit width/height instead
6035                 // as this prevents resizing of elements with right/bottom set (see #7772)
6036                 this._normalizeRightBottom();
6037
6038                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
6039
6040                 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
6041                 if ( $.ui.ddmanager ) {
6042                         $.ui.ddmanager.dragStart(this, event);
6043                 }
6044
6045                 return true;
6046         },
6047
6048         _refreshOffsets: function( event ) {
6049                 this.offset = {
6050                         top: this.positionAbs.top - this.margins.top,
6051                         left: this.positionAbs.left - this.margins.left,
6052                         scroll: false,
6053                         parent: this._getParentOffset(),
6054                         relative: this._getRelativeOffset()
6055                 };
6056
6057                 this.offset.click = {
6058                         left: event.pageX - this.offset.left,
6059                         top: event.pageY - this.offset.top
6060                 };
6061         },
6062
6063         _mouseDrag: function(event, noPropagation) {
6064                 // reset any necessary cached properties (see #5009)
6065                 if ( this.hasFixedAncestor ) {
6066                         this.offset.parent = this._getParentOffset();
6067                 }
6068
6069                 //Compute the helpers position
6070                 this.position = this._generatePosition( event, true );
6071                 this.positionAbs = this._convertPositionTo("absolute");
6072
6073                 //Call plugins and callbacks and use the resulting position if something is returned
6074                 if (!noPropagation) {
6075                         var ui = this._uiHash();
6076                         if (this._trigger("drag", event, ui) === false) {
6077                                 this._mouseUp({});
6078                                 return false;
6079                         }
6080                         this.position = ui.position;
6081                 }
6082
6083                 this.helper[ 0 ].style.left = this.position.left + "px";
6084                 this.helper[ 0 ].style.top = this.position.top + "px";
6085
6086                 if ($.ui.ddmanager) {
6087                         $.ui.ddmanager.drag(this, event);
6088                 }
6089
6090                 return false;
6091         },
6092
6093         _mouseStop: function(event) {
6094
6095                 //If we are using droppables, inform the manager about the drop
6096                 var that = this,
6097                         dropped = false;
6098                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
6099                         dropped = $.ui.ddmanager.drop(this, event);
6100                 }
6101
6102                 //if a drop comes from outside (a sortable)
6103                 if (this.dropped) {
6104                         dropped = this.dropped;
6105                         this.dropped = false;
6106                 }
6107
6108                 if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
6109                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
6110                                 if (that._trigger("stop", event) !== false) {
6111                                         that._clear();
6112                                 }
6113                         });
6114                 } else {
6115                         if (this._trigger("stop", event) !== false) {
6116                                 this._clear();
6117                         }
6118                 }
6119
6120                 return false;
6121         },
6122
6123         _mouseUp: function( event ) {
6124                 this._unblockFrames();
6125
6126                 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
6127                 if ( $.ui.ddmanager ) {
6128                         $.ui.ddmanager.dragStop(this, event);
6129                 }
6130
6131                 // Only need to focus if the event occurred on the draggable itself, see #10527
6132                 if ( this.handleElement.is( event.target ) ) {
6133                         // The interaction is over; whether or not the click resulted in a drag, focus the element
6134                         this.element.focus();
6135                 }
6136
6137                 return $.ui.mouse.prototype._mouseUp.call(this, event);
6138         },
6139
6140         cancel: function() {
6141
6142                 if (this.helper.is(".ui-draggable-dragging")) {
6143                         this._mouseUp({});
6144                 } else {
6145                         this._clear();
6146                 }
6147
6148                 return this;
6149
6150         },
6151
6152         _getHandle: function(event) {
6153                 return this.options.handle ?
6154                         !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
6155                         true;
6156         },
6157
6158         _setHandleClassName: function() {
6159                 this.handleElement = this.options.handle ?
6160                         this.element.find( this.options.handle ) : this.element;
6161                 this.handleElement.addClass( "ui-draggable-handle" );
6162         },
6163
6164         _removeHandleClassName: function() {
6165                 this.handleElement.removeClass( "ui-draggable-handle" );
6166         },
6167
6168         _createHelper: function(event) {
6169
6170                 var o = this.options,
6171                         helperIsFunction = $.isFunction( o.helper ),
6172                         helper = helperIsFunction ?
6173                                 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
6174                                 ( o.helper === "clone" ?
6175                                         this.element.clone().removeAttr( "id" ) :
6176                                         this.element );
6177
6178                 if (!helper.parents("body").length) {
6179                         helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
6180                 }
6181
6182                 // http://bugs.jqueryui.com/ticket/9446
6183                 // a helper function can return the original element
6184                 // which wouldn't have been set to relative in _create
6185                 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
6186                         this._setPositionRelative();
6187                 }
6188
6189                 if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
6190                         helper.css("position", "absolute");
6191                 }
6192
6193                 return helper;
6194
6195         },
6196
6197         _setPositionRelative: function() {
6198                 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
6199                         this.element[ 0 ].style.position = "relative";
6200                 }
6201         },
6202
6203         _adjustOffsetFromHelper: function(obj) {
6204                 if (typeof obj === "string") {
6205                         obj = obj.split(" ");
6206                 }
6207                 if ($.isArray(obj)) {
6208                         obj = { left: +obj[0], top: +obj[1] || 0 };
6209                 }
6210                 if ("left" in obj) {
6211                         this.offset.click.left = obj.left + this.margins.left;
6212                 }
6213                 if ("right" in obj) {
6214                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6215                 }
6216                 if ("top" in obj) {
6217                         this.offset.click.top = obj.top + this.margins.top;
6218                 }
6219                 if ("bottom" in obj) {
6220                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6221                 }
6222         },
6223
6224         _isRootNode: function( element ) {
6225                 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
6226         },
6227
6228         _getParentOffset: function() {
6229
6230                 //Get the offsetParent and cache its position
6231                 var po = this.offsetParent.offset(),
6232                         document = this.document[ 0 ];
6233
6234                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
6235                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
6236                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
6237                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
6238                 if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
6239                         po.left += this.scrollParent.scrollLeft();
6240                         po.top += this.scrollParent.scrollTop();
6241                 }
6242
6243                 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
6244                         po = { top: 0, left: 0 };
6245                 }
6246
6247                 return {
6248                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
6249                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
6250                 };
6251
6252         },
6253
6254         _getRelativeOffset: function() {
6255                 if ( this.cssPosition !== "relative" ) {
6256                         return { top: 0, left: 0 };
6257                 }
6258
6259                 var p = this.element.position(),
6260                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6261
6262                 return {
6263                         top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
6264                         left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
6265                 };
6266
6267         },
6268
6269         _cacheMargins: function() {
6270                 this.margins = {
6271                         left: (parseInt(this.element.css("marginLeft"), 10) || 0),
6272                         top: (parseInt(this.element.css("marginTop"), 10) || 0),
6273                         right: (parseInt(this.element.css("marginRight"), 10) || 0),
6274                         bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
6275                 };
6276         },
6277
6278         _cacheHelperProportions: function() {
6279                 this.helperProportions = {
6280                         width: this.helper.outerWidth(),
6281                         height: this.helper.outerHeight()
6282                 };
6283         },
6284
6285         _setContainment: function() {
6286
6287                 var isUserScrollable, c, ce,
6288                         o = this.options,
6289                         document = this.document[ 0 ];
6290
6291                 this.relativeContainer = null;
6292
6293                 if ( !o.containment ) {
6294                         this.containment = null;
6295                         return;
6296                 }
6297
6298                 if ( o.containment === "window" ) {
6299                         this.containment = [
6300                                 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
6301                                 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
6302                                 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
6303                                 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6304                         ];
6305                         return;
6306                 }
6307
6308                 if ( o.containment === "document") {
6309                         this.containment = [
6310                                 0,
6311                                 0,
6312                                 $( document ).width() - this.helperProportions.width - this.margins.left,
6313                                 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6314                         ];
6315                         return;
6316                 }
6317
6318                 if ( o.containment.constructor === Array ) {
6319                         this.containment = o.containment;
6320                         return;
6321                 }
6322
6323                 if ( o.containment === "parent" ) {
6324                         o.containment = this.helper[ 0 ].parentNode;
6325                 }
6326
6327                 c = $( o.containment );
6328                 ce = c[ 0 ];
6329
6330                 if ( !ce ) {
6331                         return;
6332                 }
6333
6334                 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
6335
6336                 this.containment = [
6337                         ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
6338                         ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
6339                         ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
6340                                 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
6341                                 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
6342                                 this.helperProportions.width -
6343                                 this.margins.left -
6344                                 this.margins.right,
6345                         ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
6346                                 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
6347                                 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
6348                                 this.helperProportions.height -
6349                                 this.margins.top -
6350                                 this.margins.bottom
6351                 ];
6352                 this.relativeContainer = c;
6353         },
6354
6355         _convertPositionTo: function(d, pos) {
6356
6357                 if (!pos) {
6358                         pos = this.position;
6359                 }
6360
6361                 var mod = d === "absolute" ? 1 : -1,
6362                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6363
6364                 return {
6365                         top: (
6366                                 pos.top +                                                                                                                               // The absolute mouse position
6367                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6368                                 this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
6369                                 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
6370                         ),
6371                         left: (
6372                                 pos.left +                                                                                                                              // The absolute mouse position
6373                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
6374                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
6375                                 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
6376                         )
6377                 };
6378
6379         },
6380
6381         _generatePosition: function( event, constrainPosition ) {
6382
6383                 var containment, co, top, left,
6384                         o = this.options,
6385                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
6386                         pageX = event.pageX,
6387                         pageY = event.pageY;
6388
6389                 // Cache the scroll
6390                 if ( !scrollIsRootNode || !this.offset.scroll ) {
6391                         this.offset.scroll = {
6392                                 top: this.scrollParent.scrollTop(),
6393                                 left: this.scrollParent.scrollLeft()
6394                         };
6395                 }
6396
6397                 /*
6398                  * - Position constraining -
6399                  * Constrain the position to a mix of grid, containment.
6400                  */
6401
6402                 // If we are not dragging yet, we won't check for options
6403                 if ( constrainPosition ) {
6404                         if ( this.containment ) {
6405                                 if ( this.relativeContainer ){
6406                                         co = this.relativeContainer.offset();
6407                                         containment = [
6408                                                 this.containment[ 0 ] + co.left,
6409                                                 this.containment[ 1 ] + co.top,
6410                                                 this.containment[ 2 ] + co.left,
6411                                                 this.containment[ 3 ] + co.top
6412                                         ];
6413                                 } else {
6414                                         containment = this.containment;
6415                                 }
6416
6417                                 if (event.pageX - this.offset.click.left < containment[0]) {
6418                                         pageX = containment[0] + this.offset.click.left;
6419                                 }
6420                                 if (event.pageY - this.offset.click.top < containment[1]) {
6421                                         pageY = containment[1] + this.offset.click.top;
6422                                 }
6423                                 if (event.pageX - this.offset.click.left > containment[2]) {
6424                                         pageX = containment[2] + this.offset.click.left;
6425                                 }
6426                                 if (event.pageY - this.offset.click.top > containment[3]) {
6427                                         pageY = containment[3] + this.offset.click.top;
6428                                 }
6429                         }
6430
6431                         if (o.grid) {
6432                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
6433                                 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
6434                                 pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
6435
6436                                 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
6437                                 pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
6438                         }
6439
6440                         if ( o.axis === "y" ) {
6441                                 pageX = this.originalPageX;
6442                         }
6443
6444                         if ( o.axis === "x" ) {
6445                                 pageY = this.originalPageY;
6446                         }
6447                 }
6448
6449                 return {
6450                         top: (
6451                                 pageY -                                                                                                                                 // The absolute mouse position
6452                                 this.offset.click.top   -                                                                                               // Click offset (relative to the element)
6453                                 this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
6454                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
6455                                 ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
6456                         ),
6457                         left: (
6458                                 pageX -                                                                                                                                 // The absolute mouse position
6459                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
6460                                 this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
6461                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
6462                                 ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
6463                         )
6464                 };
6465
6466         },
6467
6468         _clear: function() {
6469                 this.helper.removeClass("ui-draggable-dragging");
6470                 if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
6471                         this.helper.remove();
6472                 }
6473                 this.helper = null;
6474                 this.cancelHelperRemoval = false;
6475                 if ( this.destroyOnClear ) {
6476                         this.destroy();
6477                 }
6478         },
6479
6480         _normalizeRightBottom: function() {
6481                 if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
6482                         this.helper.width( this.helper.width() );
6483                         this.helper.css( "right", "auto" );
6484                 }
6485                 if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
6486                         this.helper.height( this.helper.height() );
6487                         this.helper.css( "bottom", "auto" );
6488                 }
6489         },
6490
6491         // From now on bulk stuff - mainly helpers
6492
6493         _trigger: function( type, event, ui ) {
6494                 ui = ui || this._uiHash();
6495                 $.ui.plugin.call( this, type, [ event, ui, this ], true );
6496
6497                 // Absolute position and offset (see #6884 ) have to be recalculated after plugins
6498                 if ( /^(drag|start|stop)/.test( type ) ) {
6499                         this.positionAbs = this._convertPositionTo( "absolute" );
6500                         ui.offset = this.positionAbs;
6501                 }
6502                 return $.Widget.prototype._trigger.call( this, type, event, ui );
6503         },
6504
6505         plugins: {},
6506
6507         _uiHash: function() {
6508                 return {
6509                         helper: this.helper,
6510                         position: this.position,
6511                         originalPosition: this.originalPosition,
6512                         offset: this.positionAbs
6513                 };
6514         }
6515
6516 });
6517
6518 $.ui.plugin.add( "draggable", "connectToSortable", {
6519         start: function( event, ui, draggable ) {
6520                 var uiSortable = $.extend( {}, ui, {
6521                         item: draggable.element
6522                 });
6523
6524                 draggable.sortables = [];
6525                 $( draggable.options.connectToSortable ).each(function() {
6526                         var sortable = $( this ).sortable( "instance" );
6527
6528                         if ( sortable && !sortable.options.disabled ) {
6529                                 draggable.sortables.push( sortable );
6530
6531                                 // refreshPositions is called at drag start to refresh the containerCache
6532                                 // which is used in drag. This ensures it's initialized and synchronized
6533                                 // with any changes that might have happened on the page since initialization.
6534                                 sortable.refreshPositions();
6535                                 sortable._trigger("activate", event, uiSortable);
6536                         }
6537                 });
6538         },
6539         stop: function( event, ui, draggable ) {
6540                 var uiSortable = $.extend( {}, ui, {
6541                         item: draggable.element
6542                 });
6543
6544                 draggable.cancelHelperRemoval = false;
6545
6546                 $.each( draggable.sortables, function() {
6547                         var sortable = this;
6548
6549                         if ( sortable.isOver ) {
6550                                 sortable.isOver = 0;
6551
6552                                 // Allow this sortable to handle removing the helper
6553                                 draggable.cancelHelperRemoval = true;
6554                                 sortable.cancelHelperRemoval = false;
6555
6556                                 // Use _storedCSS To restore properties in the sortable,
6557                                 // as this also handles revert (#9675) since the draggable
6558                                 // may have modified them in unexpected ways (#8809)
6559                                 sortable._storedCSS = {
6560                                         position: sortable.placeholder.css( "position" ),
6561                                         top: sortable.placeholder.css( "top" ),
6562                                         left: sortable.placeholder.css( "left" )
6563                                 };
6564
6565                                 sortable._mouseStop(event);
6566
6567                                 // Once drag has ended, the sortable should return to using
6568                                 // its original helper, not the shared helper from draggable
6569                                 sortable.options.helper = sortable.options._helper;
6570                         } else {
6571                                 // Prevent this Sortable from removing the helper.
6572                                 // However, don't set the draggable to remove the helper
6573                                 // either as another connected Sortable may yet handle the removal.
6574                                 sortable.cancelHelperRemoval = true;
6575
6576                                 sortable._trigger( "deactivate", event, uiSortable );
6577                         }
6578                 });
6579         },
6580         drag: function( event, ui, draggable ) {
6581                 $.each( draggable.sortables, function() {
6582                         var innermostIntersecting = false,
6583                                 sortable = this;
6584
6585                         // Copy over variables that sortable's _intersectsWith uses
6586                         sortable.positionAbs = draggable.positionAbs;
6587                         sortable.helperProportions = draggable.helperProportions;
6588                         sortable.offset.click = draggable.offset.click;
6589
6590                         if ( sortable._intersectsWith( sortable.containerCache ) ) {
6591                                 innermostIntersecting = true;
6592
6593                                 $.each( draggable.sortables, function() {
6594                                         // Copy over variables that sortable's _intersectsWith uses
6595                                         this.positionAbs = draggable.positionAbs;
6596                                         this.helperProportions = draggable.helperProportions;
6597                                         this.offset.click = draggable.offset.click;
6598
6599                                         if ( this !== sortable &&
6600                                                         this._intersectsWith( this.containerCache ) &&
6601                                                         $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
6602                                                 innermostIntersecting = false;
6603                                         }
6604
6605                                         return innermostIntersecting;
6606                                 });
6607                         }
6608
6609                         if ( innermostIntersecting ) {
6610                                 // If it intersects, we use a little isOver variable and set it once,
6611                                 // so that the move-in stuff gets fired only once.
6612                                 if ( !sortable.isOver ) {
6613                                         sortable.isOver = 1;
6614
6615                                         sortable.currentItem = ui.helper
6616                                                 .appendTo( sortable.element )
6617                                                 .data( "ui-sortable-item", true );
6618
6619                                         // Store helper option to later restore it
6620                                         sortable.options._helper = sortable.options.helper;
6621
6622                                         sortable.options.helper = function() {
6623                                                 return ui.helper[ 0 ];
6624                                         };
6625
6626                                         // Fire the start events of the sortable with our passed browser event,
6627                                         // and our own helper (so it doesn't create a new one)
6628                                         event.target = sortable.currentItem[ 0 ];
6629                                         sortable._mouseCapture( event, true );
6630                                         sortable._mouseStart( event, true, true );
6631
6632                                         // Because the browser event is way off the new appended portlet,
6633                                         // modify necessary variables to reflect the changes
6634                                         sortable.offset.click.top = draggable.offset.click.top;
6635                                         sortable.offset.click.left = draggable.offset.click.left;
6636                                         sortable.offset.parent.left -= draggable.offset.parent.left -
6637                                                 sortable.offset.parent.left;
6638                                         sortable.offset.parent.top -= draggable.offset.parent.top -
6639                                                 sortable.offset.parent.top;
6640
6641                                         draggable._trigger( "toSortable", event );
6642
6643                                         // Inform draggable that the helper is in a valid drop zone,
6644                                         // used solely in the revert option to handle "valid/invalid".
6645                                         draggable.dropped = sortable.element;
6646
6647                                         // Need to refreshPositions of all sortables in the case that
6648                                         // adding to one sortable changes the location of the other sortables (#9675)
6649                                         $.each( draggable.sortables, function() {
6650                                                 this.refreshPositions();
6651                                         });
6652
6653                                         // hack so receive/update callbacks work (mostly)
6654                                         draggable.currentItem = draggable.element;
6655                                         sortable.fromOutside = draggable;
6656                                 }
6657
6658                                 if ( sortable.currentItem ) {
6659                                         sortable._mouseDrag( event );
6660                                         // Copy the sortable's position because the draggable's can potentially reflect
6661                                         // a relative position, while sortable is always absolute, which the dragged
6662                                         // element has now become. (#8809)
6663                                         ui.position = sortable.position;
6664                                 }
6665                         } else {
6666                                 // If it doesn't intersect with the sortable, and it intersected before,
6667                                 // we fake the drag stop of the sortable, but make sure it doesn't remove
6668                                 // the helper by using cancelHelperRemoval.
6669                                 if ( sortable.isOver ) {
6670
6671                                         sortable.isOver = 0;
6672                                         sortable.cancelHelperRemoval = true;
6673
6674                                         // Calling sortable's mouseStop would trigger a revert,
6675                                         // so revert must be temporarily false until after mouseStop is called.
6676                                         sortable.options._revert = sortable.options.revert;
6677                                         sortable.options.revert = false;
6678
6679                                         sortable._trigger( "out", event, sortable._uiHash( sortable ) );
6680                                         sortable._mouseStop( event, true );
6681
6682                                         // restore sortable behaviors that were modfied
6683                                         // when the draggable entered the sortable area (#9481)
6684                                         sortable.options.revert = sortable.options._revert;
6685                                         sortable.options.helper = sortable.options._helper;
6686
6687                                         if ( sortable.placeholder ) {
6688                                                 sortable.placeholder.remove();
6689                                         }
6690
6691                                         // Recalculate the draggable's offset considering the sortable
6692                                         // may have modified them in unexpected ways (#8809)
6693                                         draggable._refreshOffsets( event );
6694                                         ui.position = draggable._generatePosition( event, true );
6695
6696                                         draggable._trigger( "fromSortable", event );
6697
6698                                         // Inform draggable that the helper is no longer in a valid drop zone
6699                                         draggable.dropped = false;
6700
6701                                         // Need to refreshPositions of all sortables just in case removing
6702                                         // from one sortable changes the location of other sortables (#9675)
6703                                         $.each( draggable.sortables, function() {
6704                                                 this.refreshPositions();
6705                                         });
6706                                 }
6707                         }
6708                 });
6709         }
6710 });
6711
6712 $.ui.plugin.add("draggable", "cursor", {
6713         start: function( event, ui, instance ) {
6714                 var t = $( "body" ),
6715                         o = instance.options;
6716
6717                 if (t.css("cursor")) {
6718                         o._cursor = t.css("cursor");
6719                 }
6720                 t.css("cursor", o.cursor);
6721         },
6722         stop: function( event, ui, instance ) {
6723                 var o = instance.options;
6724                 if (o._cursor) {
6725                         $("body").css("cursor", o._cursor);
6726                 }
6727         }
6728 });
6729
6730 $.ui.plugin.add("draggable", "opacity", {
6731         start: function( event, ui, instance ) {
6732                 var t = $( ui.helper ),
6733                         o = instance.options;
6734                 if (t.css("opacity")) {
6735                         o._opacity = t.css("opacity");
6736                 }
6737                 t.css("opacity", o.opacity);
6738         },
6739         stop: function( event, ui, instance ) {
6740                 var o = instance.options;
6741                 if (o._opacity) {
6742                         $(ui.helper).css("opacity", o._opacity);
6743                 }
6744         }
6745 });
6746
6747 $.ui.plugin.add("draggable", "scroll", {
6748         start: function( event, ui, i ) {
6749                 if ( !i.scrollParentNotHidden ) {
6750                         i.scrollParentNotHidden = i.helper.scrollParent( false );
6751                 }
6752
6753                 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
6754                         i.overflowOffset = i.scrollParentNotHidden.offset();
6755                 }
6756         },
6757         drag: function( event, ui, i  ) {
6758
6759                 var o = i.options,
6760                         scrolled = false,
6761                         scrollParent = i.scrollParentNotHidden[ 0 ],
6762                         document = i.document[ 0 ];
6763
6764                 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
6765                         if ( !o.axis || o.axis !== "x" ) {
6766                                 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
6767                                         scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
6768                                 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
6769                                         scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
6770                                 }
6771                         }
6772
6773                         if ( !o.axis || o.axis !== "y" ) {
6774                                 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
6775                                         scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
6776                                 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
6777                                         scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
6778                                 }
6779                         }
6780
6781                 } else {
6782
6783                         if (!o.axis || o.axis !== "x") {
6784                                 if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
6785                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
6786                                 } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
6787                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
6788                                 }
6789                         }
6790
6791                         if (!o.axis || o.axis !== "y") {
6792                                 if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
6793                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
6794                                 } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
6795                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
6796                                 }
6797                         }
6798
6799                 }
6800
6801                 if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
6802                         $.ui.ddmanager.prepareOffsets(i, event);
6803                 }
6804
6805         }
6806 });
6807
6808 $.ui.plugin.add("draggable", "snap", {
6809         start: function( event, ui, i ) {
6810
6811                 var o = i.options;
6812
6813                 i.snapElements = [];
6814
6815                 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
6816                         var $t = $(this),
6817                                 $o = $t.offset();
6818                         if (this !== i.element[0]) {
6819                                 i.snapElements.push({
6820                                         item: this,
6821                                         width: $t.outerWidth(), height: $t.outerHeight(),
6822                                         top: $o.top, left: $o.left
6823                                 });
6824                         }
6825                 });
6826
6827         },
6828         drag: function( event, ui, inst ) {
6829
6830                 var ts, bs, ls, rs, l, r, t, b, i, first,
6831                         o = inst.options,
6832                         d = o.snapTolerance,
6833                         x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
6834                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
6835
6836                 for (i = inst.snapElements.length - 1; i >= 0; i--){
6837
6838                         l = inst.snapElements[i].left - inst.margins.left;
6839                         r = l + inst.snapElements[i].width;
6840                         t = inst.snapElements[i].top - inst.margins.top;
6841                         b = t + inst.snapElements[i].height;
6842
6843                         if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
6844                                 if (inst.snapElements[i].snapping) {
6845                                         (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6846                                 }
6847                                 inst.snapElements[i].snapping = false;
6848                                 continue;
6849                         }
6850
6851                         if (o.snapMode !== "inner") {
6852                                 ts = Math.abs(t - y2) <= d;
6853                                 bs = Math.abs(b - y1) <= d;
6854                                 ls = Math.abs(l - x2) <= d;
6855                                 rs = Math.abs(r - x1) <= d;
6856                                 if (ts) {
6857                                         ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
6858                                 }
6859                                 if (bs) {
6860                                         ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
6861                                 }
6862                                 if (ls) {
6863                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
6864                                 }
6865                                 if (rs) {
6866                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
6867                                 }
6868                         }
6869
6870                         first = (ts || bs || ls || rs);
6871
6872                         if (o.snapMode !== "outer") {
6873                                 ts = Math.abs(t - y1) <= d;
6874                                 bs = Math.abs(b - y2) <= d;
6875                                 ls = Math.abs(l - x1) <= d;
6876                                 rs = Math.abs(r - x2) <= d;
6877                                 if (ts) {
6878                                         ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
6879                                 }
6880                                 if (bs) {
6881                                         ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
6882                                 }
6883                                 if (ls) {
6884                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
6885                                 }
6886                                 if (rs) {
6887                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
6888                                 }
6889                         }
6890
6891                         if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
6892                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6893                         }
6894                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
6895
6896                 }
6897
6898         }
6899 });
6900
6901 $.ui.plugin.add("draggable", "stack", {
6902         start: function( event, ui, instance ) {
6903                 var min,
6904                         o = instance.options,
6905                         group = $.makeArray($(o.stack)).sort(function(a, b) {
6906                                 return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
6907                         });
6908
6909                 if (!group.length) { return; }
6910
6911                 min = parseInt($(group[0]).css("zIndex"), 10) || 0;
6912                 $(group).each(function(i) {
6913                         $(this).css("zIndex", min + i);
6914                 });
6915                 this.css("zIndex", (min + group.length));
6916         }
6917 });
6918
6919 $.ui.plugin.add("draggable", "zIndex", {
6920         start: function( event, ui, instance ) {
6921                 var t = $( ui.helper ),
6922                         o = instance.options;
6923
6924                 if (t.css("zIndex")) {
6925                         o._zIndex = t.css("zIndex");
6926                 }
6927                 t.css("zIndex", o.zIndex);
6928         },
6929         stop: function( event, ui, instance ) {
6930                 var o = instance.options;
6931
6932                 if (o._zIndex) {
6933                         $(ui.helper).css("zIndex", o._zIndex);
6934                 }
6935         }
6936 });
6937
6938 var draggable = $.ui.draggable;
6939
6940
6941 /*!
6942  * jQuery UI Resizable 1.11.2
6943  * http://jqueryui.com
6944  *
6945  * Copyright 2014 jQuery Foundation and other contributors
6946  * Released under the MIT license.
6947  * http://jquery.org/license
6948  *
6949  * http://api.jqueryui.com/resizable/
6950  */
6951
6952
6953 $.widget("ui.resizable", $.ui.mouse, {
6954         version: "1.11.2",
6955         widgetEventPrefix: "resize",
6956         options: {
6957                 alsoResize: false,
6958                 animate: false,
6959                 animateDuration: "slow",
6960                 animateEasing: "swing",
6961                 aspectRatio: false,
6962                 autoHide: false,
6963                 containment: false,
6964                 ghost: false,
6965                 grid: false,
6966                 handles: "e,s,se",
6967                 helper: false,
6968                 maxHeight: null,
6969                 maxWidth: null,
6970                 minHeight: 10,
6971                 minWidth: 10,
6972                 // See #7960
6973                 zIndex: 90,
6974
6975                 // callbacks
6976                 resize: null,
6977                 start: null,
6978                 stop: null
6979         },
6980
6981         _num: function( value ) {
6982                 return parseInt( value, 10 ) || 0;
6983         },
6984
6985         _isNumber: function( value ) {
6986                 return !isNaN( parseInt( value, 10 ) );
6987         },
6988
6989         _hasScroll: function( el, a ) {
6990
6991                 if ( $( el ).css( "overflow" ) === "hidden") {
6992                         return false;
6993                 }
6994
6995                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
6996                         has = false;
6997
6998                 if ( el[ scroll ] > 0 ) {
6999                         return true;
7000                 }
7001
7002                 // TODO: determine which cases actually cause this to happen
7003                 // if the element doesn't have the scroll set, see if it's possible to
7004                 // set the scroll
7005                 el[ scroll ] = 1;
7006                 has = ( el[ scroll ] > 0 );
7007                 el[ scroll ] = 0;
7008                 return has;
7009         },
7010
7011         _create: function() {
7012
7013                 var n, i, handle, axis, hname,
7014                         that = this,
7015                         o = this.options;
7016                 this.element.addClass("ui-resizable");
7017
7018                 $.extend(this, {
7019                         _aspectRatio: !!(o.aspectRatio),
7020                         aspectRatio: o.aspectRatio,
7021                         originalElement: this.element,
7022                         _proportionallyResizeElements: [],
7023                         _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
7024                 });
7025
7026                 // Wrap the element if it cannot hold child nodes
7027                 if (this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
7028
7029                         this.element.wrap(
7030                                 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
7031                                         position: this.element.css("position"),
7032                                         width: this.element.outerWidth(),
7033                                         height: this.element.outerHeight(),
7034                                         top: this.element.css("top"),
7035                                         left: this.element.css("left")
7036                                 })
7037                         );
7038
7039                         this.element = this.element.parent().data(
7040                                 "ui-resizable", this.element.resizable( "instance" )
7041                         );
7042
7043                         this.elementIsWrapper = true;
7044
7045                         this.element.css({
7046                                 marginLeft: this.originalElement.css("marginLeft"),
7047                                 marginTop: this.originalElement.css("marginTop"),
7048                                 marginRight: this.originalElement.css("marginRight"),
7049                                 marginBottom: this.originalElement.css("marginBottom")
7050                         });
7051                         this.originalElement.css({
7052                                 marginLeft: 0,
7053                                 marginTop: 0,
7054                                 marginRight: 0,
7055                                 marginBottom: 0
7056                         });
7057                         // support: Safari
7058                         // Prevent Safari textarea resize
7059                         this.originalResizeStyle = this.originalElement.css("resize");
7060                         this.originalElement.css("resize", "none");
7061
7062                         this._proportionallyResizeElements.push( this.originalElement.css({
7063                                 position: "static",
7064                                 zoom: 1,
7065                                 display: "block"
7066                         }) );
7067
7068                         // support: IE9
7069                         // avoid IE jump (hard set the margin)
7070                         this.originalElement.css({ margin: this.originalElement.css("margin") });
7071
7072                         this._proportionallyResize();
7073                 }
7074
7075                 this.handles = o.handles ||
7076                         ( !$(".ui-resizable-handle", this.element).length ?
7077                                 "e,s,se" : {
7078                                         n: ".ui-resizable-n",
7079                                         e: ".ui-resizable-e",
7080                                         s: ".ui-resizable-s",
7081                                         w: ".ui-resizable-w",
7082                                         se: ".ui-resizable-se",
7083                                         sw: ".ui-resizable-sw",
7084                                         ne: ".ui-resizable-ne",
7085                                         nw: ".ui-resizable-nw"
7086                                 } );
7087
7088                 if (this.handles.constructor === String) {
7089
7090                         if ( this.handles === "all") {
7091                                 this.handles = "n,e,s,w,se,sw,ne,nw";
7092                         }
7093
7094                         n = this.handles.split(",");
7095                         this.handles = {};
7096
7097                         for (i = 0; i < n.length; i++) {
7098
7099                                 handle = $.trim(n[i]);
7100                                 hname = "ui-resizable-" + handle;
7101                                 axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
7102
7103                                 axis.css({ zIndex: o.zIndex });
7104
7105                                 // TODO : What's going on here?
7106                                 if ("se" === handle) {
7107                                         axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
7108                                 }
7109
7110                                 this.handles[handle] = ".ui-resizable-" + handle;
7111                                 this.element.append(axis);
7112                         }
7113
7114                 }
7115
7116                 this._renderAxis = function(target) {
7117
7118                         var i, axis, padPos, padWrapper;
7119
7120                         target = target || this.element;
7121
7122                         for (i in this.handles) {
7123
7124                                 if (this.handles[i].constructor === String) {
7125                                         this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
7126                                 }
7127
7128                                 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
7129
7130                                         axis = $(this.handles[i], this.element);
7131
7132                                         padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
7133
7134                                         padPos = [ "padding",
7135                                                 /ne|nw|n/.test(i) ? "Top" :
7136                                                 /se|sw|s/.test(i) ? "Bottom" :
7137                                                 /^e$/.test(i) ? "Right" : "Left" ].join("");
7138
7139                                         target.css(padPos, padWrapper);
7140
7141                                         this._proportionallyResize();
7142
7143                                 }
7144
7145                                 // TODO: What's that good for? There's not anything to be executed left
7146                                 if (!$(this.handles[i]).length) {
7147                                         continue;
7148                                 }
7149                         }
7150                 };
7151
7152                 // TODO: make renderAxis a prototype function
7153                 this._renderAxis(this.element);
7154
7155                 this._handles = $(".ui-resizable-handle", this.element)
7156                         .disableSelection();
7157
7158                 this._handles.mouseover(function() {
7159                         if (!that.resizing) {
7160                                 if (this.className) {
7161                                         axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
7162                                 }
7163                                 that.axis = axis && axis[1] ? axis[1] : "se";
7164                         }
7165                 });
7166
7167                 if (o.autoHide) {
7168                         this._handles.hide();
7169                         $(this.element)
7170                                 .addClass("ui-resizable-autohide")
7171                                 .mouseenter(function() {
7172                                         if (o.disabled) {
7173                                                 return;
7174                                         }
7175                                         $(this).removeClass("ui-resizable-autohide");
7176                                         that._handles.show();
7177                                 })
7178                                 .mouseleave(function() {
7179                                         if (o.disabled) {
7180                                                 return;
7181                                         }
7182                                         if (!that.resizing) {
7183                                                 $(this).addClass("ui-resizable-autohide");
7184                                                 that._handles.hide();
7185                                         }
7186                                 });
7187                 }
7188
7189                 this._mouseInit();
7190
7191         },
7192
7193         _destroy: function() {
7194
7195                 this._mouseDestroy();
7196
7197                 var wrapper,
7198                         _destroy = function(exp) {
7199                                 $(exp)
7200                                         .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
7201                                         .removeData("resizable")
7202                                         .removeData("ui-resizable")
7203                                         .unbind(".resizable")
7204                                         .find(".ui-resizable-handle")
7205                                                 .remove();
7206                         };
7207
7208                 // TODO: Unwrap at same DOM position
7209                 if (this.elementIsWrapper) {
7210                         _destroy(this.element);
7211                         wrapper = this.element;
7212                         this.originalElement.css({
7213                                 position: wrapper.css("position"),
7214                                 width: wrapper.outerWidth(),
7215                                 height: wrapper.outerHeight(),
7216                                 top: wrapper.css("top"),
7217                                 left: wrapper.css("left")
7218                         }).insertAfter( wrapper );
7219                         wrapper.remove();
7220                 }
7221
7222                 this.originalElement.css("resize", this.originalResizeStyle);
7223                 _destroy(this.originalElement);
7224
7225                 return this;
7226         },
7227
7228         _mouseCapture: function(event) {
7229                 var i, handle,
7230                         capture = false;
7231
7232                 for (i in this.handles) {
7233                         handle = $(this.handles[i])[0];
7234                         if (handle === event.target || $.contains(handle, event.target)) {
7235                                 capture = true;
7236                         }
7237                 }
7238
7239                 return !this.options.disabled && capture;
7240         },
7241
7242         _mouseStart: function(event) {
7243
7244                 var curleft, curtop, cursor,
7245                         o = this.options,
7246                         el = this.element;
7247
7248                 this.resizing = true;
7249
7250                 this._renderProxy();
7251
7252                 curleft = this._num(this.helper.css("left"));
7253                 curtop = this._num(this.helper.css("top"));
7254
7255                 if (o.containment) {
7256                         curleft += $(o.containment).scrollLeft() || 0;
7257                         curtop += $(o.containment).scrollTop() || 0;
7258                 }
7259
7260                 this.offset = this.helper.offset();
7261                 this.position = { left: curleft, top: curtop };
7262
7263                 this.size = this._helper ? {
7264                                 width: this.helper.width(),
7265                                 height: this.helper.height()
7266                         } : {
7267                                 width: el.width(),
7268                                 height: el.height()
7269                         };
7270
7271                 this.originalSize = this._helper ? {
7272                                 width: el.outerWidth(),
7273                                 height: el.outerHeight()
7274                         } : {
7275                                 width: el.width(),
7276                                 height: el.height()
7277                         };
7278
7279                 this.sizeDiff = {
7280                         width: el.outerWidth() - el.width(),
7281                         height: el.outerHeight() - el.height()
7282                 };
7283
7284                 this.originalPosition = { left: curleft, top: curtop };
7285                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
7286
7287                 this.aspectRatio = (typeof o.aspectRatio === "number") ?
7288                         o.aspectRatio :
7289                         ((this.originalSize.width / this.originalSize.height) || 1);
7290
7291                 cursor = $(".ui-resizable-" + this.axis).css("cursor");
7292                 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
7293
7294                 el.addClass("ui-resizable-resizing");
7295                 this._propagate("start", event);
7296                 return true;
7297         },
7298
7299         _mouseDrag: function(event) {
7300
7301                 var data, props,
7302                         smp = this.originalMousePosition,
7303                         a = this.axis,
7304                         dx = (event.pageX - smp.left) || 0,
7305                         dy = (event.pageY - smp.top) || 0,
7306                         trigger = this._change[a];
7307
7308                 this._updatePrevProperties();
7309
7310                 if (!trigger) {
7311                         return false;
7312                 }
7313
7314                 data = trigger.apply(this, [ event, dx, dy ]);
7315
7316                 this._updateVirtualBoundaries(event.shiftKey);
7317                 if (this._aspectRatio || event.shiftKey) {
7318                         data = this._updateRatio(data, event);
7319                 }
7320
7321                 data = this._respectSize(data, event);
7322
7323                 this._updateCache(data);
7324
7325                 this._propagate("resize", event);
7326
7327                 props = this._applyChanges();
7328
7329                 if ( !this._helper && this._proportionallyResizeElements.length ) {
7330                         this._proportionallyResize();
7331                 }
7332
7333                 if ( !$.isEmptyObject( props ) ) {
7334                         this._updatePrevProperties();
7335                         this._trigger( "resize", event, this.ui() );
7336                         this._applyChanges();
7337                 }
7338
7339                 return false;
7340         },
7341
7342         _mouseStop: function(event) {
7343
7344                 this.resizing = false;
7345                 var pr, ista, soffseth, soffsetw, s, left, top,
7346                         o = this.options, that = this;
7347
7348                 if (this._helper) {
7349
7350                         pr = this._proportionallyResizeElements;
7351                         ista = pr.length && (/textarea/i).test(pr[0].nodeName);
7352                         soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
7353                         soffsetw = ista ? 0 : that.sizeDiff.width;
7354
7355                         s = {
7356                                 width: (that.helper.width()  - soffsetw),
7357                                 height: (that.helper.height() - soffseth)
7358                         };
7359                         left = (parseInt(that.element.css("left"), 10) +
7360                                 (that.position.left - that.originalPosition.left)) || null;
7361                         top = (parseInt(that.element.css("top"), 10) +
7362                                 (that.position.top - that.originalPosition.top)) || null;
7363
7364                         if (!o.animate) {
7365                                 this.element.css($.extend(s, { top: top, left: left }));
7366                         }
7367
7368                         that.helper.height(that.size.height);
7369                         that.helper.width(that.size.width);
7370
7371                         if (this._helper && !o.animate) {
7372                                 this._proportionallyResize();
7373                         }
7374                 }
7375
7376                 $("body").css("cursor", "auto");
7377
7378                 this.element.removeClass("ui-resizable-resizing");
7379
7380                 this._propagate("stop", event);
7381
7382                 if (this._helper) {
7383                         this.helper.remove();
7384                 }
7385
7386                 return false;
7387
7388         },
7389
7390         _updatePrevProperties: function() {
7391                 this.prevPosition = {
7392                         top: this.position.top,
7393                         left: this.position.left
7394                 };
7395                 this.prevSize = {
7396                         width: this.size.width,
7397                         height: this.size.height
7398                 };
7399         },
7400
7401         _applyChanges: function() {
7402                 var props = {};
7403
7404                 if ( this.position.top !== this.prevPosition.top ) {
7405                         props.top = this.position.top + "px";
7406                 }
7407                 if ( this.position.left !== this.prevPosition.left ) {
7408                         props.left = this.position.left + "px";
7409                 }
7410                 if ( this.size.width !== this.prevSize.width ) {
7411                         props.width = this.size.width + "px";
7412                 }
7413                 if ( this.size.height !== this.prevSize.height ) {
7414                         props.height = this.size.height + "px";
7415                 }
7416
7417                 this.helper.css( props );
7418
7419                 return props;
7420         },
7421
7422         _updateVirtualBoundaries: function(forceAspectRatio) {
7423                 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
7424                         o = this.options;
7425
7426                 b = {
7427                         minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
7428                         maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
7429                         minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
7430                         maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
7431                 };
7432
7433                 if (this._aspectRatio || forceAspectRatio) {
7434                         pMinWidth = b.minHeight * this.aspectRatio;
7435                         pMinHeight = b.minWidth / this.aspectRatio;
7436                         pMaxWidth = b.maxHeight * this.aspectRatio;
7437                         pMaxHeight = b.maxWidth / this.aspectRatio;
7438
7439                         if (pMinWidth > b.minWidth) {
7440                                 b.minWidth = pMinWidth;
7441                         }
7442                         if (pMinHeight > b.minHeight) {
7443                                 b.minHeight = pMinHeight;
7444                         }
7445                         if (pMaxWidth < b.maxWidth) {
7446                                 b.maxWidth = pMaxWidth;
7447                         }
7448                         if (pMaxHeight < b.maxHeight) {
7449                                 b.maxHeight = pMaxHeight;
7450                         }
7451                 }
7452                 this._vBoundaries = b;
7453         },
7454
7455         _updateCache: function(data) {
7456                 this.offset = this.helper.offset();
7457                 if (this._isNumber(data.left)) {
7458                         this.position.left = data.left;
7459                 }
7460                 if (this._isNumber(data.top)) {
7461                         this.position.top = data.top;
7462                 }
7463                 if (this._isNumber(data.height)) {
7464                         this.size.height = data.height;
7465                 }
7466                 if (this._isNumber(data.width)) {
7467                         this.size.width = data.width;
7468                 }
7469         },
7470
7471         _updateRatio: function( data ) {
7472
7473                 var cpos = this.position,
7474                         csize = this.size,
7475                         a = this.axis;
7476
7477                 if (this._isNumber(data.height)) {
7478                         data.width = (data.height * this.aspectRatio);
7479                 } else if (this._isNumber(data.width)) {
7480                         data.height = (data.width / this.aspectRatio);
7481                 }
7482
7483                 if (a === "sw") {
7484                         data.left = cpos.left + (csize.width - data.width);
7485                         data.top = null;
7486                 }
7487                 if (a === "nw") {
7488                         data.top = cpos.top + (csize.height - data.height);
7489                         data.left = cpos.left + (csize.width - data.width);
7490                 }
7491
7492                 return data;
7493         },
7494
7495         _respectSize: function( data ) {
7496
7497                 var o = this._vBoundaries,
7498                         a = this.axis,
7499                         ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
7500                         ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
7501                         isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
7502                         isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
7503                         dw = this.originalPosition.left + this.originalSize.width,
7504                         dh = this.position.top + this.size.height,
7505                         cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
7506                 if (isminw) {
7507                         data.width = o.minWidth;
7508                 }
7509                 if (isminh) {
7510                         data.height = o.minHeight;
7511                 }
7512                 if (ismaxw) {
7513                         data.width = o.maxWidth;
7514                 }
7515                 if (ismaxh) {
7516                         data.height = o.maxHeight;
7517                 }
7518
7519                 if (isminw && cw) {
7520                         data.left = dw - o.minWidth;
7521                 }
7522                 if (ismaxw && cw) {
7523                         data.left = dw - o.maxWidth;
7524                 }
7525                 if (isminh && ch) {
7526                         data.top = dh - o.minHeight;
7527                 }
7528                 if (ismaxh && ch) {
7529                         data.top = dh - o.maxHeight;
7530                 }
7531
7532                 // Fixing jump error on top/left - bug #2330
7533                 if (!data.width && !data.height && !data.left && data.top) {
7534                         data.top = null;
7535                 } else if (!data.width && !data.height && !data.top && data.left) {
7536                         data.left = null;
7537                 }
7538
7539                 return data;
7540         },
7541
7542         _getPaddingPlusBorderDimensions: function( element ) {
7543                 var i = 0,
7544                         widths = [],
7545                         borders = [
7546                                 element.css( "borderTopWidth" ),
7547                                 element.css( "borderRightWidth" ),
7548                                 element.css( "borderBottomWidth" ),
7549                                 element.css( "borderLeftWidth" )
7550                         ],
7551                         paddings = [
7552                                 element.css( "paddingTop" ),
7553                                 element.css( "paddingRight" ),
7554                                 element.css( "paddingBottom" ),
7555                                 element.css( "paddingLeft" )
7556                         ];
7557
7558                 for ( ; i < 4; i++ ) {
7559                         widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
7560                         widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
7561                 }
7562
7563                 return {
7564                         height: widths[ 0 ] + widths[ 2 ],
7565                         width: widths[ 1 ] + widths[ 3 ]
7566                 };
7567         },
7568
7569         _proportionallyResize: function() {
7570
7571                 if (!this._proportionallyResizeElements.length) {
7572                         return;
7573                 }
7574
7575                 var prel,
7576                         i = 0,
7577                         element = this.helper || this.element;
7578
7579                 for ( ; i < this._proportionallyResizeElements.length; i++) {
7580
7581                         prel = this._proportionallyResizeElements[i];
7582
7583                         // TODO: Seems like a bug to cache this.outerDimensions
7584                         // considering that we are in a loop.
7585                         if (!this.outerDimensions) {
7586                                 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
7587                         }
7588
7589                         prel.css({
7590                                 height: (element.height() - this.outerDimensions.height) || 0,
7591                                 width: (element.width() - this.outerDimensions.width) || 0
7592                         });
7593
7594                 }
7595
7596         },
7597
7598         _renderProxy: function() {
7599
7600                 var el = this.element, o = this.options;
7601                 this.elementOffset = el.offset();
7602
7603                 if (this._helper) {
7604
7605                         this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
7606
7607                         this.helper.addClass(this._helper).css({
7608                                 width: this.element.outerWidth() - 1,
7609                                 height: this.element.outerHeight() - 1,
7610                                 position: "absolute",
7611                                 left: this.elementOffset.left + "px",
7612                                 top: this.elementOffset.top + "px",
7613                                 zIndex: ++o.zIndex //TODO: Don't modify option
7614                         });
7615
7616                         this.helper
7617                                 .appendTo("body")
7618                                 .disableSelection();
7619
7620                 } else {
7621                         this.helper = this.element;
7622                 }
7623
7624         },
7625
7626         _change: {
7627                 e: function(event, dx) {
7628                         return { width: this.originalSize.width + dx };
7629                 },
7630                 w: function(event, dx) {
7631                         var cs = this.originalSize, sp = this.originalPosition;
7632                         return { left: sp.left + dx, width: cs.width - dx };
7633                 },
7634                 n: function(event, dx, dy) {
7635                         var cs = this.originalSize, sp = this.originalPosition;
7636                         return { top: sp.top + dy, height: cs.height - dy };
7637                 },
7638                 s: function(event, dx, dy) {
7639                         return { height: this.originalSize.height + dy };
7640                 },
7641                 se: function(event, dx, dy) {
7642                         return $.extend(this._change.s.apply(this, arguments),
7643                                 this._change.e.apply(this, [ event, dx, dy ]));
7644                 },
7645                 sw: function(event, dx, dy) {
7646                         return $.extend(this._change.s.apply(this, arguments),
7647                                 this._change.w.apply(this, [ event, dx, dy ]));
7648                 },
7649                 ne: function(event, dx, dy) {
7650                         return $.extend(this._change.n.apply(this, arguments),
7651                                 this._change.e.apply(this, [ event, dx, dy ]));
7652                 },
7653                 nw: function(event, dx, dy) {
7654                         return $.extend(this._change.n.apply(this, arguments),
7655                                 this._change.w.apply(this, [ event, dx, dy ]));
7656                 }
7657         },
7658
7659         _propagate: function(n, event) {
7660                 $.ui.plugin.call(this, n, [ event, this.ui() ]);
7661                 (n !== "resize" && this._trigger(n, event, this.ui()));
7662         },
7663
7664         plugins: {},
7665
7666         ui: function() {
7667                 return {
7668                         originalElement: this.originalElement,
7669                         element: this.element,
7670                         helper: this.helper,
7671                         position: this.position,
7672                         size: this.size,
7673                         originalSize: this.originalSize,
7674                         originalPosition: this.originalPosition
7675                 };
7676         }
7677
7678 });
7679
7680 /*
7681  * Resizable Extensions
7682  */
7683
7684 $.ui.plugin.add("resizable", "animate", {
7685
7686         stop: function( event ) {
7687                 var that = $(this).resizable( "instance" ),
7688                         o = that.options,
7689                         pr = that._proportionallyResizeElements,
7690                         ista = pr.length && (/textarea/i).test(pr[0].nodeName),
7691                         soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
7692                         soffsetw = ista ? 0 : that.sizeDiff.width,
7693                         style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
7694                         left = (parseInt(that.element.css("left"), 10) +
7695                                 (that.position.left - that.originalPosition.left)) || null,
7696                         top = (parseInt(that.element.css("top"), 10) +
7697                                 (that.position.top - that.originalPosition.top)) || null;
7698
7699                 that.element.animate(
7700                         $.extend(style, top && left ? { top: top, left: left } : {}), {
7701                                 duration: o.animateDuration,
7702                                 easing: o.animateEasing,
7703                                 step: function() {
7704
7705                                         var data = {
7706                                                 width: parseInt(that.element.css("width"), 10),
7707                                                 height: parseInt(that.element.css("height"), 10),
7708                                                 top: parseInt(that.element.css("top"), 10),
7709                                                 left: parseInt(that.element.css("left"), 10)
7710                                         };
7711
7712                                         if (pr && pr.length) {
7713                                                 $(pr[0]).css({ width: data.width, height: data.height });
7714                                         }
7715
7716                                         // propagating resize, and updating values for each animation step
7717                                         that._updateCache(data);
7718                                         that._propagate("resize", event);
7719
7720                                 }
7721                         }
7722                 );
7723         }
7724
7725 });
7726
7727 $.ui.plugin.add( "resizable", "containment", {
7728
7729         start: function() {
7730                 var element, p, co, ch, cw, width, height,
7731                         that = $( this ).resizable( "instance" ),
7732                         o = that.options,
7733                         el = that.element,
7734                         oc = o.containment,
7735                         ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
7736
7737                 if ( !ce ) {
7738                         return;
7739                 }
7740
7741                 that.containerElement = $( ce );
7742
7743                 if ( /document/.test( oc ) || oc === document ) {
7744                         that.containerOffset = {
7745                                 left: 0,
7746                                 top: 0
7747                         };
7748                         that.containerPosition = {
7749                                 left: 0,
7750                                 top: 0
7751                         };
7752
7753                         that.parentData = {
7754                                 element: $( document ),
7755                                 left: 0,
7756                                 top: 0,
7757                                 width: $( document ).width(),
7758                                 height: $( document ).height() || document.body.parentNode.scrollHeight
7759                         };
7760                 } else {
7761                         element = $( ce );
7762                         p = [];
7763                         $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
7764                                 p[ i ] = that._num( element.css( "padding" + name ) );
7765                         });
7766
7767                         that.containerOffset = element.offset();
7768                         that.containerPosition = element.position();
7769                         that.containerSize = {
7770                                 height: ( element.innerHeight() - p[ 3 ] ),
7771                                 width: ( element.innerWidth() - p[ 1 ] )
7772                         };
7773
7774                         co = that.containerOffset;
7775                         ch = that.containerSize.height;
7776                         cw = that.containerSize.width;
7777                         width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
7778                         height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
7779
7780                         that.parentData = {
7781                                 element: ce,
7782                                 left: co.left,
7783                                 top: co.top,
7784                                 width: width,
7785                                 height: height
7786                         };
7787                 }
7788         },
7789
7790         resize: function( event ) {
7791                 var woset, hoset, isParent, isOffsetRelative,
7792                         that = $( this ).resizable( "instance" ),
7793                         o = that.options,
7794                         co = that.containerOffset,
7795                         cp = that.position,
7796                         pRatio = that._aspectRatio || event.shiftKey,
7797                         cop = {
7798                                 top: 0,
7799                                 left: 0
7800                         },
7801                         ce = that.containerElement,
7802                         continueResize = true;
7803
7804                 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
7805                         cop = co;
7806                 }
7807
7808                 if ( cp.left < ( that._helper ? co.left : 0 ) ) {
7809                         that.size.width = that.size.width +
7810                                 ( that._helper ?
7811                                         ( that.position.left - co.left ) :
7812                                         ( that.position.left - cop.left ) );
7813
7814                         if ( pRatio ) {
7815                                 that.size.height = that.size.width / that.aspectRatio;
7816                                 continueResize = false;
7817                         }
7818                         that.position.left = o.helper ? co.left : 0;
7819                 }
7820
7821                 if ( cp.top < ( that._helper ? co.top : 0 ) ) {
7822                         that.size.height = that.size.height +
7823                                 ( that._helper ?
7824                                         ( that.position.top - co.top ) :
7825                                         that.position.top );
7826
7827                         if ( pRatio ) {
7828                                 that.size.width = that.size.height * that.aspectRatio;
7829                                 continueResize = false;
7830                         }
7831                         that.position.top = that._helper ? co.top : 0;
7832                 }
7833
7834                 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
7835                 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
7836
7837                 if ( isParent && isOffsetRelative ) {
7838                         that.offset.left = that.parentData.left + that.position.left;
7839                         that.offset.top = that.parentData.top + that.position.top;
7840                 } else {
7841                         that.offset.left = that.element.offset().left;
7842                         that.offset.top = that.element.offset().top;
7843                 }
7844
7845                 woset = Math.abs( that.sizeDiff.width +
7846                         (that._helper ?
7847                                 that.offset.left - cop.left :
7848                                 (that.offset.left - co.left)) );
7849
7850                 hoset = Math.abs( that.sizeDiff.height +
7851                         (that._helper ?
7852                                 that.offset.top - cop.top :
7853                                 (that.offset.top - co.top)) );
7854
7855                 if ( woset + that.size.width >= that.parentData.width ) {
7856                         that.size.width = that.parentData.width - woset;
7857                         if ( pRatio ) {
7858                                 that.size.height = that.size.width / that.aspectRatio;
7859                                 continueResize = false;
7860                         }
7861                 }
7862
7863                 if ( hoset + that.size.height >= that.parentData.height ) {
7864                         that.size.height = that.parentData.height - hoset;
7865                         if ( pRatio ) {
7866                                 that.size.width = that.size.height * that.aspectRatio;
7867                                 continueResize = false;
7868                         }
7869                 }
7870
7871                 if ( !continueResize ){
7872                         that.position.left = that.prevPosition.left;
7873                         that.position.top = that.prevPosition.top;
7874                         that.size.width = that.prevSize.width;
7875                         that.size.height = that.prevSize.height;
7876                 }
7877         },
7878
7879         stop: function() {
7880                 var that = $( this ).resizable( "instance" ),
7881                         o = that.options,
7882                         co = that.containerOffset,
7883                         cop = that.containerPosition,
7884                         ce = that.containerElement,
7885                         helper = $( that.helper ),
7886                         ho = helper.offset(),
7887                         w = helper.outerWidth() - that.sizeDiff.width,
7888                         h = helper.outerHeight() - that.sizeDiff.height;
7889
7890                 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
7891                         $( this ).css({
7892                                 left: ho.left - cop.left - co.left,
7893                                 width: w,
7894                                 height: h
7895                         });
7896                 }
7897
7898                 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
7899                         $( this ).css({
7900                                 left: ho.left - cop.left - co.left,
7901                                 width: w,
7902                                 height: h
7903                         });
7904                 }
7905         }
7906 });
7907
7908 $.ui.plugin.add("resizable", "alsoResize", {
7909
7910         start: function() {
7911                 var that = $(this).resizable( "instance" ),
7912                         o = that.options,
7913                         _store = function(exp) {
7914                                 $(exp).each(function() {
7915                                         var el = $(this);
7916                                         el.data("ui-resizable-alsoresize", {
7917                                                 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
7918                                                 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
7919                                         });
7920                                 });
7921                         };
7922
7923                 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
7924                         if (o.alsoResize.length) {
7925                                 o.alsoResize = o.alsoResize[0];
7926                                 _store(o.alsoResize);
7927                         } else {
7928                                 $.each(o.alsoResize, function(exp) {
7929                                         _store(exp);
7930                                 });
7931                         }
7932                 } else {
7933                         _store(o.alsoResize);
7934                 }
7935         },
7936
7937         resize: function(event, ui) {
7938                 var that = $(this).resizable( "instance" ),
7939                         o = that.options,
7940                         os = that.originalSize,
7941                         op = that.originalPosition,
7942                         delta = {
7943                                 height: (that.size.height - os.height) || 0,
7944                                 width: (that.size.width - os.width) || 0,
7945                                 top: (that.position.top - op.top) || 0,
7946                                 left: (that.position.left - op.left) || 0
7947                         },
7948
7949                         _alsoResize = function(exp, c) {
7950                                 $(exp).each(function() {
7951                                         var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
7952                                                 css = c && c.length ?
7953                                                         c :
7954                                                         el.parents(ui.originalElement[0]).length ?
7955                                                                 [ "width", "height" ] :
7956                                                                 [ "width", "height", "top", "left" ];
7957
7958                                         $.each(css, function(i, prop) {
7959                                                 var sum = (start[prop] || 0) + (delta[prop] || 0);
7960                                                 if (sum && sum >= 0) {
7961                                                         style[prop] = sum || null;
7962                                                 }
7963                                         });
7964
7965                                         el.css(style);
7966                                 });
7967                         };
7968
7969                 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
7970                         $.each(o.alsoResize, function(exp, c) {
7971                                 _alsoResize(exp, c);
7972                         });
7973                 } else {
7974                         _alsoResize(o.alsoResize);
7975                 }
7976         },
7977
7978         stop: function() {
7979                 $(this).removeData("resizable-alsoresize");
7980         }
7981 });
7982
7983 $.ui.plugin.add("resizable", "ghost", {
7984
7985         start: function() {
7986
7987                 var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
7988
7989                 that.ghost = that.originalElement.clone();
7990                 that.ghost
7991                         .css({
7992                                 opacity: 0.25,
7993                                 display: "block",
7994                                 position: "relative",
7995                                 height: cs.height,
7996                                 width: cs.width,
7997                                 margin: 0,
7998                                 left: 0,
7999                                 top: 0
8000                         })
8001                         .addClass("ui-resizable-ghost")
8002                         .addClass(typeof o.ghost === "string" ? o.ghost : "");
8003
8004                 that.ghost.appendTo(that.helper);
8005
8006         },
8007
8008         resize: function() {
8009                 var that = $(this).resizable( "instance" );
8010                 if (that.ghost) {
8011                         that.ghost.css({
8012                                 position: "relative",
8013                                 height: that.size.height,
8014                                 width: that.size.width
8015                         });
8016                 }
8017         },
8018
8019         stop: function() {
8020                 var that = $(this).resizable( "instance" );
8021                 if (that.ghost && that.helper) {
8022                         that.helper.get(0).removeChild(that.ghost.get(0));
8023                 }
8024         }
8025
8026 });
8027
8028 $.ui.plugin.add("resizable", "grid", {
8029
8030         resize: function() {
8031                 var outerDimensions,
8032                         that = $(this).resizable( "instance" ),
8033                         o = that.options,
8034                         cs = that.size,
8035                         os = that.originalSize,
8036                         op = that.originalPosition,
8037                         a = that.axis,
8038                         grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
8039                         gridX = (grid[0] || 1),
8040                         gridY = (grid[1] || 1),
8041                         ox = Math.round((cs.width - os.width) / gridX) * gridX,
8042                         oy = Math.round((cs.height - os.height) / gridY) * gridY,
8043                         newWidth = os.width + ox,
8044                         newHeight = os.height + oy,
8045                         isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
8046                         isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
8047                         isMinWidth = o.minWidth && (o.minWidth > newWidth),
8048                         isMinHeight = o.minHeight && (o.minHeight > newHeight);
8049
8050                 o.grid = grid;
8051
8052                 if (isMinWidth) {
8053                         newWidth += gridX;
8054                 }
8055                 if (isMinHeight) {
8056                         newHeight += gridY;
8057                 }
8058                 if (isMaxWidth) {
8059                         newWidth -= gridX;
8060                 }
8061                 if (isMaxHeight) {
8062                         newHeight -= gridY;
8063                 }
8064
8065                 if (/^(se|s|e)$/.test(a)) {
8066                         that.size.width = newWidth;
8067                         that.size.height = newHeight;
8068                 } else if (/^(ne)$/.test(a)) {
8069                         that.size.width = newWidth;
8070                         that.size.height = newHeight;
8071                         that.position.top = op.top - oy;
8072                 } else if (/^(sw)$/.test(a)) {
8073                         that.size.width = newWidth;
8074                         that.size.height = newHeight;
8075                         that.position.left = op.left - ox;
8076                 } else {
8077                         if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
8078                                 outerDimensions = that._getPaddingPlusBorderDimensions( this );
8079                         }
8080
8081                         if ( newHeight - gridY > 0 ) {
8082                                 that.size.height = newHeight;
8083                                 that.position.top = op.top - oy;
8084                         } else {
8085                                 newHeight = gridY - outerDimensions.height;
8086                                 that.size.height = newHeight;
8087                                 that.position.top = op.top + os.height - newHeight;
8088                         }
8089                         if ( newWidth - gridX > 0 ) {
8090                                 that.size.width = newWidth;
8091                                 that.position.left = op.left - ox;
8092                         } else {
8093                                 newWidth = gridY - outerDimensions.height;
8094                                 that.size.width = newWidth;
8095                                 that.position.left = op.left + os.width - newWidth;
8096                         }
8097                 }
8098         }
8099
8100 });
8101
8102 var resizable = $.ui.resizable;
8103
8104
8105 /*!
8106  * jQuery UI Dialog 1.11.2
8107  * http://jqueryui.com
8108  *
8109  * Copyright 2014 jQuery Foundation and other contributors
8110  * Released under the MIT license.
8111  * http://jquery.org/license
8112  *
8113  * http://api.jqueryui.com/dialog/
8114  */
8115
8116
8117 var dialog = $.widget( "ui.dialog", {
8118         version: "1.11.2",
8119         options: {
8120                 appendTo: "body",
8121                 autoOpen: true,
8122                 buttons: [],
8123                 closeOnEscape: true,
8124                 closeText: "Close",
8125                 dialogClass: "",
8126                 draggable: true,
8127                 hide: null,
8128                 height: "auto",
8129                 maxHeight: null,
8130                 maxWidth: null,
8131                 minHeight: 150,
8132                 minWidth: 150,
8133                 modal: false,
8134                 position: {
8135                         my: "center",
8136                         at: "center",
8137                         of: window,
8138                         collision: "fit",
8139                         // Ensure the titlebar is always visible
8140                         using: function( pos ) {
8141                                 var topOffset = $( this ).css( pos ).offset().top;
8142                                 if ( topOffset < 0 ) {
8143                                         $( this ).css( "top", pos.top - topOffset );
8144                                 }
8145                         }
8146                 },
8147                 resizable: true,
8148                 show: null,
8149                 title: null,
8150                 width: 300,
8151
8152                 // callbacks
8153                 beforeClose: null,
8154                 close: null,
8155                 drag: null,
8156                 dragStart: null,
8157                 dragStop: null,
8158                 focus: null,
8159                 open: null,
8160                 resize: null,
8161                 resizeStart: null,
8162                 resizeStop: null
8163         },
8164
8165         sizeRelatedOptions: {
8166                 buttons: true,
8167                 height: true,
8168                 maxHeight: true,
8169                 maxWidth: true,
8170                 minHeight: true,
8171                 minWidth: true,
8172                 width: true
8173         },
8174
8175         resizableRelatedOptions: {
8176                 maxHeight: true,
8177                 maxWidth: true,
8178                 minHeight: true,
8179                 minWidth: true
8180         },
8181
8182         _create: function() {
8183                 this.originalCss = {
8184                         display: this.element[ 0 ].style.display,
8185                         width: this.element[ 0 ].style.width,
8186                         minHeight: this.element[ 0 ].style.minHeight,
8187                         maxHeight: this.element[ 0 ].style.maxHeight,
8188                         height: this.element[ 0 ].style.height
8189                 };
8190                 this.originalPosition = {
8191                         parent: this.element.parent(),
8192                         index: this.element.parent().children().index( this.element )
8193                 };
8194                 this.originalTitle = this.element.attr( "title" );
8195                 this.options.title = this.options.title || this.originalTitle;
8196
8197                 this._createWrapper();
8198
8199                 this.element
8200                         .show()
8201                         .removeAttr( "title" )
8202                         .addClass( "ui-dialog-content ui-widget-content" )
8203                         .appendTo( this.uiDialog );
8204
8205                 this._createTitlebar();
8206                 this._createButtonPane();
8207
8208                 if ( this.options.draggable && $.fn.draggable ) {
8209                         this._makeDraggable();
8210                 }
8211                 if ( this.options.resizable && $.fn.resizable ) {
8212                         this._makeResizable();
8213                 }
8214
8215                 this._isOpen = false;
8216
8217                 this._trackFocus();
8218         },
8219
8220         _init: function() {
8221                 if ( this.options.autoOpen ) {
8222                         this.open();
8223                 }
8224         },
8225
8226         _appendTo: function() {
8227                 var element = this.options.appendTo;
8228                 if ( element && (element.jquery || element.nodeType) ) {
8229                         return $( element );
8230                 }
8231                 return this.document.find( element || "body" ).eq( 0 );
8232         },
8233
8234         _destroy: function() {
8235                 var next,
8236                         originalPosition = this.originalPosition;
8237
8238                 this._destroyOverlay();
8239
8240                 this.element
8241                         .removeUniqueId()
8242                         .removeClass( "ui-dialog-content ui-widget-content" )
8243                         .css( this.originalCss )
8244                         // Without detaching first, the following becomes really slow
8245                         .detach();
8246
8247                 this.uiDialog.stop( true, true ).remove();
8248
8249                 if ( this.originalTitle ) {
8250                         this.element.attr( "title", this.originalTitle );
8251                 }
8252
8253                 next = originalPosition.parent.children().eq( originalPosition.index );
8254                 // Don't try to place the dialog next to itself (#8613)
8255                 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
8256                         next.before( this.element );
8257                 } else {
8258                         originalPosition.parent.append( this.element );
8259                 }
8260         },
8261
8262         widget: function() {
8263                 return this.uiDialog;
8264         },
8265
8266         disable: $.noop,
8267         enable: $.noop,
8268
8269         close: function( event ) {
8270                 var activeElement,
8271                         that = this;
8272
8273                 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
8274                         return;
8275                 }
8276
8277                 this._isOpen = false;
8278                 this._focusedElement = null;
8279                 this._destroyOverlay();
8280                 this._untrackInstance();
8281
8282                 if ( !this.opener.filter( ":focusable" ).focus().length ) {
8283
8284                         // support: IE9
8285                         // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
8286                         try {
8287                                 activeElement = this.document[ 0 ].activeElement;
8288
8289                                 // Support: IE9, IE10
8290                                 // If the <body> is blurred, IE will switch windows, see #4520
8291                                 if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
8292
8293                                         // Hiding a focused element doesn't trigger blur in WebKit
8294                                         // so in case we have nothing to focus on, explicitly blur the active element
8295                                         // https://bugs.webkit.org/show_bug.cgi?id=47182
8296                                         $( activeElement ).blur();
8297                                 }
8298                         } catch ( error ) {}
8299                 }
8300
8301                 this._hide( this.uiDialog, this.options.hide, function() {
8302                         that._trigger( "close", event );
8303                 });
8304         },
8305
8306         isOpen: function() {
8307                 return this._isOpen;
8308         },
8309
8310         moveToTop: function() {
8311                 this._moveToTop();
8312         },
8313
8314         _moveToTop: function( event, silent ) {
8315                 var moved = false,
8316                         zIndicies = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
8317                                 return +$( this ).css( "z-index" );
8318                         }).get(),
8319                         zIndexMax = Math.max.apply( null, zIndicies );
8320
8321                 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
8322                         this.uiDialog.css( "z-index", zIndexMax + 1 );
8323                         moved = true;
8324                 }
8325
8326                 if ( moved && !silent ) {
8327                         this._trigger( "focus", event );
8328                 }
8329                 return moved;
8330         },
8331
8332         open: function() {
8333                 var that = this;
8334                 if ( this._isOpen ) {
8335                         if ( this._moveToTop() ) {
8336                                 this._focusTabbable();
8337                         }
8338                         return;
8339                 }
8340
8341                 this._isOpen = true;
8342                 this.opener = $( this.document[ 0 ].activeElement );
8343
8344                 this._size();
8345                 this._position();
8346                 this._createOverlay();
8347                 this._moveToTop( null, true );
8348
8349                 // Ensure the overlay is moved to the top with the dialog, but only when
8350                 // opening. The overlay shouldn't move after the dialog is open so that
8351                 // modeless dialogs opened after the modal dialog stack properly.
8352                 if ( this.overlay ) {
8353                         this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
8354                 }
8355
8356                 this._show( this.uiDialog, this.options.show, function() {
8357                         that._focusTabbable();
8358                         that._trigger( "focus" );
8359                 });
8360
8361                 // Track the dialog immediately upon openening in case a focus event
8362                 // somehow occurs outside of the dialog before an element inside the
8363                 // dialog is focused (#10152)
8364                 this._makeFocusTarget();
8365
8366                 this._trigger( "open" );
8367         },
8368
8369         _focusTabbable: function() {
8370                 // Set focus to the first match:
8371                 // 1. An element that was focused previously
8372                 // 2. First element inside the dialog matching [autofocus]
8373                 // 3. Tabbable element inside the content element
8374                 // 4. Tabbable element inside the buttonpane
8375                 // 5. The close button
8376                 // 6. The dialog itself
8377                 var hasFocus = this._focusedElement;
8378                 if ( !hasFocus ) {
8379                         hasFocus = this.element.find( "[autofocus]" );
8380                 }
8381                 if ( !hasFocus.length ) {
8382                         hasFocus = this.element.find( ":tabbable" );
8383                 }
8384                 if ( !hasFocus.length ) {
8385                         hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
8386                 }
8387                 if ( !hasFocus.length ) {
8388                         hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
8389                 }
8390                 if ( !hasFocus.length ) {
8391                         hasFocus = this.uiDialog;
8392                 }
8393                 hasFocus.eq( 0 ).focus();
8394         },
8395
8396         _keepFocus: function( event ) {
8397                 function checkFocus() {
8398                         var activeElement = this.document[0].activeElement,
8399                                 isActive = this.uiDialog[0] === activeElement ||
8400                                         $.contains( this.uiDialog[0], activeElement );
8401                         if ( !isActive ) {
8402                                 this._focusTabbable();
8403                         }
8404                 }
8405                 event.preventDefault();
8406                 checkFocus.call( this );
8407                 // support: IE
8408                 // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
8409                 // so we check again later
8410                 this._delay( checkFocus );
8411         },
8412
8413         _createWrapper: function() {
8414                 this.uiDialog = $("<div>")
8415                         .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
8416                                 this.options.dialogClass )
8417                         .hide()
8418                         .attr({
8419                                 // Setting tabIndex makes the div focusable
8420                                 tabIndex: -1,
8421                                 role: "dialog"
8422                         })
8423                         .appendTo( this._appendTo() );
8424
8425                 this._on( this.uiDialog, {
8426                         keydown: function( event ) {
8427                                 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
8428                                                 event.keyCode === $.ui.keyCode.ESCAPE ) {
8429                                         event.preventDefault();
8430                                         this.close( event );
8431                                         return;
8432                                 }
8433
8434                                 // prevent tabbing out of dialogs
8435                                 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
8436                                         return;
8437                                 }
8438                                 var tabbables = this.uiDialog.find( ":tabbable" ),
8439                                         first = tabbables.filter( ":first" ),
8440                                         last = tabbables.filter( ":last" );
8441
8442                                 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
8443                                         this._delay(function() {
8444                                                 first.focus();
8445                                         });
8446                                         event.preventDefault();
8447                                 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
8448                                         this._delay(function() {
8449                                                 last.focus();
8450                                         });
8451                                         event.preventDefault();
8452                                 }
8453                         },
8454                         mousedown: function( event ) {
8455                                 if ( this._moveToTop( event ) ) {
8456                                         this._focusTabbable();
8457                                 }
8458                         }
8459                 });
8460
8461                 // We assume that any existing aria-describedby attribute means
8462                 // that the dialog content is marked up properly
8463                 // otherwise we brute force the content as the description
8464                 if ( !this.element.find( "[aria-describedby]" ).length ) {
8465                         this.uiDialog.attr({
8466                                 "aria-describedby": this.element.uniqueId().attr( "id" )
8467                         });
8468                 }
8469         },
8470
8471         _createTitlebar: function() {
8472                 var uiDialogTitle;
8473
8474                 this.uiDialogTitlebar = $( "<div>" )
8475                         .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
8476                         .prependTo( this.uiDialog );
8477                 this._on( this.uiDialogTitlebar, {
8478                         mousedown: function( event ) {
8479                                 // Don't prevent click on close button (#8838)
8480                                 // Focusing a dialog that is partially scrolled out of view
8481                                 // causes the browser to scroll it into view, preventing the click event
8482                                 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
8483                                         // Dialog isn't getting focus when dragging (#8063)
8484                                         this.uiDialog.focus();
8485                                 }
8486                         }
8487                 });
8488
8489                 // support: IE
8490                 // Use type="button" to prevent enter keypresses in textboxes from closing the
8491                 // dialog in IE (#9312)
8492                 this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
8493                         .button({
8494                                 label: this.options.closeText,
8495                                 icons: {
8496                                         primary: "ui-icon-closethick"
8497                                 },
8498                                 text: false
8499                         })
8500                         .addClass( "ui-dialog-titlebar-close" )
8501                         .appendTo( this.uiDialogTitlebar );
8502                 this._on( this.uiDialogTitlebarClose, {
8503                         click: function( event ) {
8504                                 event.preventDefault();
8505                                 this.close( event );
8506                         }
8507                 });
8508
8509                 uiDialogTitle = $( "<span>" )
8510                         .uniqueId()
8511                         .addClass( "ui-dialog-title" )
8512                         .prependTo( this.uiDialogTitlebar );
8513                 this._title( uiDialogTitle );
8514
8515                 this.uiDialog.attr({
8516                         "aria-labelledby": uiDialogTitle.attr( "id" )
8517                 });
8518         },
8519
8520         _title: function( title ) {
8521                 if ( !this.options.title ) {
8522                         title.html( "&#160;" );
8523                 }
8524                 title.text( this.options.title );
8525         },
8526
8527         _createButtonPane: function() {
8528                 this.uiDialogButtonPane = $( "<div>" )
8529                         .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
8530
8531                 this.uiButtonSet = $( "<div>" )
8532                         .addClass( "ui-dialog-buttonset" )
8533                         .appendTo( this.uiDialogButtonPane );
8534
8535                 this._createButtons();
8536         },
8537
8538         _createButtons: function() {
8539                 var that = this,
8540                         buttons = this.options.buttons;
8541
8542                 // if we already have a button pane, remove it
8543                 this.uiDialogButtonPane.remove();
8544                 this.uiButtonSet.empty();
8545
8546                 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
8547                         this.uiDialog.removeClass( "ui-dialog-buttons" );
8548                         return;
8549                 }
8550
8551                 $.each( buttons, function( name, props ) {
8552                         var click, buttonOptions;
8553                         props = $.isFunction( props ) ?
8554                                 { click: props, text: name } :
8555                                 props;
8556                         // Default to a non-submitting button
8557                         props = $.extend( { type: "button" }, props );
8558                         // Change the context for the click callback to be the main element
8559                         click = props.click;
8560                         props.click = function() {
8561                                 click.apply( that.element[ 0 ], arguments );
8562                         };
8563                         buttonOptions = {
8564                                 icons: props.icons,
8565                                 text: props.showText
8566                         };
8567                         delete props.icons;
8568                         delete props.showText;
8569                         $( "<button></button>", props )
8570                                 .button( buttonOptions )
8571                                 .appendTo( that.uiButtonSet );
8572                 });
8573                 this.uiDialog.addClass( "ui-dialog-buttons" );
8574                 this.uiDialogButtonPane.appendTo( this.uiDialog );
8575         },
8576
8577         _makeDraggable: function() {
8578                 var that = this,
8579                         options = this.options;
8580
8581                 function filteredUi( ui ) {
8582                         return {
8583                                 position: ui.position,
8584                                 offset: ui.offset
8585                         };
8586                 }
8587
8588                 this.uiDialog.draggable({
8589                         cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
8590                         handle: ".ui-dialog-titlebar",
8591                         containment: "document",
8592                         start: function( event, ui ) {
8593                                 $( this ).addClass( "ui-dialog-dragging" );
8594                                 that._blockFrames();
8595                                 that._trigger( "dragStart", event, filteredUi( ui ) );
8596                         },
8597                         drag: function( event, ui ) {
8598                                 that._trigger( "drag", event, filteredUi( ui ) );
8599                         },
8600                         stop: function( event, ui ) {
8601                                 var left = ui.offset.left - that.document.scrollLeft(),
8602                                         top = ui.offset.top - that.document.scrollTop();
8603
8604                                 options.position = {
8605                                         my: "left top",
8606                                         at: "left" + (left >= 0 ? "+" : "") + left + " " +
8607                                                 "top" + (top >= 0 ? "+" : "") + top,
8608                                         of: that.window
8609                                 };
8610                                 $( this ).removeClass( "ui-dialog-dragging" );
8611                                 that._unblockFrames();
8612                                 that._trigger( "dragStop", event, filteredUi( ui ) );
8613                         }
8614                 });
8615         },
8616
8617         _makeResizable: function() {
8618                 var that = this,
8619                         options = this.options,
8620                         handles = options.resizable,
8621                         // .ui-resizable has position: relative defined in the stylesheet
8622                         // but dialogs have to use absolute or fixed positioning
8623                         position = this.uiDialog.css("position"),
8624                         resizeHandles = typeof handles === "string" ?
8625                                 handles :
8626                                 "n,e,s,w,se,sw,ne,nw";
8627
8628                 function filteredUi( ui ) {
8629                         return {
8630                                 originalPosition: ui.originalPosition,
8631                                 originalSize: ui.originalSize,
8632                                 position: ui.position,
8633                                 size: ui.size
8634                         };
8635                 }
8636
8637                 this.uiDialog.resizable({
8638                         cancel: ".ui-dialog-content",
8639                         containment: "document",
8640                         alsoResize: this.element,
8641                         maxWidth: options.maxWidth,
8642                         maxHeight: options.maxHeight,
8643                         minWidth: options.minWidth,
8644                         minHeight: this._minHeight(),
8645                         handles: resizeHandles,
8646                         start: function( event, ui ) {
8647                                 $( this ).addClass( "ui-dialog-resizing" );
8648                                 that._blockFrames();
8649                                 that._trigger( "resizeStart", event, filteredUi( ui ) );
8650                         },
8651                         resize: function( event, ui ) {
8652                                 that._trigger( "resize", event, filteredUi( ui ) );
8653                         },
8654                         stop: function( event, ui ) {
8655                                 var offset = that.uiDialog.offset(),
8656                                         left = offset.left - that.document.scrollLeft(),
8657                                         top = offset.top - that.document.scrollTop();
8658
8659                                 options.height = that.uiDialog.height();
8660                                 options.width = that.uiDialog.width();
8661                                 options.position = {
8662                                         my: "left top",
8663                                         at: "left" + (left >= 0 ? "+" : "") + left + " " +
8664                                                 "top" + (top >= 0 ? "+" : "") + top,
8665                                         of: that.window
8666                                 };
8667                                 $( this ).removeClass( "ui-dialog-resizing" );
8668                                 that._unblockFrames();
8669                                 that._trigger( "resizeStop", event, filteredUi( ui ) );
8670                         }
8671                 })
8672                 .css( "position", position );
8673         },
8674
8675         _trackFocus: function() {
8676                 this._on( this.widget(), {
8677                         focusin: function( event ) {
8678                                 this._makeFocusTarget();
8679                                 this._focusedElement = $( event.target );
8680                         }
8681                 });
8682         },
8683
8684         _makeFocusTarget: function() {
8685                 this._untrackInstance();
8686                 this._trackingInstances().unshift( this );
8687         },
8688
8689         _untrackInstance: function() {
8690                 var instances = this._trackingInstances(),
8691                         exists = $.inArray( this, instances );
8692                 if ( exists !== -1 ) {
8693                         instances.splice( exists, 1 );
8694                 }
8695         },
8696
8697         _trackingInstances: function() {
8698                 var instances = this.document.data( "ui-dialog-instances" );
8699                 if ( !instances ) {
8700                         instances = [];
8701                         this.document.data( "ui-dialog-instances", instances );
8702                 }
8703                 return instances;
8704         },
8705
8706         _minHeight: function() {
8707                 var options = this.options;
8708
8709                 return options.height === "auto" ?
8710                         options.minHeight :
8711                         Math.min( options.minHeight, options.height );
8712         },
8713
8714         _position: function() {
8715                 // Need to show the dialog to get the actual offset in the position plugin
8716                 var isVisible = this.uiDialog.is( ":visible" );
8717                 if ( !isVisible ) {
8718                         this.uiDialog.show();
8719                 }
8720                 this.uiDialog.position( this.options.position );
8721                 if ( !isVisible ) {
8722                         this.uiDialog.hide();
8723                 }
8724         },
8725
8726         _setOptions: function( options ) {
8727                 var that = this,
8728                         resize = false,
8729                         resizableOptions = {};
8730
8731                 $.each( options, function( key, value ) {
8732                         that._setOption( key, value );
8733
8734                         if ( key in that.sizeRelatedOptions ) {
8735                                 resize = true;
8736                         }
8737                         if ( key in that.resizableRelatedOptions ) {
8738                                 resizableOptions[ key ] = value;
8739                         }
8740                 });
8741
8742                 if ( resize ) {
8743                         this._size();
8744                         this._position();
8745                 }
8746                 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8747                         this.uiDialog.resizable( "option", resizableOptions );
8748                 }
8749         },
8750
8751         _setOption: function( key, value ) {
8752                 var isDraggable, isResizable,
8753                         uiDialog = this.uiDialog;
8754
8755                 if ( key === "dialogClass" ) {
8756                         uiDialog
8757                                 .removeClass( this.options.dialogClass )
8758                                 .addClass( value );
8759                 }
8760
8761                 if ( key === "disabled" ) {
8762                         return;
8763                 }
8764
8765                 this._super( key, value );
8766
8767                 if ( key === "appendTo" ) {
8768                         this.uiDialog.appendTo( this._appendTo() );
8769                 }
8770
8771                 if ( key === "buttons" ) {
8772                         this._createButtons();
8773                 }
8774
8775                 if ( key === "closeText" ) {
8776                         this.uiDialogTitlebarClose.button({
8777                                 // Ensure that we always pass a string
8778                                 label: "" + value
8779                         });
8780                 }
8781
8782                 if ( key === "draggable" ) {
8783                         isDraggable = uiDialog.is( ":data(ui-draggable)" );
8784                         if ( isDraggable && !value ) {
8785                                 uiDialog.draggable( "destroy" );
8786                         }
8787
8788                         if ( !isDraggable && value ) {
8789                                 this._makeDraggable();
8790                         }
8791                 }
8792
8793                 if ( key === "position" ) {
8794                         this._position();
8795                 }
8796
8797                 if ( key === "resizable" ) {
8798                         // currently resizable, becoming non-resizable
8799                         isResizable = uiDialog.is( ":data(ui-resizable)" );
8800                         if ( isResizable && !value ) {
8801                                 uiDialog.resizable( "destroy" );
8802                         }
8803
8804                         // currently resizable, changing handles
8805                         if ( isResizable && typeof value === "string" ) {
8806                                 uiDialog.resizable( "option", "handles", value );
8807                         }
8808
8809                         // currently non-resizable, becoming resizable
8810                         if ( !isResizable && value !== false ) {
8811                                 this._makeResizable();
8812                         }
8813                 }
8814
8815                 if ( key === "title" ) {
8816                         this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
8817                 }
8818         },
8819
8820         _size: function() {
8821                 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
8822                 // divs will both have width and height set, so we need to reset them
8823                 var nonContentHeight, minContentHeight, maxContentHeight,
8824                         options = this.options;
8825
8826                 // Reset content sizing
8827                 this.element.show().css({
8828                         width: "auto",
8829                         minHeight: 0,
8830                         maxHeight: "none",
8831                         height: 0
8832                 });
8833
8834                 if ( options.minWidth > options.width ) {
8835                         options.width = options.minWidth;
8836                 }
8837
8838                 // reset wrapper sizing
8839                 // determine the height of all the non-content elements
8840                 nonContentHeight = this.uiDialog.css({
8841                                 height: "auto",
8842                                 width: options.width
8843                         })
8844                         .outerHeight();
8845                 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
8846                 maxContentHeight = typeof options.maxHeight === "number" ?
8847                         Math.max( 0, options.maxHeight - nonContentHeight ) :
8848                         "none";
8849
8850                 if ( options.height === "auto" ) {
8851                         this.element.css({
8852                                 minHeight: minContentHeight,
8853                                 maxHeight: maxContentHeight,
8854                                 height: "auto"
8855                         });
8856                 } else {
8857                         this.element.height( Math.max( 0, options.height - nonContentHeight ) );
8858                 }
8859
8860                 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8861                         this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
8862                 }
8863         },
8864
8865         _blockFrames: function() {
8866                 this.iframeBlocks = this.document.find( "iframe" ).map(function() {
8867                         var iframe = $( this );
8868
8869                         return $( "<div>" )
8870                                 .css({
8871                                         position: "absolute",
8872                                         width: iframe.outerWidth(),
8873                                         height: iframe.outerHeight()
8874                                 })
8875                                 .appendTo( iframe.parent() )
8876                                 .offset( iframe.offset() )[0];
8877                 });
8878         },
8879
8880         _unblockFrames: function() {
8881                 if ( this.iframeBlocks ) {
8882                         this.iframeBlocks.remove();
8883                         delete this.iframeBlocks;
8884                 }
8885         },
8886
8887         _allowInteraction: function( event ) {
8888                 if ( $( event.target ).closest( ".ui-dialog" ).length ) {
8889                         return true;
8890                 }
8891
8892                 // TODO: Remove hack when datepicker implements
8893                 // the .ui-front logic (#8989)
8894                 return !!$( event.target ).closest( ".ui-datepicker" ).length;
8895         },
8896
8897         _createOverlay: function() {
8898                 if ( !this.options.modal ) {
8899                         return;
8900                 }
8901
8902                 // We use a delay in case the overlay is created from an
8903                 // event that we're going to be cancelling (#2804)
8904                 var isOpening = true;
8905                 this._delay(function() {
8906                         isOpening = false;
8907                 });
8908
8909                 if ( !this.document.data( "ui-dialog-overlays" ) ) {
8910
8911                         // Prevent use of anchors and inputs
8912                         // Using _on() for an event handler shared across many instances is
8913                         // safe because the dialogs stack and must be closed in reverse order
8914                         this._on( this.document, {
8915                                 focusin: function( event ) {
8916                                         if ( isOpening ) {
8917                                                 return;
8918                                         }
8919
8920                                         if ( !this._allowInteraction( event ) ) {
8921                                                 event.preventDefault();
8922                                                 this._trackingInstances()[ 0 ]._focusTabbable();
8923                                         }
8924                                 }
8925                         });
8926                 }
8927
8928                 this.overlay = $( "<div>" )
8929                         .addClass( "ui-widget-overlay ui-front" )
8930                         .appendTo( this._appendTo() );
8931                 this._on( this.overlay, {
8932                         mousedown: "_keepFocus"
8933                 });
8934                 this.document.data( "ui-dialog-overlays",
8935                         (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
8936         },
8937
8938         _destroyOverlay: function() {
8939                 if ( !this.options.modal ) {
8940                         return;
8941                 }
8942
8943                 if ( this.overlay ) {
8944                         var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
8945
8946                         if ( !overlays ) {
8947                                 this.document
8948                                         .unbind( "focusin" )
8949                                         .removeData( "ui-dialog-overlays" );
8950                         } else {
8951                                 this.document.data( "ui-dialog-overlays", overlays );
8952                         }
8953
8954                         this.overlay.remove();
8955                         this.overlay = null;
8956                 }
8957         }
8958 });
8959
8960
8961 /*!
8962  * jQuery UI Droppable 1.11.2
8963  * http://jqueryui.com
8964  *
8965  * Copyright 2014 jQuery Foundation and other contributors
8966  * Released under the MIT license.
8967  * http://jquery.org/license
8968  *
8969  * http://api.jqueryui.com/droppable/
8970  */
8971
8972
8973 $.widget( "ui.droppable", {
8974         version: "1.11.2",
8975         widgetEventPrefix: "drop",
8976         options: {
8977                 accept: "*",
8978                 activeClass: false,
8979                 addClasses: true,
8980                 greedy: false,
8981                 hoverClass: false,
8982                 scope: "default",
8983                 tolerance: "intersect",
8984
8985                 // callbacks
8986                 activate: null,
8987                 deactivate: null,
8988                 drop: null,
8989                 out: null,
8990                 over: null
8991         },
8992         _create: function() {
8993
8994                 var proportions,
8995                         o = this.options,
8996                         accept = o.accept;
8997
8998                 this.isover = false;
8999                 this.isout = true;
9000
9001                 this.accept = $.isFunction( accept ) ? accept : function( d ) {
9002                         return d.is( accept );
9003                 };
9004
9005                 this.proportions = function( /* valueToWrite */ ) {
9006                         if ( arguments.length ) {
9007                                 // Store the droppable's proportions
9008                                 proportions = arguments[ 0 ];
9009                         } else {
9010                                 // Retrieve or derive the droppable's proportions
9011                                 return proportions ?
9012                                         proportions :
9013                                         proportions = {
9014                                                 width: this.element[ 0 ].offsetWidth,
9015                                                 height: this.element[ 0 ].offsetHeight
9016                                         };
9017                         }
9018                 };
9019
9020                 this._addToManager( o.scope );
9021
9022                 o.addClasses && this.element.addClass( "ui-droppable" );
9023
9024         },
9025
9026         _addToManager: function( scope ) {
9027                 // Add the reference and positions to the manager
9028                 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
9029                 $.ui.ddmanager.droppables[ scope ].push( this );
9030         },
9031
9032         _splice: function( drop ) {
9033                 var i = 0;
9034                 for ( ; i < drop.length; i++ ) {
9035                         if ( drop[ i ] === this ) {
9036                                 drop.splice( i, 1 );
9037                         }
9038                 }
9039         },
9040
9041         _destroy: function() {
9042                 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
9043
9044                 this._splice( drop );
9045
9046                 this.element.removeClass( "ui-droppable ui-droppable-disabled" );
9047         },
9048
9049         _setOption: function( key, value ) {
9050
9051                 if ( key === "accept" ) {
9052                         this.accept = $.isFunction( value ) ? value : function( d ) {
9053                                 return d.is( value );
9054                         };
9055                 } else if ( key === "scope" ) {
9056                         var drop = $.ui.ddmanager.droppables[ this.options.scope ];
9057
9058                         this._splice( drop );
9059                         this._addToManager( value );
9060                 }
9061
9062                 this._super( key, value );
9063         },
9064
9065         _activate: function( event ) {
9066                 var draggable = $.ui.ddmanager.current;
9067                 if ( this.options.activeClass ) {
9068                         this.element.addClass( this.options.activeClass );
9069                 }
9070                 if ( draggable ){
9071                         this._trigger( "activate", event, this.ui( draggable ) );
9072                 }
9073         },
9074
9075         _deactivate: function( event ) {
9076                 var draggable = $.ui.ddmanager.current;
9077                 if ( this.options.activeClass ) {
9078                         this.element.removeClass( this.options.activeClass );
9079                 }
9080                 if ( draggable ){
9081                         this._trigger( "deactivate", event, this.ui( draggable ) );
9082                 }
9083         },
9084
9085         _over: function( event ) {
9086
9087                 var draggable = $.ui.ddmanager.current;
9088
9089                 // Bail if draggable and droppable are same element
9090                 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9091                         return;
9092                 }
9093
9094                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9095                         if ( this.options.hoverClass ) {
9096                                 this.element.addClass( this.options.hoverClass );
9097                         }
9098                         this._trigger( "over", event, this.ui( draggable ) );
9099                 }
9100
9101         },
9102
9103         _out: function( event ) {
9104
9105                 var draggable = $.ui.ddmanager.current;
9106
9107                 // Bail if draggable and droppable are same element
9108                 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9109                         return;
9110                 }
9111
9112                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9113                         if ( this.options.hoverClass ) {
9114                                 this.element.removeClass( this.options.hoverClass );
9115                         }
9116                         this._trigger( "out", event, this.ui( draggable ) );
9117                 }
9118
9119         },
9120
9121         _drop: function( event, custom ) {
9122
9123                 var draggable = custom || $.ui.ddmanager.current,
9124                         childrenIntersection = false;
9125
9126                 // Bail if draggable and droppable are same element
9127                 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9128                         return false;
9129                 }
9130
9131                 this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
9132                         var inst = $( this ).droppable( "instance" );
9133                         if (
9134                                 inst.options.greedy &&
9135                                 !inst.options.disabled &&
9136                                 inst.options.scope === draggable.options.scope &&
9137                                 inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
9138                                 $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
9139                         ) { childrenIntersection = true; return false; }
9140                 });
9141                 if ( childrenIntersection ) {
9142                         return false;
9143                 }
9144
9145                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9146                         if ( this.options.activeClass ) {
9147                                 this.element.removeClass( this.options.activeClass );
9148                         }
9149                         if ( this.options.hoverClass ) {
9150                                 this.element.removeClass( this.options.hoverClass );
9151                         }
9152                         this._trigger( "drop", event, this.ui( draggable ) );
9153                         return this.element;
9154                 }
9155
9156                 return false;
9157
9158         },
9159
9160         ui: function( c ) {
9161                 return {
9162                         draggable: ( c.currentItem || c.element ),
9163                         helper: c.helper,
9164                         position: c.position,
9165                         offset: c.positionAbs
9166                 };
9167         }
9168
9169 });
9170
9171 $.ui.intersect = (function() {
9172         function isOverAxis( x, reference, size ) {
9173                 return ( x >= reference ) && ( x < ( reference + size ) );
9174         }
9175
9176         return function( draggable, droppable, toleranceMode, event ) {
9177
9178                 if ( !droppable.offset ) {
9179                         return false;
9180                 }
9181
9182                 var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
9183                         y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
9184                         x2 = x1 + draggable.helperProportions.width,
9185                         y2 = y1 + draggable.helperProportions.height,
9186                         l = droppable.offset.left,
9187                         t = droppable.offset.top,
9188                         r = l + droppable.proportions().width,
9189                         b = t + droppable.proportions().height;
9190
9191                 switch ( toleranceMode ) {
9192                 case "fit":
9193                         return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
9194                 case "intersect":
9195                         return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
9196                                 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
9197                                 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
9198                                 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
9199                 case "pointer":
9200                         return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
9201                 case "touch":
9202                         return (
9203                                 ( y1 >= t && y1 <= b ) || // Top edge touching
9204                                 ( y2 >= t && y2 <= b ) || // Bottom edge touching
9205                                 ( y1 < t && y2 > b ) // Surrounded vertically
9206                         ) && (
9207                                 ( x1 >= l && x1 <= r ) || // Left edge touching
9208                                 ( x2 >= l && x2 <= r ) || // Right edge touching
9209                                 ( x1 < l && x2 > r ) // Surrounded horizontally
9210                         );
9211                 default:
9212                         return false;
9213                 }
9214         };
9215 })();
9216
9217 /*
9218         This manager tracks offsets of draggables and droppables
9219 */
9220 $.ui.ddmanager = {
9221         current: null,
9222         droppables: { "default": [] },
9223         prepareOffsets: function( t, event ) {
9224
9225                 var i, j,
9226                         m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
9227                         type = event ? event.type : null, // workaround for #2317
9228                         list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
9229
9230                 droppablesLoop: for ( i = 0; i < m.length; i++ ) {
9231
9232                         // No disabled and non-accepted
9233                         if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
9234                                 continue;
9235                         }
9236
9237                         // Filter out elements in the current dragged item
9238                         for ( j = 0; j < list.length; j++ ) {
9239                                 if ( list[ j ] === m[ i ].element[ 0 ] ) {
9240                                         m[ i ].proportions().height = 0;
9241                                         continue droppablesLoop;
9242                                 }
9243                         }
9244
9245                         m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
9246                         if ( !m[ i ].visible ) {
9247                                 continue;
9248                         }
9249
9250                         // Activate the droppable if used directly from draggables
9251                         if ( type === "mousedown" ) {
9252                                 m[ i ]._activate.call( m[ i ], event );
9253                         }
9254
9255                         m[ i ].offset = m[ i ].element.offset();
9256                         m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
9257
9258                 }
9259
9260         },
9261         drop: function( draggable, event ) {
9262
9263                 var dropped = false;
9264                 // Create a copy of the droppables in case the list changes during the drop (#9116)
9265                 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
9266
9267                         if ( !this.options ) {
9268                                 return;
9269                         }
9270                         if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
9271                                 dropped = this._drop.call( this, event ) || dropped;
9272                         }
9273
9274                         if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9275                                 this.isout = true;
9276                                 this.isover = false;
9277                                 this._deactivate.call( this, event );
9278                         }
9279
9280                 });
9281                 return dropped;
9282
9283         },
9284         dragStart: function( draggable, event ) {
9285                 // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
9286                 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
9287                         if ( !draggable.options.refreshPositions ) {
9288                                 $.ui.ddmanager.prepareOffsets( draggable, event );
9289                         }
9290                 });
9291         },
9292         drag: function( draggable, event ) {
9293
9294                 // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
9295                 if ( draggable.options.refreshPositions ) {
9296                         $.ui.ddmanager.prepareOffsets( draggable, event );
9297                 }
9298
9299                 // Run through all droppables and check their positions based on specific tolerance options
9300                 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
9301
9302                         if ( this.options.disabled || this.greedyChild || !this.visible ) {
9303                                 return;
9304                         }
9305
9306                         var parentInstance, scope, parent,
9307                                 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
9308                                 c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
9309                         if ( !c ) {
9310                                 return;
9311                         }
9312
9313                         if ( this.options.greedy ) {
9314                                 // find droppable parents with same scope
9315                                 scope = this.options.scope;
9316                                 parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
9317                                         return $( this ).droppable( "instance" ).options.scope === scope;
9318                                 });
9319
9320                                 if ( parent.length ) {
9321                                         parentInstance = $( parent[ 0 ] ).droppable( "instance" );
9322                                         parentInstance.greedyChild = ( c === "isover" );
9323                                 }
9324                         }
9325
9326                         // we just moved into a greedy child
9327                         if ( parentInstance && c === "isover" ) {
9328                                 parentInstance.isover = false;
9329                                 parentInstance.isout = true;
9330                                 parentInstance._out.call( parentInstance, event );
9331                         }
9332
9333                         this[ c ] = true;
9334                         this[c === "isout" ? "isover" : "isout"] = false;
9335                         this[c === "isover" ? "_over" : "_out"].call( this, event );
9336
9337                         // we just moved out of a greedy child
9338                         if ( parentInstance && c === "isout" ) {
9339                                 parentInstance.isout = false;
9340                                 parentInstance.isover = true;
9341                                 parentInstance._over.call( parentInstance, event );
9342                         }
9343                 });
9344
9345         },
9346         dragStop: function( draggable, event ) {
9347                 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
9348                 // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
9349                 if ( !draggable.options.refreshPositions ) {
9350                         $.ui.ddmanager.prepareOffsets( draggable, event );
9351                 }
9352         }
9353 };
9354
9355 var droppable = $.ui.droppable;
9356
9357
9358 /*!
9359  * jQuery UI Effects 1.11.2
9360  * http://jqueryui.com
9361  *
9362  * Copyright 2014 jQuery Foundation and other contributors
9363  * Released under the MIT license.
9364  * http://jquery.org/license
9365  *
9366  * http://api.jqueryui.com/category/effects-core/
9367  */
9368
9369
9370 var dataSpace = "ui-effects-",
9371
9372         // Create a local jQuery because jQuery Color relies on it and the
9373         // global may not exist with AMD and a custom build (#10199)
9374         jQuery = $;
9375
9376 $.effects = {
9377         effect: {}
9378 };
9379
9380 /*!
9381  * jQuery Color Animations v2.1.2
9382  * https://github.com/jquery/jquery-color
9383  *
9384  * Copyright 2014 jQuery Foundation and other contributors
9385  * Released under the MIT license.
9386  * http://jquery.org/license
9387  *
9388  * Date: Wed Jan 16 08:47:09 2013 -0600
9389  */
9390 (function( jQuery, undefined ) {
9391
9392         var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
9393
9394         // plusequals test for += 100 -= 100
9395         rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
9396         // a set of RE's that can match strings and generate color tuples.
9397         stringParsers = [ {
9398                         re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9399                         parse: function( execResult ) {
9400                                 return [
9401                                         execResult[ 1 ],
9402                                         execResult[ 2 ],
9403                                         execResult[ 3 ],
9404                                         execResult[ 4 ]
9405                                 ];
9406                         }
9407                 }, {
9408                         re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9409                         parse: function( execResult ) {
9410                                 return [
9411                                         execResult[ 1 ] * 2.55,
9412                                         execResult[ 2 ] * 2.55,
9413                                         execResult[ 3 ] * 2.55,
9414                                         execResult[ 4 ]
9415                                 ];
9416                         }
9417                 }, {
9418                         // this regex ignores A-F because it's compared against an already lowercased string
9419                         re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
9420                         parse: function( execResult ) {
9421                                 return [
9422                                         parseInt( execResult[ 1 ], 16 ),
9423                                         parseInt( execResult[ 2 ], 16 ),
9424                                         parseInt( execResult[ 3 ], 16 )
9425                                 ];
9426                         }
9427                 }, {
9428                         // this regex ignores A-F because it's compared against an already lowercased string
9429                         re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
9430                         parse: function( execResult ) {
9431                                 return [
9432                                         parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
9433                                         parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
9434                                         parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
9435                                 ];
9436                         }
9437                 }, {
9438                         re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9439                         space: "hsla",
9440                         parse: function( execResult ) {
9441                                 return [
9442                                         execResult[ 1 ],
9443                                         execResult[ 2 ] / 100,
9444                                         execResult[ 3 ] / 100,
9445                                         execResult[ 4 ]
9446                                 ];
9447                         }
9448                 } ],
9449
9450         // jQuery.Color( )
9451         color = jQuery.Color = function( color, green, blue, alpha ) {
9452                 return new jQuery.Color.fn.parse( color, green, blue, alpha );
9453         },
9454         spaces = {
9455                 rgba: {
9456                         props: {
9457                                 red: {
9458                                         idx: 0,
9459                                         type: "byte"
9460                                 },
9461                                 green: {
9462                                         idx: 1,
9463                                         type: "byte"
9464                                 },
9465                                 blue: {
9466                                         idx: 2,
9467                                         type: "byte"
9468                                 }
9469                         }
9470                 },
9471
9472                 hsla: {
9473                         props: {
9474                                 hue: {
9475                                         idx: 0,
9476                                         type: "degrees"
9477                                 },
9478                                 saturation: {
9479                                         idx: 1,
9480                                         type: "percent"
9481                                 },
9482                                 lightness: {
9483                                         idx: 2,
9484                                         type: "percent"
9485                                 }
9486                         }
9487                 }
9488         },
9489         propTypes = {
9490                 "byte": {
9491                         floor: true,
9492                         max: 255
9493                 },
9494                 "percent": {
9495                         max: 1
9496                 },
9497                 "degrees": {
9498                         mod: 360,
9499                         floor: true
9500                 }
9501         },
9502         support = color.support = {},
9503
9504         // element for support tests
9505         supportElem = jQuery( "<p>" )[ 0 ],
9506
9507         // colors = jQuery.Color.names
9508         colors,
9509
9510         // local aliases of functions called often
9511         each = jQuery.each;
9512
9513 // determine rgba support immediately
9514 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
9515 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
9516
9517 // define cache name and alpha properties
9518 // for rgba and hsla spaces
9519 each( spaces, function( spaceName, space ) {
9520         space.cache = "_" + spaceName;
9521         space.props.alpha = {
9522                 idx: 3,
9523                 type: "percent",
9524                 def: 1
9525         };
9526 });
9527
9528 function clamp( value, prop, allowEmpty ) {
9529         var type = propTypes[ prop.type ] || {};
9530
9531         if ( value == null ) {
9532                 return (allowEmpty || !prop.def) ? null : prop.def;
9533         }
9534
9535         // ~~ is an short way of doing floor for positive numbers
9536         value = type.floor ? ~~value : parseFloat( value );
9537
9538         // IE will pass in empty strings as value for alpha,
9539         // which will hit this case
9540         if ( isNaN( value ) ) {
9541                 return prop.def;
9542         }
9543
9544         if ( type.mod ) {
9545                 // we add mod before modding to make sure that negatives values
9546                 // get converted properly: -10 -> 350
9547                 return (value + type.mod) % type.mod;
9548         }
9549
9550         // for now all property types without mod have min and max
9551         return 0 > value ? 0 : type.max < value ? type.max : value;
9552 }
9553
9554 function stringParse( string ) {
9555         var inst = color(),
9556                 rgba = inst._rgba = [];
9557
9558         string = string.toLowerCase();
9559
9560         each( stringParsers, function( i, parser ) {
9561                 var parsed,
9562                         match = parser.re.exec( string ),
9563                         values = match && parser.parse( match ),
9564                         spaceName = parser.space || "rgba";
9565
9566                 if ( values ) {
9567                         parsed = inst[ spaceName ]( values );
9568
9569                         // if this was an rgba parse the assignment might happen twice
9570                         // oh well....
9571                         inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
9572                         rgba = inst._rgba = parsed._rgba;
9573
9574                         // exit each( stringParsers ) here because we matched
9575                         return false;
9576                 }
9577         });
9578
9579         // Found a stringParser that handled it
9580         if ( rgba.length ) {
9581
9582                 // if this came from a parsed string, force "transparent" when alpha is 0
9583                 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
9584                 if ( rgba.join() === "0,0,0,0" ) {
9585                         jQuery.extend( rgba, colors.transparent );
9586                 }
9587                 return inst;
9588         }
9589
9590         // named colors
9591         return colors[ string ];
9592 }
9593
9594 color.fn = jQuery.extend( color.prototype, {
9595         parse: function( red, green, blue, alpha ) {
9596                 if ( red === undefined ) {
9597                         this._rgba = [ null, null, null, null ];
9598                         return this;
9599                 }
9600                 if ( red.jquery || red.nodeType ) {
9601                         red = jQuery( red ).css( green );
9602                         green = undefined;
9603                 }
9604
9605                 var inst = this,
9606                         type = jQuery.type( red ),
9607                         rgba = this._rgba = [];
9608
9609                 // more than 1 argument specified - assume ( red, green, blue, alpha )
9610                 if ( green !== undefined ) {
9611                         red = [ red, green, blue, alpha ];
9612                         type = "array";
9613                 }
9614
9615                 if ( type === "string" ) {
9616                         return this.parse( stringParse( red ) || colors._default );
9617                 }
9618
9619                 if ( type === "array" ) {
9620                         each( spaces.rgba.props, function( key, prop ) {
9621                                 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
9622                         });
9623                         return this;
9624                 }
9625
9626                 if ( type === "object" ) {
9627                         if ( red instanceof color ) {
9628                                 each( spaces, function( spaceName, space ) {
9629                                         if ( red[ space.cache ] ) {
9630                                                 inst[ space.cache ] = red[ space.cache ].slice();
9631                                         }
9632                                 });
9633                         } else {
9634                                 each( spaces, function( spaceName, space ) {
9635                                         var cache = space.cache;
9636                                         each( space.props, function( key, prop ) {
9637
9638                                                 // if the cache doesn't exist, and we know how to convert
9639                                                 if ( !inst[ cache ] && space.to ) {
9640
9641                                                         // if the value was null, we don't need to copy it
9642                                                         // if the key was alpha, we don't need to copy it either
9643                                                         if ( key === "alpha" || red[ key ] == null ) {
9644                                                                 return;
9645                                                         }
9646                                                         inst[ cache ] = space.to( inst._rgba );
9647                                                 }
9648
9649                                                 // this is the only case where we allow nulls for ALL properties.
9650                                                 // call clamp with alwaysAllowEmpty
9651                                                 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
9652                                         });
9653
9654                                         // everything defined but alpha?
9655                                         if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
9656                                                 // use the default of 1
9657                                                 inst[ cache ][ 3 ] = 1;
9658                                                 if ( space.from ) {
9659                                                         inst._rgba = space.from( inst[ cache ] );
9660                                                 }
9661                                         }
9662                                 });
9663                         }
9664                         return this;
9665                 }
9666         },
9667         is: function( compare ) {
9668                 var is = color( compare ),
9669                         same = true,
9670                         inst = this;
9671
9672                 each( spaces, function( _, space ) {
9673                         var localCache,
9674                                 isCache = is[ space.cache ];
9675                         if (isCache) {
9676                                 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
9677                                 each( space.props, function( _, prop ) {
9678                                         if ( isCache[ prop.idx ] != null ) {
9679                                                 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
9680                                                 return same;
9681                                         }
9682                                 });
9683                         }
9684                         return same;
9685                 });
9686                 return same;
9687         },
9688         _space: function() {
9689                 var used = [],
9690                         inst = this;
9691                 each( spaces, function( spaceName, space ) {
9692                         if ( inst[ space.cache ] ) {
9693                                 used.push( spaceName );
9694                         }
9695                 });
9696                 return used.pop();
9697         },
9698         transition: function( other, distance ) {
9699                 var end = color( other ),
9700                         spaceName = end._space(),
9701                         space = spaces[ spaceName ],
9702                         startColor = this.alpha() === 0 ? color( "transparent" ) : this,
9703                         start = startColor[ space.cache ] || space.to( startColor._rgba ),
9704                         result = start.slice();
9705
9706                 end = end[ space.cache ];
9707                 each( space.props, function( key, prop ) {
9708                         var index = prop.idx,
9709                                 startValue = start[ index ],
9710                                 endValue = end[ index ],
9711                                 type = propTypes[ prop.type ] || {};
9712
9713                         // if null, don't override start value
9714                         if ( endValue === null ) {
9715                                 return;
9716                         }
9717                         // if null - use end
9718                         if ( startValue === null ) {
9719                                 result[ index ] = endValue;
9720                         } else {
9721                                 if ( type.mod ) {
9722                                         if ( endValue - startValue > type.mod / 2 ) {
9723                                                 startValue += type.mod;
9724                                         } else if ( startValue - endValue > type.mod / 2 ) {
9725                                                 startValue -= type.mod;
9726                                         }
9727                                 }
9728                                 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
9729                         }
9730                 });
9731                 return this[ spaceName ]( result );
9732         },
9733         blend: function( opaque ) {
9734                 // if we are already opaque - return ourself
9735                 if ( this._rgba[ 3 ] === 1 ) {
9736                         return this;
9737                 }
9738
9739                 var rgb = this._rgba.slice(),
9740                         a = rgb.pop(),
9741                         blend = color( opaque )._rgba;
9742
9743                 return color( jQuery.map( rgb, function( v, i ) {
9744                         return ( 1 - a ) * blend[ i ] + a * v;
9745                 }));
9746         },
9747         toRgbaString: function() {
9748                 var prefix = "rgba(",
9749                         rgba = jQuery.map( this._rgba, function( v, i ) {
9750                                 return v == null ? ( i > 2 ? 1 : 0 ) : v;
9751                         });
9752
9753                 if ( rgba[ 3 ] === 1 ) {
9754                         rgba.pop();
9755                         prefix = "rgb(";
9756                 }
9757
9758                 return prefix + rgba.join() + ")";
9759         },
9760         toHslaString: function() {
9761                 var prefix = "hsla(",
9762                         hsla = jQuery.map( this.hsla(), function( v, i ) {
9763                                 if ( v == null ) {
9764                                         v = i > 2 ? 1 : 0;
9765                                 }
9766
9767                                 // catch 1 and 2
9768                                 if ( i && i < 3 ) {
9769                                         v = Math.round( v * 100 ) + "%";
9770                                 }
9771                                 return v;
9772                         });
9773
9774                 if ( hsla[ 3 ] === 1 ) {
9775                         hsla.pop();
9776                         prefix = "hsl(";
9777                 }
9778                 return prefix + hsla.join() + ")";
9779         },
9780         toHexString: function( includeAlpha ) {
9781                 var rgba = this._rgba.slice(),
9782                         alpha = rgba.pop();
9783
9784                 if ( includeAlpha ) {
9785                         rgba.push( ~~( alpha * 255 ) );
9786                 }
9787
9788                 return "#" + jQuery.map( rgba, function( v ) {
9789
9790                         // default to 0 when nulls exist
9791                         v = ( v || 0 ).toString( 16 );
9792                         return v.length === 1 ? "0" + v : v;
9793                 }).join("");
9794         },
9795         toString: function() {
9796                 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
9797         }
9798 });
9799 color.fn.parse.prototype = color.fn;
9800
9801 // hsla conversions adapted from:
9802 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
9803
9804 function hue2rgb( p, q, h ) {
9805         h = ( h + 1 ) % 1;
9806         if ( h * 6 < 1 ) {
9807                 return p + ( q - p ) * h * 6;
9808         }
9809         if ( h * 2 < 1) {
9810                 return q;
9811         }
9812         if ( h * 3 < 2 ) {
9813                 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
9814         }
9815         return p;
9816 }
9817
9818 spaces.hsla.to = function( rgba ) {
9819         if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
9820                 return [ null, null, null, rgba[ 3 ] ];
9821         }
9822         var r = rgba[ 0 ] / 255,
9823                 g = rgba[ 1 ] / 255,
9824                 b = rgba[ 2 ] / 255,
9825                 a = rgba[ 3 ],
9826                 max = Math.max( r, g, b ),
9827                 min = Math.min( r, g, b ),
9828                 diff = max - min,
9829                 add = max + min,
9830                 l = add * 0.5,
9831                 h, s;
9832
9833         if ( min === max ) {
9834                 h = 0;
9835         } else if ( r === max ) {
9836                 h = ( 60 * ( g - b ) / diff ) + 360;
9837         } else if ( g === max ) {
9838                 h = ( 60 * ( b - r ) / diff ) + 120;
9839         } else {
9840                 h = ( 60 * ( r - g ) / diff ) + 240;
9841         }
9842
9843         // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
9844         // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
9845         if ( diff === 0 ) {
9846                 s = 0;
9847         } else if ( l <= 0.5 ) {
9848                 s = diff / add;
9849         } else {
9850                 s = diff / ( 2 - add );
9851         }
9852         return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
9853 };
9854
9855 spaces.hsla.from = function( hsla ) {
9856         if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
9857                 return [ null, null, null, hsla[ 3 ] ];
9858         }
9859         var h = hsla[ 0 ] / 360,
9860                 s = hsla[ 1 ],
9861                 l = hsla[ 2 ],
9862                 a = hsla[ 3 ],
9863                 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
9864                 p = 2 * l - q;
9865
9866         return [
9867                 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
9868                 Math.round( hue2rgb( p, q, h ) * 255 ),
9869                 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
9870                 a
9871         ];
9872 };
9873
9874 each( spaces, function( spaceName, space ) {
9875         var props = space.props,
9876                 cache = space.cache,
9877                 to = space.to,
9878                 from = space.from;
9879
9880         // makes rgba() and hsla()
9881         color.fn[ spaceName ] = function( value ) {
9882
9883                 // generate a cache for this space if it doesn't exist
9884                 if ( to && !this[ cache ] ) {
9885                         this[ cache ] = to( this._rgba );
9886                 }
9887                 if ( value === undefined ) {
9888                         return this[ cache ].slice();
9889                 }
9890
9891                 var ret,
9892                         type = jQuery.type( value ),
9893                         arr = ( type === "array" || type === "object" ) ? value : arguments,
9894                         local = this[ cache ].slice();
9895
9896                 each( props, function( key, prop ) {
9897                         var val = arr[ type === "object" ? key : prop.idx ];
9898                         if ( val == null ) {
9899                                 val = local[ prop.idx ];
9900                         }
9901                         local[ prop.idx ] = clamp( val, prop );
9902                 });
9903
9904                 if ( from ) {
9905                         ret = color( from( local ) );
9906                         ret[ cache ] = local;
9907                         return ret;
9908                 } else {
9909                         return color( local );
9910                 }
9911         };
9912
9913         // makes red() green() blue() alpha() hue() saturation() lightness()
9914         each( props, function( key, prop ) {
9915                 // alpha is included in more than one space
9916                 if ( color.fn[ key ] ) {
9917                         return;
9918                 }
9919                 color.fn[ key ] = function( value ) {
9920                         var vtype = jQuery.type( value ),
9921                                 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
9922                                 local = this[ fn ](),
9923                                 cur = local[ prop.idx ],
9924                                 match;
9925
9926                         if ( vtype === "undefined" ) {
9927                                 return cur;
9928                         }
9929
9930                         if ( vtype === "function" ) {
9931                                 value = value.call( this, cur );
9932                                 vtype = jQuery.type( value );
9933                         }
9934                         if ( value == null && prop.empty ) {
9935                                 return this;
9936                         }
9937                         if ( vtype === "string" ) {
9938                                 match = rplusequals.exec( value );
9939                                 if ( match ) {
9940                                         value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
9941                                 }
9942                         }
9943                         local[ prop.idx ] = value;
9944                         return this[ fn ]( local );
9945                 };
9946         });
9947 });
9948
9949 // add cssHook and .fx.step function for each named hook.
9950 // accept a space separated string of properties
9951 color.hook = function( hook ) {
9952         var hooks = hook.split( " " );
9953         each( hooks, function( i, hook ) {
9954                 jQuery.cssHooks[ hook ] = {
9955                         set: function( elem, value ) {
9956                                 var parsed, curElem,
9957                                         backgroundColor = "";
9958
9959                                 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
9960                                         value = color( parsed || value );
9961                                         if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
9962                                                 curElem = hook === "backgroundColor" ? elem.parentNode : elem;
9963                                                 while (
9964                                                         (backgroundColor === "" || backgroundColor === "transparent") &&
9965                                                         curElem && curElem.style
9966                                                 ) {
9967                                                         try {
9968                                                                 backgroundColor = jQuery.css( curElem, "backgroundColor" );
9969                                                                 curElem = curElem.parentNode;
9970                                                         } catch ( e ) {
9971                                                         }
9972                                                 }
9973
9974                                                 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
9975                                                         backgroundColor :
9976                                                         "_default" );
9977                                         }
9978
9979                                         value = value.toRgbaString();
9980                                 }
9981                                 try {
9982                                         elem.style[ hook ] = value;
9983                                 } catch ( e ) {
9984                                         // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
9985                                 }
9986                         }
9987                 };
9988                 jQuery.fx.step[ hook ] = function( fx ) {
9989                         if ( !fx.colorInit ) {
9990                                 fx.start = color( fx.elem, hook );
9991                                 fx.end = color( fx.end );
9992                                 fx.colorInit = true;
9993                         }
9994                         jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
9995                 };
9996         });
9997
9998 };
9999
10000 color.hook( stepHooks );
10001
10002 jQuery.cssHooks.borderColor = {
10003         expand: function( value ) {
10004                 var expanded = {};
10005
10006                 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
10007                         expanded[ "border" + part + "Color" ] = value;
10008                 });
10009                 return expanded;
10010         }
10011 };
10012
10013 // Basic color names only.
10014 // Usage of any of the other color names requires adding yourself or including
10015 // jquery.color.svg-names.js.
10016 colors = jQuery.Color.names = {
10017         // 4.1. Basic color keywords
10018         aqua: "#00ffff",
10019         black: "#000000",
10020         blue: "#0000ff",
10021         fuchsia: "#ff00ff",
10022         gray: "#808080",
10023         green: "#008000",
10024         lime: "#00ff00",
10025         maroon: "#800000",
10026         navy: "#000080",
10027         olive: "#808000",
10028         purple: "#800080",
10029         red: "#ff0000",
10030         silver: "#c0c0c0",
10031         teal: "#008080",
10032         white: "#ffffff",
10033         yellow: "#ffff00",
10034
10035         // 4.2.3. "transparent" color keyword
10036         transparent: [ null, null, null, 0 ],
10037
10038         _default: "#ffffff"
10039 };
10040
10041 })( jQuery );
10042
10043 /******************************************************************************/
10044 /****************************** CLASS ANIMATIONS ******************************/
10045 /******************************************************************************/
10046 (function() {
10047
10048 var classAnimationActions = [ "add", "remove", "toggle" ],
10049         shorthandStyles = {
10050                 border: 1,
10051                 borderBottom: 1,
10052                 borderColor: 1,
10053                 borderLeft: 1,
10054                 borderRight: 1,
10055                 borderTop: 1,
10056                 borderWidth: 1,
10057                 margin: 1,
10058                 padding: 1
10059         };
10060
10061 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
10062         $.fx.step[ prop ] = function( fx ) {
10063                 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
10064                         jQuery.style( fx.elem, prop, fx.end );
10065                         fx.setAttr = true;
10066                 }
10067         };
10068 });
10069
10070 function getElementStyles( elem ) {
10071         var key, len,
10072                 style = elem.ownerDocument.defaultView ?
10073                         elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
10074                         elem.currentStyle,
10075                 styles = {};
10076
10077         if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
10078                 len = style.length;
10079                 while ( len-- ) {
10080                         key = style[ len ];
10081                         if ( typeof style[ key ] === "string" ) {
10082                                 styles[ $.camelCase( key ) ] = style[ key ];
10083                         }
10084                 }
10085         // support: Opera, IE <9
10086         } else {
10087                 for ( key in style ) {
10088                         if ( typeof style[ key ] === "string" ) {
10089                                 styles[ key ] = style[ key ];
10090                         }
10091                 }
10092         }
10093
10094         return styles;
10095 }
10096
10097 function styleDifference( oldStyle, newStyle ) {
10098         var diff = {},
10099                 name, value;
10100
10101         for ( name in newStyle ) {
10102                 value = newStyle[ name ];
10103                 if ( oldStyle[ name ] !== value ) {
10104                         if ( !shorthandStyles[ name ] ) {
10105                                 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
10106                                         diff[ name ] = value;
10107                                 }
10108                         }
10109                 }
10110         }
10111
10112         return diff;
10113 }
10114
10115 // support: jQuery <1.8
10116 if ( !$.fn.addBack ) {
10117         $.fn.addBack = function( selector ) {
10118                 return this.add( selector == null ?
10119                         this.prevObject : this.prevObject.filter( selector )
10120                 );
10121         };
10122 }
10123
10124 $.effects.animateClass = function( value, duration, easing, callback ) {
10125         var o = $.speed( duration, easing, callback );
10126
10127         return this.queue( function() {
10128                 var animated = $( this ),
10129                         baseClass = animated.attr( "class" ) || "",
10130                         applyClassChange,
10131                         allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
10132
10133                 // map the animated objects to store the original styles.
10134                 allAnimations = allAnimations.map(function() {
10135                         var el = $( this );
10136                         return {
10137                                 el: el,
10138                                 start: getElementStyles( this )
10139                         };
10140                 });
10141
10142                 // apply class change
10143                 applyClassChange = function() {
10144                         $.each( classAnimationActions, function(i, action) {
10145                                 if ( value[ action ] ) {
10146                                         animated[ action + "Class" ]( value[ action ] );
10147                                 }
10148                         });
10149                 };
10150                 applyClassChange();
10151
10152                 // map all animated objects again - calculate new styles and diff
10153                 allAnimations = allAnimations.map(function() {
10154                         this.end = getElementStyles( this.el[ 0 ] );
10155                         this.diff = styleDifference( this.start, this.end );
10156                         return this;
10157                 });
10158
10159                 // apply original class
10160                 animated.attr( "class", baseClass );
10161
10162                 // map all animated objects again - this time collecting a promise
10163                 allAnimations = allAnimations.map(function() {
10164                         var styleInfo = this,
10165                                 dfd = $.Deferred(),
10166                                 opts = $.extend({}, o, {
10167                                         queue: false,
10168                                         complete: function() {
10169                                                 dfd.resolve( styleInfo );
10170                                         }
10171                                 });
10172
10173                         this.el.animate( this.diff, opts );
10174                         return dfd.promise();
10175                 });
10176
10177                 // once all animations have completed:
10178                 $.when.apply( $, allAnimations.get() ).done(function() {
10179
10180                         // set the final class
10181                         applyClassChange();
10182
10183                         // for each animated element,
10184                         // clear all css properties that were animated
10185                         $.each( arguments, function() {
10186                                 var el = this.el;
10187                                 $.each( this.diff, function(key) {
10188                                         el.css( key, "" );
10189                                 });
10190                         });
10191
10192                         // this is guarnteed to be there if you use jQuery.speed()
10193                         // it also handles dequeuing the next anim...
10194                         o.complete.call( animated[ 0 ] );
10195                 });
10196         });
10197 };
10198
10199 $.fn.extend({
10200         addClass: (function( orig ) {
10201                 return function( classNames, speed, easing, callback ) {
10202                         return speed ?
10203                                 $.effects.animateClass.call( this,
10204                                         { add: classNames }, speed, easing, callback ) :
10205                                 orig.apply( this, arguments );
10206                 };
10207         })( $.fn.addClass ),
10208
10209         removeClass: (function( orig ) {
10210                 return function( classNames, speed, easing, callback ) {
10211                         return arguments.length > 1 ?
10212                                 $.effects.animateClass.call( this,
10213                                         { remove: classNames }, speed, easing, callback ) :
10214                                 orig.apply( this, arguments );
10215                 };
10216         })( $.fn.removeClass ),
10217
10218         toggleClass: (function( orig ) {
10219                 return function( classNames, force, speed, easing, callback ) {
10220                         if ( typeof force === "boolean" || force === undefined ) {
10221                                 if ( !speed ) {
10222                                         // without speed parameter
10223                                         return orig.apply( this, arguments );
10224                                 } else {
10225                                         return $.effects.animateClass.call( this,
10226                                                 (force ? { add: classNames } : { remove: classNames }),
10227                                                 speed, easing, callback );
10228                                 }
10229                         } else {
10230                                 // without force parameter
10231                                 return $.effects.animateClass.call( this,
10232                                         { toggle: classNames }, force, speed, easing );
10233                         }
10234                 };
10235         })( $.fn.toggleClass ),
10236
10237         switchClass: function( remove, add, speed, easing, callback) {
10238                 return $.effects.animateClass.call( this, {
10239                         add: add,
10240                         remove: remove
10241                 }, speed, easing, callback );
10242         }
10243 });
10244
10245 })();
10246
10247 /******************************************************************************/
10248 /*********************************** EFFECTS **********************************/
10249 /******************************************************************************/
10250
10251 (function() {
10252
10253 $.extend( $.effects, {
10254         version: "1.11.2",
10255
10256         // Saves a set of properties in a data storage
10257         save: function( element, set ) {
10258                 for ( var i = 0; i < set.length; i++ ) {
10259                         if ( set[ i ] !== null ) {
10260                                 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
10261                         }
10262                 }
10263         },
10264
10265         // Restores a set of previously saved properties from a data storage
10266         restore: function( element, set ) {
10267                 var val, i;
10268                 for ( i = 0; i < set.length; i++ ) {
10269                         if ( set[ i ] !== null ) {
10270                                 val = element.data( dataSpace + set[ i ] );
10271                                 // support: jQuery 1.6.2
10272                                 // http://bugs.jquery.com/ticket/9917
10273                                 // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
10274                                 // We can't differentiate between "" and 0 here, so we just assume
10275                                 // empty string since it's likely to be a more common value...
10276                                 if ( val === undefined ) {
10277                                         val = "";
10278                                 }
10279                                 element.css( set[ i ], val );
10280                         }
10281                 }
10282         },
10283
10284         setMode: function( el, mode ) {
10285                 if (mode === "toggle") {
10286                         mode = el.is( ":hidden" ) ? "show" : "hide";
10287                 }
10288                 return mode;
10289         },
10290
10291         // Translates a [top,left] array into a baseline value
10292         // this should be a little more flexible in the future to handle a string & hash
10293         getBaseline: function( origin, original ) {
10294                 var y, x;
10295                 switch ( origin[ 0 ] ) {
10296                         case "top": y = 0; break;
10297                         case "middle": y = 0.5; break;
10298                         case "bottom": y = 1; break;
10299                         default: y = origin[ 0 ] / original.height;
10300                 }
10301                 switch ( origin[ 1 ] ) {
10302                         case "left": x = 0; break;
10303                         case "center": x = 0.5; break;
10304                         case "right": x = 1; break;
10305                         default: x = origin[ 1 ] / original.width;
10306                 }
10307                 return {
10308                         x: x,
10309                         y: y
10310                 };
10311         },
10312
10313         // Wraps the element around a wrapper that copies position properties
10314         createWrapper: function( element ) {
10315
10316                 // if the element is already wrapped, return it
10317                 if ( element.parent().is( ".ui-effects-wrapper" )) {
10318                         return element.parent();
10319                 }
10320
10321                 // wrap the element
10322                 var props = {
10323                                 width: element.outerWidth(true),
10324                                 height: element.outerHeight(true),
10325                                 "float": element.css( "float" )
10326                         },
10327                         wrapper = $( "<div></div>" )
10328                                 .addClass( "ui-effects-wrapper" )
10329                                 .css({
10330                                         fontSize: "100%",
10331                                         background: "transparent",
10332                                         border: "none",
10333                                         margin: 0,
10334                                         padding: 0
10335                                 }),
10336                         // Store the size in case width/height are defined in % - Fixes #5245
10337                         size = {
10338                                 width: element.width(),
10339                                 height: element.height()
10340                         },
10341                         active = document.activeElement;
10342
10343                 // support: Firefox
10344                 // Firefox incorrectly exposes anonymous content
10345                 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
10346                 try {
10347                         active.id;
10348                 } catch ( e ) {
10349                         active = document.body;
10350                 }
10351
10352                 element.wrap( wrapper );
10353
10354                 // Fixes #7595 - Elements lose focus when wrapped.
10355                 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10356                         $( active ).focus();
10357                 }
10358
10359                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
10360
10361                 // transfer positioning properties to the wrapper
10362                 if ( element.css( "position" ) === "static" ) {
10363                         wrapper.css({ position: "relative" });
10364                         element.css({ position: "relative" });
10365                 } else {
10366                         $.extend( props, {
10367                                 position: element.css( "position" ),
10368                                 zIndex: element.css( "z-index" )
10369                         });
10370                         $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
10371                                 props[ pos ] = element.css( pos );
10372                                 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
10373                                         props[ pos ] = "auto";
10374                                 }
10375                         });
10376                         element.css({
10377                                 position: "relative",
10378                                 top: 0,
10379                                 left: 0,
10380                                 right: "auto",
10381                                 bottom: "auto"
10382                         });
10383                 }
10384                 element.css(size);
10385
10386                 return wrapper.css( props ).show();
10387         },
10388
10389         removeWrapper: function( element ) {
10390                 var active = document.activeElement;
10391
10392                 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
10393                         element.parent().replaceWith( element );
10394
10395                         // Fixes #7595 - Elements lose focus when wrapped.
10396                         if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10397                                 $( active ).focus();
10398                         }
10399                 }
10400
10401                 return element;
10402         },
10403
10404         setTransition: function( element, list, factor, value ) {
10405                 value = value || {};
10406                 $.each( list, function( i, x ) {
10407                         var unit = element.cssUnit( x );
10408                         if ( unit[ 0 ] > 0 ) {
10409                                 value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
10410                         }
10411                 });
10412                 return value;
10413         }
10414 });
10415
10416 // return an effect options object for the given parameters:
10417 function _normalizeArguments( effect, options, speed, callback ) {
10418
10419         // allow passing all options as the first parameter
10420         if ( $.isPlainObject( effect ) ) {
10421                 options = effect;
10422                 effect = effect.effect;
10423         }
10424
10425         // convert to an object
10426         effect = { effect: effect };
10427
10428         // catch (effect, null, ...)
10429         if ( options == null ) {
10430                 options = {};
10431         }
10432
10433         // catch (effect, callback)
10434         if ( $.isFunction( options ) ) {
10435                 callback = options;
10436                 speed = null;
10437                 options = {};
10438         }
10439
10440         // catch (effect, speed, ?)
10441         if ( typeof options === "number" || $.fx.speeds[ options ] ) {
10442                 callback = speed;
10443                 speed = options;
10444                 options = {};
10445         }
10446
10447         // catch (effect, options, callback)
10448         if ( $.isFunction( speed ) ) {
10449                 callback = speed;
10450                 speed = null;
10451         }
10452
10453         // add options to effect
10454         if ( options ) {
10455                 $.extend( effect, options );
10456         }
10457
10458         speed = speed || options.duration;
10459         effect.duration = $.fx.off ? 0 :
10460                 typeof speed === "number" ? speed :
10461                 speed in $.fx.speeds ? $.fx.speeds[ speed ] :
10462                 $.fx.speeds._default;
10463
10464         effect.complete = callback || options.complete;
10465
10466         return effect;
10467 }
10468
10469 function standardAnimationOption( option ) {
10470         // Valid standard speeds (nothing, number, named speed)
10471         if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
10472                 return true;
10473         }
10474
10475         // Invalid strings - treat as "normal" speed
10476         if ( typeof option === "string" && !$.effects.effect[ option ] ) {
10477                 return true;
10478         }
10479
10480         // Complete callback
10481         if ( $.isFunction( option ) ) {
10482                 return true;
10483         }
10484
10485         // Options hash (but not naming an effect)
10486         if ( typeof option === "object" && !option.effect ) {
10487                 return true;
10488         }
10489
10490         // Didn't match any standard API
10491         return false;
10492 }
10493
10494 $.fn.extend({
10495         effect: function( /* effect, options, speed, callback */ ) {
10496                 var args = _normalizeArguments.apply( this, arguments ),
10497                         mode = args.mode,
10498                         queue = args.queue,
10499                         effectMethod = $.effects.effect[ args.effect ];
10500
10501                 if ( $.fx.off || !effectMethod ) {
10502                         // delegate to the original method (e.g., .show()) if possible
10503                         if ( mode ) {
10504                                 return this[ mode ]( args.duration, args.complete );
10505                         } else {
10506                                 return this.each( function() {
10507                                         if ( args.complete ) {
10508                                                 args.complete.call( this );
10509                                         }
10510                                 });
10511                         }
10512                 }
10513
10514                 function run( next ) {
10515                         var elem = $( this ),
10516                                 complete = args.complete,
10517                                 mode = args.mode;
10518
10519                         function done() {
10520                                 if ( $.isFunction( complete ) ) {
10521                                         complete.call( elem[0] );
10522                                 }
10523                                 if ( $.isFunction( next ) ) {
10524                                         next();
10525                                 }
10526                         }
10527
10528                         // If the element already has the correct final state, delegate to
10529                         // the core methods so the internal tracking of "olddisplay" works.
10530                         if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
10531                                 elem[ mode ]();
10532                                 done();
10533                         } else {
10534                                 effectMethod.call( elem[0], args, done );
10535                         }
10536                 }
10537
10538                 return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
10539         },
10540
10541         show: (function( orig ) {
10542                 return function( option ) {
10543                         if ( standardAnimationOption( option ) ) {
10544                                 return orig.apply( this, arguments );
10545                         } else {
10546                                 var args = _normalizeArguments.apply( this, arguments );
10547                                 args.mode = "show";
10548                                 return this.effect.call( this, args );
10549                         }
10550                 };
10551         })( $.fn.show ),
10552
10553         hide: (function( orig ) {
10554                 return function( option ) {
10555                         if ( standardAnimationOption( option ) ) {
10556                                 return orig.apply( this, arguments );
10557                         } else {
10558                                 var args = _normalizeArguments.apply( this, arguments );
10559                                 args.mode = "hide";
10560                                 return this.effect.call( this, args );
10561                         }
10562                 };
10563         })( $.fn.hide ),
10564
10565         toggle: (function( orig ) {
10566                 return function( option ) {
10567                         if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
10568                                 return orig.apply( this, arguments );
10569                         } else {
10570                                 var args = _normalizeArguments.apply( this, arguments );
10571                                 args.mode = "toggle";
10572                                 return this.effect.call( this, args );
10573                         }
10574                 };
10575         })( $.fn.toggle ),
10576
10577         // helper functions
10578         cssUnit: function(key) {
10579                 var style = this.css( key ),
10580                         val = [];
10581
10582                 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
10583                         if ( style.indexOf( unit ) > 0 ) {
10584                                 val = [ parseFloat( style ), unit ];
10585                         }
10586                 });
10587                 return val;
10588         }
10589 });
10590
10591 })();
10592
10593 /******************************************************************************/
10594 /*********************************** EASING ***********************************/
10595 /******************************************************************************/
10596
10597 (function() {
10598
10599 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
10600
10601 var baseEasings = {};
10602
10603 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
10604         baseEasings[ name ] = function( p ) {
10605                 return Math.pow( p, i + 2 );
10606         };
10607 });
10608
10609 $.extend( baseEasings, {
10610         Sine: function( p ) {
10611                 return 1 - Math.cos( p * Math.PI / 2 );
10612         },
10613         Circ: function( p ) {
10614                 return 1 - Math.sqrt( 1 - p * p );
10615         },
10616         Elastic: function( p ) {
10617                 return p === 0 || p === 1 ? p :
10618                         -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
10619         },
10620         Back: function( p ) {
10621                 return p * p * ( 3 * p - 2 );
10622         },
10623         Bounce: function( p ) {
10624                 var pow2,
10625                         bounce = 4;
10626
10627                 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
10628                 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
10629         }
10630 });
10631
10632 $.each( baseEasings, function( name, easeIn ) {
10633         $.easing[ "easeIn" + name ] = easeIn;
10634         $.easing[ "easeOut" + name ] = function( p ) {
10635                 return 1 - easeIn( 1 - p );
10636         };
10637         $.easing[ "easeInOut" + name ] = function( p ) {
10638                 return p < 0.5 ?
10639                         easeIn( p * 2 ) / 2 :
10640                         1 - easeIn( p * -2 + 2 ) / 2;
10641         };
10642 });
10643
10644 })();
10645
10646 var effect = $.effects;
10647
10648
10649 /*!
10650  * jQuery UI Effects Blind 1.11.2
10651  * http://jqueryui.com
10652  *
10653  * Copyright 2014 jQuery Foundation and other contributors
10654  * Released under the MIT license.
10655  * http://jquery.org/license
10656  *
10657  * http://api.jqueryui.com/blind-effect/
10658  */
10659
10660
10661 var effectBlind = $.effects.effect.blind = function( o, done ) {
10662         // Create element
10663         var el = $( this ),
10664                 rvertical = /up|down|vertical/,
10665                 rpositivemotion = /up|left|vertical|horizontal/,
10666                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10667                 mode = $.effects.setMode( el, o.mode || "hide" ),
10668                 direction = o.direction || "up",
10669                 vertical = rvertical.test( direction ),
10670                 ref = vertical ? "height" : "width",
10671                 ref2 = vertical ? "top" : "left",
10672                 motion = rpositivemotion.test( direction ),
10673                 animation = {},
10674                 show = mode === "show",
10675                 wrapper, distance, margin;
10676
10677         // if already wrapped, the wrapper's properties are my property. #6245
10678         if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10679                 $.effects.save( el.parent(), props );
10680         } else {
10681                 $.effects.save( el, props );
10682         }
10683         el.show();
10684         wrapper = $.effects.createWrapper( el ).css({
10685                 overflow: "hidden"
10686         });
10687
10688         distance = wrapper[ ref ]();
10689         margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10690
10691         animation[ ref ] = show ? distance : 0;
10692         if ( !motion ) {
10693                 el
10694                         .css( vertical ? "bottom" : "right", 0 )
10695                         .css( vertical ? "top" : "left", "auto" )
10696                         .css({ position: "absolute" });
10697
10698                 animation[ ref2 ] = show ? margin : distance + margin;
10699         }
10700
10701         // start at 0 if we are showing
10702         if ( show ) {
10703                 wrapper.css( ref, 0 );
10704                 if ( !motion ) {
10705                         wrapper.css( ref2, margin + distance );
10706                 }
10707         }
10708
10709         // Animate
10710         wrapper.animate( animation, {
10711                 duration: o.duration,
10712                 easing: o.easing,
10713                 queue: false,
10714                 complete: function() {
10715                         if ( mode === "hide" ) {
10716                                 el.hide();
10717                         }
10718                         $.effects.restore( el, props );
10719                         $.effects.removeWrapper( el );
10720                         done();
10721                 }
10722         });
10723 };
10724
10725
10726 /*!
10727  * jQuery UI Effects Bounce 1.11.2
10728  * http://jqueryui.com
10729  *
10730  * Copyright 2014 jQuery Foundation and other contributors
10731  * Released under the MIT license.
10732  * http://jquery.org/license
10733  *
10734  * http://api.jqueryui.com/bounce-effect/
10735  */
10736
10737
10738 var effectBounce = $.effects.effect.bounce = function( o, done ) {
10739         var el = $( this ),
10740                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10741
10742                 // defaults:
10743                 mode = $.effects.setMode( el, o.mode || "effect" ),
10744                 hide = mode === "hide",
10745                 show = mode === "show",
10746                 direction = o.direction || "up",
10747                 distance = o.distance,
10748                 times = o.times || 5,
10749
10750                 // number of internal animations
10751                 anims = times * 2 + ( show || hide ? 1 : 0 ),
10752                 speed = o.duration / anims,
10753                 easing = o.easing,
10754
10755                 // utility:
10756                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10757                 motion = ( direction === "up" || direction === "left" ),
10758                 i,
10759                 upAnim,
10760                 downAnim,
10761
10762                 // we will need to re-assemble the queue to stack our animations in place
10763                 queue = el.queue(),
10764                 queuelen = queue.length;
10765
10766         // Avoid touching opacity to prevent clearType and PNG issues in IE
10767         if ( show || hide ) {
10768                 props.push( "opacity" );
10769         }
10770
10771         $.effects.save( el, props );
10772         el.show();
10773         $.effects.createWrapper( el ); // Create Wrapper
10774
10775         // default distance for the BIGGEST bounce is the outer Distance / 3
10776         if ( !distance ) {
10777                 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10778         }
10779
10780         if ( show ) {
10781                 downAnim = { opacity: 1 };
10782                 downAnim[ ref ] = 0;
10783
10784                 // if we are showing, force opacity 0 and set the initial position
10785                 // then do the "first" animation
10786                 el.css( "opacity", 0 )
10787                         .css( ref, motion ? -distance * 2 : distance * 2 )
10788                         .animate( downAnim, speed, easing );
10789         }
10790
10791         // start at the smallest distance if we are hiding
10792         if ( hide ) {
10793                 distance = distance / Math.pow( 2, times - 1 );
10794         }
10795
10796         downAnim = {};
10797         downAnim[ ref ] = 0;
10798         // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10799         for ( i = 0; i < times; i++ ) {
10800                 upAnim = {};
10801                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10802
10803                 el.animate( upAnim, speed, easing )
10804                         .animate( downAnim, speed, easing );
10805
10806                 distance = hide ? distance * 2 : distance / 2;
10807         }
10808
10809         // Last Bounce when Hiding
10810         if ( hide ) {
10811                 upAnim = { opacity: 0 };
10812                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10813
10814                 el.animate( upAnim, speed, easing );
10815         }
10816
10817         el.queue(function() {
10818                 if ( hide ) {
10819                         el.hide();
10820                 }
10821                 $.effects.restore( el, props );
10822                 $.effects.removeWrapper( el );
10823                 done();
10824         });
10825
10826         // inject all the animations we just queued to be first in line (after "inprogress")
10827         if ( queuelen > 1) {
10828                 queue.splice.apply( queue,
10829                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10830         }
10831         el.dequeue();
10832
10833 };
10834
10835
10836 /*!
10837  * jQuery UI Effects Clip 1.11.2
10838  * http://jqueryui.com
10839  *
10840  * Copyright 2014 jQuery Foundation and other contributors
10841  * Released under the MIT license.
10842  * http://jquery.org/license
10843  *
10844  * http://api.jqueryui.com/clip-effect/
10845  */
10846
10847
10848 var effectClip = $.effects.effect.clip = function( o, done ) {
10849         // Create element
10850         var el = $( this ),
10851                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10852                 mode = $.effects.setMode( el, o.mode || "hide" ),
10853                 show = mode === "show",
10854                 direction = o.direction || "vertical",
10855                 vert = direction === "vertical",
10856                 size = vert ? "height" : "width",
10857                 position = vert ? "top" : "left",
10858                 animation = {},
10859                 wrapper, animate, distance;
10860
10861         // Save & Show
10862         $.effects.save( el, props );
10863         el.show();
10864
10865         // Create Wrapper
10866         wrapper = $.effects.createWrapper( el ).css({
10867                 overflow: "hidden"
10868         });
10869         animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10870         distance = animate[ size ]();
10871
10872         // Shift
10873         if ( show ) {
10874                 animate.css( size, 0 );
10875                 animate.css( position, distance / 2 );
10876         }
10877
10878         // Create Animation Object:
10879         animation[ size ] = show ? distance : 0;
10880         animation[ position ] = show ? 0 : distance / 2;
10881
10882         // Animate
10883         animate.animate( animation, {
10884                 queue: false,
10885                 duration: o.duration,
10886                 easing: o.easing,
10887                 complete: function() {
10888                         if ( !show ) {
10889                                 el.hide();
10890                         }
10891                         $.effects.restore( el, props );
10892                         $.effects.removeWrapper( el );
10893                         done();
10894                 }
10895         });
10896
10897 };
10898
10899
10900 /*!
10901  * jQuery UI Effects Drop 1.11.2
10902  * http://jqueryui.com
10903  *
10904  * Copyright 2014 jQuery Foundation and other contributors
10905  * Released under the MIT license.
10906  * http://jquery.org/license
10907  *
10908  * http://api.jqueryui.com/drop-effect/
10909  */
10910
10911
10912 var effectDrop = $.effects.effect.drop = function( o, done ) {
10913
10914         var el = $( this ),
10915                 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10916                 mode = $.effects.setMode( el, o.mode || "hide" ),
10917                 show = mode === "show",
10918                 direction = o.direction || "left",
10919                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10920                 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10921                 animation = {
10922                         opacity: show ? 1 : 0
10923                 },
10924                 distance;
10925
10926         // Adjust
10927         $.effects.save( el, props );
10928         el.show();
10929         $.effects.createWrapper( el );
10930
10931         distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
10932
10933         if ( show ) {
10934                 el
10935                         .css( "opacity", 0 )
10936                         .css( ref, motion === "pos" ? -distance : distance );
10937         }
10938
10939         // Animation
10940         animation[ ref ] = ( show ?
10941                 ( motion === "pos" ? "+=" : "-=" ) :
10942                 ( motion === "pos" ? "-=" : "+=" ) ) +
10943                 distance;
10944
10945         // Animate
10946         el.animate( animation, {
10947                 queue: false,
10948                 duration: o.duration,
10949                 easing: o.easing,
10950                 complete: function() {
10951                         if ( mode === "hide" ) {
10952                                 el.hide();
10953                         }
10954                         $.effects.restore( el, props );
10955                         $.effects.removeWrapper( el );
10956                         done();
10957                 }
10958         });
10959 };
10960
10961
10962 /*!
10963  * jQuery UI Effects Explode 1.11.2
10964  * http://jqueryui.com
10965  *
10966  * Copyright 2014 jQuery Foundation and other contributors
10967  * Released under the MIT license.
10968  * http://jquery.org/license
10969  *
10970  * http://api.jqueryui.com/explode-effect/
10971  */
10972
10973
10974 var effectExplode = $.effects.effect.explode = function( o, done ) {
10975
10976         var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10977                 cells = rows,
10978                 el = $( this ),
10979                 mode = $.effects.setMode( el, o.mode || "hide" ),
10980                 show = mode === "show",
10981
10982                 // show and then visibility:hidden the element before calculating offset
10983                 offset = el.show().css( "visibility", "hidden" ).offset(),
10984
10985                 // width and height of a piece
10986                 width = Math.ceil( el.outerWidth() / cells ),
10987                 height = Math.ceil( el.outerHeight() / rows ),
10988                 pieces = [],
10989
10990                 // loop
10991                 i, j, left, top, mx, my;
10992
10993         // children animate complete:
10994         function childComplete() {
10995                 pieces.push( this );
10996                 if ( pieces.length === rows * cells ) {
10997                         animComplete();
10998                 }
10999         }
11000
11001         // clone the element for each row and cell.
11002         for ( i = 0; i < rows ; i++ ) { // ===>
11003                 top = offset.top + i * height;
11004                 my = i - ( rows - 1 ) / 2 ;
11005
11006                 for ( j = 0; j < cells ; j++ ) { // |||
11007                         left = offset.left + j * width;
11008                         mx = j - ( cells - 1 ) / 2 ;
11009
11010                         // Create a clone of the now hidden main element that will be absolute positioned
11011                         // within a wrapper div off the -left and -top equal to size of our pieces
11012                         el
11013                                 .clone()
11014                                 .appendTo( "body" )
11015                                 .wrap( "<div></div>" )
11016                                 .css({
11017                                         position: "absolute",
11018                                         visibility: "visible",
11019                                         left: -j * width,
11020                                         top: -i * height
11021                                 })
11022
11023                         // select the wrapper - make it overflow: hidden and absolute positioned based on
11024                         // where the original was located +left and +top equal to the size of pieces
11025                                 .parent()
11026                                 .addClass( "ui-effects-explode" )
11027                                 .css({
11028                                         position: "absolute",
11029                                         overflow: "hidden",
11030                                         width: width,
11031                                         height: height,
11032                                         left: left + ( show ? mx * width : 0 ),
11033                                         top: top + ( show ? my * height : 0 ),
11034                                         opacity: show ? 0 : 1
11035                                 }).animate({
11036                                         left: left + ( show ? 0 : mx * width ),
11037                                         top: top + ( show ? 0 : my * height ),
11038                                         opacity: show ? 1 : 0
11039                                 }, o.duration || 500, o.easing, childComplete );
11040                 }
11041         }
11042
11043         function animComplete() {
11044                 el.css({
11045                         visibility: "visible"
11046                 });
11047                 $( pieces ).remove();
11048                 if ( !show ) {
11049                         el.hide();
11050                 }
11051                 done();
11052         }
11053 };
11054
11055
11056 /*!
11057  * jQuery UI Effects Fade 1.11.2
11058  * http://jqueryui.com
11059  *
11060  * Copyright 2014 jQuery Foundation and other contributors
11061  * Released under the MIT license.
11062  * http://jquery.org/license
11063  *
11064  * http://api.jqueryui.com/fade-effect/
11065  */
11066
11067
11068 var effectFade = $.effects.effect.fade = function( o, done ) {
11069         var el = $( this ),
11070                 mode = $.effects.setMode( el, o.mode || "toggle" );
11071
11072         el.animate({
11073                 opacity: mode
11074         }, {
11075                 queue: false,
11076                 duration: o.duration,
11077                 easing: o.easing,
11078                 complete: done
11079         });
11080 };
11081
11082
11083 /*!
11084  * jQuery UI Effects Fold 1.11.2
11085  * http://jqueryui.com
11086  *
11087  * Copyright 2014 jQuery Foundation and other contributors
11088  * Released under the MIT license.
11089  * http://jquery.org/license
11090  *
11091  * http://api.jqueryui.com/fold-effect/
11092  */
11093
11094
11095 var effectFold = $.effects.effect.fold = function( o, done ) {
11096
11097         // Create element
11098         var el = $( this ),
11099                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11100                 mode = $.effects.setMode( el, o.mode || "hide" ),
11101                 show = mode === "show",
11102                 hide = mode === "hide",
11103                 size = o.size || 15,
11104                 percent = /([0-9]+)%/.exec( size ),
11105                 horizFirst = !!o.horizFirst,
11106                 widthFirst = show !== horizFirst,
11107                 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
11108                 duration = o.duration / 2,
11109                 wrapper, distance,
11110                 animation1 = {},
11111                 animation2 = {};
11112
11113         $.effects.save( el, props );
11114         el.show();
11115
11116         // Create Wrapper
11117         wrapper = $.effects.createWrapper( el ).css({
11118                 overflow: "hidden"
11119         });
11120         distance = widthFirst ?
11121                 [ wrapper.width(), wrapper.height() ] :
11122                 [ wrapper.height(), wrapper.width() ];
11123
11124         if ( percent ) {
11125                 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
11126         }
11127         if ( show ) {
11128                 wrapper.css( horizFirst ? {
11129                         height: 0,
11130                         width: size
11131                 } : {
11132                         height: size,
11133                         width: 0
11134                 });
11135         }
11136
11137         // Animation
11138         animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
11139         animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
11140
11141         // Animate
11142         wrapper
11143                 .animate( animation1, duration, o.easing )
11144                 .animate( animation2, duration, o.easing, function() {
11145                         if ( hide ) {
11146                                 el.hide();
11147                         }
11148                         $.effects.restore( el, props );
11149                         $.effects.removeWrapper( el );
11150                         done();
11151                 });
11152
11153 };
11154
11155
11156 /*!
11157  * jQuery UI Effects Highlight 1.11.2
11158  * http://jqueryui.com
11159  *
11160  * Copyright 2014 jQuery Foundation and other contributors
11161  * Released under the MIT license.
11162  * http://jquery.org/license
11163  *
11164  * http://api.jqueryui.com/highlight-effect/
11165  */
11166
11167
11168 var effectHighlight = $.effects.effect.highlight = function( o, done ) {
11169         var elem = $( this ),
11170                 props = [ "backgroundImage", "backgroundColor", "opacity" ],
11171                 mode = $.effects.setMode( elem, o.mode || "show" ),
11172                 animation = {
11173                         backgroundColor: elem.css( "backgroundColor" )
11174                 };
11175
11176         if (mode === "hide") {
11177                 animation.opacity = 0;
11178         }
11179
11180         $.effects.save( elem, props );
11181
11182         elem
11183                 .show()
11184                 .css({
11185                         backgroundImage: "none",
11186                         backgroundColor: o.color || "#ffff99"
11187                 })
11188                 .animate( animation, {
11189                         queue: false,
11190                         duration: o.duration,
11191                         easing: o.easing,
11192                         complete: function() {
11193                                 if ( mode === "hide" ) {
11194                                         elem.hide();
11195                                 }
11196                                 $.effects.restore( elem, props );
11197                                 done();
11198                         }
11199                 });
11200 };
11201
11202
11203 /*!
11204  * jQuery UI Effects Size 1.11.2
11205  * http://jqueryui.com
11206  *
11207  * Copyright 2014 jQuery Foundation and other contributors
11208  * Released under the MIT license.
11209  * http://jquery.org/license
11210  *
11211  * http://api.jqueryui.com/size-effect/
11212  */
11213
11214
11215 var effectSize = $.effects.effect.size = function( o, done ) {
11216
11217         // Create element
11218         var original, baseline, factor,
11219                 el = $( this ),
11220                 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11221
11222                 // Always restore
11223                 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11224
11225                 // Copy for children
11226                 props2 = [ "width", "height", "overflow" ],
11227                 cProps = [ "fontSize" ],
11228                 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11229                 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11230
11231                 // Set options
11232                 mode = $.effects.setMode( el, o.mode || "effect" ),
11233                 restore = o.restore || mode !== "effect",
11234                 scale = o.scale || "both",
11235                 origin = o.origin || [ "middle", "center" ],
11236                 position = el.css( "position" ),
11237                 props = restore ? props0 : props1,
11238                 zero = {
11239                         height: 0,
11240                         width: 0,
11241                         outerHeight: 0,
11242                         outerWidth: 0
11243                 };
11244
11245         if ( mode === "show" ) {
11246                 el.show();
11247         }
11248         original = {
11249                 height: el.height(),
11250                 width: el.width(),
11251                 outerHeight: el.outerHeight(),
11252                 outerWidth: el.outerWidth()
11253         };
11254
11255         if ( o.mode === "toggle" && mode === "show" ) {
11256                 el.from = o.to || zero;
11257                 el.to = o.from || original;
11258         } else {
11259                 el.from = o.from || ( mode === "show" ? zero : original );
11260                 el.to = o.to || ( mode === "hide" ? zero : original );
11261         }
11262
11263         // Set scaling factor
11264         factor = {
11265                 from: {
11266                         y: el.from.height / original.height,
11267                         x: el.from.width / original.width
11268                 },
11269                 to: {
11270                         y: el.to.height / original.height,
11271                         x: el.to.width / original.width
11272                 }
11273         };
11274
11275         // Scale the css box
11276         if ( scale === "box" || scale === "both" ) {
11277
11278                 // Vertical props scaling
11279                 if ( factor.from.y !== factor.to.y ) {
11280                         props = props.concat( vProps );
11281                         el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11282                         el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11283                 }
11284
11285                 // Horizontal props scaling
11286                 if ( factor.from.x !== factor.to.x ) {
11287                         props = props.concat( hProps );
11288                         el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11289                         el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11290                 }
11291         }
11292
11293         // Scale the content
11294         if ( scale === "content" || scale === "both" ) {
11295
11296                 // Vertical props scaling
11297                 if ( factor.from.y !== factor.to.y ) {
11298                         props = props.concat( cProps ).concat( props2 );
11299                         el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11300                         el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11301                 }
11302         }
11303
11304         $.effects.save( el, props );
11305         el.show();
11306         $.effects.createWrapper( el );
11307         el.css( "overflow", "hidden" ).css( el.from );
11308
11309         // Adjust
11310         if (origin) { // Calculate baseline shifts
11311                 baseline = $.effects.getBaseline( origin, original );
11312                 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11313                 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11314                 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11315                 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11316         }
11317         el.css( el.from ); // set top & left
11318
11319         // Animate
11320         if ( scale === "content" || scale === "both" ) { // Scale the children
11321
11322                 // Add margins/font-size
11323                 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11324                 hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11325                 props2 = props0.concat(vProps).concat(hProps);
11326
11327                 el.find( "*[width]" ).each( function() {
11328                         var child = $( this ),
11329                                 c_original = {
11330                                         height: child.height(),
11331                                         width: child.width(),
11332                                         outerHeight: child.outerHeight(),
11333                                         outerWidth: child.outerWidth()
11334                                 };
11335                         if (restore) {
11336                                 $.effects.save(child, props2);
11337                         }
11338
11339                         child.from = {
11340                                 height: c_original.height * factor.from.y,
11341                                 width: c_original.width * factor.from.x,
11342                                 outerHeight: c_original.outerHeight * factor.from.y,
11343                                 outerWidth: c_original.outerWidth * factor.from.x
11344                         };
11345                         child.to = {
11346                                 height: c_original.height * factor.to.y,
11347                                 width: c_original.width * factor.to.x,
11348                                 outerHeight: c_original.height * factor.to.y,
11349                                 outerWidth: c_original.width * factor.to.x
11350                         };
11351
11352                         // Vertical props scaling
11353                         if ( factor.from.y !== factor.to.y ) {
11354                                 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11355                                 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11356                         }
11357
11358                         // Horizontal props scaling
11359                         if ( factor.from.x !== factor.to.x ) {
11360                                 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11361                                 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11362                         }
11363
11364                         // Animate children
11365                         child.css( child.from );
11366                         child.animate( child.to, o.duration, o.easing, function() {
11367
11368                                 // Restore children
11369                                 if ( restore ) {
11370                                         $.effects.restore( child, props2 );
11371                                 }
11372                         });
11373                 });
11374         }
11375
11376         // Animate
11377         el.animate( el.to, {
11378                 queue: false,
11379                 duration: o.duration,
11380                 easing: o.easing,
11381                 complete: function() {
11382                         if ( el.to.opacity === 0 ) {
11383                                 el.css( "opacity", el.from.opacity );
11384                         }
11385                         if ( mode === "hide" ) {
11386                                 el.hide();
11387                         }
11388                         $.effects.restore( el, props );
11389                         if ( !restore ) {
11390
11391                                 // we need to calculate our new positioning based on the scaling
11392                                 if ( position === "static" ) {
11393                                         el.css({
11394                                                 position: "relative",
11395                                                 top: el.to.top,
11396                                                 left: el.to.left
11397                                         });
11398                                 } else {
11399                                         $.each([ "top", "left" ], function( idx, pos ) {
11400                                                 el.css( pos, function( _, str ) {
11401                                                         var val = parseInt( str, 10 ),
11402                                                                 toRef = idx ? el.to.left : el.to.top;
11403
11404                                                         // if original was "auto", recalculate the new value from wrapper
11405                                                         if ( str === "auto" ) {
11406                                                                 return toRef + "px";
11407                                                         }
11408
11409                                                         return val + toRef + "px";
11410                                                 });
11411                                         });
11412                                 }
11413                         }
11414
11415                         $.effects.removeWrapper( el );
11416                         done();
11417                 }
11418         });
11419
11420 };
11421
11422
11423 /*!
11424  * jQuery UI Effects Scale 1.11.2
11425  * http://jqueryui.com
11426  *
11427  * Copyright 2014 jQuery Foundation and other contributors
11428  * Released under the MIT license.
11429  * http://jquery.org/license
11430  *
11431  * http://api.jqueryui.com/scale-effect/
11432  */
11433
11434
11435 var effectScale = $.effects.effect.scale = function( o, done ) {
11436
11437         // Create element
11438         var el = $( this ),
11439                 options = $.extend( true, {}, o ),
11440                 mode = $.effects.setMode( el, o.mode || "effect" ),
11441                 percent = parseInt( o.percent, 10 ) ||
11442                         ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
11443                 direction = o.direction || "both",
11444                 origin = o.origin,
11445                 original = {
11446                         height: el.height(),
11447                         width: el.width(),
11448                         outerHeight: el.outerHeight(),
11449                         outerWidth: el.outerWidth()
11450                 },
11451                 factor = {
11452                         y: direction !== "horizontal" ? (percent / 100) : 1,
11453                         x: direction !== "vertical" ? (percent / 100) : 1
11454                 };
11455
11456         // We are going to pass this effect to the size effect:
11457         options.effect = "size";
11458         options.queue = false;
11459         options.complete = done;
11460
11461         // Set default origin and restore for show/hide
11462         if ( mode !== "effect" ) {
11463                 options.origin = origin || [ "middle", "center" ];
11464                 options.restore = true;
11465         }
11466
11467         options.from = o.from || ( mode === "show" ? {
11468                 height: 0,
11469                 width: 0,
11470                 outerHeight: 0,
11471                 outerWidth: 0
11472         } : original );
11473         options.to = {
11474                 height: original.height * factor.y,
11475                 width: original.width * factor.x,
11476                 outerHeight: original.outerHeight * factor.y,
11477                 outerWidth: original.outerWidth * factor.x
11478         };
11479
11480         // Fade option to support puff
11481         if ( options.fade ) {
11482                 if ( mode === "show" ) {
11483                         options.from.opacity = 0;
11484                         options.to.opacity = 1;
11485                 }
11486                 if ( mode === "hide" ) {
11487                         options.from.opacity = 1;
11488                         options.to.opacity = 0;
11489                 }
11490         }
11491
11492         // Animate
11493         el.effect( options );
11494
11495 };
11496
11497
11498 /*!
11499  * jQuery UI Effects Puff 1.11.2
11500  * http://jqueryui.com
11501  *
11502  * Copyright 2014 jQuery Foundation and other contributors
11503  * Released under the MIT license.
11504  * http://jquery.org/license
11505  *
11506  * http://api.jqueryui.com/puff-effect/
11507  */
11508
11509
11510 var effectPuff = $.effects.effect.puff = function( o, done ) {
11511         var elem = $( this ),
11512                 mode = $.effects.setMode( elem, o.mode || "hide" ),
11513                 hide = mode === "hide",
11514                 percent = parseInt( o.percent, 10 ) || 150,
11515                 factor = percent / 100,
11516                 original = {
11517                         height: elem.height(),
11518                         width: elem.width(),
11519                         outerHeight: elem.outerHeight(),
11520                         outerWidth: elem.outerWidth()
11521                 };
11522
11523         $.extend( o, {
11524                 effect: "scale",
11525                 queue: false,
11526                 fade: true,
11527                 mode: mode,
11528                 complete: done,
11529                 percent: hide ? percent : 100,
11530                 from: hide ?
11531                         original :
11532                         {
11533                                 height: original.height * factor,
11534                                 width: original.width * factor,
11535                                 outerHeight: original.outerHeight * factor,
11536                                 outerWidth: original.outerWidth * factor
11537                         }
11538         });
11539
11540         elem.effect( o );
11541 };
11542
11543
11544 /*!
11545  * jQuery UI Effects Pulsate 1.11.2
11546  * http://jqueryui.com
11547  *
11548  * Copyright 2014 jQuery Foundation and other contributors
11549  * Released under the MIT license.
11550  * http://jquery.org/license
11551  *
11552  * http://api.jqueryui.com/pulsate-effect/
11553  */
11554
11555
11556 var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
11557         var elem = $( this ),
11558                 mode = $.effects.setMode( elem, o.mode || "show" ),
11559                 show = mode === "show",
11560                 hide = mode === "hide",
11561                 showhide = ( show || mode === "hide" ),
11562
11563                 // showing or hiding leaves of the "last" animation
11564                 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
11565                 duration = o.duration / anims,
11566                 animateTo = 0,
11567                 queue = elem.queue(),
11568                 queuelen = queue.length,
11569                 i;
11570
11571         if ( show || !elem.is(":visible")) {
11572                 elem.css( "opacity", 0 ).show();
11573                 animateTo = 1;
11574         }
11575
11576         // anims - 1 opacity "toggles"
11577         for ( i = 1; i < anims; i++ ) {
11578                 elem.animate({
11579                         opacity: animateTo
11580                 }, duration, o.easing );
11581                 animateTo = 1 - animateTo;
11582         }
11583
11584         elem.animate({
11585                 opacity: animateTo
11586         }, duration, o.easing);
11587
11588         elem.queue(function() {
11589                 if ( hide ) {
11590                         elem.hide();
11591                 }
11592                 done();
11593         });
11594
11595         // We just queued up "anims" animations, we need to put them next in the queue
11596         if ( queuelen > 1 ) {
11597                 queue.splice.apply( queue,
11598                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11599         }
11600         elem.dequeue();
11601 };
11602
11603
11604 /*!
11605  * jQuery UI Effects Shake 1.11.2
11606  * http://jqueryui.com
11607  *
11608  * Copyright 2014 jQuery Foundation and other contributors
11609  * Released under the MIT license.
11610  * http://jquery.org/license
11611  *
11612  * http://api.jqueryui.com/shake-effect/
11613  */
11614
11615
11616 var effectShake = $.effects.effect.shake = function( o, done ) {
11617
11618         var el = $( this ),
11619                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11620                 mode = $.effects.setMode( el, o.mode || "effect" ),
11621                 direction = o.direction || "left",
11622                 distance = o.distance || 20,
11623                 times = o.times || 3,
11624                 anims = times * 2 + 1,
11625                 speed = Math.round( o.duration / anims ),
11626                 ref = (direction === "up" || direction === "down") ? "top" : "left",
11627                 positiveMotion = (direction === "up" || direction === "left"),
11628                 animation = {},
11629                 animation1 = {},
11630                 animation2 = {},
11631                 i,
11632
11633                 // we will need to re-assemble the queue to stack our animations in place
11634                 queue = el.queue(),
11635                 queuelen = queue.length;
11636
11637         $.effects.save( el, props );
11638         el.show();
11639         $.effects.createWrapper( el );
11640
11641         // Animation
11642         animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11643         animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11644         animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11645
11646         // Animate
11647         el.animate( animation, speed, o.easing );
11648
11649         // Shakes
11650         for ( i = 1; i < times; i++ ) {
11651                 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11652         }
11653         el
11654                 .animate( animation1, speed, o.easing )
11655                 .animate( animation, speed / 2, o.easing )
11656                 .queue(function() {
11657                         if ( mode === "hide" ) {
11658                                 el.hide();
11659                         }
11660                         $.effects.restore( el, props );
11661                         $.effects.removeWrapper( el );
11662                         done();
11663                 });
11664
11665         // inject all the animations we just queued to be first in line (after "inprogress")
11666         if ( queuelen > 1) {
11667                 queue.splice.apply( queue,
11668                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11669         }
11670         el.dequeue();
11671
11672 };
11673
11674
11675 /*!
11676  * jQuery UI Effects Slide 1.11.2
11677  * http://jqueryui.com
11678  *
11679  * Copyright 2014 jQuery Foundation and other contributors
11680  * Released under the MIT license.
11681  * http://jquery.org/license
11682  *
11683  * http://api.jqueryui.com/slide-effect/
11684  */
11685
11686
11687 var effectSlide = $.effects.effect.slide = function( o, done ) {
11688
11689         // Create element
11690         var el = $( this ),
11691                 props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11692                 mode = $.effects.setMode( el, o.mode || "show" ),
11693                 show = mode === "show",
11694                 direction = o.direction || "left",
11695                 ref = (direction === "up" || direction === "down") ? "top" : "left",
11696                 positiveMotion = (direction === "up" || direction === "left"),
11697                 distance,
11698                 animation = {};
11699
11700         // Adjust
11701         $.effects.save( el, props );
11702         el.show();
11703         distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11704
11705         $.effects.createWrapper( el ).css({
11706                 overflow: "hidden"
11707         });
11708
11709         if ( show ) {
11710                 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11711         }
11712
11713         // Animation
11714         animation[ ref ] = ( show ?
11715                 ( positiveMotion ? "+=" : "-=") :
11716                 ( positiveMotion ? "-=" : "+=")) +
11717                 distance;
11718
11719         // Animate
11720         el.animate( animation, {
11721                 queue: false,
11722                 duration: o.duration,
11723                 easing: o.easing,
11724                 complete: function() {
11725                         if ( mode === "hide" ) {
11726                                 el.hide();
11727                         }
11728                         $.effects.restore( el, props );
11729                         $.effects.removeWrapper( el );
11730                         done();
11731                 }
11732         });
11733 };
11734
11735
11736 /*!
11737  * jQuery UI Effects Transfer 1.11.2
11738  * http://jqueryui.com
11739  *
11740  * Copyright 2014 jQuery Foundation and other contributors
11741  * Released under the MIT license.
11742  * http://jquery.org/license
11743  *
11744  * http://api.jqueryui.com/transfer-effect/
11745  */
11746
11747
11748 var effectTransfer = $.effects.effect.transfer = function( o, done ) {
11749         var elem = $( this ),
11750                 target = $( o.to ),
11751                 targetFixed = target.css( "position" ) === "fixed",
11752                 body = $("body"),
11753                 fixTop = targetFixed ? body.scrollTop() : 0,
11754                 fixLeft = targetFixed ? body.scrollLeft() : 0,
11755                 endPosition = target.offset(),
11756                 animation = {
11757                         top: endPosition.top - fixTop,
11758                         left: endPosition.left - fixLeft,
11759                         height: target.innerHeight(),
11760                         width: target.innerWidth()
11761                 },
11762                 startPosition = elem.offset(),
11763                 transfer = $( "<div class='ui-effects-transfer'></div>" )
11764                         .appendTo( document.body )
11765                         .addClass( o.className )
11766                         .css({
11767                                 top: startPosition.top - fixTop,
11768                                 left: startPosition.left - fixLeft,
11769                                 height: elem.innerHeight(),
11770                                 width: elem.innerWidth(),
11771                                 position: targetFixed ? "fixed" : "absolute"
11772                         })
11773                         .animate( animation, o.duration, o.easing, function() {
11774                                 transfer.remove();
11775                                 done();
11776                         });
11777 };
11778
11779
11780 /*!
11781  * jQuery UI Progressbar 1.11.2
11782  * http://jqueryui.com
11783  *
11784  * Copyright 2014 jQuery Foundation and other contributors
11785  * Released under the MIT license.
11786  * http://jquery.org/license
11787  *
11788  * http://api.jqueryui.com/progressbar/
11789  */
11790
11791
11792 var progressbar = $.widget( "ui.progressbar", {
11793         version: "1.11.2",
11794         options: {
11795                 max: 100,
11796                 value: 0,
11797
11798                 change: null,
11799                 complete: null
11800         },
11801
11802         min: 0,
11803
11804         _create: function() {
11805                 // Constrain initial value
11806                 this.oldValue = this.options.value = this._constrainedValue();
11807
11808                 this.element
11809                         .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11810                         .attr({
11811                                 // Only set static values, aria-valuenow and aria-valuemax are
11812                                 // set inside _refreshValue()
11813                                 role: "progressbar",
11814                                 "aria-valuemin": this.min
11815                         });
11816
11817                 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
11818                         .appendTo( this.element );
11819
11820                 this._refreshValue();
11821         },
11822
11823         _destroy: function() {
11824                 this.element
11825                         .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11826                         .removeAttr( "role" )
11827                         .removeAttr( "aria-valuemin" )
11828                         .removeAttr( "aria-valuemax" )
11829                         .removeAttr( "aria-valuenow" );
11830
11831                 this.valueDiv.remove();
11832         },
11833
11834         value: function( newValue ) {
11835                 if ( newValue === undefined ) {
11836                         return this.options.value;
11837                 }
11838
11839                 this.options.value = this._constrainedValue( newValue );
11840                 this._refreshValue();
11841         },
11842
11843         _constrainedValue: function( newValue ) {
11844                 if ( newValue === undefined ) {
11845                         newValue = this.options.value;
11846                 }
11847
11848                 this.indeterminate = newValue === false;
11849
11850                 // sanitize value
11851                 if ( typeof newValue !== "number" ) {
11852                         newValue = 0;
11853                 }
11854
11855                 return this.indeterminate ? false :
11856                         Math.min( this.options.max, Math.max( this.min, newValue ) );
11857         },
11858
11859         _setOptions: function( options ) {
11860                 // Ensure "value" option is set after other values (like max)
11861                 var value = options.value;
11862                 delete options.value;
11863
11864                 this._super( options );
11865
11866                 this.options.value = this._constrainedValue( value );
11867                 this._refreshValue();
11868         },
11869
11870         _setOption: function( key, value ) {
11871                 if ( key === "max" ) {
11872                         // Don't allow a max less than min
11873                         value = Math.max( this.min, value );
11874                 }
11875                 if ( key === "disabled" ) {
11876                         this.element
11877                                 .toggleClass( "ui-state-disabled", !!value )
11878                                 .attr( "aria-disabled", value );
11879                 }
11880                 this._super( key, value );
11881         },
11882
11883         _percentage: function() {
11884                 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
11885         },
11886
11887         _refreshValue: function() {
11888                 var value = this.options.value,
11889                         percentage = this._percentage();
11890
11891                 this.valueDiv
11892                         .toggle( this.indeterminate || value > this.min )
11893                         .toggleClass( "ui-corner-right", value === this.options.max )
11894                         .width( percentage.toFixed(0) + "%" );
11895
11896                 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
11897
11898                 if ( this.indeterminate ) {
11899                         this.element.removeAttr( "aria-valuenow" );
11900                         if ( !this.overlayDiv ) {
11901                                 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
11902                         }
11903                 } else {
11904                         this.element.attr({
11905                                 "aria-valuemax": this.options.max,
11906                                 "aria-valuenow": value
11907                         });
11908                         if ( this.overlayDiv ) {
11909                                 this.overlayDiv.remove();
11910                                 this.overlayDiv = null;
11911                         }
11912                 }
11913
11914                 if ( this.oldValue !== value ) {
11915                         this.oldValue = value;
11916                         this._trigger( "change" );
11917                 }
11918                 if ( value === this.options.max ) {
11919                         this._trigger( "complete" );
11920                 }
11921         }
11922 });
11923
11924
11925 /*!
11926  * jQuery UI Selectable 1.11.2
11927  * http://jqueryui.com
11928  *
11929  * Copyright 2014 jQuery Foundation and other contributors
11930  * Released under the MIT license.
11931  * http://jquery.org/license
11932  *
11933  * http://api.jqueryui.com/selectable/
11934  */
11935
11936
11937 var selectable = $.widget("ui.selectable", $.ui.mouse, {
11938         version: "1.11.2",
11939         options: {
11940                 appendTo: "body",
11941                 autoRefresh: true,
11942                 distance: 0,
11943                 filter: "*",
11944                 tolerance: "touch",
11945
11946                 // callbacks
11947                 selected: null,
11948                 selecting: null,
11949                 start: null,
11950                 stop: null,
11951                 unselected: null,
11952                 unselecting: null
11953         },
11954         _create: function() {
11955                 var selectees,
11956                         that = this;
11957
11958                 this.element.addClass("ui-selectable");
11959
11960                 this.dragged = false;
11961
11962                 // cache selectee children based on filter
11963                 this.refresh = function() {
11964                         selectees = $(that.options.filter, that.element[0]);
11965                         selectees.addClass("ui-selectee");
11966                         selectees.each(function() {
11967                                 var $this = $(this),
11968                                         pos = $this.offset();
11969                                 $.data(this, "selectable-item", {
11970                                         element: this,
11971                                         $element: $this,
11972                                         left: pos.left,
11973                                         top: pos.top,
11974                                         right: pos.left + $this.outerWidth(),
11975                                         bottom: pos.top + $this.outerHeight(),
11976                                         startselected: false,
11977                                         selected: $this.hasClass("ui-selected"),
11978                                         selecting: $this.hasClass("ui-selecting"),
11979                                         unselecting: $this.hasClass("ui-unselecting")
11980                                 });
11981                         });
11982                 };
11983                 this.refresh();
11984
11985                 this.selectees = selectees.addClass("ui-selectee");
11986
11987                 this._mouseInit();
11988
11989                 this.helper = $("<div class='ui-selectable-helper'></div>");
11990         },
11991
11992         _destroy: function() {
11993                 this.selectees
11994                         .removeClass("ui-selectee")
11995                         .removeData("selectable-item");
11996                 this.element
11997                         .removeClass("ui-selectable ui-selectable-disabled");
11998                 this._mouseDestroy();
11999         },
12000
12001         _mouseStart: function(event) {
12002                 var that = this,
12003                         options = this.options;
12004
12005                 this.opos = [ event.pageX, event.pageY ];
12006
12007                 if (this.options.disabled) {
12008                         return;
12009                 }
12010
12011                 this.selectees = $(options.filter, this.element[0]);
12012
12013                 this._trigger("start", event);
12014
12015                 $(options.appendTo).append(this.helper);
12016                 // position helper (lasso)
12017                 this.helper.css({
12018                         "left": event.pageX,
12019                         "top": event.pageY,
12020                         "width": 0,
12021                         "height": 0
12022                 });
12023
12024                 if (options.autoRefresh) {
12025                         this.refresh();
12026                 }
12027
12028                 this.selectees.filter(".ui-selected").each(function() {
12029                         var selectee = $.data(this, "selectable-item");
12030                         selectee.startselected = true;
12031                         if (!event.metaKey && !event.ctrlKey) {
12032                                 selectee.$element.removeClass("ui-selected");
12033                                 selectee.selected = false;
12034                                 selectee.$element.addClass("ui-unselecting");
12035                                 selectee.unselecting = true;
12036                                 // selectable UNSELECTING callback
12037                                 that._trigger("unselecting", event, {
12038                                         unselecting: selectee.element
12039                                 });
12040                         }
12041                 });
12042
12043                 $(event.target).parents().addBack().each(function() {
12044                         var doSelect,
12045                                 selectee = $.data(this, "selectable-item");
12046                         if (selectee) {
12047                                 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
12048                                 selectee.$element
12049                                         .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
12050                                         .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
12051                                 selectee.unselecting = !doSelect;
12052                                 selectee.selecting = doSelect;
12053                                 selectee.selected = doSelect;
12054                                 // selectable (UN)SELECTING callback
12055                                 if (doSelect) {
12056                                         that._trigger("selecting", event, {
12057                                                 selecting: selectee.element
12058                                         });
12059                                 } else {
12060                                         that._trigger("unselecting", event, {
12061                                                 unselecting: selectee.element
12062                                         });
12063                                 }
12064                                 return false;
12065                         }
12066                 });
12067
12068         },
12069
12070         _mouseDrag: function(event) {
12071
12072                 this.dragged = true;
12073
12074                 if (this.options.disabled) {
12075                         return;
12076                 }
12077
12078                 var tmp,
12079                         that = this,
12080                         options = this.options,
12081                         x1 = this.opos[0],
12082                         y1 = this.opos[1],
12083                         x2 = event.pageX,
12084                         y2 = event.pageY;
12085
12086                 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
12087                 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
12088                 this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
12089
12090                 this.selectees.each(function() {
12091                         var selectee = $.data(this, "selectable-item"),
12092                                 hit = false;
12093
12094                         //prevent helper from being selected if appendTo: selectable
12095                         if (!selectee || selectee.element === that.element[0]) {
12096                                 return;
12097                         }
12098
12099                         if (options.tolerance === "touch") {
12100                                 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
12101                         } else if (options.tolerance === "fit") {
12102                                 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
12103                         }
12104
12105                         if (hit) {
12106                                 // SELECT
12107                                 if (selectee.selected) {
12108                                         selectee.$element.removeClass("ui-selected");
12109                                         selectee.selected = false;
12110                                 }
12111                                 if (selectee.unselecting) {
12112                                         selectee.$element.removeClass("ui-unselecting");
12113                                         selectee.unselecting = false;
12114                                 }
12115                                 if (!selectee.selecting) {
12116                                         selectee.$element.addClass("ui-selecting");
12117                                         selectee.selecting = true;
12118                                         // selectable SELECTING callback
12119                                         that._trigger("selecting", event, {
12120                                                 selecting: selectee.element
12121                                         });
12122                                 }
12123                         } else {
12124                                 // UNSELECT
12125                                 if (selectee.selecting) {
12126                                         if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
12127                                                 selectee.$element.removeClass("ui-selecting");
12128                                                 selectee.selecting = false;
12129                                                 selectee.$element.addClass("ui-selected");
12130                                                 selectee.selected = true;
12131                                         } else {
12132                                                 selectee.$element.removeClass("ui-selecting");
12133                                                 selectee.selecting = false;
12134                                                 if (selectee.startselected) {
12135                                                         selectee.$element.addClass("ui-unselecting");
12136                                                         selectee.unselecting = true;
12137                                                 }
12138                                                 // selectable UNSELECTING callback
12139                                                 that._trigger("unselecting", event, {
12140                                                         unselecting: selectee.element
12141                                                 });
12142                                         }
12143                                 }
12144                                 if (selectee.selected) {
12145                                         if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
12146                                                 selectee.$element.removeClass("ui-selected");
12147                                                 selectee.selected = false;
12148
12149                                                 selectee.$element.addClass("ui-unselecting");
12150                                                 selectee.unselecting = true;
12151                                                 // selectable UNSELECTING callback
12152                                                 that._trigger("unselecting", event, {
12153                                                         unselecting: selectee.element
12154                                                 });
12155                                         }
12156                                 }
12157                         }
12158                 });
12159
12160                 return false;
12161         },
12162
12163         _mouseStop: function(event) {
12164                 var that = this;
12165
12166                 this.dragged = false;
12167
12168                 $(".ui-unselecting", this.element[0]).each(function() {
12169                         var selectee = $.data(this, "selectable-item");
12170                         selectee.$element.removeClass("ui-unselecting");
12171                         selectee.unselecting = false;
12172                         selectee.startselected = false;
12173                         that._trigger("unselected", event, {
12174                                 unselected: selectee.element
12175                         });
12176                 });
12177                 $(".ui-selecting", this.element[0]).each(function() {
12178                         var selectee = $.data(this, "selectable-item");
12179                         selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
12180                         selectee.selecting = false;
12181                         selectee.selected = true;
12182                         selectee.startselected = true;
12183                         that._trigger("selected", event, {
12184                                 selected: selectee.element
12185                         });
12186                 });
12187                 this._trigger("stop", event);
12188
12189                 this.helper.remove();
12190
12191                 return false;
12192         }
12193
12194 });
12195
12196
12197 /*!
12198  * jQuery UI Selectmenu 1.11.2
12199  * http://jqueryui.com
12200  *
12201  * Copyright 2014 jQuery Foundation and other contributors
12202  * Released under the MIT license.
12203  * http://jquery.org/license
12204  *
12205  * http://api.jqueryui.com/selectmenu
12206  */
12207
12208
12209 var selectmenu = $.widget( "ui.selectmenu", {
12210         version: "1.11.2",
12211         defaultElement: "<select>",
12212         options: {
12213                 appendTo: null,
12214                 disabled: null,
12215                 icons: {
12216                         button: "ui-icon-triangle-1-s"
12217                 },
12218                 position: {
12219                         my: "left top",
12220                         at: "left bottom",
12221                         collision: "none"
12222                 },
12223                 width: null,
12224
12225                 // callbacks
12226                 change: null,
12227                 close: null,
12228                 focus: null,
12229                 open: null,
12230                 select: null
12231         },
12232
12233         _create: function() {
12234                 var selectmenuId = this.element.uniqueId().attr( "id" );
12235                 this.ids = {
12236                         element: selectmenuId,
12237                         button: selectmenuId + "-button",
12238                         menu: selectmenuId + "-menu"
12239                 };
12240
12241                 this._drawButton();
12242                 this._drawMenu();
12243
12244                 if ( this.options.disabled ) {
12245                         this.disable();
12246                 }
12247         },
12248
12249         _drawButton: function() {
12250                 var that = this,
12251                         tabindex = this.element.attr( "tabindex" );
12252
12253                 // Associate existing label with the new button
12254                 this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
12255                 this._on( this.label, {
12256                         click: function( event ) {
12257                                 this.button.focus();
12258                                 event.preventDefault();
12259                         }
12260                 });
12261
12262                 // Hide original select element
12263                 this.element.hide();
12264
12265                 // Create button
12266                 this.button = $( "<span>", {
12267                         "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
12268                         tabindex: tabindex || this.options.disabled ? -1 : 0,
12269                         id: this.ids.button,
12270                         role: "combobox",
12271                         "aria-expanded": "false",
12272                         "aria-autocomplete": "list",
12273                         "aria-owns": this.ids.menu,
12274                         "aria-haspopup": "true"
12275                 })
12276                         .insertAfter( this.element );
12277
12278                 $( "<span>", {
12279                         "class": "ui-icon " + this.options.icons.button
12280                 })
12281                         .prependTo( this.button );
12282
12283                 this.buttonText = $( "<span>", {
12284                         "class": "ui-selectmenu-text"
12285                 })
12286                         .appendTo( this.button );
12287
12288                 this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
12289                 this._resizeButton();
12290
12291                 this._on( this.button, this._buttonEvents );
12292                 this.button.one( "focusin", function() {
12293
12294                         // Delay rendering the menu items until the button receives focus.
12295                         // The menu may have already been rendered via a programmatic open.
12296                         if ( !that.menuItems ) {
12297                                 that._refreshMenu();
12298                         }
12299                 });
12300                 this._hoverable( this.button );
12301                 this._focusable( this.button );
12302         },
12303
12304         _drawMenu: function() {
12305                 var that = this;
12306
12307                 // Create menu
12308                 this.menu = $( "<ul>", {
12309                         "aria-hidden": "true",
12310                         "aria-labelledby": this.ids.button,
12311                         id: this.ids.menu
12312                 });
12313
12314                 // Wrap menu
12315                 this.menuWrap = $( "<div>", {
12316                         "class": "ui-selectmenu-menu ui-front"
12317                 })
12318                         .append( this.menu )
12319                         .appendTo( this._appendTo() );
12320
12321                 // Initialize menu widget
12322                 this.menuInstance = this.menu
12323                         .menu({
12324                                 role: "listbox",
12325                                 select: function( event, ui ) {
12326                                         event.preventDefault();
12327
12328                                         // support: IE8
12329                                         // If the item was selected via a click, the text selection
12330                                         // will be destroyed in IE
12331                                         that._setSelection();
12332
12333                                         that._select( ui.item.data( "ui-selectmenu-item" ), event );
12334                                 },
12335                                 focus: function( event, ui ) {
12336                                         var item = ui.item.data( "ui-selectmenu-item" );
12337
12338                                         // Prevent inital focus from firing and check if its a newly focused item
12339                                         if ( that.focusIndex != null && item.index !== that.focusIndex ) {
12340                                                 that._trigger( "focus", event, { item: item } );
12341                                                 if ( !that.isOpen ) {
12342                                                         that._select( item, event );
12343                                                 }
12344                                         }
12345                                         that.focusIndex = item.index;
12346
12347                                         that.button.attr( "aria-activedescendant",
12348                                                 that.menuItems.eq( item.index ).attr( "id" ) );
12349                                 }
12350                         })
12351                         .menu( "instance" );
12352
12353                 // Adjust menu styles to dropdown
12354                 this.menu
12355                         .addClass( "ui-corner-bottom" )
12356                         .removeClass( "ui-corner-all" );
12357
12358                 // Don't close the menu on mouseleave
12359                 this.menuInstance._off( this.menu, "mouseleave" );
12360
12361                 // Cancel the menu's collapseAll on document click
12362                 this.menuInstance._closeOnDocumentClick = function() {
12363                         return false;
12364                 };
12365
12366                 // Selects often contain empty items, but never contain dividers
12367                 this.menuInstance._isDivider = function() {
12368                         return false;
12369                 };
12370         },
12371
12372         refresh: function() {
12373                 this._refreshMenu();
12374                 this._setText( this.buttonText, this._getSelectedItem().text() );
12375                 if ( !this.options.width ) {
12376                         this._resizeButton();
12377                 }
12378         },
12379
12380         _refreshMenu: function() {
12381                 this.menu.empty();
12382
12383                 var item,
12384                         options = this.element.find( "option" );
12385
12386                 if ( !options.length ) {
12387                         return;
12388                 }
12389
12390                 this._parseOptions( options );
12391                 this._renderMenu( this.menu, this.items );
12392
12393                 this.menuInstance.refresh();
12394                 this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
12395
12396                 item = this._getSelectedItem();
12397
12398                 // Update the menu to have the correct item focused
12399                 this.menuInstance.focus( null, item );
12400                 this._setAria( item.data( "ui-selectmenu-item" ) );
12401
12402                 // Set disabled state
12403                 this._setOption( "disabled", this.element.prop( "disabled" ) );
12404         },
12405
12406         open: function( event ) {
12407                 if ( this.options.disabled ) {
12408                         return;
12409                 }
12410
12411                 // If this is the first time the menu is being opened, render the items
12412                 if ( !this.menuItems ) {
12413                         this._refreshMenu();
12414                 } else {
12415
12416                         // Menu clears focus on close, reset focus to selected item
12417                         this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
12418                         this.menuInstance.focus( null, this._getSelectedItem() );
12419                 }
12420
12421                 this.isOpen = true;
12422                 this._toggleAttr();
12423                 this._resizeMenu();
12424                 this._position();
12425
12426                 this._on( this.document, this._documentClick );
12427
12428                 this._trigger( "open", event );
12429         },
12430
12431         _position: function() {
12432                 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
12433         },
12434
12435         close: function( event ) {
12436                 if ( !this.isOpen ) {
12437                         return;
12438                 }
12439
12440                 this.isOpen = false;
12441                 this._toggleAttr();
12442
12443                 this.range = null;
12444                 this._off( this.document );
12445
12446                 this._trigger( "close", event );
12447         },
12448
12449         widget: function() {
12450                 return this.button;
12451         },
12452
12453         menuWidget: function() {
12454                 return this.menu;
12455         },
12456
12457         _renderMenu: function( ul, items ) {
12458                 var that = this,
12459                         currentOptgroup = "";
12460
12461                 $.each( items, function( index, item ) {
12462                         if ( item.optgroup !== currentOptgroup ) {
12463                                 $( "<li>", {
12464                                         "class": "ui-selectmenu-optgroup ui-menu-divider" +
12465                                                 ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
12466                                                         " ui-state-disabled" :
12467                                                         "" ),
12468                                         text: item.optgroup
12469                                 })
12470                                         .appendTo( ul );
12471
12472                                 currentOptgroup = item.optgroup;
12473                         }
12474
12475                         that._renderItemData( ul, item );
12476                 });
12477         },
12478
12479         _renderItemData: function( ul, item ) {
12480                 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
12481         },
12482
12483         _renderItem: function( ul, item ) {
12484                 var li = $( "<li>" );
12485
12486                 if ( item.disabled ) {
12487                         li.addClass( "ui-state-disabled" );
12488                 }
12489                 this._setText( li, item.label );
12490
12491                 return li.appendTo( ul );
12492         },
12493
12494         _setText: function( element, value ) {
12495                 if ( value ) {
12496                         element.text( value );
12497                 } else {
12498                         element.html( "&#160;" );
12499                 }
12500         },
12501
12502         _move: function( direction, event ) {
12503                 var item, next,
12504                         filter = ".ui-menu-item";
12505
12506                 if ( this.isOpen ) {
12507                         item = this.menuItems.eq( this.focusIndex );
12508                 } else {
12509                         item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
12510                         filter += ":not(.ui-state-disabled)";
12511                 }
12512
12513                 if ( direction === "first" || direction === "last" ) {
12514                         next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
12515                 } else {
12516                         next = item[ direction + "All" ]( filter ).eq( 0 );
12517                 }
12518
12519                 if ( next.length ) {
12520                         this.menuInstance.focus( event, next );
12521                 }
12522         },
12523
12524         _getSelectedItem: function() {
12525                 return this.menuItems.eq( this.element[ 0 ].selectedIndex );
12526         },
12527
12528         _toggle: function( event ) {
12529                 this[ this.isOpen ? "close" : "open" ]( event );
12530         },
12531
12532         _setSelection: function() {
12533                 var selection;
12534
12535                 if ( !this.range ) {
12536                         return;
12537                 }
12538
12539                 if ( window.getSelection ) {
12540                         selection = window.getSelection();
12541                         selection.removeAllRanges();
12542                         selection.addRange( this.range );
12543
12544                 // support: IE8
12545                 } else {
12546                         this.range.select();
12547                 }
12548
12549                 // support: IE
12550                 // Setting the text selection kills the button focus in IE, but
12551                 // restoring the focus doesn't kill the selection.
12552                 this.button.focus();
12553         },
12554
12555         _documentClick: {
12556                 mousedown: function( event ) {
12557                         if ( !this.isOpen ) {
12558                                 return;
12559                         }
12560
12561                         if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
12562                                 this.close( event );
12563                         }
12564                 }
12565         },
12566
12567         _buttonEvents: {
12568
12569                 // Prevent text selection from being reset when interacting with the selectmenu (#10144)
12570                 mousedown: function() {
12571                         var selection;
12572
12573                         if ( window.getSelection ) {
12574                                 selection = window.getSelection();
12575                                 if ( selection.rangeCount ) {
12576                                         this.range = selection.getRangeAt( 0 );
12577                                 }
12578
12579                         // support: IE8
12580                         } else {
12581                                 this.range = document.selection.createRange();
12582                         }
12583                 },
12584
12585                 click: function( event ) {
12586                         this._setSelection();
12587                         this._toggle( event );
12588                 },
12589
12590                 keydown: function( event ) {
12591                         var preventDefault = true;
12592                         switch ( event.keyCode ) {
12593                                 case $.ui.keyCode.TAB:
12594                                 case $.ui.keyCode.ESCAPE:
12595                                         this.close( event );
12596                                         preventDefault = false;
12597                                         break;
12598                                 case $.ui.keyCode.ENTER:
12599                                         if ( this.isOpen ) {
12600                                                 this._selectFocusedItem( event );
12601                                         }
12602                                         break;
12603                                 case $.ui.keyCode.UP:
12604                                         if ( event.altKey ) {
12605                                                 this._toggle( event );
12606                                         } else {
12607                                                 this._move( "prev", event );
12608                                         }
12609                                         break;
12610                                 case $.ui.keyCode.DOWN:
12611                                         if ( event.altKey ) {
12612                                                 this._toggle( event );
12613                                         } else {
12614                                                 this._move( "next", event );
12615                                         }
12616                                         break;
12617                                 case $.ui.keyCode.SPACE:
12618                                         if ( this.isOpen ) {
12619                                                 this._selectFocusedItem( event );
12620                                         } else {
12621                                                 this._toggle( event );
12622                                         }
12623                                         break;
12624                                 case $.ui.keyCode.LEFT:
12625                                         this._move( "prev", event );
12626                                         break;
12627                                 case $.ui.keyCode.RIGHT:
12628                                         this._move( "next", event );
12629                                         break;
12630                                 case $.ui.keyCode.HOME:
12631                                 case $.ui.keyCode.PAGE_UP:
12632                                         this._move( "first", event );
12633                                         break;
12634                                 case $.ui.keyCode.END:
12635                                 case $.ui.keyCode.PAGE_DOWN:
12636                                         this._move( "last", event );
12637                                         break;
12638                                 default:
12639                                         this.menu.trigger( event );
12640                                         preventDefault = false;
12641                         }
12642
12643                         if ( preventDefault ) {
12644                                 event.preventDefault();
12645                         }
12646                 }
12647         },
12648
12649         _selectFocusedItem: function( event ) {
12650                 var item = this.menuItems.eq( this.focusIndex );
12651                 if ( !item.hasClass( "ui-state-disabled" ) ) {
12652                         this._select( item.data( "ui-selectmenu-item" ), event );
12653                 }
12654         },
12655
12656         _select: function( item, event ) {
12657                 var oldIndex = this.element[ 0 ].selectedIndex;
12658
12659                 // Change native select element
12660                 this.element[ 0 ].selectedIndex = item.index;
12661                 this._setText( this.buttonText, item.label );
12662                 this._setAria( item );
12663                 this._trigger( "select", event, { item: item } );
12664
12665                 if ( item.index !== oldIndex ) {
12666                         this._trigger( "change", event, { item: item } );
12667                 }
12668
12669                 this.close( event );
12670         },
12671
12672         _setAria: function( item ) {
12673                 var id = this.menuItems.eq( item.index ).attr( "id" );
12674
12675                 this.button.attr({
12676                         "aria-labelledby": id,
12677                         "aria-activedescendant": id
12678                 });
12679                 this.menu.attr( "aria-activedescendant", id );
12680         },
12681
12682         _setOption: function( key, value ) {
12683                 if ( key === "icons" ) {
12684                         this.button.find( "span.ui-icon" )
12685                                 .removeClass( this.options.icons.button )
12686                                 .addClass( value.button );
12687                 }
12688
12689                 this._super( key, value );
12690
12691                 if ( key === "appendTo" ) {
12692                         this.menuWrap.appendTo( this._appendTo() );
12693                 }
12694
12695                 if ( key === "disabled" ) {
12696                         this.menuInstance.option( "disabled", value );
12697                         this.button
12698                                 .toggleClass( "ui-state-disabled", value )
12699                                 .attr( "aria-disabled", value );
12700
12701                         this.element.prop( "disabled", value );
12702                         if ( value ) {
12703                                 this.button.attr( "tabindex", -1 );
12704                                 this.close();
12705                         } else {
12706                                 this.button.attr( "tabindex", 0 );
12707                         }
12708                 }
12709
12710                 if ( key === "width" ) {
12711                         this._resizeButton();
12712                 }
12713         },
12714
12715         _appendTo: function() {
12716                 var element = this.options.appendTo;
12717
12718                 if ( element ) {
12719                         element = element.jquery || element.nodeType ?
12720                                 $( element ) :
12721                                 this.document.find( element ).eq( 0 );
12722                 }
12723
12724                 if ( !element || !element[ 0 ] ) {
12725                         element = this.element.closest( ".ui-front" );
12726                 }
12727
12728                 if ( !element.length ) {
12729                         element = this.document[ 0 ].body;
12730                 }
12731
12732                 return element;
12733         },
12734
12735         _toggleAttr: function() {
12736                 this.button
12737                         .toggleClass( "ui-corner-top", this.isOpen )
12738                         .toggleClass( "ui-corner-all", !this.isOpen )
12739                         .attr( "aria-expanded", this.isOpen );
12740                 this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
12741                 this.menu.attr( "aria-hidden", !this.isOpen );
12742         },
12743
12744         _resizeButton: function() {
12745                 var width = this.options.width;
12746
12747                 if ( !width ) {
12748                         width = this.element.show().outerWidth();
12749                         this.element.hide();
12750                 }
12751
12752                 this.button.outerWidth( width );
12753         },
12754
12755         _resizeMenu: function() {
12756                 this.menu.outerWidth( Math.max(
12757                         this.button.outerWidth(),
12758
12759                         // support: IE10
12760                         // IE10 wraps long text (possibly a rounding bug)
12761                         // so we add 1px to avoid the wrapping
12762                         this.menu.width( "" ).outerWidth() + 1
12763                 ) );
12764         },
12765
12766         _getCreateOptions: function() {
12767                 return { disabled: this.element.prop( "disabled" ) };
12768         },
12769
12770         _parseOptions: function( options ) {
12771                 var data = [];
12772                 options.each(function( index, item ) {
12773                         var option = $( item ),
12774                                 optgroup = option.parent( "optgroup" );
12775                         data.push({
12776                                 element: option,
12777                                 index: index,
12778                                 value: option.attr( "value" ),
12779                                 label: option.text(),
12780                                 optgroup: optgroup.attr( "label" ) || "",
12781                                 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
12782                         });
12783                 });
12784                 this.items = data;
12785         },
12786
12787         _destroy: function() {
12788                 this.menuWrap.remove();
12789                 this.button.remove();
12790                 this.element.show();
12791                 this.element.removeUniqueId();
12792                 this.label.attr( "for", this.ids.element );
12793         }
12794 });
12795
12796
12797 /*!
12798  * jQuery UI Slider 1.11.2
12799  * http://jqueryui.com
12800  *
12801  * Copyright 2014 jQuery Foundation and other contributors
12802  * Released under the MIT license.
12803  * http://jquery.org/license
12804  *
12805  * http://api.jqueryui.com/slider/
12806  */
12807
12808
12809 var slider = $.widget( "ui.slider", $.ui.mouse, {
12810         version: "1.11.2",
12811         widgetEventPrefix: "slide",
12812
12813         options: {
12814                 animate: false,
12815                 distance: 0,
12816                 max: 100,
12817                 min: 0,
12818                 orientation: "horizontal",
12819                 range: false,
12820                 step: 1,
12821                 value: 0,
12822                 values: null,
12823
12824                 // callbacks
12825                 change: null,
12826                 slide: null,
12827                 start: null,
12828                 stop: null
12829         },
12830
12831         // number of pages in a slider
12832         // (how many times can you page up/down to go through the whole range)
12833         numPages: 5,
12834
12835         _create: function() {
12836                 this._keySliding = false;
12837                 this._mouseSliding = false;
12838                 this._animateOff = true;
12839                 this._handleIndex = null;
12840                 this._detectOrientation();
12841                 this._mouseInit();
12842                 this._calculateNewMax();
12843
12844                 this.element
12845                         .addClass( "ui-slider" +
12846                                 " ui-slider-" + this.orientation +
12847                                 " ui-widget" +
12848                                 " ui-widget-content" +
12849                                 " ui-corner-all");
12850
12851                 this._refresh();
12852                 this._setOption( "disabled", this.options.disabled );
12853
12854                 this._animateOff = false;
12855         },
12856
12857         _refresh: function() {
12858                 this._createRange();
12859                 this._createHandles();
12860                 this._setupEvents();
12861                 this._refreshValue();
12862         },
12863
12864         _createHandles: function() {
12865                 var i, handleCount,
12866                         options = this.options,
12867                         existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12868                         handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
12869                         handles = [];
12870
12871                 handleCount = ( options.values && options.values.length ) || 1;
12872
12873                 if ( existingHandles.length > handleCount ) {
12874                         existingHandles.slice( handleCount ).remove();
12875                         existingHandles = existingHandles.slice( 0, handleCount );
12876                 }
12877
12878                 for ( i = existingHandles.length; i < handleCount; i++ ) {
12879                         handles.push( handle );
12880                 }
12881
12882                 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12883
12884                 this.handle = this.handles.eq( 0 );
12885
12886                 this.handles.each(function( i ) {
12887                         $( this ).data( "ui-slider-handle-index", i );
12888                 });
12889         },
12890
12891         _createRange: function() {
12892                 var options = this.options,
12893                         classes = "";
12894
12895                 if ( options.range ) {
12896                         if ( options.range === true ) {
12897                                 if ( !options.values ) {
12898                                         options.values = [ this._valueMin(), this._valueMin() ];
12899                                 } else if ( options.values.length && options.values.length !== 2 ) {
12900                                         options.values = [ options.values[0], options.values[0] ];
12901                                 } else if ( $.isArray( options.values ) ) {
12902                                         options.values = options.values.slice(0);
12903                                 }
12904                         }
12905
12906                         if ( !this.range || !this.range.length ) {
12907                                 this.range = $( "<div></div>" )
12908                                         .appendTo( this.element );
12909
12910                                 classes = "ui-slider-range" +
12911                                 // note: this isn't the most fittingly semantic framework class for this element,
12912                                 // but worked best visually with a variety of themes
12913                                 " ui-widget-header ui-corner-all";
12914                         } else {
12915                                 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12916                                         // Handle range switching from true to min/max
12917                                         .css({
12918                                                 "left": "",
12919                                                 "bottom": ""
12920                                         });
12921                         }
12922
12923                         this.range.addClass( classes +
12924                                 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12925                 } else {
12926                         if ( this.range ) {
12927                                 this.range.remove();
12928                         }
12929                         this.range = null;
12930                 }
12931         },
12932
12933         _setupEvents: function() {
12934                 this._off( this.handles );
12935                 this._on( this.handles, this._handleEvents );
12936                 this._hoverable( this.handles );
12937                 this._focusable( this.handles );
12938         },
12939
12940         _destroy: function() {
12941                 this.handles.remove();
12942                 if ( this.range ) {
12943                         this.range.remove();
12944                 }
12945
12946                 this.element
12947                         .removeClass( "ui-slider" +
12948                                 " ui-slider-horizontal" +
12949                                 " ui-slider-vertical" +
12950                                 " ui-widget" +
12951                                 " ui-widget-content" +
12952                                 " ui-corner-all" );
12953
12954                 this._mouseDestroy();
12955         },
12956
12957         _mouseCapture: function( event ) {
12958                 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12959                         that = this,
12960                         o = this.options;
12961
12962                 if ( o.disabled ) {
12963                         return false;
12964                 }
12965
12966                 this.elementSize = {
12967                         width: this.element.outerWidth(),
12968                         height: this.element.outerHeight()
12969                 };
12970                 this.elementOffset = this.element.offset();
12971
12972                 position = { x: event.pageX, y: event.pageY };
12973                 normValue = this._normValueFromMouse( position );
12974                 distance = this._valueMax() - this._valueMin() + 1;
12975                 this.handles.each(function( i ) {
12976                         var thisDistance = Math.abs( normValue - that.values(i) );
12977                         if (( distance > thisDistance ) ||
12978                                 ( distance === thisDistance &&
12979                                         (i === that._lastChangedValue || that.values(i) === o.min ))) {
12980                                 distance = thisDistance;
12981                                 closestHandle = $( this );
12982                                 index = i;
12983                         }
12984                 });
12985
12986                 allowed = this._start( event, index );
12987                 if ( allowed === false ) {
12988                         return false;
12989                 }
12990                 this._mouseSliding = true;
12991
12992                 this._handleIndex = index;
12993
12994                 closestHandle
12995                         .addClass( "ui-state-active" )
12996                         .focus();
12997
12998                 offset = closestHandle.offset();
12999                 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
13000                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
13001                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
13002                         top: event.pageY - offset.top -
13003                                 ( closestHandle.height() / 2 ) -
13004                                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
13005                                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
13006                                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
13007                 };
13008
13009                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
13010                         this._slide( event, index, normValue );
13011                 }
13012                 this._animateOff = true;
13013                 return true;
13014         },
13015
13016         _mouseStart: function() {
13017                 return true;
13018         },
13019
13020         _mouseDrag: function( event ) {
13021                 var position = { x: event.pageX, y: event.pageY },
13022                         normValue = this._normValueFromMouse( position );
13023
13024                 this._slide( event, this._handleIndex, normValue );
13025
13026                 return false;
13027         },
13028
13029         _mouseStop: function( event ) {
13030                 this.handles.removeClass( "ui-state-active" );
13031                 this._mouseSliding = false;
13032
13033                 this._stop( event, this._handleIndex );
13034                 this._change( event, this._handleIndex );
13035
13036                 this._handleIndex = null;
13037                 this._clickOffset = null;
13038                 this._animateOff = false;
13039
13040                 return false;
13041         },
13042
13043         _detectOrientation: function() {
13044                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
13045         },
13046
13047         _normValueFromMouse: function( position ) {
13048                 var pixelTotal,
13049                         pixelMouse,
13050                         percentMouse,
13051                         valueTotal,
13052                         valueMouse;
13053
13054                 if ( this.orientation === "horizontal" ) {
13055                         pixelTotal = this.elementSize.width;
13056                         pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
13057                 } else {
13058                         pixelTotal = this.elementSize.height;
13059                         pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
13060                 }
13061
13062                 percentMouse = ( pixelMouse / pixelTotal );
13063                 if ( percentMouse > 1 ) {
13064                         percentMouse = 1;
13065                 }
13066                 if ( percentMouse < 0 ) {
13067                         percentMouse = 0;
13068                 }
13069                 if ( this.orientation === "vertical" ) {
13070                         percentMouse = 1 - percentMouse;
13071                 }
13072
13073                 valueTotal = this._valueMax() - this._valueMin();
13074                 valueMouse = this._valueMin() + percentMouse * valueTotal;
13075
13076                 return this._trimAlignValue( valueMouse );
13077         },
13078
13079         _start: function( event, index ) {
13080                 var uiHash = {
13081                         handle: this.handles[ index ],
13082                         value: this.value()
13083                 };
13084                 if ( this.options.values && this.options.values.length ) {
13085                         uiHash.value = this.values( index );
13086                         uiHash.values = this.values();
13087                 }
13088                 return this._trigger( "start", event, uiHash );
13089         },
13090
13091         _slide: function( event, index, newVal ) {
13092                 var otherVal,
13093                         newValues,
13094                         allowed;
13095
13096                 if ( this.options.values && this.options.values.length ) {
13097                         otherVal = this.values( index ? 0 : 1 );
13098
13099                         if ( ( this.options.values.length === 2 && this.options.range === true ) &&
13100                                         ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
13101                                 ) {
13102                                 newVal = otherVal;
13103                         }
13104
13105                         if ( newVal !== this.values( index ) ) {
13106                                 newValues = this.values();
13107                                 newValues[ index ] = newVal;
13108                                 // A slide can be canceled by returning false from the slide callback
13109                                 allowed = this._trigger( "slide", event, {
13110                                         handle: this.handles[ index ],
13111                                         value: newVal,
13112                                         values: newValues
13113                                 } );
13114                                 otherVal = this.values( index ? 0 : 1 );
13115                                 if ( allowed !== false ) {
13116                                         this.values( index, newVal );
13117                                 }
13118                         }
13119                 } else {
13120                         if ( newVal !== this.value() ) {
13121                                 // A slide can be canceled by returning false from the slide callback
13122                                 allowed = this._trigger( "slide", event, {
13123                                         handle: this.handles[ index ],
13124                                         value: newVal
13125                                 } );
13126                                 if ( allowed !== false ) {
13127                                         this.value( newVal );
13128                                 }
13129                         }
13130                 }
13131         },
13132
13133         _stop: function( event, index ) {
13134                 var uiHash = {
13135                         handle: this.handles[ index ],
13136                         value: this.value()
13137                 };
13138                 if ( this.options.values && this.options.values.length ) {
13139                         uiHash.value = this.values( index );
13140                         uiHash.values = this.values();
13141                 }
13142
13143                 this._trigger( "stop", event, uiHash );
13144         },
13145
13146         _change: function( event, index ) {
13147                 if ( !this._keySliding && !this._mouseSliding ) {
13148                         var uiHash = {
13149                                 handle: this.handles[ index ],
13150                                 value: this.value()
13151                         };
13152                         if ( this.options.values && this.options.values.length ) {
13153                                 uiHash.value = this.values( index );
13154                                 uiHash.values = this.values();
13155                         }
13156
13157                         //store the last changed value index for reference when handles overlap
13158                         this._lastChangedValue = index;
13159
13160                         this._trigger( "change", event, uiHash );
13161                 }
13162         },
13163
13164         value: function( newValue ) {
13165                 if ( arguments.length ) {
13166                         this.options.value = this._trimAlignValue( newValue );
13167                         this._refreshValue();
13168                         this._change( null, 0 );
13169                         return;
13170                 }
13171
13172                 return this._value();
13173         },
13174
13175         values: function( index, newValue ) {
13176                 var vals,
13177                         newValues,
13178                         i;
13179
13180                 if ( arguments.length > 1 ) {
13181                         this.options.values[ index ] = this._trimAlignValue( newValue );
13182                         this._refreshValue();
13183                         this._change( null, index );
13184                         return;
13185                 }
13186
13187                 if ( arguments.length ) {
13188                         if ( $.isArray( arguments[ 0 ] ) ) {
13189                                 vals = this.options.values;
13190                                 newValues = arguments[ 0 ];
13191                                 for ( i = 0; i < vals.length; i += 1 ) {
13192                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
13193                                         this._change( null, i );
13194                                 }
13195                                 this._refreshValue();
13196                         } else {
13197                                 if ( this.options.values && this.options.values.length ) {
13198                                         return this._values( index );
13199                                 } else {
13200                                         return this.value();
13201                                 }
13202                         }
13203                 } else {
13204                         return this._values();
13205                 }
13206         },
13207
13208         _setOption: function( key, value ) {
13209                 var i,
13210                         valsLength = 0;
13211
13212                 if ( key === "range" && this.options.range === true ) {
13213                         if ( value === "min" ) {
13214                                 this.options.value = this._values( 0 );
13215                                 this.options.values = null;
13216                         } else if ( value === "max" ) {
13217                                 this.options.value = this._values( this.options.values.length - 1 );
13218                                 this.options.values = null;
13219                         }
13220                 }
13221
13222                 if ( $.isArray( this.options.values ) ) {
13223                         valsLength = this.options.values.length;
13224                 }
13225
13226                 if ( key === "disabled" ) {
13227                         this.element.toggleClass( "ui-state-disabled", !!value );
13228                 }
13229
13230                 this._super( key, value );
13231
13232                 switch ( key ) {
13233                         case "orientation":
13234                                 this._detectOrientation();
13235                                 this.element
13236                                         .removeClass( "ui-slider-horizontal ui-slider-vertical" )
13237                                         .addClass( "ui-slider-" + this.orientation );
13238                                 this._refreshValue();
13239
13240                                 // Reset positioning from previous orientation
13241                                 this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
13242                                 break;
13243                         case "value":
13244                                 this._animateOff = true;
13245                                 this._refreshValue();
13246                                 this._change( null, 0 );
13247                                 this._animateOff = false;
13248                                 break;
13249                         case "values":
13250                                 this._animateOff = true;
13251                                 this._refreshValue();
13252                                 for ( i = 0; i < valsLength; i += 1 ) {
13253                                         this._change( null, i );
13254                                 }
13255                                 this._animateOff = false;
13256                                 break;
13257                         case "step":
13258                         case "min":
13259                         case "max":
13260                                 this._animateOff = true;
13261                                 this._calculateNewMax();
13262                                 this._refreshValue();
13263                                 this._animateOff = false;
13264                                 break;
13265                         case "range":
13266                                 this._animateOff = true;
13267                                 this._refresh();
13268                                 this._animateOff = false;
13269                                 break;
13270                 }
13271         },
13272
13273         //internal value getter
13274         // _value() returns value trimmed by min and max, aligned by step
13275         _value: function() {
13276                 var val = this.options.value;
13277                 val = this._trimAlignValue( val );
13278
13279                 return val;
13280         },
13281
13282         //internal values getter
13283         // _values() returns array of values trimmed by min and max, aligned by step
13284         // _values( index ) returns single value trimmed by min and max, aligned by step
13285         _values: function( index ) {
13286                 var val,
13287                         vals,
13288                         i;
13289
13290                 if ( arguments.length ) {
13291                         val = this.options.values[ index ];
13292                         val = this._trimAlignValue( val );
13293
13294                         return val;
13295                 } else if ( this.options.values && this.options.values.length ) {
13296                         // .slice() creates a copy of the array
13297                         // this copy gets trimmed by min and max and then returned
13298                         vals = this.options.values.slice();
13299                         for ( i = 0; i < vals.length; i += 1) {
13300                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
13301                         }
13302
13303                         return vals;
13304                 } else {
13305                         return [];
13306                 }
13307         },
13308
13309         // returns the step-aligned value that val is closest to, between (inclusive) min and max
13310         _trimAlignValue: function( val ) {
13311                 if ( val <= this._valueMin() ) {
13312                         return this._valueMin();
13313                 }
13314                 if ( val >= this._valueMax() ) {
13315                         return this._valueMax();
13316                 }
13317                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
13318                         valModStep = (val - this._valueMin()) % step,
13319                         alignValue = val - valModStep;
13320
13321                 if ( Math.abs(valModStep) * 2 >= step ) {
13322                         alignValue += ( valModStep > 0 ) ? step : ( -step );
13323                 }
13324
13325                 // Since JavaScript has problems with large floats, round
13326                 // the final value to 5 digits after the decimal point (see #4124)
13327                 return parseFloat( alignValue.toFixed(5) );
13328         },
13329
13330         _calculateNewMax: function() {
13331                 var remainder = ( this.options.max - this._valueMin() ) % this.options.step;
13332                 this.max = this.options.max - remainder;
13333         },
13334
13335         _valueMin: function() {
13336                 return this.options.min;
13337         },
13338
13339         _valueMax: function() {
13340                 return this.max;
13341         },
13342
13343         _refreshValue: function() {
13344                 var lastValPercent, valPercent, value, valueMin, valueMax,
13345                         oRange = this.options.range,
13346                         o = this.options,
13347                         that = this,
13348                         animate = ( !this._animateOff ) ? o.animate : false,
13349                         _set = {};
13350
13351                 if ( this.options.values && this.options.values.length ) {
13352                         this.handles.each(function( i ) {
13353                                 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13354                                 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13355                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13356                                 if ( that.options.range === true ) {
13357                                         if ( that.orientation === "horizontal" ) {
13358                                                 if ( i === 0 ) {
13359                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13360                                                 }
13361                                                 if ( i === 1 ) {
13362                                                         that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13363                                                 }
13364                                         } else {
13365                                                 if ( i === 0 ) {
13366                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13367                                                 }
13368                                                 if ( i === 1 ) {
13369                                                         that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13370                                                 }
13371                                         }
13372                                 }
13373                                 lastValPercent = valPercent;
13374                         });
13375                 } else {
13376                         value = this.value();
13377                         valueMin = this._valueMin();
13378                         valueMax = this._valueMax();
13379                         valPercent = ( valueMax !== valueMin ) ?
13380                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13381                                         0;
13382                         _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13383                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13384
13385                         if ( oRange === "min" && this.orientation === "horizontal" ) {
13386                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13387                         }
13388                         if ( oRange === "max" && this.orientation === "horizontal" ) {
13389                                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13390                         }
13391                         if ( oRange === "min" && this.orientation === "vertical" ) {
13392                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13393                         }
13394                         if ( oRange === "max" && this.orientation === "vertical" ) {
13395                                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13396                         }
13397                 }
13398         },
13399
13400         _handleEvents: {
13401                 keydown: function( event ) {
13402                         var allowed, curVal, newVal, step,
13403                                 index = $( event.target ).data( "ui-slider-handle-index" );
13404
13405                         switch ( event.keyCode ) {
13406                                 case $.ui.keyCode.HOME:
13407                                 case $.ui.keyCode.END:
13408                                 case $.ui.keyCode.PAGE_UP:
13409                                 case $.ui.keyCode.PAGE_DOWN:
13410                                 case $.ui.keyCode.UP:
13411                                 case $.ui.keyCode.RIGHT:
13412                                 case $.ui.keyCode.DOWN:
13413                                 case $.ui.keyCode.LEFT:
13414                                         event.preventDefault();
13415                                         if ( !this._keySliding ) {
13416                                                 this._keySliding = true;
13417                                                 $( event.target ).addClass( "ui-state-active" );
13418                                                 allowed = this._start( event, index );
13419                                                 if ( allowed === false ) {
13420                                                         return;
13421                                                 }
13422                                         }
13423                                         break;
13424                         }
13425
13426                         step = this.options.step;
13427                         if ( this.options.values && this.options.values.length ) {
13428                                 curVal = newVal = this.values( index );
13429                         } else {
13430                                 curVal = newVal = this.value();
13431                         }
13432
13433                         switch ( event.keyCode ) {
13434                                 case $.ui.keyCode.HOME:
13435                                         newVal = this._valueMin();
13436                                         break;
13437                                 case $.ui.keyCode.END:
13438                                         newVal = this._valueMax();
13439                                         break;
13440                                 case $.ui.keyCode.PAGE_UP:
13441                                         newVal = this._trimAlignValue(
13442                                                 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
13443                                         );
13444                                         break;
13445                                 case $.ui.keyCode.PAGE_DOWN:
13446                                         newVal = this._trimAlignValue(
13447                                                 curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
13448                                         break;
13449                                 case $.ui.keyCode.UP:
13450                                 case $.ui.keyCode.RIGHT:
13451                                         if ( curVal === this._valueMax() ) {
13452                                                 return;
13453                                         }
13454                                         newVal = this._trimAlignValue( curVal + step );
13455                                         break;
13456                                 case $.ui.keyCode.DOWN:
13457                                 case $.ui.keyCode.LEFT:
13458                                         if ( curVal === this._valueMin() ) {
13459                                                 return;
13460                                         }
13461                                         newVal = this._trimAlignValue( curVal - step );
13462                                         break;
13463                         }
13464
13465                         this._slide( event, index, newVal );
13466                 },
13467                 keyup: function( event ) {
13468                         var index = $( event.target ).data( "ui-slider-handle-index" );
13469
13470                         if ( this._keySliding ) {
13471                                 this._keySliding = false;
13472                                 this._stop( event, index );
13473                                 this._change( event, index );
13474                                 $( event.target ).removeClass( "ui-state-active" );
13475                         }
13476                 }
13477         }
13478 });
13479
13480
13481 /*!
13482  * jQuery UI Sortable 1.11.2
13483  * http://jqueryui.com
13484  *
13485  * Copyright 2014 jQuery Foundation and other contributors
13486  * Released under the MIT license.
13487  * http://jquery.org/license
13488  *
13489  * http://api.jqueryui.com/sortable/
13490  */
13491
13492
13493 var sortable = $.widget("ui.sortable", $.ui.mouse, {
13494         version: "1.11.2",
13495         widgetEventPrefix: "sort",
13496         ready: false,
13497         options: {
13498                 appendTo: "parent",
13499                 axis: false,
13500                 connectWith: false,
13501                 containment: false,
13502                 cursor: "auto",
13503                 cursorAt: false,
13504                 dropOnEmpty: true,
13505                 forcePlaceholderSize: false,
13506                 forceHelperSize: false,
13507                 grid: false,
13508                 handle: false,
13509                 helper: "original",
13510                 items: "> *",
13511                 opacity: false,
13512                 placeholder: false,
13513                 revert: false,
13514                 scroll: true,
13515                 scrollSensitivity: 20,
13516                 scrollSpeed: 20,
13517                 scope: "default",
13518                 tolerance: "intersect",
13519                 zIndex: 1000,
13520
13521                 // callbacks
13522                 activate: null,
13523                 beforeStop: null,
13524                 change: null,
13525                 deactivate: null,
13526                 out: null,
13527                 over: null,
13528                 receive: null,
13529                 remove: null,
13530                 sort: null,
13531                 start: null,
13532                 stop: null,
13533                 update: null
13534         },
13535
13536         _isOverAxis: function( x, reference, size ) {
13537                 return ( x >= reference ) && ( x < ( reference + size ) );
13538         },
13539
13540         _isFloating: function( item ) {
13541                 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
13542         },
13543
13544         _create: function() {
13545
13546                 var o = this.options;
13547                 this.containerCache = {};
13548                 this.element.addClass("ui-sortable");
13549
13550                 //Get the items
13551                 this.refresh();
13552
13553                 //Let's determine if the items are being displayed horizontally
13554                 this.floating = this.items.length ? o.axis === "x" || this._isFloating(this.items[0].item) : false;
13555
13556                 //Let's determine the parent's offset
13557                 this.offset = this.element.offset();
13558
13559                 //Initialize mouse events for interaction
13560                 this._mouseInit();
13561
13562                 this._setHandleClassName();
13563
13564                 //We're ready to go
13565                 this.ready = true;
13566
13567         },
13568
13569         _setOption: function( key, value ) {
13570                 this._super( key, value );
13571
13572                 if ( key === "handle" ) {
13573                         this._setHandleClassName();
13574                 }
13575         },
13576
13577         _setHandleClassName: function() {
13578                 this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
13579                 $.each( this.items, function() {
13580                         ( this.instance.options.handle ?
13581                                 this.item.find( this.instance.options.handle ) : this.item )
13582                                 .addClass( "ui-sortable-handle" );
13583                 });
13584         },
13585
13586         _destroy: function() {
13587                 this.element
13588                         .removeClass( "ui-sortable ui-sortable-disabled" )
13589                         .find( ".ui-sortable-handle" )
13590                                 .removeClass( "ui-sortable-handle" );
13591                 this._mouseDestroy();
13592
13593                 for ( var i = this.items.length - 1; i >= 0; i-- ) {
13594                         this.items[i].item.removeData(this.widgetName + "-item");
13595                 }
13596
13597                 return this;
13598         },
13599
13600         _mouseCapture: function(event, overrideHandle) {
13601                 var currentItem = null,
13602                         validHandle = false,
13603                         that = this;
13604
13605                 if (this.reverting) {
13606                         return false;
13607                 }
13608
13609                 if(this.options.disabled || this.options.type === "static") {
13610                         return false;
13611                 }
13612
13613                 //We have to refresh the items data once first
13614                 this._refreshItems(event);
13615
13616                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
13617                 $(event.target).parents().each(function() {
13618                         if($.data(this, that.widgetName + "-item") === that) {
13619                                 currentItem = $(this);
13620                                 return false;
13621                         }
13622                 });
13623                 if($.data(event.target, that.widgetName + "-item") === that) {
13624                         currentItem = $(event.target);
13625                 }
13626
13627                 if(!currentItem) {
13628                         return false;
13629                 }
13630                 if(this.options.handle && !overrideHandle) {
13631                         $(this.options.handle, currentItem).find("*").addBack().each(function() {
13632                                 if(this === event.target) {
13633                                         validHandle = true;
13634                                 }
13635                         });
13636                         if(!validHandle) {
13637                                 return false;
13638                         }
13639                 }
13640
13641                 this.currentItem = currentItem;
13642                 this._removeCurrentsFromItems();
13643                 return true;
13644
13645         },
13646
13647         _mouseStart: function(event, overrideHandle, noActivation) {
13648
13649                 var i, body,
13650                         o = this.options;
13651
13652                 this.currentContainer = this;
13653
13654                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
13655                 this.refreshPositions();
13656
13657                 //Create and append the visible helper
13658                 this.helper = this._createHelper(event);
13659
13660                 //Cache the helper size
13661                 this._cacheHelperProportions();
13662
13663                 /*
13664                  * - Position generation -
13665                  * This block generates everything position related - it's the core of draggables.
13666                  */
13667
13668                 //Cache the margins of the original element
13669                 this._cacheMargins();
13670
13671                 //Get the next scrolling parent
13672                 this.scrollParent = this.helper.scrollParent();
13673
13674                 //The element's absolute position on the page minus margins
13675                 this.offset = this.currentItem.offset();
13676                 this.offset = {
13677                         top: this.offset.top - this.margins.top,
13678                         left: this.offset.left - this.margins.left
13679                 };
13680
13681                 $.extend(this.offset, {
13682                         click: { //Where the click happened, relative to the element
13683                                 left: event.pageX - this.offset.left,
13684                                 top: event.pageY - this.offset.top
13685                         },
13686                         parent: this._getParentOffset(),
13687                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
13688                 });
13689
13690                 // Only after we got the offset, we can change the helper's position to absolute
13691                 // TODO: Still need to figure out a way to make relative sorting possible
13692                 this.helper.css("position", "absolute");
13693                 this.cssPosition = this.helper.css("position");
13694
13695                 //Generate the original position
13696                 this.originalPosition = this._generatePosition(event);
13697                 this.originalPageX = event.pageX;
13698                 this.originalPageY = event.pageY;
13699
13700                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
13701                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
13702
13703                 //Cache the former DOM position
13704                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
13705
13706                 //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
13707                 if(this.helper[0] !== this.currentItem[0]) {
13708                         this.currentItem.hide();
13709                 }
13710
13711                 //Create the placeholder
13712                 this._createPlaceholder();
13713
13714                 //Set a containment if given in the options
13715                 if(o.containment) {
13716                         this._setContainment();
13717                 }
13718
13719                 if( o.cursor && o.cursor !== "auto" ) { // cursor option
13720                         body = this.document.find( "body" );
13721
13722                         // support: IE
13723                         this.storedCursor = body.css( "cursor" );
13724                         body.css( "cursor", o.cursor );
13725
13726                         this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
13727                 }
13728
13729                 if(o.opacity) { // opacity option
13730                         if (this.helper.css("opacity")) {
13731                                 this._storedOpacity = this.helper.css("opacity");
13732                         }
13733                         this.helper.css("opacity", o.opacity);
13734                 }
13735
13736                 if(o.zIndex) { // zIndex option
13737                         if (this.helper.css("zIndex")) {
13738                                 this._storedZIndex = this.helper.css("zIndex");
13739                         }
13740                         this.helper.css("zIndex", o.zIndex);
13741                 }
13742
13743                 //Prepare scrolling
13744                 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
13745                         this.overflowOffset = this.scrollParent.offset();
13746                 }
13747
13748                 //Call callbacks
13749                 this._trigger("start", event, this._uiHash());
13750
13751                 //Recache the helper size
13752                 if(!this._preserveHelperProportions) {
13753                         this._cacheHelperProportions();
13754                 }
13755
13756
13757                 //Post "activate" events to possible containers
13758                 if( !noActivation ) {
13759                         for ( i = this.containers.length - 1; i >= 0; i-- ) {
13760                                 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
13761                         }
13762                 }
13763
13764                 //Prepare possible droppables
13765                 if($.ui.ddmanager) {
13766                         $.ui.ddmanager.current = this;
13767                 }
13768
13769                 if ($.ui.ddmanager && !o.dropBehaviour) {
13770                         $.ui.ddmanager.prepareOffsets(this, event);
13771                 }
13772
13773                 this.dragging = true;
13774
13775                 this.helper.addClass("ui-sortable-helper");
13776                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
13777                 return true;
13778
13779         },
13780
13781         _mouseDrag: function(event) {
13782                 var i, item, itemElement, intersection,
13783                         o = this.options,
13784                         scrolled = false;
13785
13786                 //Compute the helpers position
13787                 this.position = this._generatePosition(event);
13788                 this.positionAbs = this._convertPositionTo("absolute");
13789
13790                 if (!this.lastPositionAbs) {
13791                         this.lastPositionAbs = this.positionAbs;
13792                 }
13793
13794                 //Do scrolling
13795                 if(this.options.scroll) {
13796                         if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
13797
13798                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
13799                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
13800                                 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
13801                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
13802                                 }
13803
13804                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
13805                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
13806                                 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
13807                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
13808                                 }
13809
13810                         } else {
13811
13812                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
13813                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
13814                                 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
13815                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
13816                                 }
13817
13818                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
13819                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
13820                                 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
13821                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
13822                                 }
13823
13824                         }
13825
13826                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
13827                                 $.ui.ddmanager.prepareOffsets(this, event);
13828                         }
13829                 }
13830
13831                 //Regenerate the absolute position used for position checks
13832                 this.positionAbs = this._convertPositionTo("absolute");
13833
13834                 //Set the helper position
13835                 if(!this.options.axis || this.options.axis !== "y") {
13836                         this.helper[0].style.left = this.position.left+"px";
13837                 }
13838                 if(!this.options.axis || this.options.axis !== "x") {
13839                         this.helper[0].style.top = this.position.top+"px";
13840                 }
13841
13842                 //Rearrange
13843                 for (i = this.items.length - 1; i >= 0; i--) {
13844
13845                         //Cache variables and intersection, continue if no intersection
13846                         item = this.items[i];
13847                         itemElement = item.item[0];
13848                         intersection = this._intersectsWithPointer(item);
13849                         if (!intersection) {
13850                                 continue;
13851                         }
13852
13853                         // Only put the placeholder inside the current Container, skip all
13854                         // items from other containers. This works because when moving
13855                         // an item from one container to another the
13856                         // currentContainer is switched before the placeholder is moved.
13857                         //
13858                         // Without this, moving items in "sub-sortables" can cause
13859                         // the placeholder to jitter between the outer and inner container.
13860                         if (item.instance !== this.currentContainer) {
13861                                 continue;
13862                         }
13863
13864                         // cannot intersect with itself
13865                         // no useless actions that have been done before
13866                         // no action if the item moved is the parent of the item checked
13867                         if (itemElement !== this.currentItem[0] &&
13868                                 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
13869                                 !$.contains(this.placeholder[0], itemElement) &&
13870                                 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
13871                         ) {
13872
13873                                 this.direction = intersection === 1 ? "down" : "up";
13874
13875                                 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
13876                                         this._rearrange(event, item);
13877                                 } else {
13878                                         break;
13879                                 }
13880
13881                                 this._trigger("change", event, this._uiHash());
13882                                 break;
13883                         }
13884                 }
13885
13886                 //Post events to containers
13887                 this._contactContainers(event);
13888
13889                 //Interconnect with droppables
13890                 if($.ui.ddmanager) {
13891                         $.ui.ddmanager.drag(this, event);
13892                 }
13893
13894                 //Call callbacks
13895                 this._trigger("sort", event, this._uiHash());
13896
13897                 this.lastPositionAbs = this.positionAbs;
13898                 return false;
13899
13900         },
13901
13902         _mouseStop: function(event, noPropagation) {
13903
13904                 if(!event) {
13905                         return;
13906                 }
13907
13908                 //If we are using droppables, inform the manager about the drop
13909                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
13910                         $.ui.ddmanager.drop(this, event);
13911                 }
13912
13913                 if(this.options.revert) {
13914                         var that = this,
13915                                 cur = this.placeholder.offset(),
13916                                 axis = this.options.axis,
13917                                 animation = {};
13918
13919                         if ( !axis || axis === "x" ) {
13920                                 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
13921                         }
13922                         if ( !axis || axis === "y" ) {
13923                                 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
13924                         }
13925                         this.reverting = true;
13926                         $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
13927                                 that._clear(event);
13928                         });
13929                 } else {
13930                         this._clear(event, noPropagation);
13931                 }
13932
13933                 return false;
13934
13935         },
13936
13937         cancel: function() {
13938
13939                 if(this.dragging) {
13940
13941                         this._mouseUp({ target: null });
13942
13943                         if(this.options.helper === "original") {
13944                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
13945                         } else {
13946                                 this.currentItem.show();
13947                         }
13948
13949                         //Post deactivating events to containers
13950                         for (var i = this.containers.length - 1; i >= 0; i--){
13951                                 this.containers[i]._trigger("deactivate", null, this._uiHash(this));
13952                                 if(this.containers[i].containerCache.over) {
13953                                         this.containers[i]._trigger("out", null, this._uiHash(this));
13954                                         this.containers[i].containerCache.over = 0;
13955                                 }
13956                         }
13957
13958                 }
13959
13960                 if (this.placeholder) {
13961                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
13962                         if(this.placeholder[0].parentNode) {
13963                                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
13964                         }
13965                         if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
13966                                 this.helper.remove();
13967                         }
13968
13969                         $.extend(this, {
13970                                 helper: null,
13971                                 dragging: false,
13972                                 reverting: false,
13973                                 _noFinalSort: null
13974                         });
13975
13976                         if(this.domPosition.prev) {
13977                                 $(this.domPosition.prev).after(this.currentItem);
13978                         } else {
13979                                 $(this.domPosition.parent).prepend(this.currentItem);
13980                         }
13981                 }
13982
13983                 return this;
13984
13985         },
13986
13987         serialize: function(o) {
13988
13989                 var items = this._getItemsAsjQuery(o && o.connected),
13990                         str = [];
13991                 o = o || {};
13992
13993                 $(items).each(function() {
13994                         var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
13995                         if (res) {
13996                                 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
13997                         }
13998                 });
13999
14000                 if(!str.length && o.key) {
14001                         str.push(o.key + "=");
14002                 }
14003
14004                 return str.join("&");
14005
14006         },
14007
14008         toArray: function(o) {
14009
14010                 var items = this._getItemsAsjQuery(o && o.connected),
14011                         ret = [];
14012
14013                 o = o || {};
14014
14015                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
14016                 return ret;
14017
14018         },
14019
14020         /* Be careful with the following core functions */
14021         _intersectsWith: function(item) {
14022
14023                 var x1 = this.positionAbs.left,
14024                         x2 = x1 + this.helperProportions.width,
14025                         y1 = this.positionAbs.top,
14026                         y2 = y1 + this.helperProportions.height,
14027                         l = item.left,
14028                         r = l + item.width,
14029                         t = item.top,
14030                         b = t + item.height,
14031                         dyClick = this.offset.click.top,
14032                         dxClick = this.offset.click.left,
14033                         isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
14034                         isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
14035                         isOverElement = isOverElementHeight && isOverElementWidth;
14036
14037                 if ( this.options.tolerance === "pointer" ||
14038                         this.options.forcePointerForContainers ||
14039                         (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
14040                 ) {
14041                         return isOverElement;
14042                 } else {
14043
14044                         return (l < x1 + (this.helperProportions.width / 2) && // Right Half
14045                                 x2 - (this.helperProportions.width / 2) < r && // Left Half
14046                                 t < y1 + (this.helperProportions.height / 2) && // Bottom Half
14047                                 y2 - (this.helperProportions.height / 2) < b ); // Top Half
14048
14049                 }
14050         },
14051
14052         _intersectsWithPointer: function(item) {
14053
14054                 var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
14055                         isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
14056                         isOverElement = isOverElementHeight && isOverElementWidth,
14057                         verticalDirection = this._getDragVerticalDirection(),
14058                         horizontalDirection = this._getDragHorizontalDirection();
14059
14060                 if (!isOverElement) {
14061                         return false;
14062                 }
14063
14064                 return this.floating ?
14065                         ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
14066                         : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
14067
14068         },
14069
14070         _intersectsWithSides: function(item) {
14071
14072                 var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
14073                         isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
14074                         verticalDirection = this._getDragVerticalDirection(),
14075                         horizontalDirection = this._getDragHorizontalDirection();
14076
14077                 if (this.floating && horizontalDirection) {
14078                         return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
14079                 } else {
14080                         return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
14081                 }
14082
14083         },
14084
14085         _getDragVerticalDirection: function() {
14086                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
14087                 return delta !== 0 && (delta > 0 ? "down" : "up");
14088         },
14089
14090         _getDragHorizontalDirection: function() {
14091                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
14092                 return delta !== 0 && (delta > 0 ? "right" : "left");
14093         },
14094
14095         refresh: function(event) {
14096                 this._refreshItems(event);
14097                 this._setHandleClassName();
14098                 this.refreshPositions();
14099                 return this;
14100         },
14101
14102         _connectWith: function() {
14103                 var options = this.options;
14104                 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
14105         },
14106
14107         _getItemsAsjQuery: function(connected) {
14108
14109                 var i, j, cur, inst,
14110                         items = [],
14111                         queries = [],
14112                         connectWith = this._connectWith();
14113
14114                 if(connectWith && connected) {
14115                         for (i = connectWith.length - 1; i >= 0; i--){
14116                                 cur = $(connectWith[i]);
14117                                 for ( j = cur.length - 1; j >= 0; j--){
14118                                         inst = $.data(cur[j], this.widgetFullName);
14119                                         if(inst && inst !== this && !inst.options.disabled) {
14120                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
14121                                         }
14122                                 }
14123                         }
14124                 }
14125
14126                 queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
14127
14128                 function addItems() {
14129                         items.push( this );
14130                 }
14131                 for (i = queries.length - 1; i >= 0; i--){
14132                         queries[i][0].each( addItems );
14133                 }
14134
14135                 return $(items);
14136
14137         },
14138
14139         _removeCurrentsFromItems: function() {
14140
14141                 var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
14142
14143                 this.items = $.grep(this.items, function (item) {
14144                         for (var j=0; j < list.length; j++) {
14145                                 if(list[j] === item.item[0]) {
14146                                         return false;
14147                                 }
14148                         }
14149                         return true;
14150                 });
14151
14152         },
14153
14154         _refreshItems: function(event) {
14155
14156                 this.items = [];
14157                 this.containers = [this];
14158
14159                 var i, j, cur, inst, targetData, _queries, item, queriesLength,
14160                         items = this.items,
14161                         queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
14162                         connectWith = this._connectWith();
14163
14164                 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
14165                         for (i = connectWith.length - 1; i >= 0; i--){
14166                                 cur = $(connectWith[i]);
14167                                 for (j = cur.length - 1; j >= 0; j--){
14168                                         inst = $.data(cur[j], this.widgetFullName);
14169                                         if(inst && inst !== this && !inst.options.disabled) {
14170                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
14171                                                 this.containers.push(inst);
14172                                         }
14173                                 }
14174                         }
14175                 }
14176
14177                 for (i = queries.length - 1; i >= 0; i--) {
14178                         targetData = queries[i][1];
14179                         _queries = queries[i][0];
14180
14181                         for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
14182                                 item = $(_queries[j]);
14183
14184                                 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
14185
14186                                 items.push({
14187                                         item: item,
14188                                         instance: targetData,
14189                                         width: 0, height: 0,
14190                                         left: 0, top: 0
14191                                 });
14192                         }
14193                 }
14194
14195         },
14196
14197         refreshPositions: function(fast) {
14198
14199                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
14200                 if(this.offsetParent && this.helper) {
14201                         this.offset.parent = this._getParentOffset();
14202                 }
14203
14204                 var i, item, t, p;
14205
14206                 for (i = this.items.length - 1; i >= 0; i--){
14207                         item = this.items[i];
14208
14209                         //We ignore calculating positions of all connected containers when we're not over them
14210                         if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
14211                                 continue;
14212                         }
14213
14214                         t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
14215
14216                         if (!fast) {
14217                                 item.width = t.outerWidth();
14218                                 item.height = t.outerHeight();
14219                         }
14220
14221                         p = t.offset();
14222                         item.left = p.left;
14223                         item.top = p.top;
14224                 }
14225
14226                 if(this.options.custom && this.options.custom.refreshContainers) {
14227                         this.options.custom.refreshContainers.call(this);
14228                 } else {
14229                         for (i = this.containers.length - 1; i >= 0; i--){
14230                                 p = this.containers[i].element.offset();
14231                                 this.containers[i].containerCache.left = p.left;
14232                                 this.containers[i].containerCache.top = p.top;
14233                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
14234                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
14235                         }
14236                 }
14237
14238                 return this;
14239         },
14240
14241         _createPlaceholder: function(that) {
14242                 that = that || this;
14243                 var className,
14244                         o = that.options;
14245
14246                 if(!o.placeholder || o.placeholder.constructor === String) {
14247                         className = o.placeholder;
14248                         o.placeholder = {
14249                                 element: function() {
14250
14251                                         var nodeName = that.currentItem[0].nodeName.toLowerCase(),
14252                                                 element = $( "<" + nodeName + ">", that.document[0] )
14253                                                         .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
14254                                                         .removeClass("ui-sortable-helper");
14255
14256                                         if ( nodeName === "tr" ) {
14257                                                 that.currentItem.children().each(function() {
14258                                                         $( "<td>&#160;</td>", that.document[0] )
14259                                                                 .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
14260                                                                 .appendTo( element );
14261                                                 });
14262                                         } else if ( nodeName === "img" ) {
14263                                                 element.attr( "src", that.currentItem.attr( "src" ) );
14264                                         }
14265
14266                                         if ( !className ) {
14267                                                 element.css( "visibility", "hidden" );
14268                                         }
14269
14270                                         return element;
14271                                 },
14272                                 update: function(container, p) {
14273
14274                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
14275                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
14276                                         if(className && !o.forcePlaceholderSize) {
14277                                                 return;
14278                                         }
14279
14280                                         //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
14281                                         if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
14282                                         if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
14283                                 }
14284                         };
14285                 }
14286
14287                 //Create the placeholder
14288                 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
14289
14290                 //Append it after the actual current item
14291                 that.currentItem.after(that.placeholder);
14292
14293                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
14294                 o.placeholder.update(that, that.placeholder);
14295
14296         },
14297
14298         _contactContainers: function(event) {
14299                 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
14300                         innermostContainer = null,
14301                         innermostIndex = null;
14302
14303                 // get innermost container that intersects with item
14304                 for (i = this.containers.length - 1; i >= 0; i--) {
14305
14306                         // never consider a container that's located within the item itself
14307                         if($.contains(this.currentItem[0], this.containers[i].element[0])) {
14308                                 continue;
14309                         }
14310
14311                         if(this._intersectsWith(this.containers[i].containerCache)) {
14312
14313                                 // if we've already found a container and it's more "inner" than this, then continue
14314                                 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
14315                                         continue;
14316                                 }
14317
14318                                 innermostContainer = this.containers[i];
14319                                 innermostIndex = i;
14320
14321                         } else {
14322                                 // container doesn't intersect. trigger "out" event if necessary
14323                                 if(this.containers[i].containerCache.over) {
14324                                         this.containers[i]._trigger("out", event, this._uiHash(this));
14325                                         this.containers[i].containerCache.over = 0;
14326                                 }
14327                         }
14328
14329                 }
14330
14331                 // if no intersecting containers found, return
14332                 if(!innermostContainer) {
14333                         return;
14334                 }
14335
14336                 // move the item into the container if it's not there already
14337                 if(this.containers.length === 1) {
14338                         if (!this.containers[innermostIndex].containerCache.over) {
14339                                 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14340                                 this.containers[innermostIndex].containerCache.over = 1;
14341                         }
14342                 } else {
14343
14344                         //When entering a new container, we will find the item with the least distance and append our item near it
14345                         dist = 10000;
14346                         itemWithLeastDistance = null;
14347                         floating = innermostContainer.floating || this._isFloating(this.currentItem);
14348                         posProperty = floating ? "left" : "top";
14349                         sizeProperty = floating ? "width" : "height";
14350                         axis = floating ? "clientX" : "clientY";
14351
14352                         for (j = this.items.length - 1; j >= 0; j--) {
14353                                 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
14354                                         continue;
14355                                 }
14356                                 if(this.items[j].item[0] === this.currentItem[0]) {
14357                                         continue;
14358                                 }
14359
14360                                 cur = this.items[j].item.offset()[posProperty];
14361                                 nearBottom = false;
14362                                 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
14363                                         nearBottom = true;
14364                                 }
14365
14366                                 if ( Math.abs( event[ axis ] - cur ) < dist ) {
14367                                         dist = Math.abs( event[ axis ] - cur );
14368                                         itemWithLeastDistance = this.items[ j ];
14369                                         this.direction = nearBottom ? "up": "down";
14370                                 }
14371                         }
14372
14373                         //Check if dropOnEmpty is enabled
14374                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
14375                                 return;
14376                         }
14377
14378                         if(this.currentContainer === this.containers[innermostIndex]) {
14379                                 if ( !this.currentContainer.containerCache.over ) {
14380                                         this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
14381                                         this.currentContainer.containerCache.over = 1;
14382                                 }
14383                                 return;
14384                         }
14385
14386                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
14387                         this._trigger("change", event, this._uiHash());
14388                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
14389                         this.currentContainer = this.containers[innermostIndex];
14390
14391                         //Update the placeholder
14392                         this.options.placeholder.update(this.currentContainer, this.placeholder);
14393
14394                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14395                         this.containers[innermostIndex].containerCache.over = 1;
14396                 }
14397
14398
14399         },
14400
14401         _createHelper: function(event) {
14402
14403                 var o = this.options,
14404                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
14405
14406                 //Add the helper to the DOM if that didn't happen already
14407                 if(!helper.parents("body").length) {
14408                         $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
14409                 }
14410
14411                 if(helper[0] === this.currentItem[0]) {
14412                         this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
14413                 }
14414
14415                 if(!helper[0].style.width || o.forceHelperSize) {
14416                         helper.width(this.currentItem.width());
14417                 }
14418                 if(!helper[0].style.height || o.forceHelperSize) {
14419                         helper.height(this.currentItem.height());
14420                 }
14421
14422                 return helper;
14423
14424         },
14425
14426         _adjustOffsetFromHelper: function(obj) {
14427                 if (typeof obj === "string") {
14428                         obj = obj.split(" ");
14429                 }
14430                 if ($.isArray(obj)) {
14431                         obj = {left: +obj[0], top: +obj[1] || 0};
14432                 }
14433                 if ("left" in obj) {
14434                         this.offset.click.left = obj.left + this.margins.left;
14435                 }
14436                 if ("right" in obj) {
14437                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
14438                 }
14439                 if ("top" in obj) {
14440                         this.offset.click.top = obj.top + this.margins.top;
14441                 }
14442                 if ("bottom" in obj) {
14443                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
14444                 }
14445         },
14446
14447         _getParentOffset: function() {
14448
14449
14450                 //Get the offsetParent and cache its position
14451                 this.offsetParent = this.helper.offsetParent();
14452                 var po = this.offsetParent.offset();
14453
14454                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
14455                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
14456                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
14457                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
14458                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
14459                         po.left += this.scrollParent.scrollLeft();
14460                         po.top += this.scrollParent.scrollTop();
14461                 }
14462
14463                 // This needs to be actually done for all browsers, since pageX/pageY includes this information
14464                 // with an ugly IE fix
14465                 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
14466                         po = { top: 0, left: 0 };
14467                 }
14468
14469                 return {
14470                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
14471                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
14472                 };
14473
14474         },
14475
14476         _getRelativeOffset: function() {
14477
14478                 if(this.cssPosition === "relative") {
14479                         var p = this.currentItem.position();
14480                         return {
14481                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
14482                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
14483                         };
14484                 } else {
14485                         return { top: 0, left: 0 };
14486                 }
14487
14488         },
14489
14490         _cacheMargins: function() {
14491                 this.margins = {
14492                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
14493                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
14494                 };
14495         },
14496
14497         _cacheHelperProportions: function() {
14498                 this.helperProportions = {
14499                         width: this.helper.outerWidth(),
14500                         height: this.helper.outerHeight()
14501                 };
14502         },
14503
14504         _setContainment: function() {
14505
14506                 var ce, co, over,
14507                         o = this.options;
14508                 if(o.containment === "parent") {
14509                         o.containment = this.helper[0].parentNode;
14510                 }
14511                 if(o.containment === "document" || o.containment === "window") {
14512                         this.containment = [
14513                                 0 - this.offset.relative.left - this.offset.parent.left,
14514                                 0 - this.offset.relative.top - this.offset.parent.top,
14515                                 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
14516                                 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
14517                         ];
14518                 }
14519
14520                 if(!(/^(document|window|parent)$/).test(o.containment)) {
14521                         ce = $(o.containment)[0];
14522                         co = $(o.containment).offset();
14523                         over = ($(ce).css("overflow") !== "hidden");
14524
14525                         this.containment = [
14526                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
14527                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
14528                                 co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
14529                                 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
14530                         ];
14531                 }
14532
14533         },
14534
14535         _convertPositionTo: function(d, pos) {
14536
14537                 if(!pos) {
14538                         pos = this.position;
14539                 }
14540                 var mod = d === "absolute" ? 1 : -1,
14541                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
14542                         scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14543
14544                 return {
14545                         top: (
14546                                 pos.top +                                                                                                                               // The absolute mouse position
14547                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
14548                                 this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
14549                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
14550                         ),
14551                         left: (
14552                                 pos.left +                                                                                                                              // The absolute mouse position
14553                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
14554                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
14555                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
14556                         )
14557                 };
14558
14559         },
14560
14561         _generatePosition: function(event) {
14562
14563                 var top, left,
14564                         o = this.options,
14565                         pageX = event.pageX,
14566                         pageY = event.pageY,
14567                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14568
14569                 // This is another very weird special case that only happens for relative elements:
14570                 // 1. If the css position is relative
14571                 // 2. and the scroll parent is the document or similar to the offset parent
14572                 // we have to refresh the relative offset during the scroll so there are no jumps
14573                 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
14574                         this.offset.relative = this._getRelativeOffset();
14575                 }
14576
14577                 /*
14578                  * - Position constraining -
14579                  * Constrain the position to a mix of grid, containment.
14580                  */
14581
14582                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
14583
14584                         if(this.containment) {
14585                                 if(event.pageX - this.offset.click.left < this.containment[0]) {
14586                                         pageX = this.containment[0] + this.offset.click.left;
14587                                 }
14588                                 if(event.pageY - this.offset.click.top < this.containment[1]) {
14589                                         pageY = this.containment[1] + this.offset.click.top;
14590                                 }
14591                                 if(event.pageX - this.offset.click.left > this.containment[2]) {
14592                                         pageX = this.containment[2] + this.offset.click.left;
14593                                 }
14594                                 if(event.pageY - this.offset.click.top > this.containment[3]) {
14595                                         pageY = this.containment[3] + this.offset.click.top;
14596                                 }
14597                         }
14598
14599                         if(o.grid) {
14600                                 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
14601                                 pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
14602
14603                                 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
14604                                 pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
14605                         }
14606
14607                 }
14608
14609                 return {
14610                         top: (
14611                                 pageY -                                                                                                                         // The absolute mouse position
14612                                 this.offset.click.top -                                                                                                 // Click offset (relative to the element)
14613                                 this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
14614                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
14615                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
14616                         ),
14617                         left: (
14618                                 pageX -                                                                                                                         // The absolute mouse position
14619                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
14620                                 this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
14621                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
14622                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
14623                         )
14624                 };
14625
14626         },
14627
14628         _rearrange: function(event, i, a, hardRefresh) {
14629
14630                 a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
14631
14632                 //Various things done here to improve the performance:
14633                 // 1. we create a setTimeout, that calls refreshPositions
14634                 // 2. on the instance, we have a counter variable, that get's higher after every append
14635                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
14636                 // 4. this lets only the last addition to the timeout stack through
14637                 this.counter = this.counter ? ++this.counter : 1;
14638                 var counter = this.counter;
14639
14640                 this._delay(function() {
14641                         if(counter === this.counter) {
14642                                 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
14643                         }
14644                 });
14645
14646         },
14647
14648         _clear: function(event, noPropagation) {
14649
14650                 this.reverting = false;
14651                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
14652                 // everything else normalized again
14653                 var i,
14654                         delayedTriggers = [];
14655
14656                 // We first have to update the dom position of the actual currentItem
14657                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
14658                 if(!this._noFinalSort && this.currentItem.parent().length) {
14659                         this.placeholder.before(this.currentItem);
14660                 }
14661                 this._noFinalSort = null;
14662
14663                 if(this.helper[0] === this.currentItem[0]) {
14664                         for(i in this._storedCSS) {
14665                                 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
14666                                         this._storedCSS[i] = "";
14667                                 }
14668                         }
14669                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
14670                 } else {
14671                         this.currentItem.show();
14672                 }
14673
14674                 if(this.fromOutside && !noPropagation) {
14675                         delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
14676                 }
14677                 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
14678                         delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
14679                 }
14680
14681                 // Check if the items Container has Changed and trigger appropriate
14682                 // events.
14683                 if (this !== this.currentContainer) {
14684                         if(!noPropagation) {
14685                                 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
14686                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
14687                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
14688                         }
14689                 }
14690
14691
14692                 //Post events to containers
14693                 function delayEvent( type, instance, container ) {
14694                         return function( event ) {
14695                                 container._trigger( type, event, instance._uiHash( instance ) );
14696                         };
14697                 }
14698                 for (i = this.containers.length - 1; i >= 0; i--){
14699                         if (!noPropagation) {
14700                                 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
14701                         }
14702                         if(this.containers[i].containerCache.over) {
14703                                 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
14704                                 this.containers[i].containerCache.over = 0;
14705                         }
14706                 }
14707
14708                 //Do what was originally in plugins
14709                 if ( this.storedCursor ) {
14710                         this.document.find( "body" ).css( "cursor", this.storedCursor );
14711                         this.storedStylesheet.remove();
14712                 }
14713                 if(this._storedOpacity) {
14714                         this.helper.css("opacity", this._storedOpacity);
14715                 }
14716                 if(this._storedZIndex) {
14717                         this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
14718                 }
14719
14720                 this.dragging = false;
14721
14722                 if(!noPropagation) {
14723                         this._trigger("beforeStop", event, this._uiHash());
14724                 }
14725
14726                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
14727                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
14728
14729                 if ( !this.cancelHelperRemoval ) {
14730                         if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
14731                                 this.helper.remove();
14732                         }
14733                         this.helper = null;
14734                 }
14735
14736                 if(!noPropagation) {
14737                         for (i=0; i < delayedTriggers.length; i++) {
14738                                 delayedTriggers[i].call(this, event);
14739                         } //Trigger all delayed events
14740                         this._trigger("stop", event, this._uiHash());
14741                 }
14742
14743                 this.fromOutside = false;
14744                 return !this.cancelHelperRemoval;
14745
14746         },
14747
14748         _trigger: function() {
14749                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
14750                         this.cancel();
14751                 }
14752         },
14753
14754         _uiHash: function(_inst) {
14755                 var inst = _inst || this;
14756                 return {
14757                         helper: inst.helper,
14758                         placeholder: inst.placeholder || $([]),
14759                         position: inst.position,
14760                         originalPosition: inst.originalPosition,
14761                         offset: inst.positionAbs,
14762                         item: inst.currentItem,
14763                         sender: _inst ? _inst.element : null
14764                 };
14765         }
14766
14767 });
14768
14769
14770 /*!
14771  * jQuery UI Spinner 1.11.2
14772  * http://jqueryui.com
14773  *
14774  * Copyright 2014 jQuery Foundation and other contributors
14775  * Released under the MIT license.
14776  * http://jquery.org/license
14777  *
14778  * http://api.jqueryui.com/spinner/
14779  */
14780
14781
14782 function spinner_modifier( fn ) {
14783         return function() {
14784                 var previous = this.element.val();
14785                 fn.apply( this, arguments );
14786                 this._refresh();
14787                 if ( previous !== this.element.val() ) {
14788                         this._trigger( "change" );
14789                 }
14790         };
14791 }
14792
14793 var spinner = $.widget( "ui.spinner", {
14794         version: "1.11.2",
14795         defaultElement: "<input>",
14796         widgetEventPrefix: "spin",
14797         options: {
14798                 culture: null,
14799                 icons: {
14800                         down: "ui-icon-triangle-1-s",
14801                         up: "ui-icon-triangle-1-n"
14802                 },
14803                 incremental: true,
14804                 max: null,
14805                 min: null,
14806                 numberFormat: null,
14807                 page: 10,
14808                 step: 1,
14809
14810                 change: null,
14811                 spin: null,
14812                 start: null,
14813                 stop: null
14814         },
14815
14816         _create: function() {
14817                 // handle string values that need to be parsed
14818                 this._setOption( "max", this.options.max );
14819                 this._setOption( "min", this.options.min );
14820                 this._setOption( "step", this.options.step );
14821
14822                 // Only format if there is a value, prevents the field from being marked
14823                 // as invalid in Firefox, see #9573.
14824                 if ( this.value() !== "" ) {
14825                         // Format the value, but don't constrain.
14826                         this._value( this.element.val(), true );
14827                 }
14828
14829                 this._draw();
14830                 this._on( this._events );
14831                 this._refresh();
14832
14833                 // turning off autocomplete prevents the browser from remembering the
14834                 // value when navigating through history, so we re-enable autocomplete
14835                 // if the page is unloaded before the widget is destroyed. #7790
14836                 this._on( this.window, {
14837                         beforeunload: function() {
14838                                 this.element.removeAttr( "autocomplete" );
14839                         }
14840                 });
14841         },
14842
14843         _getCreateOptions: function() {
14844                 var options = {},
14845                         element = this.element;
14846
14847                 $.each( [ "min", "max", "step" ], function( i, option ) {
14848                         var value = element.attr( option );
14849                         if ( value !== undefined && value.length ) {
14850                                 options[ option ] = value;
14851                         }
14852                 });
14853
14854                 return options;
14855         },
14856
14857         _events: {
14858                 keydown: function( event ) {
14859                         if ( this._start( event ) && this._keydown( event ) ) {
14860                                 event.preventDefault();
14861                         }
14862                 },
14863                 keyup: "_stop",
14864                 focus: function() {
14865                         this.previous = this.element.val();
14866                 },
14867                 blur: function( event ) {
14868                         if ( this.cancelBlur ) {
14869                                 delete this.cancelBlur;
14870                                 return;
14871                         }
14872
14873                         this._stop();
14874                         this._refresh();
14875                         if ( this.previous !== this.element.val() ) {
14876                                 this._trigger( "change", event );
14877                         }
14878                 },
14879                 mousewheel: function( event, delta ) {
14880                         if ( !delta ) {
14881                                 return;
14882                         }
14883                         if ( !this.spinning && !this._start( event ) ) {
14884                                 return false;
14885                         }
14886
14887                         this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
14888                         clearTimeout( this.mousewheelTimer );
14889                         this.mousewheelTimer = this._delay(function() {
14890                                 if ( this.spinning ) {
14891                                         this._stop( event );
14892                                 }
14893                         }, 100 );
14894                         event.preventDefault();
14895                 },
14896                 "mousedown .ui-spinner-button": function( event ) {
14897                         var previous;
14898
14899                         // We never want the buttons to have focus; whenever the user is
14900                         // interacting with the spinner, the focus should be on the input.
14901                         // If the input is focused then this.previous is properly set from
14902                         // when the input first received focus. If the input is not focused
14903                         // then we need to set this.previous based on the value before spinning.
14904                         previous = this.element[0] === this.document[0].activeElement ?
14905                                 this.previous : this.element.val();
14906                         function checkFocus() {
14907                                 var isActive = this.element[0] === this.document[0].activeElement;
14908                                 if ( !isActive ) {
14909                                         this.element.focus();
14910                                         this.previous = previous;
14911                                         // support: IE
14912                                         // IE sets focus asynchronously, so we need to check if focus
14913                                         // moved off of the input because the user clicked on the button.
14914                                         this._delay(function() {
14915                                                 this.previous = previous;
14916                                         });
14917                                 }
14918                         }
14919
14920                         // ensure focus is on (or stays on) the text field
14921                         event.preventDefault();
14922                         checkFocus.call( this );
14923
14924                         // support: IE
14925                         // IE doesn't prevent moving focus even with event.preventDefault()
14926                         // so we set a flag to know when we should ignore the blur event
14927                         // and check (again) if focus moved off of the input.
14928                         this.cancelBlur = true;
14929                         this._delay(function() {
14930                                 delete this.cancelBlur;
14931                                 checkFocus.call( this );
14932                         });
14933
14934                         if ( this._start( event ) === false ) {
14935                                 return;
14936                         }
14937
14938                         this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14939                 },
14940                 "mouseup .ui-spinner-button": "_stop",
14941                 "mouseenter .ui-spinner-button": function( event ) {
14942                         // button will add ui-state-active if mouse was down while mouseleave and kept down
14943                         if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
14944                                 return;
14945                         }
14946
14947                         if ( this._start( event ) === false ) {
14948                                 return false;
14949                         }
14950                         this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14951                 },
14952                 // TODO: do we really want to consider this a stop?
14953                 // shouldn't we just stop the repeater and wait until mouseup before
14954                 // we trigger the stop event?
14955                 "mouseleave .ui-spinner-button": "_stop"
14956         },
14957
14958         _draw: function() {
14959                 var uiSpinner = this.uiSpinner = this.element
14960                         .addClass( "ui-spinner-input" )
14961                         .attr( "autocomplete", "off" )
14962                         .wrap( this._uiSpinnerHtml() )
14963                         .parent()
14964                                 // add buttons
14965                                 .append( this._buttonHtml() );
14966
14967                 this.element.attr( "role", "spinbutton" );
14968
14969                 // button bindings
14970                 this.buttons = uiSpinner.find( ".ui-spinner-button" )
14971                         .attr( "tabIndex", -1 )
14972                         .button()
14973                         .removeClass( "ui-corner-all" );
14974
14975                 // IE 6 doesn't understand height: 50% for the buttons
14976                 // unless the wrapper has an explicit height
14977                 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
14978                                 uiSpinner.height() > 0 ) {
14979                         uiSpinner.height( uiSpinner.height() );
14980                 }
14981
14982                 // disable spinner if element was already disabled
14983                 if ( this.options.disabled ) {
14984                         this.disable();
14985                 }
14986         },
14987
14988         _keydown: function( event ) {
14989                 var options = this.options,
14990                         keyCode = $.ui.keyCode;
14991
14992                 switch ( event.keyCode ) {
14993                 case keyCode.UP:
14994                         this._repeat( null, 1, event );
14995                         return true;
14996                 case keyCode.DOWN:
14997                         this._repeat( null, -1, event );
14998                         return true;
14999                 case keyCode.PAGE_UP:
15000                         this._repeat( null, options.page, event );
15001                         return true;
15002                 case keyCode.PAGE_DOWN:
15003                         this._repeat( null, -options.page, event );
15004                         return true;
15005                 }
15006
15007                 return false;
15008         },
15009
15010         _uiSpinnerHtml: function() {
15011                 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
15012         },
15013
15014         _buttonHtml: function() {
15015                 return "" +
15016                         "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
15017                                 "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
15018                         "</a>" +
15019                         "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
15020                                 "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
15021                         "</a>";
15022         },
15023
15024         _start: function( event ) {
15025                 if ( !this.spinning && this._trigger( "start", event ) === false ) {
15026                         return false;
15027                 }
15028
15029                 if ( !this.counter ) {
15030                         this.counter = 1;
15031                 }
15032                 this.spinning = true;
15033                 return true;
15034         },
15035
15036         _repeat: function( i, steps, event ) {
15037                 i = i || 500;
15038
15039                 clearTimeout( this.timer );
15040                 this.timer = this._delay(function() {
15041                         this._repeat( 40, steps, event );
15042                 }, i );
15043
15044                 this._spin( steps * this.options.step, event );
15045         },
15046
15047         _spin: function( step, event ) {
15048                 var value = this.value() || 0;
15049
15050                 if ( !this.counter ) {
15051                         this.counter = 1;
15052                 }
15053
15054                 value = this._adjustValue( value + step * this._increment( this.counter ) );
15055
15056                 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
15057                         this._value( value );
15058                         this.counter++;
15059                 }
15060         },
15061
15062         _increment: function( i ) {
15063                 var incremental = this.options.incremental;
15064
15065                 if ( incremental ) {
15066                         return $.isFunction( incremental ) ?
15067                                 incremental( i ) :
15068                                 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
15069                 }
15070
15071                 return 1;
15072         },
15073
15074         _precision: function() {
15075                 var precision = this._precisionOf( this.options.step );
15076                 if ( this.options.min !== null ) {
15077                         precision = Math.max( precision, this._precisionOf( this.options.min ) );
15078                 }
15079                 return precision;
15080         },
15081
15082         _precisionOf: function( num ) {
15083                 var str = num.toString(),
15084                         decimal = str.indexOf( "." );
15085                 return decimal === -1 ? 0 : str.length - decimal - 1;
15086         },
15087
15088         _adjustValue: function( value ) {
15089                 var base, aboveMin,
15090                         options = this.options;
15091
15092                 // make sure we're at a valid step
15093                 // - find out where we are relative to the base (min or 0)
15094                 base = options.min !== null ? options.min : 0;
15095                 aboveMin = value - base;
15096                 // - round to the nearest step
15097                 aboveMin = Math.round(aboveMin / options.step) * options.step;
15098                 // - rounding is based on 0, so adjust back to our base
15099                 value = base + aboveMin;
15100
15101                 // fix precision from bad JS floating point math
15102                 value = parseFloat( value.toFixed( this._precision() ) );
15103
15104                 // clamp the value
15105                 if ( options.max !== null && value > options.max) {
15106                         return options.max;
15107                 }
15108                 if ( options.min !== null && value < options.min ) {
15109                         return options.min;
15110                 }
15111
15112                 return value;
15113         },
15114
15115         _stop: function( event ) {
15116                 if ( !this.spinning ) {
15117                         return;
15118                 }
15119
15120                 clearTimeout( this.timer );
15121                 clearTimeout( this.mousewheelTimer );
15122                 this.counter = 0;
15123                 this.spinning = false;
15124                 this._trigger( "stop", event );
15125         },
15126
15127         _setOption: function( key, value ) {
15128                 if ( key === "culture" || key === "numberFormat" ) {
15129                         var prevValue = this._parse( this.element.val() );
15130                         this.options[ key ] = value;
15131                         this.element.val( this._format( prevValue ) );
15132                         return;
15133                 }
15134
15135                 if ( key === "max" || key === "min" || key === "step" ) {
15136                         if ( typeof value === "string" ) {
15137                                 value = this._parse( value );
15138                         }
15139                 }
15140                 if ( key === "icons" ) {
15141                         this.buttons.first().find( ".ui-icon" )
15142                                 .removeClass( this.options.icons.up )
15143                                 .addClass( value.up );
15144                         this.buttons.last().find( ".ui-icon" )
15145                                 .removeClass( this.options.icons.down )
15146                                 .addClass( value.down );
15147                 }
15148
15149                 this._super( key, value );
15150
15151                 if ( key === "disabled" ) {
15152                         this.widget().toggleClass( "ui-state-disabled", !!value );
15153                         this.element.prop( "disabled", !!value );
15154                         this.buttons.button( value ? "disable" : "enable" );
15155                 }
15156         },
15157
15158         _setOptions: spinner_modifier(function( options ) {
15159                 this._super( options );
15160         }),
15161
15162         _parse: function( val ) {
15163                 if ( typeof val === "string" && val !== "" ) {
15164                         val = window.Globalize && this.options.numberFormat ?
15165                                 Globalize.parseFloat( val, 10, this.options.culture ) : +val;
15166                 }
15167                 return val === "" || isNaN( val ) ? null : val;
15168         },
15169
15170         _format: function( value ) {
15171                 if ( value === "" ) {
15172                         return "";
15173                 }
15174                 return window.Globalize && this.options.numberFormat ?
15175                         Globalize.format( value, this.options.numberFormat, this.options.culture ) :
15176                         value;
15177         },
15178
15179         _refresh: function() {
15180                 this.element.attr({
15181                         "aria-valuemin": this.options.min,
15182                         "aria-valuemax": this.options.max,
15183                         // TODO: what should we do with values that can't be parsed?
15184                         "aria-valuenow": this._parse( this.element.val() )
15185                 });
15186         },
15187
15188         isValid: function() {
15189                 var value = this.value();
15190
15191                 // null is invalid
15192                 if ( value === null ) {
15193                         return false;
15194                 }
15195
15196                 // if value gets adjusted, it's invalid
15197                 return value === this._adjustValue( value );
15198         },
15199
15200         // update the value without triggering change
15201         _value: function( value, allowAny ) {
15202                 var parsed;
15203                 if ( value !== "" ) {
15204                         parsed = this._parse( value );
15205                         if ( parsed !== null ) {
15206                                 if ( !allowAny ) {
15207                                         parsed = this._adjustValue( parsed );
15208                                 }
15209                                 value = this._format( parsed );
15210                         }
15211                 }
15212                 this.element.val( value );
15213                 this._refresh();
15214         },
15215
15216         _destroy: function() {
15217                 this.element
15218                         .removeClass( "ui-spinner-input" )
15219                         .prop( "disabled", false )
15220                         .removeAttr( "autocomplete" )
15221                         .removeAttr( "role" )
15222                         .removeAttr( "aria-valuemin" )
15223                         .removeAttr( "aria-valuemax" )
15224                         .removeAttr( "aria-valuenow" );
15225                 this.uiSpinner.replaceWith( this.element );
15226         },
15227
15228         stepUp: spinner_modifier(function( steps ) {
15229                 this._stepUp( steps );
15230         }),
15231         _stepUp: function( steps ) {
15232                 if ( this._start() ) {
15233                         this._spin( (steps || 1) * this.options.step );
15234                         this._stop();
15235                 }
15236         },
15237
15238         stepDown: spinner_modifier(function( steps ) {
15239                 this._stepDown( steps );
15240         }),
15241         _stepDown: function( steps ) {
15242                 if ( this._start() ) {
15243                         this._spin( (steps || 1) * -this.options.step );
15244                         this._stop();
15245                 }
15246         },
15247
15248         pageUp: spinner_modifier(function( pages ) {
15249                 this._stepUp( (pages || 1) * this.options.page );
15250         }),
15251
15252         pageDown: spinner_modifier(function( pages ) {
15253                 this._stepDown( (pages || 1) * this.options.page );
15254         }),
15255
15256         value: function( newVal ) {
15257                 if ( !arguments.length ) {
15258                         return this._parse( this.element.val() );
15259                 }
15260                 spinner_modifier( this._value ).call( this, newVal );
15261         },
15262
15263         widget: function() {
15264                 return this.uiSpinner;
15265         }
15266 });
15267
15268
15269 /*!
15270  * jQuery UI Tabs 1.11.2
15271  * http://jqueryui.com
15272  *
15273  * Copyright 2014 jQuery Foundation and other contributors
15274  * Released under the MIT license.
15275  * http://jquery.org/license
15276  *
15277  * http://api.jqueryui.com/tabs/
15278  */
15279
15280
15281 var tabs = $.widget( "ui.tabs", {
15282         version: "1.11.2",
15283         delay: 300,
15284         options: {
15285                 active: null,
15286                 collapsible: false,
15287                 event: "click",
15288                 heightStyle: "content",
15289                 hide: null,
15290                 show: null,
15291
15292                 // callbacks
15293                 activate: null,
15294                 beforeActivate: null,
15295                 beforeLoad: null,
15296                 load: null
15297         },
15298
15299         _isLocal: (function() {
15300                 var rhash = /#.*$/;
15301
15302                 return function( anchor ) {
15303                         var anchorUrl, locationUrl;
15304
15305                         // support: IE7
15306                         // IE7 doesn't normalize the href property when set via script (#9317)
15307                         anchor = anchor.cloneNode( false );
15308
15309                         anchorUrl = anchor.href.replace( rhash, "" );
15310                         locationUrl = location.href.replace( rhash, "" );
15311
15312                         // decoding may throw an error if the URL isn't UTF-8 (#9518)
15313                         try {
15314                                 anchorUrl = decodeURIComponent( anchorUrl );
15315                         } catch ( error ) {}
15316                         try {
15317                                 locationUrl = decodeURIComponent( locationUrl );
15318                         } catch ( error ) {}
15319
15320                         return anchor.hash.length > 1 && anchorUrl === locationUrl;
15321                 };
15322         })(),
15323
15324         _create: function() {
15325                 var that = this,
15326                         options = this.options;
15327
15328                 this.running = false;
15329
15330                 this.element
15331                         .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
15332                         .toggleClass( "ui-tabs-collapsible", options.collapsible );
15333
15334                 this._processTabs();
15335                 options.active = this._initialActive();
15336
15337                 // Take disabling tabs via class attribute from HTML
15338                 // into account and update option properly.
15339                 if ( $.isArray( options.disabled ) ) {
15340                         options.disabled = $.unique( options.disabled.concat(
15341                                 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
15342                                         return that.tabs.index( li );
15343                                 })
15344                         ) ).sort();
15345                 }
15346
15347                 // check for length avoids error when initializing empty list
15348                 if ( this.options.active !== false && this.anchors.length ) {
15349                         this.active = this._findActive( options.active );
15350                 } else {
15351                         this.active = $();
15352                 }
15353
15354                 this._refresh();
15355
15356                 if ( this.active.length ) {
15357                         this.load( options.active );
15358                 }
15359         },
15360
15361         _initialActive: function() {
15362                 var active = this.options.active,
15363                         collapsible = this.options.collapsible,
15364                         locationHash = location.hash.substring( 1 );
15365
15366                 if ( active === null ) {
15367                         // check the fragment identifier in the URL
15368                         if ( locationHash ) {
15369                                 this.tabs.each(function( i, tab ) {
15370                                         if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
15371                                                 active = i;
15372                                                 return false;
15373                                         }
15374                                 });
15375                         }
15376
15377                         // check for a tab marked active via a class
15378                         if ( active === null ) {
15379                                 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
15380                         }
15381
15382                         // no active tab, set to false
15383                         if ( active === null || active === -1 ) {
15384                                 active = this.tabs.length ? 0 : false;
15385                         }
15386                 }
15387
15388                 // handle numbers: negative, out of range
15389                 if ( active !== false ) {
15390                         active = this.tabs.index( this.tabs.eq( active ) );
15391                         if ( active === -1 ) {
15392                                 active = collapsible ? false : 0;
15393                         }
15394                 }
15395
15396                 // don't allow collapsible: false and active: false
15397                 if ( !collapsible && active === false && this.anchors.length ) {
15398                         active = 0;
15399                 }
15400
15401                 return active;
15402         },
15403
15404         _getCreateEventData: function() {
15405                 return {
15406                         tab: this.active,
15407                         panel: !this.active.length ? $() : this._getPanelForTab( this.active )
15408                 };
15409         },
15410
15411         _tabKeydown: function( event ) {
15412                 var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
15413                         selectedIndex = this.tabs.index( focusedTab ),
15414                         goingForward = true;
15415
15416                 if ( this._handlePageNav( event ) ) {
15417                         return;
15418                 }
15419
15420                 switch ( event.keyCode ) {
15421                         case $.ui.keyCode.RIGHT:
15422                         case $.ui.keyCode.DOWN:
15423                                 selectedIndex++;
15424                                 break;
15425                         case $.ui.keyCode.UP:
15426                         case $.ui.keyCode.LEFT:
15427                                 goingForward = false;
15428                                 selectedIndex--;
15429                                 break;
15430                         case $.ui.keyCode.END:
15431                                 selectedIndex = this.anchors.length - 1;
15432                                 break;
15433                         case $.ui.keyCode.HOME:
15434                                 selectedIndex = 0;
15435                                 break;
15436                         case $.ui.keyCode.SPACE:
15437                                 // Activate only, no collapsing
15438                                 event.preventDefault();
15439                                 clearTimeout( this.activating );
15440                                 this._activate( selectedIndex );
15441                                 return;
15442                         case $.ui.keyCode.ENTER:
15443                                 // Toggle (cancel delayed activation, allow collapsing)
15444                                 event.preventDefault();
15445                                 clearTimeout( this.activating );
15446                                 // Determine if we should collapse or activate
15447                                 this._activate( selectedIndex === this.options.active ? false : selectedIndex );
15448                                 return;
15449                         default:
15450                                 return;
15451                 }
15452
15453                 // Focus the appropriate tab, based on which key was pressed
15454                 event.preventDefault();
15455                 clearTimeout( this.activating );
15456                 selectedIndex = this._focusNextTab( selectedIndex, goingForward );
15457
15458                 // Navigating with control key will prevent automatic activation
15459                 if ( !event.ctrlKey ) {
15460                         // Update aria-selected immediately so that AT think the tab is already selected.
15461                         // Otherwise AT may confuse the user by stating that they need to activate the tab,
15462                         // but the tab will already be activated by the time the announcement finishes.
15463                         focusedTab.attr( "aria-selected", "false" );
15464                         this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
15465
15466                         this.activating = this._delay(function() {
15467                                 this.option( "active", selectedIndex );
15468                         }, this.delay );
15469                 }
15470         },
15471
15472         _panelKeydown: function( event ) {
15473                 if ( this._handlePageNav( event ) ) {
15474                         return;
15475                 }
15476
15477                 // Ctrl+up moves focus to the current tab
15478                 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
15479                         event.preventDefault();
15480                         this.active.focus();
15481                 }
15482         },
15483
15484         // Alt+page up/down moves focus to the previous/next tab (and activates)
15485         _handlePageNav: function( event ) {
15486                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
15487                         this._activate( this._focusNextTab( this.options.active - 1, false ) );
15488                         return true;
15489                 }
15490                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
15491                         this._activate( this._focusNextTab( this.options.active + 1, true ) );
15492                         return true;
15493                 }
15494         },
15495
15496         _findNextTab: function( index, goingForward ) {
15497                 var lastTabIndex = this.tabs.length - 1;
15498
15499                 function constrain() {
15500                         if ( index > lastTabIndex ) {
15501                                 index = 0;
15502                         }
15503                         if ( index < 0 ) {
15504                                 index = lastTabIndex;
15505                         }
15506                         return index;
15507                 }
15508
15509                 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
15510                         index = goingForward ? index + 1 : index - 1;
15511                 }
15512
15513                 return index;
15514         },
15515
15516         _focusNextTab: function( index, goingForward ) {
15517                 index = this._findNextTab( index, goingForward );
15518                 this.tabs.eq( index ).focus();
15519                 return index;
15520         },
15521
15522         _setOption: function( key, value ) {
15523                 if ( key === "active" ) {
15524                         // _activate() will handle invalid values and update this.options
15525                         this._activate( value );
15526                         return;
15527                 }
15528
15529                 if ( key === "disabled" ) {
15530                         // don't use the widget factory's disabled handling
15531                         this._setupDisabled( value );
15532                         return;
15533                 }
15534
15535                 this._super( key, value);
15536
15537                 if ( key === "collapsible" ) {
15538                         this.element.toggleClass( "ui-tabs-collapsible", value );
15539                         // Setting collapsible: false while collapsed; open first panel
15540                         if ( !value && this.options.active === false ) {
15541                                 this._activate( 0 );
15542                         }
15543                 }
15544
15545                 if ( key === "event" ) {
15546                         this._setupEvents( value );
15547                 }
15548
15549                 if ( key === "heightStyle" ) {
15550                         this._setupHeightStyle( value );
15551                 }
15552         },
15553
15554         _sanitizeSelector: function( hash ) {
15555                 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
15556         },
15557
15558         refresh: function() {
15559                 var options = this.options,
15560                         lis = this.tablist.children( ":has(a[href])" );
15561
15562                 // get disabled tabs from class attribute from HTML
15563                 // this will get converted to a boolean if needed in _refresh()
15564                 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
15565                         return lis.index( tab );
15566                 });
15567
15568                 this._processTabs();
15569
15570                 // was collapsed or no tabs
15571                 if ( options.active === false || !this.anchors.length ) {
15572                         options.active = false;
15573                         this.active = $();
15574                 // was active, but active tab is gone
15575                 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
15576                         // all remaining tabs are disabled
15577                         if ( this.tabs.length === options.disabled.length ) {
15578                                 options.active = false;
15579                                 this.active = $();
15580                         // activate previous tab
15581                         } else {
15582                                 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
15583                         }
15584                 // was active, active tab still exists
15585                 } else {
15586                         // make sure active index is correct
15587                         options.active = this.tabs.index( this.active );
15588                 }
15589
15590                 this._refresh();
15591         },
15592
15593         _refresh: function() {
15594                 this._setupDisabled( this.options.disabled );
15595                 this._setupEvents( this.options.event );
15596                 this._setupHeightStyle( this.options.heightStyle );
15597
15598                 this.tabs.not( this.active ).attr({
15599                         "aria-selected": "false",
15600                         "aria-expanded": "false",
15601                         tabIndex: -1
15602                 });
15603                 this.panels.not( this._getPanelForTab( this.active ) )
15604                         .hide()
15605                         .attr({
15606                                 "aria-hidden": "true"
15607                         });
15608
15609                 // Make sure one tab is in the tab order
15610                 if ( !this.active.length ) {
15611                         this.tabs.eq( 0 ).attr( "tabIndex", 0 );
15612                 } else {
15613                         this.active
15614                                 .addClass( "ui-tabs-active ui-state-active" )
15615                                 .attr({
15616                                         "aria-selected": "true",
15617                                         "aria-expanded": "true",
15618                                         tabIndex: 0
15619                                 });
15620                         this._getPanelForTab( this.active )
15621                                 .show()
15622                                 .attr({
15623                                         "aria-hidden": "false"
15624                                 });
15625                 }
15626         },
15627
15628         _processTabs: function() {
15629                 var that = this,
15630                         prevTabs = this.tabs,
15631                         prevAnchors = this.anchors,
15632                         prevPanels = this.panels;
15633
15634                 this.tablist = this._getList()
15635                         .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15636                         .attr( "role", "tablist" )
15637
15638                         // Prevent users from focusing disabled tabs via click
15639                         .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
15640                                 if ( $( this ).is( ".ui-state-disabled" ) ) {
15641                                         event.preventDefault();
15642                                 }
15643                         })
15644
15645                         // support: IE <9
15646                         // Preventing the default action in mousedown doesn't prevent IE
15647                         // from focusing the element, so if the anchor gets focused, blur.
15648                         // We don't have to worry about focusing the previously focused
15649                         // element since clicking on a non-focusable element should focus
15650                         // the body anyway.
15651                         .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
15652                                 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
15653                                         this.blur();
15654                                 }
15655                         });
15656
15657                 this.tabs = this.tablist.find( "> li:has(a[href])" )
15658                         .addClass( "ui-state-default ui-corner-top" )
15659                         .attr({
15660                                 role: "tab",
15661                                 tabIndex: -1
15662                         });
15663
15664                 this.anchors = this.tabs.map(function() {
15665                                 return $( "a", this )[ 0 ];
15666                         })
15667                         .addClass( "ui-tabs-anchor" )
15668                         .attr({
15669                                 role: "presentation",
15670                                 tabIndex: -1
15671                         });
15672
15673                 this.panels = $();
15674
15675                 this.anchors.each(function( i, anchor ) {
15676                         var selector, panel, panelId,
15677                                 anchorId = $( anchor ).uniqueId().attr( "id" ),
15678                                 tab = $( anchor ).closest( "li" ),
15679                                 originalAriaControls = tab.attr( "aria-controls" );
15680
15681                         // inline tab
15682                         if ( that._isLocal( anchor ) ) {
15683                                 selector = anchor.hash;
15684                                 panelId = selector.substring( 1 );
15685                                 panel = that.element.find( that._sanitizeSelector( selector ) );
15686                         // remote tab
15687                         } else {
15688                                 // If the tab doesn't already have aria-controls,
15689                                 // generate an id by using a throw-away element
15690                                 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
15691                                 selector = "#" + panelId;
15692                                 panel = that.element.find( selector );
15693                                 if ( !panel.length ) {
15694                                         panel = that._createPanel( panelId );
15695                                         panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
15696                                 }
15697                                 panel.attr( "aria-live", "polite" );
15698                         }
15699
15700                         if ( panel.length) {
15701                                 that.panels = that.panels.add( panel );
15702                         }
15703                         if ( originalAriaControls ) {
15704                                 tab.data( "ui-tabs-aria-controls", originalAriaControls );
15705                         }
15706                         tab.attr({
15707                                 "aria-controls": panelId,
15708                                 "aria-labelledby": anchorId
15709                         });
15710                         panel.attr( "aria-labelledby", anchorId );
15711                 });
15712
15713                 this.panels
15714                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15715                         .attr( "role", "tabpanel" );
15716
15717                 // Avoid memory leaks (#10056)
15718                 if ( prevTabs ) {
15719                         this._off( prevTabs.not( this.tabs ) );
15720                         this._off( prevAnchors.not( this.anchors ) );
15721                         this._off( prevPanels.not( this.panels ) );
15722                 }
15723         },
15724
15725         // allow overriding how to find the list for rare usage scenarios (#7715)
15726         _getList: function() {
15727                 return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
15728         },
15729
15730         _createPanel: function( id ) {
15731                 return $( "<div>" )
15732                         .attr( "id", id )
15733                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15734                         .data( "ui-tabs-destroy", true );
15735         },
15736
15737         _setupDisabled: function( disabled ) {
15738                 if ( $.isArray( disabled ) ) {
15739                         if ( !disabled.length ) {
15740                                 disabled = false;
15741                         } else if ( disabled.length === this.anchors.length ) {
15742                                 disabled = true;
15743                         }
15744                 }
15745
15746                 // disable tabs
15747                 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
15748                         if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
15749                                 $( li )
15750                                         .addClass( "ui-state-disabled" )
15751                                         .attr( "aria-disabled", "true" );
15752                         } else {
15753                                 $( li )
15754                                         .removeClass( "ui-state-disabled" )
15755                                         .removeAttr( "aria-disabled" );
15756                         }
15757                 }
15758
15759                 this.options.disabled = disabled;
15760         },
15761
15762         _setupEvents: function( event ) {
15763                 var events = {};
15764                 if ( event ) {
15765                         $.each( event.split(" "), function( index, eventName ) {
15766                                 events[ eventName ] = "_eventHandler";
15767                         });
15768                 }
15769
15770                 this._off( this.anchors.add( this.tabs ).add( this.panels ) );
15771                 // Always prevent the default action, even when disabled
15772                 this._on( true, this.anchors, {
15773                         click: function( event ) {
15774                                 event.preventDefault();
15775                         }
15776                 });
15777                 this._on( this.anchors, events );
15778                 this._on( this.tabs, { keydown: "_tabKeydown" } );
15779                 this._on( this.panels, { keydown: "_panelKeydown" } );
15780
15781                 this._focusable( this.tabs );
15782                 this._hoverable( this.tabs );
15783         },
15784
15785         _setupHeightStyle: function( heightStyle ) {
15786                 var maxHeight,
15787                         parent = this.element.parent();
15788
15789                 if ( heightStyle === "fill" ) {
15790                         maxHeight = parent.height();
15791                         maxHeight -= this.element.outerHeight() - this.element.height();
15792
15793                         this.element.siblings( ":visible" ).each(function() {
15794                                 var elem = $( this ),
15795                                         position = elem.css( "position" );
15796
15797                                 if ( position === "absolute" || position === "fixed" ) {
15798                                         return;
15799                                 }
15800                                 maxHeight -= elem.outerHeight( true );
15801                         });
15802
15803                         this.element.children().not( this.panels ).each(function() {
15804                                 maxHeight -= $( this ).outerHeight( true );
15805                         });
15806
15807                         this.panels.each(function() {
15808                                 $( this ).height( Math.max( 0, maxHeight -
15809                                         $( this ).innerHeight() + $( this ).height() ) );
15810                         })
15811                         .css( "overflow", "auto" );
15812                 } else if ( heightStyle === "auto" ) {
15813                         maxHeight = 0;
15814                         this.panels.each(function() {
15815                                 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15816                         }).height( maxHeight );
15817                 }
15818         },
15819
15820         _eventHandler: function( event ) {
15821                 var options = this.options,
15822                         active = this.active,
15823                         anchor = $( event.currentTarget ),
15824                         tab = anchor.closest( "li" ),
15825                         clickedIsActive = tab[ 0 ] === active[ 0 ],
15826                         collapsing = clickedIsActive && options.collapsible,
15827                         toShow = collapsing ? $() : this._getPanelForTab( tab ),
15828                         toHide = !active.length ? $() : this._getPanelForTab( active ),
15829                         eventData = {
15830                                 oldTab: active,
15831                                 oldPanel: toHide,
15832                                 newTab: collapsing ? $() : tab,
15833                                 newPanel: toShow
15834                         };
15835
15836                 event.preventDefault();
15837
15838                 if ( tab.hasClass( "ui-state-disabled" ) ||
15839                                 // tab is already loading
15840                                 tab.hasClass( "ui-tabs-loading" ) ||
15841                                 // can't switch durning an animation
15842                                 this.running ||
15843                                 // click on active header, but not collapsible
15844                                 ( clickedIsActive && !options.collapsible ) ||
15845                                 // allow canceling activation
15846                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
15847                         return;
15848                 }
15849
15850                 options.active = collapsing ? false : this.tabs.index( tab );
15851
15852                 this.active = clickedIsActive ? $() : tab;
15853                 if ( this.xhr ) {
15854                         this.xhr.abort();
15855                 }
15856
15857                 if ( !toHide.length && !toShow.length ) {
15858                         $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
15859                 }
15860
15861                 if ( toShow.length ) {
15862                         this.load( this.tabs.index( tab ), event );
15863                 }
15864                 this._toggle( event, eventData );
15865         },
15866
15867         // handles show/hide for selecting tabs
15868         _toggle: function( event, eventData ) {
15869                 var that = this,
15870                         toShow = eventData.newPanel,
15871                         toHide = eventData.oldPanel;
15872
15873                 this.running = true;
15874
15875                 function complete() {
15876                         that.running = false;
15877                         that._trigger( "activate", event, eventData );
15878                 }
15879
15880                 function show() {
15881                         eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
15882
15883                         if ( toShow.length && that.options.show ) {
15884                                 that._show( toShow, that.options.show, complete );
15885                         } else {
15886                                 toShow.show();
15887                                 complete();
15888                         }
15889                 }
15890
15891                 // start out by hiding, then showing, then completing
15892                 if ( toHide.length && this.options.hide ) {
15893                         this._hide( toHide, this.options.hide, function() {
15894                                 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15895                                 show();
15896                         });
15897                 } else {
15898                         eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15899                         toHide.hide();
15900                         show();
15901                 }
15902
15903                 toHide.attr( "aria-hidden", "true" );
15904                 eventData.oldTab.attr({
15905                         "aria-selected": "false",
15906                         "aria-expanded": "false"
15907                 });
15908                 // If we're switching tabs, remove the old tab from the tab order.
15909                 // If we're opening from collapsed state, remove the previous tab from the tab order.
15910                 // If we're collapsing, then keep the collapsing tab in the tab order.
15911                 if ( toShow.length && toHide.length ) {
15912                         eventData.oldTab.attr( "tabIndex", -1 );
15913                 } else if ( toShow.length ) {
15914                         this.tabs.filter(function() {
15915                                 return $( this ).attr( "tabIndex" ) === 0;
15916                         })
15917                         .attr( "tabIndex", -1 );
15918                 }
15919
15920                 toShow.attr( "aria-hidden", "false" );
15921                 eventData.newTab.attr({
15922                         "aria-selected": "true",
15923                         "aria-expanded": "true",
15924                         tabIndex: 0
15925                 });
15926         },
15927
15928         _activate: function( index ) {
15929                 var anchor,
15930                         active = this._findActive( index );
15931
15932                 // trying to activate the already active panel
15933                 if ( active[ 0 ] === this.active[ 0 ] ) {
15934                         return;
15935                 }
15936
15937                 // trying to collapse, simulate a click on the current active header
15938                 if ( !active.length ) {
15939                         active = this.active;
15940                 }
15941
15942                 anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
15943                 this._eventHandler({
15944                         target: anchor,
15945                         currentTarget: anchor,
15946                         preventDefault: $.noop
15947                 });
15948         },
15949
15950         _findActive: function( index ) {
15951                 return index === false ? $() : this.tabs.eq( index );
15952         },
15953
15954         _getIndex: function( index ) {
15955                 // meta-function to give users option to provide a href string instead of a numerical index.
15956                 if ( typeof index === "string" ) {
15957                         index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
15958                 }
15959
15960                 return index;
15961         },
15962
15963         _destroy: function() {
15964                 if ( this.xhr ) {
15965                         this.xhr.abort();
15966                 }
15967
15968                 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
15969
15970                 this.tablist
15971                         .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15972                         .removeAttr( "role" );
15973
15974                 this.anchors
15975                         .removeClass( "ui-tabs-anchor" )
15976                         .removeAttr( "role" )
15977                         .removeAttr( "tabIndex" )
15978                         .removeUniqueId();
15979
15980                 this.tablist.unbind( this.eventNamespace );
15981
15982                 this.tabs.add( this.panels ).each(function() {
15983                         if ( $.data( this, "ui-tabs-destroy" ) ) {
15984                                 $( this ).remove();
15985                         } else {
15986                                 $( this )
15987                                         .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
15988                                                 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
15989                                         .removeAttr( "tabIndex" )
15990                                         .removeAttr( "aria-live" )
15991                                         .removeAttr( "aria-busy" )
15992                                         .removeAttr( "aria-selected" )
15993                                         .removeAttr( "aria-labelledby" )
15994                                         .removeAttr( "aria-hidden" )
15995                                         .removeAttr( "aria-expanded" )
15996                                         .removeAttr( "role" );
15997                         }
15998                 });
15999
16000                 this.tabs.each(function() {
16001                         var li = $( this ),
16002                                 prev = li.data( "ui-tabs-aria-controls" );
16003                         if ( prev ) {
16004                                 li
16005                                         .attr( "aria-controls", prev )
16006                                         .removeData( "ui-tabs-aria-controls" );
16007                         } else {
16008                                 li.removeAttr( "aria-controls" );
16009                         }
16010                 });
16011
16012                 this.panels.show();
16013
16014                 if ( this.options.heightStyle !== "content" ) {
16015                         this.panels.css( "height", "" );
16016                 }
16017         },
16018
16019         enable: function( index ) {
16020                 var disabled = this.options.disabled;
16021                 if ( disabled === false ) {
16022                         return;
16023                 }
16024
16025                 if ( index === undefined ) {
16026                         disabled = false;
16027                 } else {
16028                         index = this._getIndex( index );
16029                         if ( $.isArray( disabled ) ) {
16030                                 disabled = $.map( disabled, function( num ) {
16031                                         return num !== index ? num : null;
16032                                 });
16033                         } else {
16034                                 disabled = $.map( this.tabs, function( li, num ) {
16035                                         return num !== index ? num : null;
16036                                 });
16037                         }
16038                 }
16039                 this._setupDisabled( disabled );
16040         },
16041
16042         disable: function( index ) {
16043                 var disabled = this.options.disabled;
16044                 if ( disabled === true ) {
16045                         return;
16046                 }
16047
16048                 if ( index === undefined ) {
16049                         disabled = true;
16050                 } else {
16051                         index = this._getIndex( index );
16052                         if ( $.inArray( index, disabled ) !== -1 ) {
16053                                 return;
16054                         }
16055                         if ( $.isArray( disabled ) ) {
16056                                 disabled = $.merge( [ index ], disabled ).sort();
16057                         } else {
16058                                 disabled = [ index ];
16059                         }
16060                 }
16061                 this._setupDisabled( disabled );
16062         },
16063
16064         load: function( index, event ) {
16065                 index = this._getIndex( index );
16066                 var that = this,
16067                         tab = this.tabs.eq( index ),
16068                         anchor = tab.find( ".ui-tabs-anchor" ),
16069                         panel = this._getPanelForTab( tab ),
16070                         eventData = {
16071                                 tab: tab,
16072                                 panel: panel
16073                         };
16074
16075                 // not remote
16076                 if ( this._isLocal( anchor[ 0 ] ) ) {
16077                         return;
16078                 }
16079
16080                 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
16081
16082                 // support: jQuery <1.8
16083                 // jQuery <1.8 returns false if the request is canceled in beforeSend,
16084                 // but as of 1.8, $.ajax() always returns a jqXHR object.
16085                 if ( this.xhr && this.xhr.statusText !== "canceled" ) {
16086                         tab.addClass( "ui-tabs-loading" );
16087                         panel.attr( "aria-busy", "true" );
16088
16089                         this.xhr
16090                                 .success(function( response ) {
16091                                         // support: jQuery <1.8
16092                                         // http://bugs.jquery.com/ticket/11778
16093                                         setTimeout(function() {
16094                                                 panel.html( response );
16095                                                 that._trigger( "load", event, eventData );
16096                                         }, 1 );
16097                                 })
16098                                 .complete(function( jqXHR, status ) {
16099                                         // support: jQuery <1.8
16100                                         // http://bugs.jquery.com/ticket/11778
16101                                         setTimeout(function() {
16102                                                 if ( status === "abort" ) {
16103                                                         that.panels.stop( false, true );
16104                                                 }
16105
16106                                                 tab.removeClass( "ui-tabs-loading" );
16107                                                 panel.removeAttr( "aria-busy" );
16108
16109                                                 if ( jqXHR === that.xhr ) {
16110                                                         delete that.xhr;
16111                                                 }
16112                                         }, 1 );
16113                                 });
16114                 }
16115         },
16116
16117         _ajaxSettings: function( anchor, event, eventData ) {
16118                 var that = this;
16119                 return {
16120                         url: anchor.attr( "href" ),
16121                         beforeSend: function( jqXHR, settings ) {
16122                                 return that._trigger( "beforeLoad", event,
16123                                         $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
16124                         }
16125                 };
16126         },
16127
16128         _getPanelForTab: function( tab ) {
16129                 var id = $( tab ).attr( "aria-controls" );
16130                 return this.element.find( this._sanitizeSelector( "#" + id ) );
16131         }
16132 });
16133
16134
16135 /*!
16136  * jQuery UI Tooltip 1.11.2
16137  * http://jqueryui.com
16138  *
16139  * Copyright 2014 jQuery Foundation and other contributors
16140  * Released under the MIT license.
16141  * http://jquery.org/license
16142  *
16143  * http://api.jqueryui.com/tooltip/
16144  */
16145
16146
16147 var tooltip = $.widget( "ui.tooltip", {
16148         version: "1.11.2",
16149         options: {
16150                 content: function() {
16151                         // support: IE<9, Opera in jQuery <1.7
16152                         // .text() can't accept undefined, so coerce to a string
16153                         var title = $( this ).attr( "title" ) || "";
16154                         // Escape title, since we're going from an attribute to raw HTML
16155                         return $( "<a>" ).text( title ).html();
16156                 },
16157                 hide: true,
16158                 // Disabled elements have inconsistent behavior across browsers (#8661)
16159                 items: "[title]:not([disabled])",
16160                 position: {
16161                         my: "left top+15",
16162                         at: "left bottom",
16163                         collision: "flipfit flip"
16164                 },
16165                 show: true,
16166                 tooltipClass: null,
16167                 track: false,
16168
16169                 // callbacks
16170                 close: null,
16171                 open: null
16172         },
16173
16174         _addDescribedBy: function( elem, id ) {
16175                 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
16176                 describedby.push( id );
16177                 elem
16178                         .data( "ui-tooltip-id", id )
16179                         .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
16180         },
16181
16182         _removeDescribedBy: function( elem ) {
16183                 var id = elem.data( "ui-tooltip-id" ),
16184                         describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
16185                         index = $.inArray( id, describedby );
16186
16187                 if ( index !== -1 ) {
16188                         describedby.splice( index, 1 );
16189                 }
16190
16191                 elem.removeData( "ui-tooltip-id" );
16192                 describedby = $.trim( describedby.join( " " ) );
16193                 if ( describedby ) {
16194                         elem.attr( "aria-describedby", describedby );
16195                 } else {
16196                         elem.removeAttr( "aria-describedby" );
16197                 }
16198         },
16199
16200         _create: function() {
16201                 this._on({
16202                         mouseover: "open",
16203                         focusin: "open"
16204                 });
16205
16206                 // IDs of generated tooltips, needed for destroy
16207                 this.tooltips = {};
16208
16209                 // IDs of parent tooltips where we removed the title attribute
16210                 this.parents = {};
16211
16212                 if ( this.options.disabled ) {
16213                         this._disable();
16214                 }
16215
16216                 // Append the aria-live region so tooltips announce correctly
16217                 this.liveRegion = $( "<div>" )
16218                         .attr({
16219                                 role: "log",
16220                                 "aria-live": "assertive",
16221                                 "aria-relevant": "additions"
16222                         })
16223                         .addClass( "ui-helper-hidden-accessible" )
16224                         .appendTo( this.document[ 0 ].body );
16225         },
16226
16227         _setOption: function( key, value ) {
16228                 var that = this;
16229
16230                 if ( key === "disabled" ) {
16231                         this[ value ? "_disable" : "_enable" ]();
16232                         this.options[ key ] = value;
16233                         // disable element style changes
16234                         return;
16235                 }
16236
16237                 this._super( key, value );
16238
16239                 if ( key === "content" ) {
16240                         $.each( this.tooltips, function( id, tooltipData ) {
16241                                 that._updateContent( tooltipData.element );
16242                         });
16243                 }
16244         },
16245
16246         _disable: function() {
16247                 var that = this;
16248
16249                 // close open tooltips
16250                 $.each( this.tooltips, function( id, tooltipData ) {
16251                         var event = $.Event( "blur" );
16252                         event.target = event.currentTarget = tooltipData.element[ 0 ];
16253                         that.close( event, true );
16254                 });
16255
16256                 // remove title attributes to prevent native tooltips
16257                 this.element.find( this.options.items ).addBack().each(function() {
16258                         var element = $( this );
16259                         if ( element.is( "[title]" ) ) {
16260                                 element
16261                                         .data( "ui-tooltip-title", element.attr( "title" ) )
16262                                         .removeAttr( "title" );
16263                         }
16264                 });
16265         },
16266
16267         _enable: function() {
16268                 // restore title attributes
16269                 this.element.find( this.options.items ).addBack().each(function() {
16270                         var element = $( this );
16271                         if ( element.data( "ui-tooltip-title" ) ) {
16272                                 element.attr( "title", element.data( "ui-tooltip-title" ) );
16273                         }
16274                 });
16275         },
16276
16277         open: function( event ) {
16278                 var that = this,
16279                         target = $( event ? event.target : this.element )
16280                                 // we need closest here due to mouseover bubbling,
16281                                 // but always pointing at the same event target
16282                                 .closest( this.options.items );
16283
16284                 // No element to show a tooltip for or the tooltip is already open
16285                 if ( !target.length || target.data( "ui-tooltip-id" ) ) {
16286                         return;
16287                 }
16288
16289                 if ( target.attr( "title" ) ) {
16290                         target.data( "ui-tooltip-title", target.attr( "title" ) );
16291                 }
16292
16293                 target.data( "ui-tooltip-open", true );
16294
16295                 // kill parent tooltips, custom or native, for hover
16296                 if ( event && event.type === "mouseover" ) {
16297                         target.parents().each(function() {
16298                                 var parent = $( this ),
16299                                         blurEvent;
16300                                 if ( parent.data( "ui-tooltip-open" ) ) {
16301                                         blurEvent = $.Event( "blur" );
16302                                         blurEvent.target = blurEvent.currentTarget = this;
16303                                         that.close( blurEvent, true );
16304                                 }
16305                                 if ( parent.attr( "title" ) ) {
16306                                         parent.uniqueId();
16307                                         that.parents[ this.id ] = {
16308                                                 element: this,
16309                                                 title: parent.attr( "title" )
16310                                         };
16311                                         parent.attr( "title", "" );
16312                                 }
16313                         });
16314                 }
16315
16316                 this._updateContent( target, event );
16317         },
16318
16319         _updateContent: function( target, event ) {
16320                 var content,
16321                         contentOption = this.options.content,
16322                         that = this,
16323                         eventType = event ? event.type : null;
16324
16325                 if ( typeof contentOption === "string" ) {
16326                         return this._open( event, target, contentOption );
16327                 }
16328
16329                 content = contentOption.call( target[0], function( response ) {
16330                         // ignore async response if tooltip was closed already
16331                         if ( !target.data( "ui-tooltip-open" ) ) {
16332                                 return;
16333                         }
16334                         // IE may instantly serve a cached response for ajax requests
16335                         // delay this call to _open so the other call to _open runs first
16336                         that._delay(function() {
16337                                 // jQuery creates a special event for focusin when it doesn't
16338                                 // exist natively. To improve performance, the native event
16339                                 // object is reused and the type is changed. Therefore, we can't
16340                                 // rely on the type being correct after the event finished
16341                                 // bubbling, so we set it back to the previous value. (#8740)
16342                                 if ( event ) {
16343                                         event.type = eventType;
16344                                 }
16345                                 this._open( event, target, response );
16346                         });
16347                 });
16348                 if ( content ) {
16349                         this._open( event, target, content );
16350                 }
16351         },
16352
16353         _open: function( event, target, content ) {
16354                 var tooltipData, tooltip, events, delayedShow, a11yContent,
16355                         positionOption = $.extend( {}, this.options.position );
16356
16357                 if ( !content ) {
16358                         return;
16359                 }
16360
16361                 // Content can be updated multiple times. If the tooltip already
16362                 // exists, then just update the content and bail.
16363                 tooltipData = this._find( target );
16364                 if ( tooltipData ) {
16365                         tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
16366                         return;
16367                 }
16368
16369                 // if we have a title, clear it to prevent the native tooltip
16370                 // we have to check first to avoid defining a title if none exists
16371                 // (we don't want to cause an element to start matching [title])
16372                 //
16373                 // We use removeAttr only for key events, to allow IE to export the correct
16374                 // accessible attributes. For mouse events, set to empty string to avoid
16375                 // native tooltip showing up (happens only when removing inside mouseover).
16376                 if ( target.is( "[title]" ) ) {
16377                         if ( event && event.type === "mouseover" ) {
16378                                 target.attr( "title", "" );
16379                         } else {
16380                                 target.removeAttr( "title" );
16381                         }
16382                 }
16383
16384                 tooltipData = this._tooltip( target );
16385                 tooltip = tooltipData.tooltip;
16386                 this._addDescribedBy( target, tooltip.attr( "id" ) );
16387                 tooltip.find( ".ui-tooltip-content" ).html( content );
16388
16389                 // Support: Voiceover on OS X, JAWS on IE <= 9
16390                 // JAWS announces deletions even when aria-relevant="additions"
16391                 // Voiceover will sometimes re-read the entire log region's contents from the beginning
16392                 this.liveRegion.children().hide();
16393                 if ( content.clone ) {
16394                         a11yContent = content.clone();
16395                         a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
16396                 } else {
16397                         a11yContent = content;
16398                 }
16399                 $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
16400
16401                 function position( event ) {
16402                         positionOption.of = event;
16403                         if ( tooltip.is( ":hidden" ) ) {
16404                                 return;
16405                         }
16406                         tooltip.position( positionOption );
16407                 }
16408                 if ( this.options.track && event && /^mouse/.test( event.type ) ) {
16409                         this._on( this.document, {
16410                                 mousemove: position
16411                         });
16412                         // trigger once to override element-relative positioning
16413                         position( event );
16414                 } else {
16415                         tooltip.position( $.extend({
16416                                 of: target
16417                         }, this.options.position ) );
16418                 }
16419
16420                 tooltip.hide();
16421
16422                 this._show( tooltip, this.options.show );
16423                 // Handle tracking tooltips that are shown with a delay (#8644). As soon
16424                 // as the tooltip is visible, position the tooltip using the most recent
16425                 // event.
16426                 if ( this.options.show && this.options.show.delay ) {
16427                         delayedShow = this.delayedShow = setInterval(function() {
16428                                 if ( tooltip.is( ":visible" ) ) {
16429                                         position( positionOption.of );
16430                                         clearInterval( delayedShow );
16431                                 }
16432                         }, $.fx.interval );
16433                 }
16434
16435                 this._trigger( "open", event, { tooltip: tooltip } );
16436
16437                 events = {
16438                         keyup: function( event ) {
16439                                 if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
16440                                         var fakeEvent = $.Event(event);
16441                                         fakeEvent.currentTarget = target[0];
16442                                         this.close( fakeEvent, true );
16443                                 }
16444                         }
16445                 };
16446
16447                 // Only bind remove handler for delegated targets. Non-delegated
16448                 // tooltips will handle this in destroy.
16449                 if ( target[ 0 ] !== this.element[ 0 ] ) {
16450                         events.remove = function() {
16451                                 this._removeTooltip( tooltip );
16452                         };
16453                 }
16454
16455                 if ( !event || event.type === "mouseover" ) {
16456                         events.mouseleave = "close";
16457                 }
16458                 if ( !event || event.type === "focusin" ) {
16459                         events.focusout = "close";
16460                 }
16461                 this._on( true, target, events );
16462         },
16463
16464         close: function( event ) {
16465                 var tooltip,
16466                         that = this,
16467                         target = $( event ? event.currentTarget : this.element ),
16468                         tooltipData = this._find( target );
16469
16470                 // The tooltip may already be closed
16471                 if ( !tooltipData ) {
16472                         return;
16473                 }
16474
16475                 tooltip = tooltipData.tooltip;
16476
16477                 // disabling closes the tooltip, so we need to track when we're closing
16478                 // to avoid an infinite loop in case the tooltip becomes disabled on close
16479                 if ( tooltipData.closing ) {
16480                         return;
16481                 }
16482
16483                 // Clear the interval for delayed tracking tooltips
16484                 clearInterval( this.delayedShow );
16485
16486                 // only set title if we had one before (see comment in _open())
16487                 // If the title attribute has changed since open(), don't restore
16488                 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
16489                         target.attr( "title", target.data( "ui-tooltip-title" ) );
16490                 }
16491
16492                 this._removeDescribedBy( target );
16493
16494                 tooltipData.hiding = true;
16495                 tooltip.stop( true );
16496                 this._hide( tooltip, this.options.hide, function() {
16497                         that._removeTooltip( $( this ) );
16498                 });
16499
16500                 target.removeData( "ui-tooltip-open" );
16501                 this._off( target, "mouseleave focusout keyup" );
16502
16503                 // Remove 'remove' binding only on delegated targets
16504                 if ( target[ 0 ] !== this.element[ 0 ] ) {
16505                         this._off( target, "remove" );
16506                 }
16507                 this._off( this.document, "mousemove" );
16508
16509                 if ( event && event.type === "mouseleave" ) {
16510                         $.each( this.parents, function( id, parent ) {
16511                                 $( parent.element ).attr( "title", parent.title );
16512                                 delete that.parents[ id ];
16513                         });
16514                 }
16515
16516                 tooltipData.closing = true;
16517                 this._trigger( "close", event, { tooltip: tooltip } );
16518                 if ( !tooltipData.hiding ) {
16519                         tooltipData.closing = false;
16520                 }
16521         },
16522
16523         _tooltip: function( element ) {
16524                 var tooltip = $( "<div>" )
16525                                 .attr( "role", "tooltip" )
16526                                 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
16527                                         ( this.options.tooltipClass || "" ) ),
16528                         id = tooltip.uniqueId().attr( "id" );
16529
16530                 $( "<div>" )
16531                         .addClass( "ui-tooltip-content" )
16532                         .appendTo( tooltip );
16533
16534                 tooltip.appendTo( this.document[0].body );
16535
16536                 return this.tooltips[ id ] = {
16537                         element: element,
16538                         tooltip: tooltip
16539                 };
16540         },
16541
16542         _find: function( target ) {
16543                 var id = target.data( "ui-tooltip-id" );
16544                 return id ? this.tooltips[ id ] : null;
16545         },
16546
16547         _removeTooltip: function( tooltip ) {
16548                 tooltip.remove();
16549                 delete this.tooltips[ tooltip.attr( "id" ) ];
16550         },
16551
16552         _destroy: function() {
16553                 var that = this;
16554
16555                 // close open tooltips
16556                 $.each( this.tooltips, function( id, tooltipData ) {
16557                         // Delegate to close method to handle common cleanup
16558                         var event = $.Event( "blur" ),
16559                                 element = tooltipData.element;
16560                         event.target = event.currentTarget = element[ 0 ];
16561                         that.close( event, true );
16562
16563                         // Remove immediately; destroying an open tooltip doesn't use the
16564                         // hide animation
16565                         $( "#" + id ).remove();
16566
16567                         // Restore the title
16568                         if ( element.data( "ui-tooltip-title" ) ) {
16569                                 // If the title attribute has changed since open(), don't restore
16570                                 if ( !element.attr( "title" ) ) {
16571                                         element.attr( "title", element.data( "ui-tooltip-title" ) );
16572                                 }
16573                                 element.removeData( "ui-tooltip-title" );
16574                         }
16575                 });
16576                 this.liveRegion.remove();
16577         }
16578 });
16579
16580
16581
16582 }));