Statistics
| Branch: | Revision:

blinker / firefox.plugin / data / jquery-ui.js @ 4a410264

History | View | Annotate | Download (459.566 KB)

1
/*! jQuery UI - v1.11.4 - 2015-03-11
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 2015 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.4
19
 * http://jqueryui.com
20
 *
21
 * Copyright 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.4",
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.4
313
 * http://jqueryui.com
314
 *
315
 * Copyright 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
                if ( isMethodCall ) {
494
                        this.each(function() {
495
                                var methodValue,
496
                                        instance = $.data( this, fullName );
497
                                if ( options === "instance" ) {
498
                                        returnValue = instance;
499
                                        return false;
500
                                }
501
                                if ( !instance ) {
502
                                        return $.error( "cannot call methods on " + name + " prior to initialization; " +
503
                                                "attempted to call method '" + options + "'" );
504
                                }
505
                                if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
506
                                        return $.error( "no such method '" + options + "' for " + name + " widget instance" );
507
                                }
508
                                methodValue = instance[ options ].apply( instance, args );
509
                                if ( methodValue !== instance && methodValue !== undefined ) {
510
                                        returnValue = methodValue && methodValue.jquery ?
511
                                                returnValue.pushStack( methodValue.get() ) :
512
                                                methodValue;
513
                                        return false;
514
                                }
515
                        });
516
                } else {
517

    
518
                        // Allow multiple hashes to be passed on init
519
                        if ( args.length ) {
520
                                options = $.widget.extend.apply( null, [ options ].concat(args) );
521
                        }
522

    
523
                        this.each(function() {
524
                                var instance = $.data( this, fullName );
525
                                if ( instance ) {
526
                                        instance.option( options || {} );
527
                                        if ( instance._init ) {
528
                                                instance._init();
529
                                        }
530
                                } else {
531
                                        $.data( this, fullName, new object( options, this ) );
532
                                }
533
                        });
534
                }
535

    
536
                return returnValue;
537
        };
538
};
539

    
540
$.Widget = function( /* options, element */ ) {};
541
$.Widget._childConstructors = [];
542

    
543
$.Widget.prototype = {
544
        widgetName: "widget",
545
        widgetEventPrefix: "",
546
        defaultElement: "<div>",
547
        options: {
548
                disabled: false,
549

    
550
                // callbacks
551
                create: null
552
        },
553
        _createWidget: function( options, element ) {
554
                element = $( element || this.defaultElement || this )[ 0 ];
555
                this.element = $( element );
556
                this.uuid = widget_uuid++;
557
                this.eventNamespace = "." + this.widgetName + this.uuid;
558

    
559
                this.bindings = $();
560
                this.hoverable = $();
561
                this.focusable = $();
562

    
563
                if ( element !== this ) {
564
                        $.data( element, this.widgetFullName, this );
565
                        this._on( true, this.element, {
566
                                remove: function( event ) {
567
                                        if ( event.target === element ) {
568
                                                this.destroy();
569
                                        }
570
                                }
571
                        });
572
                        this.document = $( element.style ?
573
                                // element within the document
574
                                element.ownerDocument :
575
                                // element is window or document
576
                                element.document || element );
577
                        this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
578
                }
579

    
580
                this.options = $.widget.extend( {},
581
                        this.options,
582
                        this._getCreateOptions(),
583
                        options );
584

    
585
                this._create();
586
                this._trigger( "create", null, this._getCreateEventData() );
587
                this._init();
588
        },
589
        _getCreateOptions: $.noop,
590
        _getCreateEventData: $.noop,
591
        _create: $.noop,
592
        _init: $.noop,
593

    
594
        destroy: function() {
595
                this._destroy();
596
                // we can probably remove the unbind calls in 2.0
597
                // all event bindings should go through this._on()
598
                this.element
599
                        .unbind( this.eventNamespace )
600
                        .removeData( this.widgetFullName )
601
                        // support: jquery <1.6.3
602
                        // http://bugs.jquery.com/ticket/9413
603
                        .removeData( $.camelCase( this.widgetFullName ) );
604
                this.widget()
605
                        .unbind( this.eventNamespace )
606
                        .removeAttr( "aria-disabled" )
607
                        .removeClass(
608
                                this.widgetFullName + "-disabled " +
609
                                "ui-state-disabled" );
610

    
611
                // clean up events and states
612
                this.bindings.unbind( this.eventNamespace );
613
                this.hoverable.removeClass( "ui-state-hover" );
614
                this.focusable.removeClass( "ui-state-focus" );
615
        },
616
        _destroy: $.noop,
617

    
618
        widget: function() {
619
                return this.element;
620
        },
621

    
622
        option: function( key, value ) {
623
                var options = key,
624
                        parts,
625
                        curOption,
626
                        i;
627

    
628
                if ( arguments.length === 0 ) {
629
                        // don't return a reference to the internal hash
630
                        return $.widget.extend( {}, this.options );
631
                }
632

    
633
                if ( typeof key === "string" ) {
634
                        // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
635
                        options = {};
636
                        parts = key.split( "." );
637
                        key = parts.shift();
638
                        if ( parts.length ) {
639
                                curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
640
                                for ( i = 0; i < parts.length - 1; i++ ) {
641
                                        curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
642
                                        curOption = curOption[ parts[ i ] ];
643
                                }
644
                                key = parts.pop();
645
                                if ( arguments.length === 1 ) {
646
                                        return curOption[ key ] === undefined ? null : curOption[ key ];
647
                                }
648
                                curOption[ key ] = value;
649
                        } else {
650
                                if ( arguments.length === 1 ) {
651
                                        return this.options[ key ] === undefined ? null : this.options[ key ];
652
                                }
653
                                options[ key ] = value;
654
                        }
655
                }
656

    
657
                this._setOptions( options );
658

    
659
                return this;
660
        },
661
        _setOptions: function( options ) {
662
                var key;
663

    
664
                for ( key in options ) {
665
                        this._setOption( key, options[ key ] );
666
                }
667

    
668
                return this;
669
        },
670
        _setOption: function( key, value ) {
671
                this.options[ key ] = value;
672

    
673
                if ( key === "disabled" ) {
674
                        this.widget()
675
                                .toggleClass( this.widgetFullName + "-disabled", !!value );
676

    
677
                        // If the widget is becoming disabled, then nothing is interactive
678
                        if ( value ) {
679
                                this.hoverable.removeClass( "ui-state-hover" );
680
                                this.focusable.removeClass( "ui-state-focus" );
681
                        }
682
                }
683

    
684
                return this;
685
        },
686

    
687
        enable: function() {
688
                return this._setOptions({ disabled: false });
689
        },
690
        disable: function() {
691
                return this._setOptions({ disabled: true });
692
        },
693

    
694
        _on: function( suppressDisabledCheck, element, handlers ) {
695
                var delegateElement,
696
                        instance = this;
697

    
698
                // no suppressDisabledCheck flag, shuffle arguments
699
                if ( typeof suppressDisabledCheck !== "boolean" ) {
700
                        handlers = element;
701
                        element = suppressDisabledCheck;
702
                        suppressDisabledCheck = false;
703
                }
704

    
705
                // no element argument, shuffle and use this.element
706
                if ( !handlers ) {
707
                        handlers = element;
708
                        element = this.element;
709
                        delegateElement = this.widget();
710
                } else {
711
                        element = delegateElement = $( element );
712
                        this.bindings = this.bindings.add( element );
713
                }
714

    
715
                $.each( handlers, function( event, handler ) {
716
                        function handlerProxy() {
717
                                // allow widgets to customize the disabled handling
718
                                // - disabled as an array instead of boolean
719
                                // - disabled class as method for disabling individual parts
720
                                if ( !suppressDisabledCheck &&
721
                                                ( instance.options.disabled === true ||
722
                                                        $( this ).hasClass( "ui-state-disabled" ) ) ) {
723
                                        return;
724
                                }
725
                                return ( typeof handler === "string" ? instance[ handler ] : handler )
726
                                        .apply( instance, arguments );
727
                        }
728

    
729
                        // copy the guid so direct unbinding works
730
                        if ( typeof handler !== "string" ) {
731
                                handlerProxy.guid = handler.guid =
732
                                        handler.guid || handlerProxy.guid || $.guid++;
733
                        }
734

    
735
                        var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
736
                                eventName = match[1] + instance.eventNamespace,
737
                                selector = match[2];
738
                        if ( selector ) {
739
                                delegateElement.delegate( selector, eventName, handlerProxy );
740
                        } else {
741
                                element.bind( eventName, handlerProxy );
742
                        }
743
                });
744
        },
745

    
746
        _off: function( element, eventName ) {
747
                eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
748
                        this.eventNamespace;
749
                element.unbind( eventName ).undelegate( eventName );
750

    
751
                // Clear the stack to avoid memory leaks (#10056)
752
                this.bindings = $( this.bindings.not( element ).get() );
753
                this.focusable = $( this.focusable.not( element ).get() );
754
                this.hoverable = $( this.hoverable.not( element ).get() );
755
        },
756

    
757
        _delay: function( handler, delay ) {
758
                function handlerProxy() {
759
                        return ( typeof handler === "string" ? instance[ handler ] : handler )
760
                                .apply( instance, arguments );
761
                }
762
                var instance = this;
763
                return setTimeout( handlerProxy, delay || 0 );
764
        },
765

    
766
        _hoverable: function( element ) {
767
                this.hoverable = this.hoverable.add( element );
768
                this._on( element, {
769
                        mouseenter: function( event ) {
770
                                $( event.currentTarget ).addClass( "ui-state-hover" );
771
                        },
772
                        mouseleave: function( event ) {
773
                                $( event.currentTarget ).removeClass( "ui-state-hover" );
774
                        }
775
                });
776
        },
777

    
778
        _focusable: function( element ) {
779
                this.focusable = this.focusable.add( element );
780
                this._on( element, {
781
                        focusin: function( event ) {
782
                                $( event.currentTarget ).addClass( "ui-state-focus" );
783
                        },
784
                        focusout: function( event ) {
785
                                $( event.currentTarget ).removeClass( "ui-state-focus" );
786
                        }
787
                });
788
        },
789

    
790
        _trigger: function( type, event, data ) {
791
                var prop, orig,
792
                        callback = this.options[ type ];
793

    
794
                data = data || {};
795
                event = $.Event( event );
796
                event.type = ( type === this.widgetEventPrefix ?
797
                        type :
798
                        this.widgetEventPrefix + type ).toLowerCase();
799
                // the original event may come from any element
800
                // so we need to reset the target on the new event
801
                event.target = this.element[ 0 ];
802

    
803
                // copy original event properties over to the new event
804
                orig = event.originalEvent;
805
                if ( orig ) {
806
                        for ( prop in orig ) {
807
                                if ( !( prop in event ) ) {
808
                                        event[ prop ] = orig[ prop ];
809
                                }
810
                        }
811
                }
812

    
813
                this.element.trigger( event, data );
814
                return !( $.isFunction( callback ) &&
815
                        callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
816
                        event.isDefaultPrevented() );
817
        }
818
};
819

    
820
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
821
        $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
822
                if ( typeof options === "string" ) {
823
                        options = { effect: options };
824
                }
825
                var hasOptions,
826
                        effectName = !options ?
827
                                method :
828
                                options === true || typeof options === "number" ?
829
                                        defaultEffect :
830
                                        options.effect || defaultEffect;
831
                options = options || {};
832
                if ( typeof options === "number" ) {
833
                        options = { duration: options };
834
                }
835
                hasOptions = !$.isEmptyObject( options );
836
                options.complete = callback;
837
                if ( options.delay ) {
838
                        element.delay( options.delay );
839
                }
840
                if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
841
                        element[ method ]( options );
842
                } else if ( effectName !== method && element[ effectName ] ) {
843
                        element[ effectName ]( options.duration, options.easing, callback );
844
                } else {
845
                        element.queue(function( next ) {
846
                                $( this )[ method ]();
847
                                if ( callback ) {
848
                                        callback.call( element[ 0 ] );
849
                                }
850
                                next();
851
                        });
852
                }
853
        };
854
});
855

    
856
var widget = $.widget;
857

    
858

    
859
/*!
860
 * jQuery UI Mouse 1.11.4
861
 * http://jqueryui.com
862
 *
863
 * Copyright jQuery Foundation and other contributors
864
 * Released under the MIT license.
865
 * http://jquery.org/license
866
 *
867
 * http://api.jqueryui.com/mouse/
868
 */
869

    
870

    
871
var mouseHandled = false;
872
$( document ).mouseup( function() {
873
        mouseHandled = false;
874
});
875

    
876
var mouse = $.widget("ui.mouse", {
877
        version: "1.11.4",
878
        options: {
879
                cancel: "input,textarea,button,select,option",
880
                distance: 1,
881
                delay: 0
882
        },
883
        _mouseInit: function() {
884
                var that = this;
885

    
886
                this.element
887
                        .bind("mousedown." + this.widgetName, function(event) {
888
                                return that._mouseDown(event);
889
                        })
890
                        .bind("click." + this.widgetName, function(event) {
891
                                if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
892
                                        $.removeData(event.target, that.widgetName + ".preventClickEvent");
893
                                        event.stopImmediatePropagation();
894
                                        return false;
895
                                }
896
                        });
897

    
898
                this.started = false;
899
        },
900

    
901
        // TODO: make sure destroying one instance of mouse doesn't mess with
902
        // other instances of mouse
903
        _mouseDestroy: function() {
904
                this.element.unbind("." + this.widgetName);
905
                if ( this._mouseMoveDelegate ) {
906
                        this.document
907
                                .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
908
                                .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
909
                }
910
        },
911

    
912
        _mouseDown: function(event) {
913
                // don't let more than one widget handle mouseStart
914
                if ( mouseHandled ) {
915
                        return;
916
                }
917

    
918
                this._mouseMoved = false;
919

    
920
                // we may have missed mouseup (out of window)
921
                (this._mouseStarted && this._mouseUp(event));
922

    
923
                this._mouseDownEvent = event;
924

    
925
                var that = this,
926
                        btnIsLeft = (event.which === 1),
927
                        // event.target.nodeName works around a bug in IE 8 with
928
                        // disabled inputs (#7620)
929
                        elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
930
                if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
931
                        return true;
932
                }
933

    
934
                this.mouseDelayMet = !this.options.delay;
935
                if (!this.mouseDelayMet) {
936
                        this._mouseDelayTimer = setTimeout(function() {
937
                                that.mouseDelayMet = true;
938
                        }, this.options.delay);
939
                }
940

    
941
                if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
942
                        this._mouseStarted = (this._mouseStart(event) !== false);
943
                        if (!this._mouseStarted) {
944
                                event.preventDefault();
945
                                return true;
946
                        }
947
                }
948

    
949
                // Click event may never have fired (Gecko & Opera)
950
                if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
951
                        $.removeData(event.target, this.widgetName + ".preventClickEvent");
952
                }
953

    
954
                // these delegates are required to keep context
955
                this._mouseMoveDelegate = function(event) {
956
                        return that._mouseMove(event);
957
                };
958
                this._mouseUpDelegate = function(event) {
959
                        return that._mouseUp(event);
960
                };
961

    
962
                this.document
963
                        .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
964
                        .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
965

    
966
                event.preventDefault();
967

    
968
                mouseHandled = true;
969
                return true;
970
        },
971

    
972
        _mouseMove: function(event) {
973
                // Only check for mouseups outside the document if you've moved inside the document
974
                // at least once. This prevents the firing of mouseup in the case of IE<9, which will
975
                // fire a mousemove event if content is placed under the cursor. See #7778
976
                // Support: IE <9
977
                if ( this._mouseMoved ) {
978
                        // IE mouseup check - mouseup happened when mouse was out of window
979
                        if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
980
                                return this._mouseUp(event);
981

    
982
                        // Iframe mouseup check - mouseup occurred in another document
983
                        } else if ( !event.which ) {
984
                                return this._mouseUp( event );
985
                        }
986
                }
987

    
988
                if ( event.which || event.button ) {
989
                        this._mouseMoved = true;
990
                }
991

    
992
                if (this._mouseStarted) {
993
                        this._mouseDrag(event);
994
                        return event.preventDefault();
995
                }
996

    
997
                if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
998
                        this._mouseStarted =
999
                                (this._mouseStart(this._mouseDownEvent, event) !== false);
1000
                        (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
1001
                }
1002

    
1003
                return !this._mouseStarted;
1004
        },
1005

    
1006
        _mouseUp: function(event) {
1007
                this.document
1008
                        .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1009
                        .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
1010

    
1011
                if (this._mouseStarted) {
1012
                        this._mouseStarted = false;
1013

    
1014
                        if (event.target === this._mouseDownEvent.target) {
1015
                                $.data(event.target, this.widgetName + ".preventClickEvent", true);
1016
                        }
1017

    
1018
                        this._mouseStop(event);
1019
                }
1020

    
1021
                mouseHandled = false;
1022
                return false;
1023
        },
1024

    
1025
        _mouseDistanceMet: function(event) {
1026
                return (Math.max(
1027
                                Math.abs(this._mouseDownEvent.pageX - event.pageX),
1028
                                Math.abs(this._mouseDownEvent.pageY - event.pageY)
1029
                        ) >= this.options.distance
1030
                );
1031
        },
1032

    
1033
        _mouseDelayMet: function(/* event */) {
1034
                return this.mouseDelayMet;
1035
        },
1036

    
1037
        // These are placeholder methods, to be overriden by extending plugin
1038
        _mouseStart: function(/* event */) {},
1039
        _mouseDrag: function(/* event */) {},
1040
        _mouseStop: function(/* event */) {},
1041
        _mouseCapture: function(/* event */) { return true; }
1042
});
1043

    
1044

    
1045
/*!
1046
 * jQuery UI Position 1.11.4
1047
 * http://jqueryui.com
1048
 *
1049
 * Copyright jQuery Foundation and other contributors
1050
 * Released under the MIT license.
1051
 * http://jquery.org/license
1052
 *
1053
 * http://api.jqueryui.com/position/
1054
 */
1055

    
1056
(function() {
1057

    
1058
$.ui = $.ui || {};
1059

    
1060
var cachedScrollbarWidth, supportsOffsetFractions,
1061
        max = Math.max,
1062
        abs = Math.abs,
1063
        round = Math.round,
1064
        rhorizontal = /left|center|right/,
1065
        rvertical = /top|center|bottom/,
1066
        roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1067
        rposition = /^\w+/,
1068
        rpercent = /%$/,
1069
        _position = $.fn.position;
1070

    
1071
function getOffsets( offsets, width, height ) {
1072
        return [
1073
                parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1074
                parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1075
        ];
1076
}
1077

    
1078
function parseCss( element, property ) {
1079
        return parseInt( $.css( element, property ), 10 ) || 0;
1080
}
1081

    
1082
function getDimensions( elem ) {
1083
        var raw = elem[0];
1084
        if ( raw.nodeType === 9 ) {
1085
                return {
1086
                        width: elem.width(),
1087
                        height: elem.height(),
1088
                        offset: { top: 0, left: 0 }
1089
                };
1090
        }
1091
        if ( $.isWindow( raw ) ) {
1092
                return {
1093
                        width: elem.width(),
1094
                        height: elem.height(),
1095
                        offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1096
                };
1097
        }
1098
        if ( raw.preventDefault ) {
1099
                return {
1100
                        width: 0,
1101
                        height: 0,
1102
                        offset: { top: raw.pageY, left: raw.pageX }
1103
                };
1104
        }
1105
        return {
1106
                width: elem.outerWidth(),
1107
                height: elem.outerHeight(),
1108
                offset: elem.offset()
1109
        };
1110
}
1111

    
1112
$.position = {
1113
        scrollbarWidth: function() {
1114
                if ( cachedScrollbarWidth !== undefined ) {
1115
                        return cachedScrollbarWidth;
1116
                }
1117
                var w1, w2,
1118
                        div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1119
                        innerDiv = div.children()[0];
1120

    
1121
                $( "body" ).append( div );
1122
                w1 = innerDiv.offsetWidth;
1123
                div.css( "overflow", "scroll" );
1124

    
1125
                w2 = innerDiv.offsetWidth;
1126

    
1127
                if ( w1 === w2 ) {
1128
                        w2 = div[0].clientWidth;
1129
                }
1130

    
1131
                div.remove();
1132

    
1133
                return (cachedScrollbarWidth = w1 - w2);
1134
        },
1135
        getScrollInfo: function( within ) {
1136
                var overflowX = within.isWindow || within.isDocument ? "" :
1137
                                within.element.css( "overflow-x" ),
1138
                        overflowY = within.isWindow || within.isDocument ? "" :
1139
                                within.element.css( "overflow-y" ),
1140
                        hasOverflowX = overflowX === "scroll" ||
1141
                                ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1142
                        hasOverflowY = overflowY === "scroll" ||
1143
                                ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1144
                return {
1145
                        width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1146
                        height: hasOverflowX ? $.position.scrollbarWidth() : 0
1147
                };
1148
        },
1149
        getWithinInfo: function( element ) {
1150
                var withinElement = $( element || window ),
1151
                        isWindow = $.isWindow( withinElement[0] ),
1152
                        isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1153
                return {
1154
                        element: withinElement,
1155
                        isWindow: isWindow,
1156
                        isDocument: isDocument,
1157
                        offset: withinElement.offset() || { left: 0, top: 0 },
1158
                        scrollLeft: withinElement.scrollLeft(),
1159
                        scrollTop: withinElement.scrollTop(),
1160

    
1161
                        // support: jQuery 1.6.x
1162
                        // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
1163
                        width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
1164
                        height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
1165
                };
1166
        }
1167
};
1168

    
1169
$.fn.position = function( options ) {
1170
        if ( !options || !options.of ) {
1171
                return _position.apply( this, arguments );
1172
        }
1173

    
1174
        // make a copy, we don't want to modify arguments
1175
        options = $.extend( {}, options );
1176

    
1177
        var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1178
                target = $( options.of ),
1179
                within = $.position.getWithinInfo( options.within ),
1180
                scrollInfo = $.position.getScrollInfo( within ),
1181
                collision = ( options.collision || "flip" ).split( " " ),
1182
                offsets = {};
1183

    
1184
        dimensions = getDimensions( target );
1185
        if ( target[0].preventDefault ) {
1186
                // force left top to allow flipping
1187
                options.at = "left top";
1188
        }
1189
        targetWidth = dimensions.width;
1190
        targetHeight = dimensions.height;
1191
        targetOffset = dimensions.offset;
1192
        // clone to reuse original targetOffset later
1193
        basePosition = $.extend( {}, targetOffset );
1194

    
1195
        // force my and at to have valid horizontal and vertical positions
1196
        // if a value is missing or invalid, it will be converted to center
1197
        $.each( [ "my", "at" ], function() {
1198
                var pos = ( options[ this ] || "" ).split( " " ),
1199
                        horizontalOffset,
1200
                        verticalOffset;
1201

    
1202
                if ( pos.length === 1) {
1203
                        pos = rhorizontal.test( pos[ 0 ] ) ?
1204
                                pos.concat( [ "center" ] ) :
1205
                                rvertical.test( pos[ 0 ] ) ?
1206
                                        [ "center" ].concat( pos ) :
1207
                                        [ "center", "center" ];
1208
                }
1209
                pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1210
                pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1211

    
1212
                // calculate offsets
1213
                horizontalOffset = roffset.exec( pos[ 0 ] );
1214
                verticalOffset = roffset.exec( pos[ 1 ] );
1215
                offsets[ this ] = [
1216
                        horizontalOffset ? horizontalOffset[ 0 ] : 0,
1217
                        verticalOffset ? verticalOffset[ 0 ] : 0
1218
                ];
1219

    
1220
                // reduce to just the positions without the offsets
1221
                options[ this ] = [
1222
                        rposition.exec( pos[ 0 ] )[ 0 ],
1223
                        rposition.exec( pos[ 1 ] )[ 0 ]
1224
                ];
1225
        });
1226

    
1227
        // normalize collision option
1228
        if ( collision.length === 1 ) {
1229
                collision[ 1 ] = collision[ 0 ];
1230
        }
1231

    
1232
        if ( options.at[ 0 ] === "right" ) {
1233
                basePosition.left += targetWidth;
1234
        } else if ( options.at[ 0 ] === "center" ) {
1235
                basePosition.left += targetWidth / 2;
1236
        }
1237

    
1238
        if ( options.at[ 1 ] === "bottom" ) {
1239
                basePosition.top += targetHeight;
1240
        } else if ( options.at[ 1 ] === "center" ) {
1241
                basePosition.top += targetHeight / 2;
1242
        }
1243

    
1244
        atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1245
        basePosition.left += atOffset[ 0 ];
1246
        basePosition.top += atOffset[ 1 ];
1247

    
1248
        return this.each(function() {
1249
                var collisionPosition, using,
1250
                        elem = $( this ),
1251
                        elemWidth = elem.outerWidth(),
1252
                        elemHeight = elem.outerHeight(),
1253
                        marginLeft = parseCss( this, "marginLeft" ),
1254
                        marginTop = parseCss( this, "marginTop" ),
1255
                        collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1256
                        collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1257
                        position = $.extend( {}, basePosition ),
1258
                        myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1259

    
1260
                if ( options.my[ 0 ] === "right" ) {
1261
                        position.left -= elemWidth;
1262
                } else if ( options.my[ 0 ] === "center" ) {
1263
                        position.left -= elemWidth / 2;
1264
                }
1265

    
1266
                if ( options.my[ 1 ] === "bottom" ) {
1267
                        position.top -= elemHeight;
1268
                } else if ( options.my[ 1 ] === "center" ) {
1269
                        position.top -= elemHeight / 2;
1270
                }
1271

    
1272
                position.left += myOffset[ 0 ];
1273
                position.top += myOffset[ 1 ];
1274

    
1275
                // if the browser doesn't support fractions, then round for consistent results
1276
                if ( !supportsOffsetFractions ) {
1277
                        position.left = round( position.left );
1278
                        position.top = round( position.top );
1279
                }
1280

    
1281
                collisionPosition = {
1282
                        marginLeft: marginLeft,
1283
                        marginTop: marginTop
1284
                };
1285

    
1286
                $.each( [ "left", "top" ], function( i, dir ) {
1287
                        if ( $.ui.position[ collision[ i ] ] ) {
1288
                                $.ui.position[ collision[ i ] ][ dir ]( position, {
1289
                                        targetWidth: targetWidth,
1290
                                        targetHeight: targetHeight,
1291
                                        elemWidth: elemWidth,
1292
                                        elemHeight: elemHeight,
1293
                                        collisionPosition: collisionPosition,
1294
                                        collisionWidth: collisionWidth,
1295
                                        collisionHeight: collisionHeight,
1296
                                        offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1297
                                        my: options.my,
1298
                                        at: options.at,
1299
                                        within: within,
1300
                                        elem: elem
1301
                                });
1302
                        }
1303
                });
1304

    
1305
                if ( options.using ) {
1306
                        // adds feedback as second argument to using callback, if present
1307
                        using = function( props ) {
1308
                                var left = targetOffset.left - position.left,
1309
                                        right = left + targetWidth - elemWidth,
1310
                                        top = targetOffset.top - position.top,
1311
                                        bottom = top + targetHeight - elemHeight,
1312
                                        feedback = {
1313
                                                target: {
1314
                                                        element: target,
1315
                                                        left: targetOffset.left,
1316
                                                        top: targetOffset.top,
1317
                                                        width: targetWidth,
1318
                                                        height: targetHeight
1319
                                                },
1320
                                                element: {
1321
                                                        element: elem,
1322
                                                        left: position.left,
1323
                                                        top: position.top,
1324
                                                        width: elemWidth,
1325
                                                        height: elemHeight
1326
                                                },
1327
                                                horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1328
                                                vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1329
                                        };
1330
                                if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1331
                                        feedback.horizontal = "center";
1332
                                }
1333
                                if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1334
                                        feedback.vertical = "middle";
1335
                                }
1336
                                if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1337
                                        feedback.important = "horizontal";
1338
                                } else {
1339
                                        feedback.important = "vertical";
1340
                                }
1341
                                options.using.call( this, props, feedback );
1342
                        };
1343
                }
1344

    
1345
                elem.offset( $.extend( position, { using: using } ) );
1346
        });
1347
};
1348

    
1349
$.ui.position = {
1350
        fit: {
1351
                left: function( position, data ) {
1352
                        var within = data.within,
1353
                                withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1354
                                outerWidth = within.width,
1355
                                collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1356
                                overLeft = withinOffset - collisionPosLeft,
1357
                                overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1358
                                newOverRight;
1359

    
1360
                        // element is wider than within
1361
                        if ( data.collisionWidth > outerWidth ) {
1362
                                // element is initially over the left side of within
1363
                                if ( overLeft > 0 && overRight <= 0 ) {
1364
                                        newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1365
                                        position.left += overLeft - newOverRight;
1366
                                // element is initially over right side of within
1367
                                } else if ( overRight > 0 && overLeft <= 0 ) {
1368
                                        position.left = withinOffset;
1369
                                // element is initially over both left and right sides of within
1370
                                } else {
1371
                                        if ( overLeft > overRight ) {
1372
                                                position.left = withinOffset + outerWidth - data.collisionWidth;
1373
                                        } else {
1374
                                                position.left = withinOffset;
1375
                                        }
1376
                                }
1377
                        // too far left -> align with left edge
1378
                        } else if ( overLeft > 0 ) {
1379
                                position.left += overLeft;
1380
                        // too far right -> align with right edge
1381
                        } else if ( overRight > 0 ) {
1382
                                position.left -= overRight;
1383
                        // adjust based on position and margin
1384
                        } else {
1385
                                position.left = max( position.left - collisionPosLeft, position.left );
1386
                        }
1387
                },
1388
                top: function( position, data ) {
1389
                        var within = data.within,
1390
                                withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1391
                                outerHeight = data.within.height,
1392
                                collisionPosTop = position.top - data.collisionPosition.marginTop,
1393
                                overTop = withinOffset - collisionPosTop,
1394
                                overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1395
                                newOverBottom;
1396

    
1397
                        // element is taller than within
1398
                        if ( data.collisionHeight > outerHeight ) {
1399
                                // element is initially over the top of within
1400
                                if ( overTop > 0 && overBottom <= 0 ) {
1401
                                        newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1402
                                        position.top += overTop - newOverBottom;
1403
                                // element is initially over bottom of within
1404
                                } else if ( overBottom > 0 && overTop <= 0 ) {
1405
                                        position.top = withinOffset;
1406
                                // element is initially over both top and bottom of within
1407
                                } else {
1408
                                        if ( overTop > overBottom ) {
1409
                                                position.top = withinOffset + outerHeight - data.collisionHeight;
1410
                                        } else {
1411
                                                position.top = withinOffset;
1412
                                        }
1413
                                }
1414
                        // too far up -> align with top
1415
                        } else if ( overTop > 0 ) {
1416
                                position.top += overTop;
1417
                        // too far down -> align with bottom edge
1418
                        } else if ( overBottom > 0 ) {
1419
                                position.top -= overBottom;
1420
                        // adjust based on position and margin
1421
                        } else {
1422
                                position.top = max( position.top - collisionPosTop, position.top );
1423
                        }
1424
                }
1425
        },
1426
        flip: {
1427
                left: function( position, data ) {
1428
                        var within = data.within,
1429
                                withinOffset = within.offset.left + within.scrollLeft,
1430
                                outerWidth = within.width,
1431
                                offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1432
                                collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1433
                                overLeft = collisionPosLeft - offsetLeft,
1434
                                overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1435
                                myOffset = data.my[ 0 ] === "left" ?
1436
                                        -data.elemWidth :
1437
                                        data.my[ 0 ] === "right" ?
1438
                                                data.elemWidth :
1439
                                                0,
1440
                                atOffset = data.at[ 0 ] === "left" ?
1441
                                        data.targetWidth :
1442
                                        data.at[ 0 ] === "right" ?
1443
                                                -data.targetWidth :
1444
                                                0,
1445
                                offset = -2 * data.offset[ 0 ],
1446
                                newOverRight,
1447
                                newOverLeft;
1448

    
1449
                        if ( overLeft < 0 ) {
1450
                                newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1451
                                if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1452
                                        position.left += myOffset + atOffset + offset;
1453
                                }
1454
                        } else if ( overRight > 0 ) {
1455
                                newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1456
                                if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1457
                                        position.left += myOffset + atOffset + offset;
1458
                                }
1459
                        }
1460
                },
1461
                top: function( position, data ) {
1462
                        var within = data.within,
1463
                                withinOffset = within.offset.top + within.scrollTop,
1464
                                outerHeight = within.height,
1465
                                offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1466
                                collisionPosTop = position.top - data.collisionPosition.marginTop,
1467
                                overTop = collisionPosTop - offsetTop,
1468
                                overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1469
                                top = data.my[ 1 ] === "top",
1470
                                myOffset = top ?
1471
                                        -data.elemHeight :
1472
                                        data.my[ 1 ] === "bottom" ?
1473
                                                data.elemHeight :
1474
                                                0,
1475
                                atOffset = data.at[ 1 ] === "top" ?
1476
                                        data.targetHeight :
1477
                                        data.at[ 1 ] === "bottom" ?
1478
                                                -data.targetHeight :
1479
                                                0,
1480
                                offset = -2 * data.offset[ 1 ],
1481
                                newOverTop,
1482
                                newOverBottom;
1483
                        if ( overTop < 0 ) {
1484
                                newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1485
                                if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1486
                                        position.top += myOffset + atOffset + offset;
1487
                                }
1488
                        } else if ( overBottom > 0 ) {
1489
                                newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1490
                                if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1491
                                        position.top += myOffset + atOffset + offset;
1492
                                }
1493
                        }
1494
                }
1495
        },
1496
        flipfit: {
1497
                left: function() {
1498
                        $.ui.position.flip.left.apply( this, arguments );
1499
                        $.ui.position.fit.left.apply( this, arguments );
1500
                },
1501
                top: function() {
1502
                        $.ui.position.flip.top.apply( this, arguments );
1503
                        $.ui.position.fit.top.apply( this, arguments );
1504
                }
1505
        }
1506
};
1507

    
1508
// fraction support test
1509
(function() {
1510
        var testElement, testElementParent, testElementStyle, offsetLeft, i,
1511
                body = document.getElementsByTagName( "body" )[ 0 ],
1512
                div = document.createElement( "div" );
1513

    
1514
        //Create a "fake body" for testing based on method used in jQuery.support
1515
        testElement = document.createElement( body ? "div" : "body" );
1516
        testElementStyle = {
1517
                visibility: "hidden",
1518
                width: 0,
1519
                height: 0,
1520
                border: 0,
1521
                margin: 0,
1522
                background: "none"
1523
        };
1524
        if ( body ) {
1525
                $.extend( testElementStyle, {
1526
                        position: "absolute",
1527
                        left: "-1000px",
1528
                        top: "-1000px"
1529
                });
1530
        }
1531
        for ( i in testElementStyle ) {
1532
                testElement.style[ i ] = testElementStyle[ i ];
1533
        }
1534
        testElement.appendChild( div );
1535
        testElementParent = body || document.documentElement;
1536
        testElementParent.insertBefore( testElement, testElementParent.firstChild );
1537

    
1538
        div.style.cssText = "position: absolute; left: 10.7432222px;";
1539

    
1540
        offsetLeft = $( div ).offset().left;
1541
        supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1542

    
1543
        testElement.innerHTML = "";
1544
        testElementParent.removeChild( testElement );
1545
})();
1546

    
1547
})();
1548

    
1549
var position = $.ui.position;
1550

    
1551

    
1552
/*!
1553
 * jQuery UI Accordion 1.11.4
1554
 * http://jqueryui.com
1555
 *
1556
 * Copyright jQuery Foundation and other contributors
1557
 * Released under the MIT license.
1558
 * http://jquery.org/license
1559
 *
1560
 * http://api.jqueryui.com/accordion/
1561
 */
1562

    
1563

    
1564
var accordion = $.widget( "ui.accordion", {
1565
        version: "1.11.4",
1566
        options: {
1567
                active: 0,
1568
                animate: {},
1569
                collapsible: false,
1570
                event: "click",
1571
                header: "> li > :first-child,> :not(li):even",
1572
                heightStyle: "auto",
1573
                icons: {
1574
                        activeHeader: "ui-icon-triangle-1-s",
1575
                        header: "ui-icon-triangle-1-e"
1576
                },
1577

    
1578
                // callbacks
1579
                activate: null,
1580
                beforeActivate: null
1581
        },
1582

    
1583
        hideProps: {
1584
                borderTopWidth: "hide",
1585
                borderBottomWidth: "hide",
1586
                paddingTop: "hide",
1587
                paddingBottom: "hide",
1588
                height: "hide"
1589
        },
1590

    
1591
        showProps: {
1592
                borderTopWidth: "show",
1593
                borderBottomWidth: "show",
1594
                paddingTop: "show",
1595
                paddingBottom: "show",
1596
                height: "show"
1597
        },
1598

    
1599
        _create: function() {
1600
                var options = this.options;
1601
                this.prevShow = this.prevHide = $();
1602
                this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
1603
                        // ARIA
1604
                        .attr( "role", "tablist" );
1605

    
1606
                // don't allow collapsible: false and active: false / null
1607
                if ( !options.collapsible && (options.active === false || options.active == null) ) {
1608
                        options.active = 0;
1609
                }
1610

    
1611
                this._processPanels();
1612
                // handle negative values
1613
                if ( options.active < 0 ) {
1614
                        options.active += this.headers.length;
1615
                }
1616
                this._refresh();
1617
        },
1618

    
1619
        _getCreateEventData: function() {
1620
                return {
1621
                        header: this.active,
1622
                        panel: !this.active.length ? $() : this.active.next()
1623
                };
1624
        },
1625

    
1626
        _createIcons: function() {
1627
                var icons = this.options.icons;
1628
                if ( icons ) {
1629
                        $( "<span>" )
1630
                                .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
1631
                                .prependTo( this.headers );
1632
                        this.active.children( ".ui-accordion-header-icon" )
1633
                                .removeClass( icons.header )
1634
                                .addClass( icons.activeHeader );
1635
                        this.headers.addClass( "ui-accordion-icons" );
1636
                }
1637
        },
1638

    
1639
        _destroyIcons: function() {
1640
                this.headers
1641
                        .removeClass( "ui-accordion-icons" )
1642
                        .children( ".ui-accordion-header-icon" )
1643
                                .remove();
1644
        },
1645

    
1646
        _destroy: function() {
1647
                var contents;
1648

    
1649
                // clean up main element
1650
                this.element
1651
                        .removeClass( "ui-accordion ui-widget ui-helper-reset" )
1652
                        .removeAttr( "role" );
1653

    
1654
                // clean up headers
1655
                this.headers
1656
                        .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
1657
                                "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
1658
                        .removeAttr( "role" )
1659
                        .removeAttr( "aria-expanded" )
1660
                        .removeAttr( "aria-selected" )
1661
                        .removeAttr( "aria-controls" )
1662
                        .removeAttr( "tabIndex" )
1663
                        .removeUniqueId();
1664

    
1665
                this._destroyIcons();
1666

    
1667
                // clean up content panels
1668
                contents = this.headers.next()
1669
                        .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
1670
                                "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
1671
                        .css( "display", "" )
1672
                        .removeAttr( "role" )
1673
                        .removeAttr( "aria-hidden" )
1674
                        .removeAttr( "aria-labelledby" )
1675
                        .removeUniqueId();
1676

    
1677
                if ( this.options.heightStyle !== "content" ) {
1678
                        contents.css( "height", "" );
1679
                }
1680
        },
1681

    
1682
        _setOption: function( key, value ) {
1683
                if ( key === "active" ) {
1684
                        // _activate() will handle invalid values and update this.options
1685
                        this._activate( value );
1686
                        return;
1687
                }
1688

    
1689
                if ( key === "event" ) {
1690
                        if ( this.options.event ) {
1691
                                this._off( this.headers, this.options.event );
1692
                        }
1693
                        this._setupEvents( value );
1694
                }
1695

    
1696
                this._super( key, value );
1697

    
1698
                // setting collapsible: false while collapsed; open first panel
1699
                if ( key === "collapsible" && !value && this.options.active === false ) {
1700
                        this._activate( 0 );
1701
                }
1702

    
1703
                if ( key === "icons" ) {
1704
                        this._destroyIcons();
1705
                        if ( value ) {
1706
                                this._createIcons();
1707
                        }
1708
                }
1709

    
1710
                // #5332 - opacity doesn't cascade to positioned elements in IE
1711
                // so we need to add the disabled class to the headers and panels
1712
                if ( key === "disabled" ) {
1713
                        this.element
1714
                                .toggleClass( "ui-state-disabled", !!value )
1715
                                .attr( "aria-disabled", value );
1716
                        this.headers.add( this.headers.next() )
1717
                                .toggleClass( "ui-state-disabled", !!value );
1718
                }
1719
        },
1720

    
1721
        _keydown: function( event ) {
1722
                if ( event.altKey || event.ctrlKey ) {
1723
                        return;
1724
                }
1725

    
1726
                var keyCode = $.ui.keyCode,
1727
                        length = this.headers.length,
1728
                        currentIndex = this.headers.index( event.target ),
1729
                        toFocus = false;
1730

    
1731
                switch ( event.keyCode ) {
1732
                        case keyCode.RIGHT:
1733
                        case keyCode.DOWN:
1734
                                toFocus = this.headers[ ( currentIndex + 1 ) % length ];
1735
                                break;
1736
                        case keyCode.LEFT:
1737
                        case keyCode.UP:
1738
                                toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
1739
                                break;
1740
                        case keyCode.SPACE:
1741
                        case keyCode.ENTER:
1742
                                this._eventHandler( event );
1743
                                break;
1744
                        case keyCode.HOME:
1745
                                toFocus = this.headers[ 0 ];
1746
                                break;
1747
                        case keyCode.END:
1748
                                toFocus = this.headers[ length - 1 ];
1749
                                break;
1750
                }
1751

    
1752
                if ( toFocus ) {
1753
                        $( event.target ).attr( "tabIndex", -1 );
1754
                        $( toFocus ).attr( "tabIndex", 0 );
1755
                        toFocus.focus();
1756
                        event.preventDefault();
1757
                }
1758
        },
1759

    
1760
        _panelKeyDown: function( event ) {
1761
                if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
1762
                        $( event.currentTarget ).prev().focus();
1763
                }
1764
        },
1765

    
1766
        refresh: function() {
1767
                var options = this.options;
1768
                this._processPanels();
1769

    
1770
                // was collapsed or no panel
1771
                if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
1772
                        options.active = false;
1773
                        this.active = $();
1774
                // active false only when collapsible is true
1775
                } else if ( options.active === false ) {
1776
                        this._activate( 0 );
1777
                // was active, but active panel is gone
1778
                } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
1779
                        // all remaining panel are disabled
1780
                        if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
1781
                                options.active = false;
1782
                                this.active = $();
1783
                        // activate previous panel
1784
                        } else {
1785
                                this._activate( Math.max( 0, options.active - 1 ) );
1786
                        }
1787
                // was active, active panel still exists
1788
                } else {
1789
                        // make sure active index is correct
1790
                        options.active = this.headers.index( this.active );
1791
                }
1792

    
1793
                this._destroyIcons();
1794

    
1795
                this._refresh();
1796
        },
1797

    
1798
        _processPanels: function() {
1799
                var prevHeaders = this.headers,
1800
                        prevPanels = this.panels;
1801

    
1802
                this.headers = this.element.find( this.options.header )
1803
                        .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
1804

    
1805
                this.panels = this.headers.next()
1806
                        .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
1807
                        .filter( ":not(.ui-accordion-content-active)" )
1808
                        .hide();
1809

    
1810
                // Avoid memory leaks (#10056)
1811
                if ( prevPanels ) {
1812
                        this._off( prevHeaders.not( this.headers ) );
1813
                        this._off( prevPanels.not( this.panels ) );
1814
                }
1815
        },
1816

    
1817
        _refresh: function() {
1818
                var maxHeight,
1819
                        options = this.options,
1820
                        heightStyle = options.heightStyle,
1821
                        parent = this.element.parent();
1822

    
1823
                this.active = this._findActive( options.active )
1824
                        .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
1825
                        .removeClass( "ui-corner-all" );
1826
                this.active.next()
1827
                        .addClass( "ui-accordion-content-active" )
1828
                        .show();
1829

    
1830
                this.headers
1831
                        .attr( "role", "tab" )
1832
                        .each(function() {
1833
                                var header = $( this ),
1834
                                        headerId = header.uniqueId().attr( "id" ),
1835
                                        panel = header.next(),
1836
                                        panelId = panel.uniqueId().attr( "id" );
1837
                                header.attr( "aria-controls", panelId );
1838
                                panel.attr( "aria-labelledby", headerId );
1839
                        })
1840
                        .next()
1841
                                .attr( "role", "tabpanel" );
1842

    
1843
                this.headers
1844
                        .not( this.active )
1845
                        .attr({
1846
                                "aria-selected": "false",
1847
                                "aria-expanded": "false",
1848
                                tabIndex: -1
1849
                        })
1850
                        .next()
1851
                                .attr({
1852
                                        "aria-hidden": "true"
1853
                                })
1854
                                .hide();
1855

    
1856
                // make sure at least one header is in the tab order
1857
                if ( !this.active.length ) {
1858
                        this.headers.eq( 0 ).attr( "tabIndex", 0 );
1859
                } else {
1860
                        this.active.attr({
1861
                                "aria-selected": "true",
1862
                                "aria-expanded": "true",
1863
                                tabIndex: 0
1864
                        })
1865
                        .next()
1866
                                .attr({
1867
                                        "aria-hidden": "false"
1868
                                });
1869
                }
1870

    
1871
                this._createIcons();
1872

    
1873
                this._setupEvents( options.event );
1874

    
1875
                if ( heightStyle === "fill" ) {
1876
                        maxHeight = parent.height();
1877
                        this.element.siblings( ":visible" ).each(function() {
1878
                                var elem = $( this ),
1879
                                        position = elem.css( "position" );
1880

    
1881
                                if ( position === "absolute" || position === "fixed" ) {
1882
                                        return;
1883
                                }
1884
                                maxHeight -= elem.outerHeight( true );
1885
                        });
1886

    
1887
                        this.headers.each(function() {
1888
                                maxHeight -= $( this ).outerHeight( true );
1889
                        });
1890

    
1891
                        this.headers.next()
1892
                                .each(function() {
1893
                                        $( this ).height( Math.max( 0, maxHeight -
1894
                                                $( this ).innerHeight() + $( this ).height() ) );
1895
                                })
1896
                                .css( "overflow", "auto" );
1897
                } else if ( heightStyle === "auto" ) {
1898
                        maxHeight = 0;
1899
                        this.headers.next()
1900
                                .each(function() {
1901
                                        maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
1902
                                })
1903
                                .height( maxHeight );
1904
                }
1905
        },
1906

    
1907
        _activate: function( index ) {
1908
                var active = this._findActive( index )[ 0 ];
1909

    
1910
                // trying to activate the already active panel
1911
                if ( active === this.active[ 0 ] ) {
1912
                        return;
1913
                }
1914

    
1915
                // trying to collapse, simulate a click on the currently active header
1916
                active = active || this.active[ 0 ];
1917

    
1918
                this._eventHandler({
1919
                        target: active,
1920
                        currentTarget: active,
1921
                        preventDefault: $.noop
1922
                });
1923
        },
1924

    
1925
        _findActive: function( selector ) {
1926
                return typeof selector === "number" ? this.headers.eq( selector ) : $();
1927
        },
1928

    
1929
        _setupEvents: function( event ) {
1930
                var events = {
1931
                        keydown: "_keydown"
1932
                };
1933
                if ( event ) {
1934
                        $.each( event.split( " " ), function( index, eventName ) {
1935
                                events[ eventName ] = "_eventHandler";
1936
                        });
1937
                }
1938

    
1939
                this._off( this.headers.add( this.headers.next() ) );
1940
                this._on( this.headers, events );
1941
                this._on( this.headers.next(), { keydown: "_panelKeyDown" });
1942
                this._hoverable( this.headers );
1943
                this._focusable( this.headers );
1944
        },
1945

    
1946
        _eventHandler: function( event ) {
1947
                var options = this.options,
1948
                        active = this.active,
1949
                        clicked = $( event.currentTarget ),
1950
                        clickedIsActive = clicked[ 0 ] === active[ 0 ],
1951
                        collapsing = clickedIsActive && options.collapsible,
1952
                        toShow = collapsing ? $() : clicked.next(),
1953
                        toHide = active.next(),
1954
                        eventData = {
1955
                                oldHeader: active,
1956
                                oldPanel: toHide,
1957
                                newHeader: collapsing ? $() : clicked,
1958
                                newPanel: toShow
1959
                        };
1960

    
1961
                event.preventDefault();
1962

    
1963
                if (
1964
                                // click on active header, but not collapsible
1965
                                ( clickedIsActive && !options.collapsible ) ||
1966
                                // allow canceling activation
1967
                                ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
1968
                        return;
1969
                }
1970

    
1971
                options.active = collapsing ? false : this.headers.index( clicked );
1972

    
1973
                // when the call to ._toggle() comes after the class changes
1974
                // it causes a very odd bug in IE 8 (see #6720)
1975
                this.active = clickedIsActive ? $() : clicked;
1976
                this._toggle( eventData );
1977

    
1978
                // switch classes
1979
                // corner classes on the previously active header stay after the animation
1980
                active.removeClass( "ui-accordion-header-active ui-state-active" );
1981
                if ( options.icons ) {
1982
                        active.children( ".ui-accordion-header-icon" )
1983
                                .removeClass( options.icons.activeHeader )
1984
                                .addClass( options.icons.header );
1985
                }
1986

    
1987
                if ( !clickedIsActive ) {
1988
                        clicked
1989
                                .removeClass( "ui-corner-all" )
1990
                                .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
1991
                        if ( options.icons ) {
1992
                                clicked.children( ".ui-accordion-header-icon" )
1993
                                        .removeClass( options.icons.header )
1994
                                        .addClass( options.icons.activeHeader );
1995
                        }
1996

    
1997
                        clicked
1998
                                .next()
1999
                                .addClass( "ui-accordion-content-active" );
2000
                }
2001
        },
2002

    
2003
        _toggle: function( data ) {
2004
                var toShow = data.newPanel,
2005
                        toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
2006

    
2007
                // handle activating a panel during the animation for another activation
2008
                this.prevShow.add( this.prevHide ).stop( true, true );
2009
                this.prevShow = toShow;
2010
                this.prevHide = toHide;
2011

    
2012
                if ( this.options.animate ) {
2013
                        this._animate( toShow, toHide, data );
2014
                } else {
2015
                        toHide.hide();
2016
                        toShow.show();
2017
                        this._toggleComplete( data );
2018
                }
2019

    
2020
                toHide.attr({
2021
                        "aria-hidden": "true"
2022
                });
2023
                toHide.prev().attr({
2024
                        "aria-selected": "false",
2025
                        "aria-expanded": "false"
2026
                });
2027
                // if we're switching panels, remove the old header from the tab order
2028
                // if we're opening from collapsed state, remove the previous header from the tab order
2029
                // if we're collapsing, then keep the collapsing header in the tab order
2030
                if ( toShow.length && toHide.length ) {
2031
                        toHide.prev().attr({
2032
                                "tabIndex": -1,
2033
                                "aria-expanded": "false"
2034
                        });
2035
                } else if ( toShow.length ) {
2036
                        this.headers.filter(function() {
2037
                                return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
2038
                        })
2039
                        .attr( "tabIndex", -1 );
2040
                }
2041

    
2042
                toShow
2043
                        .attr( "aria-hidden", "false" )
2044
                        .prev()
2045
                                .attr({
2046
                                        "aria-selected": "true",
2047
                                        "aria-expanded": "true",
2048
                                        tabIndex: 0
2049
                                });
2050
        },
2051

    
2052
        _animate: function( toShow, toHide, data ) {
2053
                var total, easing, duration,
2054
                        that = this,
2055
                        adjust = 0,
2056
                        boxSizing = toShow.css( "box-sizing" ),
2057
                        down = toShow.length &&
2058
                                ( !toHide.length || ( toShow.index() < toHide.index() ) ),
2059
                        animate = this.options.animate || {},
2060
                        options = down && animate.down || animate,
2061
                        complete = function() {
2062
                                that._toggleComplete( data );
2063
                        };
2064

    
2065
                if ( typeof options === "number" ) {
2066
                        duration = options;
2067
                }
2068
                if ( typeof options === "string" ) {
2069
                        easing = options;
2070
                }
2071
                // fall back from options to animation in case of partial down settings
2072
                easing = easing || options.easing || animate.easing;
2073
                duration = duration || options.duration || animate.duration;
2074

    
2075
                if ( !toHide.length ) {
2076
                        return toShow.animate( this.showProps, duration, easing, complete );
2077
                }
2078
                if ( !toShow.length ) {
2079
                        return toHide.animate( this.hideProps, duration, easing, complete );
2080
                }
2081

    
2082
                total = toShow.show().outerHeight();
2083
                toHide.animate( this.hideProps, {
2084
                        duration: duration,
2085
                        easing: easing,
2086
                        step: function( now, fx ) {
2087
                                fx.now = Math.round( now );
2088
                        }
2089
                });
2090
                toShow
2091
                        .hide()
2092
                        .animate( this.showProps, {
2093
                                duration: duration,
2094
                                easing: easing,
2095
                                complete: complete,
2096
                                step: function( now, fx ) {
2097
                                        fx.now = Math.round( now );
2098
                                        if ( fx.prop !== "height" ) {
2099
                                                if ( boxSizing === "content-box" ) {
2100
                                                        adjust += fx.now;
2101
                                                }
2102
                                        } else if ( that.options.heightStyle !== "content" ) {
2103
                                                fx.now = Math.round( total - toHide.outerHeight() - adjust );
2104
                                                adjust = 0;
2105
                                        }
2106
                                }
2107
                        });
2108
        },
2109

    
2110
        _toggleComplete: function( data ) {
2111
                var toHide = data.oldPanel;
2112

    
2113
                toHide
2114
                        .removeClass( "ui-accordion-content-active" )
2115
                        .prev()
2116
                                .removeClass( "ui-corner-top" )
2117
                                .addClass( "ui-corner-all" );
2118

    
2119
                // Work around for rendering bug in IE (#5421)
2120
                if ( toHide.length ) {
2121
                        toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
2122
                }
2123
                this._trigger( "activate", null, data );
2124
        }
2125
});
2126

    
2127

    
2128
/*!
2129
 * jQuery UI Menu 1.11.4
2130
 * http://jqueryui.com
2131
 *
2132
 * Copyright jQuery Foundation and other contributors
2133
 * Released under the MIT license.
2134
 * http://jquery.org/license
2135
 *
2136
 * http://api.jqueryui.com/menu/
2137
 */
2138

    
2139

    
2140
var menu = $.widget( "ui.menu", {
2141
        version: "1.11.4",
2142
        defaultElement: "<ul>",
2143
        delay: 300,
2144
        options: {
2145
                icons: {
2146
                        submenu: "ui-icon-carat-1-e"
2147
                },
2148
                items: "> *",
2149
                menus: "ul",
2150
                position: {
2151
                        my: "left-1 top",
2152
                        at: "right top"
2153
                },
2154
                role: "menu",
2155

    
2156
                // callbacks
2157
                blur: null,
2158
                focus: null,
2159
                select: null
2160
        },
2161

    
2162
        _create: function() {
2163
                this.activeMenu = this.element;
2164

    
2165
                // Flag used to prevent firing of the click handler
2166
                // as the event bubbles up through nested menus
2167
                this.mouseHandled = false;
2168
                this.element
2169
                        .uniqueId()
2170
                        .addClass( "ui-menu ui-widget ui-widget-content" )
2171
                        .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
2172
                        .attr({
2173
                                role: this.options.role,
2174
                                tabIndex: 0
2175
                        });
2176

    
2177
                if ( this.options.disabled ) {
2178
                        this.element
2179
                                .addClass( "ui-state-disabled" )
2180
                                .attr( "aria-disabled", "true" );
2181
                }
2182

    
2183
                this._on({
2184
                        // Prevent focus from sticking to links inside menu after clicking
2185
                        // them (focus should always stay on UL during navigation).
2186
                        "mousedown .ui-menu-item": function( event ) {
2187
                                event.preventDefault();
2188
                        },
2189
                        "click .ui-menu-item": function( event ) {
2190
                                var target = $( event.target );
2191
                                if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
2192
                                        this.select( event );
2193

    
2194
                                        // Only set the mouseHandled flag if the event will bubble, see #9469.
2195
                                        if ( !event.isPropagationStopped() ) {
2196
                                                this.mouseHandled = true;
2197
                                        }
2198

    
2199
                                        // Open submenu on click
2200
                                        if ( target.has( ".ui-menu" ).length ) {
2201
                                                this.expand( event );
2202
                                        } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
2203

    
2204
                                                // Redirect focus to the menu
2205
                                                this.element.trigger( "focus", [ true ] );
2206

    
2207
                                                // If the active item is on the top level, let it stay active.
2208
                                                // Otherwise, blur the active item since it is no longer visible.
2209
                                                if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
2210
                                                        clearTimeout( this.timer );
2211
                                                }
2212
                                        }
2213
                                }
2214
                        },
2215
                        "mouseenter .ui-menu-item": function( event ) {
2216
                                // Ignore mouse events while typeahead is active, see #10458.
2217
                                // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
2218
                                // is over an item in the menu
2219
                                if ( this.previousFilter ) {
2220
                                        return;
2221
                                }
2222
                                var target = $( event.currentTarget );
2223
                                // Remove ui-state-active class from siblings of the newly focused menu item
2224
                                // to avoid a jump caused by adjacent elements both having a class with a border
2225
                                target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
2226
                                this.focus( event, target );
2227
                        },
2228
                        mouseleave: "collapseAll",
2229
                        "mouseleave .ui-menu": "collapseAll",
2230
                        focus: function( event, keepActiveItem ) {
2231
                                // If there's already an active item, keep it active
2232
                                // If not, activate the first item
2233
                                var item = this.active || this.element.find( this.options.items ).eq( 0 );
2234

    
2235
                                if ( !keepActiveItem ) {
2236
                                        this.focus( event, item );
2237
                                }
2238
                        },
2239
                        blur: function( event ) {
2240
                                this._delay(function() {
2241
                                        if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
2242
                                                this.collapseAll( event );
2243
                                        }
2244
                                });
2245
                        },
2246
                        keydown: "_keydown"
2247
                });
2248

    
2249
                this.refresh();
2250

    
2251
                // Clicks outside of a menu collapse any open menus
2252
                this._on( this.document, {
2253
                        click: function( event ) {
2254
                                if ( this._closeOnDocumentClick( event ) ) {
2255
                                        this.collapseAll( event );
2256
                                }
2257

    
2258
                                // Reset the mouseHandled flag
2259
                                this.mouseHandled = false;
2260
                        }
2261
                });
2262
        },
2263

    
2264
        _destroy: function() {
2265
                // Destroy (sub)menus
2266
                this.element
2267
                        .removeAttr( "aria-activedescendant" )
2268
                        .find( ".ui-menu" ).addBack()
2269
                                .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
2270
                                .removeAttr( "role" )
2271
                                .removeAttr( "tabIndex" )
2272
                                .removeAttr( "aria-labelledby" )
2273
                                .removeAttr( "aria-expanded" )
2274
                                .removeAttr( "aria-hidden" )
2275
                                .removeAttr( "aria-disabled" )
2276
                                .removeUniqueId()
2277
                                .show();
2278

    
2279
                // Destroy menu items
2280
                this.element.find( ".ui-menu-item" )
2281
                        .removeClass( "ui-menu-item" )
2282
                        .removeAttr( "role" )
2283
                        .removeAttr( "aria-disabled" )
2284
                        .removeUniqueId()
2285
                        .removeClass( "ui-state-hover" )
2286
                        .removeAttr( "tabIndex" )
2287
                        .removeAttr( "role" )
2288
                        .removeAttr( "aria-haspopup" )
2289
                        .children().each( function() {
2290
                                var elem = $( this );
2291
                                if ( elem.data( "ui-menu-submenu-carat" ) ) {
2292
                                        elem.remove();
2293
                                }
2294
                        });
2295

    
2296
                // Destroy menu dividers
2297
                this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
2298
        },
2299

    
2300
        _keydown: function( event ) {
2301
                var match, prev, character, skip,
2302
                        preventDefault = true;
2303

    
2304
                switch ( event.keyCode ) {
2305
                case $.ui.keyCode.PAGE_UP:
2306
                        this.previousPage( event );
2307
                        break;
2308
                case $.ui.keyCode.PAGE_DOWN:
2309
                        this.nextPage( event );
2310
                        break;
2311
                case $.ui.keyCode.HOME:
2312
                        this._move( "first", "first", event );
2313
                        break;
2314
                case $.ui.keyCode.END:
2315
                        this._move( "last", "last", event );
2316
                        break;
2317
                case $.ui.keyCode.UP:
2318
                        this.previous( event );
2319
                        break;
2320
                case $.ui.keyCode.DOWN:
2321
                        this.next( event );
2322
                        break;
2323
                case $.ui.keyCode.LEFT:
2324
                        this.collapse( event );
2325
                        break;
2326
                case $.ui.keyCode.RIGHT:
2327
                        if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
2328
                                this.expand( event );
2329
                        }
2330
                        break;
2331
                case $.ui.keyCode.ENTER:
2332
                case $.ui.keyCode.SPACE:
2333
                        this._activate( event );
2334
                        break;
2335
                case $.ui.keyCode.ESCAPE:
2336
                        this.collapse( event );
2337
                        break;
2338
                default:
2339
                        preventDefault = false;
2340
                        prev = this.previousFilter || "";
2341
                        character = String.fromCharCode( event.keyCode );
2342
                        skip = false;
2343

    
2344
                        clearTimeout( this.filterTimer );
2345

    
2346
                        if ( character === prev ) {
2347
                                skip = true;
2348
                        } else {
2349
                                character = prev + character;
2350
                        }
2351

    
2352
                        match = this._filterMenuItems( character );
2353
                        match = skip && match.index( this.active.next() ) !== -1 ?
2354
                                this.active.nextAll( ".ui-menu-item" ) :
2355
                                match;
2356

    
2357
                        // If no matches on the current filter, reset to the last character pressed
2358
                        // to move down the menu to the first item that starts with that character
2359
                        if ( !match.length ) {
2360
                                character = String.fromCharCode( event.keyCode );
2361
                                match = this._filterMenuItems( character );
2362
                        }
2363

    
2364
                        if ( match.length ) {
2365
                                this.focus( event, match );
2366
                                this.previousFilter = character;
2367
                                this.filterTimer = this._delay(function() {
2368
                                        delete this.previousFilter;
2369
                                }, 1000 );
2370
                        } else {
2371
                                delete this.previousFilter;
2372
                        }
2373
                }
2374

    
2375
                if ( preventDefault ) {
2376
                        event.preventDefault();
2377
                }
2378
        },
2379

    
2380
        _activate: function( event ) {
2381
                if ( !this.active.is( ".ui-state-disabled" ) ) {
2382
                        if ( this.active.is( "[aria-haspopup='true']" ) ) {
2383
                                this.expand( event );
2384
                        } else {
2385
                                this.select( event );
2386
                        }
2387
                }
2388
        },
2389

    
2390
        refresh: function() {
2391
                var menus, items,
2392
                        that = this,
2393
                        icon = this.options.icons.submenu,
2394
                        submenus = this.element.find( this.options.menus );
2395

    
2396
                this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
2397

    
2398
                // Initialize nested menus
2399
                submenus.filter( ":not(.ui-menu)" )
2400
                        .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
2401
                        .hide()
2402
                        .attr({
2403
                                role: this.options.role,
2404
                                "aria-hidden": "true",
2405
                                "aria-expanded": "false"
2406
                        })
2407
                        .each(function() {
2408
                                var menu = $( this ),
2409
                                        item = menu.parent(),
2410
                                        submenuCarat = $( "<span>" )
2411
                                                .addClass( "ui-menu-icon ui-icon " + icon )
2412
                                                .data( "ui-menu-submenu-carat", true );
2413

    
2414
                                item
2415
                                        .attr( "aria-haspopup", "true" )
2416
                                        .prepend( submenuCarat );
2417
                                menu.attr( "aria-labelledby", item.attr( "id" ) );
2418
                        });
2419

    
2420
                menus = submenus.add( this.element );
2421
                items = menus.find( this.options.items );
2422

    
2423
                // Initialize menu-items containing spaces and/or dashes only as dividers
2424
                items.not( ".ui-menu-item" ).each(function() {
2425
                        var item = $( this );
2426
                        if ( that._isDivider( item ) ) {
2427
                                item.addClass( "ui-widget-content ui-menu-divider" );
2428
                        }
2429
                });
2430

    
2431
                // Don't refresh list items that are already adapted
2432
                items.not( ".ui-menu-item, .ui-menu-divider" )
2433
                        .addClass( "ui-menu-item" )
2434
                        .uniqueId()
2435
                        .attr({
2436
                                tabIndex: -1,
2437
                                role: this._itemRole()
2438
                        });
2439

    
2440
                // Add aria-disabled attribute to any disabled menu item
2441
                items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
2442

    
2443
                // If the active item has been removed, blur the menu
2444
                if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
2445
                        this.blur();
2446
                }
2447
        },
2448

    
2449
        _itemRole: function() {
2450
                return {
2451
                        menu: "menuitem",
2452
                        listbox: "option"
2453
                }[ this.options.role ];
2454
        },
2455

    
2456
        _setOption: function( key, value ) {
2457
                if ( key === "icons" ) {
2458
                        this.element.find( ".ui-menu-icon" )
2459
                                .removeClass( this.options.icons.submenu )
2460
                                .addClass( value.submenu );
2461
                }
2462
                if ( key === "disabled" ) {
2463
                        this.element
2464
                                .toggleClass( "ui-state-disabled", !!value )
2465
                                .attr( "aria-disabled", value );
2466
                }
2467
                this._super( key, value );
2468
        },
2469

    
2470
        focus: function( event, item ) {
2471
                var nested, focused;
2472
                this.blur( event, event && event.type === "focus" );
2473

    
2474
                this._scrollIntoView( item );
2475

    
2476
                this.active = item.first();
2477
                focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
2478
                // Only update aria-activedescendant if there's a role
2479
                // otherwise we assume focus is managed elsewhere
2480
                if ( this.options.role ) {
2481
                        this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
2482
                }
2483

    
2484
                // Highlight active parent menu item, if any
2485
                this.active
2486
                        .parent()
2487
                        .closest( ".ui-menu-item" )
2488
                        .addClass( "ui-state-active" );
2489

    
2490
                if ( event && event.type === "keydown" ) {
2491
                        this._close();
2492
                } else {
2493
                        this.timer = this._delay(function() {
2494
                                this._close();
2495
                        }, this.delay );
2496
                }
2497

    
2498
                nested = item.children( ".ui-menu" );
2499
                if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
2500
                        this._startOpening(nested);
2501
                }
2502
                this.activeMenu = item.parent();
2503

    
2504
                this._trigger( "focus", event, { item: item } );
2505
        },
2506

    
2507
        _scrollIntoView: function( item ) {
2508
                var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
2509
                if ( this._hasScroll() ) {
2510
                        borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
2511
                        paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
2512
                        offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
2513
                        scroll = this.activeMenu.scrollTop();
2514
                        elementHeight = this.activeMenu.height();
2515
                        itemHeight = item.outerHeight();
2516

    
2517
                        if ( offset < 0 ) {
2518
                                this.activeMenu.scrollTop( scroll + offset );
2519
                        } else if ( offset + itemHeight > elementHeight ) {
2520
                                this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
2521
                        }
2522
                }
2523
        },
2524

    
2525
        blur: function( event, fromFocus ) {
2526
                if ( !fromFocus ) {
2527
                        clearTimeout( this.timer );
2528
                }
2529

    
2530
                if ( !this.active ) {
2531
                        return;
2532
                }
2533

    
2534
                this.active.removeClass( "ui-state-focus" );
2535
                this.active = null;
2536

    
2537
                this._trigger( "blur", event, { item: this.active } );
2538
        },
2539

    
2540
        _startOpening: function( submenu ) {
2541
                clearTimeout( this.timer );
2542

    
2543
                // Don't open if already open fixes a Firefox bug that caused a .5 pixel
2544
                // shift in the submenu position when mousing over the carat icon
2545
                if ( submenu.attr( "aria-hidden" ) !== "true" ) {
2546
                        return;
2547
                }
2548

    
2549
                this.timer = this._delay(function() {
2550
                        this._close();
2551
                        this._open( submenu );
2552
                }, this.delay );
2553
        },
2554

    
2555
        _open: function( submenu ) {
2556
                var position = $.extend({
2557
                        of: this.active
2558
                }, this.options.position );
2559

    
2560
                clearTimeout( this.timer );
2561
                this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
2562
                        .hide()
2563
                        .attr( "aria-hidden", "true" );
2564

    
2565
                submenu
2566
                        .show()
2567
                        .removeAttr( "aria-hidden" )
2568
                        .attr( "aria-expanded", "true" )
2569
                        .position( position );
2570
        },
2571

    
2572
        collapseAll: function( event, all ) {
2573
                clearTimeout( this.timer );
2574
                this.timer = this._delay(function() {
2575
                        // If we were passed an event, look for the submenu that contains the event
2576
                        var currentMenu = all ? this.element :
2577
                                $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
2578

    
2579
                        // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
2580
                        if ( !currentMenu.length ) {
2581
                                currentMenu = this.element;
2582
                        }
2583

    
2584
                        this._close( currentMenu );
2585

    
2586
                        this.blur( event );
2587
                        this.activeMenu = currentMenu;
2588
                }, this.delay );
2589
        },
2590

    
2591
        // With no arguments, closes the currently active menu - if nothing is active
2592
        // it closes all menus.  If passed an argument, it will search for menus BELOW
2593
        _close: function( startMenu ) {
2594
                if ( !startMenu ) {
2595
                        startMenu = this.active ? this.active.parent() : this.element;
2596
                }
2597

    
2598
                startMenu
2599
                        .find( ".ui-menu" )
2600
                                .hide()
2601
                                .attr( "aria-hidden", "true" )
2602
                                .attr( "aria-expanded", "false" )
2603
                        .end()
2604
                        .find( ".ui-state-active" ).not( ".ui-state-focus" )
2605
                                .removeClass( "ui-state-active" );
2606
        },
2607

    
2608
        _closeOnDocumentClick: function( event ) {
2609
                return !$( event.target ).closest( ".ui-menu" ).length;
2610
        },
2611

    
2612
        _isDivider: function( item ) {
2613

    
2614
                // Match hyphen, em dash, en dash
2615
                return !/[^\-\u2014\u2013\s]/.test( item.text() );
2616
        },
2617

    
2618
        collapse: function( event ) {
2619
                var newItem = this.active &&
2620
                        this.active.parent().closest( ".ui-menu-item", this.element );
2621
                if ( newItem && newItem.length ) {
2622
                        this._close();
2623
                        this.focus( event, newItem );
2624
                }
2625
        },
2626

    
2627
        expand: function( event ) {
2628
                var newItem = this.active &&
2629
                        this.active
2630
                                .children( ".ui-menu " )
2631
                                .find( this.options.items )
2632
                                .first();
2633

    
2634
                if ( newItem && newItem.length ) {
2635
                        this._open( newItem.parent() );
2636

    
2637
                        // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
2638
                        this._delay(function() {
2639
                                this.focus( event, newItem );
2640
                        });
2641
                }
2642
        },
2643

    
2644
        next: function( event ) {
2645
                this._move( "next", "first", event );
2646
        },
2647

    
2648
        previous: function( event ) {
2649
                this._move( "prev", "last", event );
2650
        },
2651

    
2652
        isFirstItem: function() {
2653
                return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
2654
        },
2655

    
2656
        isLastItem: function() {
2657
                return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
2658
        },
2659

    
2660
        _move: function( direction, filter, event ) {
2661
                var next;
2662
                if ( this.active ) {
2663
                        if ( direction === "first" || direction === "last" ) {
2664
                                next = this.active
2665
                                        [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
2666
                                        .eq( -1 );
2667
                        } else {
2668
                                next = this.active
2669
                                        [ direction + "All" ]( ".ui-menu-item" )
2670
                                        .eq( 0 );
2671
                        }
2672
                }
2673
                if ( !next || !next.length || !this.active ) {
2674
                        next = this.activeMenu.find( this.options.items )[ filter ]();
2675
                }
2676

    
2677
                this.focus( event, next );
2678
        },
2679

    
2680
        nextPage: function( event ) {
2681
                var item, base, height;
2682

    
2683
                if ( !this.active ) {
2684
                        this.next( event );
2685
                        return;
2686
                }
2687
                if ( this.isLastItem() ) {
2688
                        return;
2689
                }
2690
                if ( this._hasScroll() ) {
2691
                        base = this.active.offset().top;
2692
                        height = this.element.height();
2693
                        this.active.nextAll( ".ui-menu-item" ).each(function() {
2694
                                item = $( this );
2695
                                return item.offset().top - base - height < 0;
2696
                        });
2697

    
2698
                        this.focus( event, item );
2699
                } else {
2700
                        this.focus( event, this.activeMenu.find( this.options.items )
2701
                                [ !this.active ? "first" : "last" ]() );
2702
                }
2703
        },
2704

    
2705
        previousPage: function( event ) {
2706
                var item, base, height;
2707
                if ( !this.active ) {
2708
                        this.next( event );
2709
                        return;
2710
                }
2711
                if ( this.isFirstItem() ) {
2712
                        return;
2713
                }
2714
                if ( this._hasScroll() ) {
2715
                        base = this.active.offset().top;
2716
                        height = this.element.height();
2717
                        this.active.prevAll( ".ui-menu-item" ).each(function() {
2718
                                item = $( this );
2719
                                return item.offset().top - base + height > 0;
2720
                        });
2721

    
2722
                        this.focus( event, item );
2723
                } else {
2724
                        this.focus( event, this.activeMenu.find( this.options.items ).first() );
2725
                }
2726
        },
2727

    
2728
        _hasScroll: function() {
2729
                return this.element.outerHeight() < this.element.prop( "scrollHeight" );
2730
        },
2731

    
2732
        select: function( event ) {
2733
                // TODO: It should never be possible to not have an active item at this
2734
                // point, but the tests don't trigger mouseenter before click.
2735
                this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
2736
                var ui = { item: this.active };
2737
                if ( !this.active.has( ".ui-menu" ).length ) {
2738
                        this.collapseAll( event, true );
2739
                }
2740
                this._trigger( "select", event, ui );
2741
        },
2742

    
2743
        _filterMenuItems: function(character) {
2744
                var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
2745
                        regex = new RegExp( "^" + escapedCharacter, "i" );
2746

    
2747
                return this.activeMenu
2748
                        .find( this.options.items )
2749

    
2750
                        // Only match on items, not dividers or other content (#10571)
2751
                        .filter( ".ui-menu-item" )
2752
                        .filter(function() {
2753
                                return regex.test( $.trim( $( this ).text() ) );
2754
                        });
2755
        }
2756
});
2757

    
2758

    
2759
/*!
2760
 * jQuery UI Autocomplete 1.11.4
2761
 * http://jqueryui.com
2762
 *
2763
 * Copyright jQuery Foundation and other contributors
2764
 * Released under the MIT license.
2765
 * http://jquery.org/license
2766
 *
2767
 * http://api.jqueryui.com/autocomplete/
2768
 */
2769

    
2770

    
2771
$.widget( "ui.autocomplete", {
2772
        version: "1.11.4",
2773
        defaultElement: "<input>",
2774
        options: {
2775
                appendTo: null,
2776
                autoFocus: false,
2777
                delay: 300,
2778
                minLength: 1,
2779
                position: {
2780
                        my: "left top",
2781
                        at: "left bottom",
2782
                        collision: "none"
2783
                },
2784
                source: null,
2785

    
2786
                // callbacks
2787
                change: null,
2788
                close: null,
2789
                focus: null,
2790
                open: null,
2791
                response: null,
2792
                search: null,
2793
                select: null
2794
        },
2795

    
2796
        requestIndex: 0,
2797
        pending: 0,
2798

    
2799
        _create: function() {
2800
                // Some browsers only repeat keydown events, not keypress events,
2801
                // so we use the suppressKeyPress flag to determine if we've already
2802
                // handled the keydown event. #7269
2803
                // Unfortunately the code for & in keypress is the same as the up arrow,
2804
                // so we use the suppressKeyPressRepeat flag to avoid handling keypress
2805
                // events when we know the keydown event was used to modify the
2806
                // search term. #7799
2807
                var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
2808
                        nodeName = this.element[ 0 ].nodeName.toLowerCase(),
2809
                        isTextarea = nodeName === "textarea",
2810
                        isInput = nodeName === "input";
2811

    
2812
                this.isMultiLine =
2813
                        // Textareas are always multi-line
2814
                        isTextarea ? true :
2815
                        // Inputs are always single-line, even if inside a contentEditable element
2816
                        // IE also treats inputs as contentEditable
2817
                        isInput ? false :
2818
                        // All other element types are determined by whether or not they're contentEditable
2819
                        this.element.prop( "isContentEditable" );
2820

    
2821
                this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
2822
                this.isNewMenu = true;
2823

    
2824
                this.element
2825
                        .addClass( "ui-autocomplete-input" )
2826
                        .attr( "autocomplete", "off" );
2827

    
2828
                this._on( this.element, {
2829
                        keydown: function( event ) {
2830
                                if ( this.element.prop( "readOnly" ) ) {
2831
                                        suppressKeyPress = true;
2832
                                        suppressInput = true;
2833
                                        suppressKeyPressRepeat = true;
2834
                                        return;
2835
                                }
2836

    
2837
                                suppressKeyPress = false;
2838
                                suppressInput = false;
2839
                                suppressKeyPressRepeat = false;
2840
                                var keyCode = $.ui.keyCode;
2841
                                switch ( event.keyCode ) {
2842
                                case keyCode.PAGE_UP:
2843
                                        suppressKeyPress = true;
2844
                                        this._move( "previousPage", event );
2845
                                        break;
2846
                                case keyCode.PAGE_DOWN:
2847
                                        suppressKeyPress = true;
2848
                                        this._move( "nextPage", event );
2849
                                        break;
2850
                                case keyCode.UP:
2851
                                        suppressKeyPress = true;
2852
                                        this._keyEvent( "previous", event );
2853
                                        break;
2854
                                case keyCode.DOWN:
2855
                                        suppressKeyPress = true;
2856
                                        this._keyEvent( "next", event );
2857
                                        break;
2858
                                case keyCode.ENTER:
2859
                                        // when menu is open and has focus
2860
                                        if ( this.menu.active ) {
2861
                                                // #6055 - Opera still allows the keypress to occur
2862
                                                // which causes forms to submit
2863
                                                suppressKeyPress = true;
2864
                                                event.preventDefault();
2865
                                                this.menu.select( event );
2866
                                        }
2867
                                        break;
2868
                                case keyCode.TAB:
2869
                                        if ( this.menu.active ) {
2870
                                                this.menu.select( event );
2871
                                        }
2872
                                        break;
2873
                                case keyCode.ESCAPE:
2874
                                        if ( this.menu.element.is( ":visible" ) ) {
2875
                                                if ( !this.isMultiLine ) {
2876
                                                        this._value( this.term );
2877
                                                }
2878
                                                this.close( event );
2879
                                                // Different browsers have different default behavior for escape
2880
                                                // Single press can mean undo or clear
2881
                                                // Double press in IE means clear the whole form
2882
                                                event.preventDefault();
2883
                                        }
2884
                                        break;
2885
                                default:
2886
                                        suppressKeyPressRepeat = true;
2887
                                        // search timeout should be triggered before the input value is changed
2888
                                        this._searchTimeout( event );
2889
                                        break;
2890
                                }
2891
                        },
2892
                        keypress: function( event ) {
2893
                                if ( suppressKeyPress ) {
2894
                                        suppressKeyPress = false;
2895
                                        if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
2896
                                                event.preventDefault();
2897
                                        }
2898
                                        return;
2899
                                }
2900
                                if ( suppressKeyPressRepeat ) {
2901
                                        return;
2902
                                }
2903

    
2904
                                // replicate some key handlers to allow them to repeat in Firefox and Opera
2905
                                var keyCode = $.ui.keyCode;
2906
                                switch ( event.keyCode ) {
2907
                                case keyCode.PAGE_UP:
2908
                                        this._move( "previousPage", event );
2909
                                        break;
2910
                                case keyCode.PAGE_DOWN:
2911
                                        this._move( "nextPage", event );
2912
                                        break;
2913
                                case keyCode.UP:
2914
                                        this._keyEvent( "previous", event );
2915
                                        break;
2916
                                case keyCode.DOWN:
2917
                                        this._keyEvent( "next", event );
2918
                                        break;
2919
                                }
2920
                        },
2921
                        input: function( event ) {
2922
                                if ( suppressInput ) {
2923
                                        suppressInput = false;
2924
                                        event.preventDefault();
2925
                                        return;
2926
                                }
2927
                                this._searchTimeout( event );
2928
                        },
2929
                        focus: function() {
2930
                                this.selectedItem = null;
2931
                                this.previous = this._value();
2932
                        },
2933
                        blur: function( event ) {
2934
                                if ( this.cancelBlur ) {
2935
                                        delete this.cancelBlur;
2936
                                        return;
2937
                                }
2938

    
2939
                                clearTimeout( this.searching );
2940
                                this.close( event );
2941
                                this._change( event );
2942
                        }
2943
                });
2944

    
2945
                this._initSource();
2946
                this.menu = $( "<ul>" )
2947
                        .addClass( "ui-autocomplete ui-front" )
2948
                        .appendTo( this._appendTo() )
2949
                        .menu({
2950
                                // disable ARIA support, the live region takes care of that
2951
                                role: null
2952
                        })
2953
                        .hide()
2954
                        .menu( "instance" );
2955

    
2956
                this._on( this.menu.element, {
2957
                        mousedown: function( event ) {
2958
                                // prevent moving focus out of the text field
2959
                                event.preventDefault();
2960

    
2961
                                // IE doesn't prevent moving focus even with event.preventDefault()
2962
                                // so we set a flag to know when we should ignore the blur event
2963
                                this.cancelBlur = true;
2964
                                this._delay(function() {
2965
                                        delete this.cancelBlur;
2966
                                });
2967

    
2968
                                // clicking on the scrollbar causes focus to shift to the body
2969
                                // but we can't detect a mouseup or a click immediately afterward
2970
                                // so we have to track the next mousedown and close the menu if
2971
                                // the user clicks somewhere outside of the autocomplete
2972
                                var menuElement = this.menu.element[ 0 ];
2973
                                if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
2974
                                        this._delay(function() {
2975
                                                var that = this;
2976
                                                this.document.one( "mousedown", function( event ) {
2977
                                                        if ( event.target !== that.element[ 0 ] &&
2978
                                                                        event.target !== menuElement &&
2979
                                                                        !$.contains( menuElement, event.target ) ) {
2980
                                                                that.close();
2981
                                                        }
2982
                                                });
2983
                                        });
2984
                                }
2985
                        },
2986
                        menufocus: function( event, ui ) {
2987
                                var label, item;
2988
                                // support: Firefox
2989
                                // Prevent accidental activation of menu items in Firefox (#7024 #9118)
2990
                                if ( this.isNewMenu ) {
2991
                                        this.isNewMenu = false;
2992
                                        if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
2993
                                                this.menu.blur();
2994

    
2995
                                                this.document.one( "mousemove", function() {
2996
                                                        $( event.target ).trigger( event.originalEvent );
2997
                                                });
2998

    
2999
                                                return;
3000
                                        }
3001
                                }
3002

    
3003
                                item = ui.item.data( "ui-autocomplete-item" );
3004
                                if ( false !== this._trigger( "focus", event, { item: item } ) ) {
3005
                                        // use value to match what will end up in the input, if it was a key event
3006
                                        if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
3007
                                                this._value( item.value );
3008
                                        }
3009
                                }
3010

    
3011
                                // Announce the value in the liveRegion
3012
                                label = ui.item.attr( "aria-label" ) || item.value;
3013
                                if ( label && $.trim( label ).length ) {
3014
                                        this.liveRegion.children().hide();
3015
                                        $( "<div>" ).text( label ).appendTo( this.liveRegion );
3016
                                }
3017
                        },
3018
                        menuselect: function( event, ui ) {
3019
                                var item = ui.item.data( "ui-autocomplete-item" ),
3020
                                        previous = this.previous;
3021

    
3022
                                // only trigger when focus was lost (click on menu)
3023
                                if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
3024
                                        this.element.focus();
3025
                                        this.previous = previous;
3026
                                        // #6109 - IE triggers two focus events and the second
3027
                                        // is asynchronous, so we need to reset the previous
3028
                                        // term synchronously and asynchronously :-(
3029
                                        this._delay(function() {
3030
                                                this.previous = previous;
3031
                                                this.selectedItem = item;
3032
                                        });
3033
                                }
3034

    
3035
                                if ( false !== this._trigger( "select", event, { item: item } ) ) {
3036
                                        this._value( item.value );
3037
                                }
3038
                                // reset the term after the select event
3039
                                // this allows custom select handling to work properly
3040
                                this.term = this._value();
3041

    
3042
                                this.close( event );
3043
                                this.selectedItem = item;
3044
                        }
3045
                });
3046

    
3047
                this.liveRegion = $( "<span>", {
3048
                                role: "status",
3049
                                "aria-live": "assertive",
3050
                                "aria-relevant": "additions"
3051
                        })
3052
                        .addClass( "ui-helper-hidden-accessible" )
3053
                        .appendTo( this.document[ 0 ].body );
3054

    
3055
                // turning off autocomplete prevents the browser from remembering the
3056
                // value when navigating through history, so we re-enable autocomplete
3057
                // if the page is unloaded before the widget is destroyed. #7790
3058
                this._on( this.window, {
3059
                        beforeunload: function() {
3060
                                this.element.removeAttr( "autocomplete" );
3061
                        }
3062
                });
3063
        },
3064

    
3065
        _destroy: function() {
3066
                clearTimeout( this.searching );
3067
                this.element
3068
                        .removeClass( "ui-autocomplete-input" )
3069
                        .removeAttr( "autocomplete" );
3070
                this.menu.element.remove();
3071
                this.liveRegion.remove();
3072
        },
3073

    
3074
        _setOption: function( key, value ) {
3075
                this._super( key, value );
3076
                if ( key === "source" ) {
3077
                        this._initSource();
3078
                }
3079
                if ( key === "appendTo" ) {
3080
                        this.menu.element.appendTo( this._appendTo() );
3081
                }
3082
                if ( key === "disabled" && value && this.xhr ) {
3083
                        this.xhr.abort();
3084
                }
3085
        },
3086

    
3087
        _appendTo: function() {
3088
                var element = this.options.appendTo;
3089

    
3090
                if ( element ) {
3091
                        element = element.jquery || element.nodeType ?
3092
                                $( element ) :
3093
                                this.document.find( element ).eq( 0 );
3094
                }
3095

    
3096
                if ( !element || !element[ 0 ] ) {
3097
                        element = this.element.closest( ".ui-front" );
3098
                }
3099

    
3100
                if ( !element.length ) {
3101
                        element = this.document[ 0 ].body;
3102
                }
3103

    
3104
                return element;
3105
        },
3106

    
3107
        _initSource: function() {
3108
                var array, url,
3109
                        that = this;
3110
                if ( $.isArray( this.options.source ) ) {
3111
                        array = this.options.source;
3112
                        this.source = function( request, response ) {
3113
                                response( $.ui.autocomplete.filter( array, request.term ) );
3114
                        };
3115
                } else if ( typeof this.options.source === "string" ) {
3116
                        url = this.options.source;
3117
                        this.source = function( request, response ) {
3118
                                if ( that.xhr ) {
3119
                                        that.xhr.abort();
3120
                                }
3121
                                that.xhr = $.ajax({
3122
                                        url: url,
3123
                                        data: request,
3124
                                        dataType: "json",
3125
                                        success: function( data ) {
3126
                                                response( data );
3127
                                        },
3128
                                        error: function() {
3129
                                                response([]);
3130
                                        }
3131
                                });
3132
                        };
3133
                } else {
3134
                        this.source = this.options.source;
3135
                }
3136
        },
3137

    
3138
        _searchTimeout: function( event ) {
3139
                clearTimeout( this.searching );
3140
                this.searching = this._delay(function() {
3141

    
3142
                        // Search if the value has changed, or if the user retypes the same value (see #7434)
3143
                        var equalValues = this.term === this._value(),
3144
                                menuVisible = this.menu.element.is( ":visible" ),
3145
                                modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
3146

    
3147
                        if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
3148
                                this.selectedItem = null;
3149
                                this.search( null, event );
3150
                        }
3151
                }, this.options.delay );
3152
        },
3153

    
3154
        search: function( value, event ) {
3155
                value = value != null ? value : this._value();
3156

    
3157
                // always save the actual value, not the one passed as an argument
3158
                this.term = this._value();
3159

    
3160
                if ( value.length < this.options.minLength ) {
3161
                        return this.close( event );
3162
                }
3163

    
3164
                if ( this._trigger( "search", event ) === false ) {
3165
                        return;
3166
                }
3167

    
3168
                return this._search( value );
3169
        },
3170

    
3171
        _search: function( value ) {
3172
                this.pending++;
3173
                this.element.addClass( "ui-autocomplete-loading" );
3174
                this.cancelSearch = false;
3175

    
3176
                this.source( { term: value }, this._response() );
3177
        },
3178

    
3179
        _response: function() {
3180
                var index = ++this.requestIndex;
3181

    
3182
                return $.proxy(function( content ) {
3183
                        if ( index === this.requestIndex ) {
3184
                                this.__response( content );
3185
                        }
3186

    
3187
                        this.pending--;
3188
                        if ( !this.pending ) {
3189
                                this.element.removeClass( "ui-autocomplete-loading" );
3190
                        }
3191
                }, this );
3192
        },
3193

    
3194
        __response: function( content ) {
3195
                if ( content ) {
3196
                        content = this._normalize( content );
3197
                }
3198
                this._trigger( "response", null, { content: content } );
3199
                if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
3200
                        this._suggest( content );
3201
                        this._trigger( "open" );
3202
                } else {
3203
                        // use ._close() instead of .close() so we don't cancel future searches
3204
                        this._close();
3205
                }
3206
        },
3207

    
3208
        close: function( event ) {
3209
                this.cancelSearch = true;
3210
                this._close( event );
3211
        },
3212

    
3213
        _close: function( event ) {
3214
                if ( this.menu.element.is( ":visible" ) ) {
3215
                        this.menu.element.hide();
3216
                        this.menu.blur();
3217
                        this.isNewMenu = true;
3218
                        this._trigger( "close", event );
3219
                }
3220
        },
3221

    
3222
        _change: function( event ) {
3223
                if ( this.previous !== this._value() ) {
3224
                        this._trigger( "change", event, { item: this.selectedItem } );
3225
                }
3226
        },
3227

    
3228
        _normalize: function( items ) {
3229
                // assume all items have the right format when the first item is complete
3230
                if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
3231
                        return items;
3232
                }
3233
                return $.map( items, function( item ) {
3234
                        if ( typeof item === "string" ) {
3235
                                return {
3236
                                        label: item,
3237
                                        value: item
3238
                                };
3239
                        }
3240
                        return $.extend( {}, item, {
3241
                                label: item.label || item.value,
3242
                                value: item.value || item.label
3243
                        });
3244
                });
3245
        },
3246

    
3247
        _suggest: function( items ) {
3248
                var ul = this.menu.element.empty();
3249
                this._renderMenu( ul, items );
3250
                this.isNewMenu = true;
3251
                this.menu.refresh();
3252

    
3253
                // size and position menu
3254
                ul.show();
3255
                this._resizeMenu();
3256
                ul.position( $.extend({
3257
                        of: this.element
3258
                }, this.options.position ) );
3259

    
3260
                if ( this.options.autoFocus ) {
3261
                        this.menu.next();
3262
                }
3263
        },
3264

    
3265
        _resizeMenu: function() {
3266
                var ul = this.menu.element;
3267
                ul.outerWidth( Math.max(
3268
                        // Firefox wraps long text (possibly a rounding bug)
3269
                        // so we add 1px to avoid the wrapping (#7513)
3270
                        ul.width( "" ).outerWidth() + 1,
3271
                        this.element.outerWidth()
3272
                ) );
3273
        },
3274

    
3275
        _renderMenu: function( ul, items ) {
3276
                var that = this;
3277
                $.each( items, function( index, item ) {
3278
                        that._renderItemData( ul, item );
3279
                });
3280
        },
3281

    
3282
        _renderItemData: function( ul, item ) {
3283
                return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
3284
        },
3285

    
3286
        _renderItem: function( ul, item ) {
3287
                return $( "<li>" ).text( item.label ).appendTo( ul );
3288
        },
3289

    
3290
        _move: function( direction, event ) {
3291
                if ( !this.menu.element.is( ":visible" ) ) {
3292
                        this.search( null, event );
3293
                        return;
3294
                }
3295
                if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
3296
                                this.menu.isLastItem() && /^next/.test( direction ) ) {
3297

    
3298
                        if ( !this.isMultiLine ) {
3299
                                this._value( this.term );
3300
                        }
3301

    
3302
                        this.menu.blur();
3303
                        return;
3304
                }
3305
                this.menu[ direction ]( event );
3306
        },
3307

    
3308
        widget: function() {
3309
                return this.menu.element;
3310
        },
3311

    
3312
        _value: function() {
3313
                return this.valueMethod.apply( this.element, arguments );
3314
        },
3315

    
3316
        _keyEvent: function( keyEvent, event ) {
3317
                if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
3318
                        this._move( keyEvent, event );
3319

    
3320
                        // prevents moving cursor to beginning/end of the text field in some browsers
3321
                        event.preventDefault();
3322
                }
3323
        }
3324
});
3325

    
3326
$.extend( $.ui.autocomplete, {
3327
        escapeRegex: function( value ) {
3328
                return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
3329
        },
3330
        filter: function( array, term ) {
3331
                var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
3332
                return $.grep( array, function( value ) {
3333
                        return matcher.test( value.label || value.value || value );
3334
                });
3335
        }
3336
});
3337

    
3338
// live region extension, adding a `messages` option
3339
// NOTE: This is an experimental API. We are still investigating
3340
// a full solution for string manipulation and internationalization.
3341
$.widget( "ui.autocomplete", $.ui.autocomplete, {
3342
        options: {
3343
                messages: {
3344
                        noResults: "No search results.",
3345
                        results: function( amount ) {
3346
                                return amount + ( amount > 1 ? " results are" : " result is" ) +
3347
                                        " available, use up and down arrow keys to navigate.";
3348
                        }
3349
                }
3350
        },
3351

    
3352
        __response: function( content ) {
3353
                var message;
3354
                this._superApply( arguments );
3355
                if ( this.options.disabled || this.cancelSearch ) {
3356
                        return;
3357
                }
3358
                if ( content && content.length ) {
3359
                        message = this.options.messages.results( content.length );
3360
                } else {
3361
                        message = this.options.messages.noResults;
3362
                }
3363
                this.liveRegion.children().hide();
3364
                $( "<div>" ).text( message ).appendTo( this.liveRegion );
3365
        }
3366
});
3367

    
3368
var autocomplete = $.ui.autocomplete;
3369

    
3370

    
3371
/*!
3372
 * jQuery UI Button 1.11.4
3373
 * http://jqueryui.com
3374
 *
3375
 * Copyright jQuery Foundation and other contributors
3376
 * Released under the MIT license.
3377
 * http://jquery.org/license
3378
 *
3379
 * http://api.jqueryui.com/button/
3380
 */
3381

    
3382

    
3383
var lastActive,
3384
        baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
3385
        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",
3386
        formResetHandler = function() {
3387
                var form = $( this );
3388
                setTimeout(function() {
3389
                        form.find( ":ui-button" ).button( "refresh" );
3390
                }, 1 );
3391
        },
3392
        radioGroup = function( radio ) {
3393
                var name = radio.name,
3394
                        form = radio.form,
3395
                        radios = $( [] );
3396
                if ( name ) {
3397
                        name = name.replace( /'/g, "\\'" );
3398
                        if ( form ) {
3399
                                radios = $( form ).find( "[name='" + name + "'][type=radio]" );
3400
                        } else {
3401
                                radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
3402
                                        .filter(function() {
3403
                                                return !this.form;
3404
                                        });
3405
                        }
3406
                }
3407
                return radios;
3408
        };
3409

    
3410
$.widget( "ui.button", {
3411
        version: "1.11.4",
3412
        defaultElement: "<button>",
3413
        options: {
3414
                disabled: null,
3415
                text: true,
3416
                label: null,
3417
                icons: {
3418
                        primary: null,
3419
                        secondary: null
3420
                }
3421
        },
3422
        _create: function() {
3423
                this.element.closest( "form" )
3424
                        .unbind( "reset" + this.eventNamespace )
3425
                        .bind( "reset" + this.eventNamespace, formResetHandler );
3426

    
3427
                if ( typeof this.options.disabled !== "boolean" ) {
3428
                        this.options.disabled = !!this.element.prop( "disabled" );
3429
                } else {
3430
                        this.element.prop( "disabled", this.options.disabled );
3431
                }
3432

    
3433
                this._determineButtonType();
3434
                this.hasTitle = !!this.buttonElement.attr( "title" );
3435

    
3436
                var that = this,
3437
                        options = this.options,
3438
                        toggleButton = this.type === "checkbox" || this.type === "radio",
3439
                        activeClass = !toggleButton ? "ui-state-active" : "";
3440

    
3441
                if ( options.label === null ) {
3442
                        options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
3443
                }
3444

    
3445
                this._hoverable( this.buttonElement );
3446

    
3447
                this.buttonElement
3448
                        .addClass( baseClasses )
3449
                        .attr( "role", "button" )
3450
                        .bind( "mouseenter" + this.eventNamespace, function() {
3451
                                if ( options.disabled ) {
3452
                                        return;
3453
                                }
3454
                                if ( this === lastActive ) {
3455
                                        $( this ).addClass( "ui-state-active" );
3456
                                }
3457
                        })
3458
                        .bind( "mouseleave" + this.eventNamespace, function() {
3459
                                if ( options.disabled ) {
3460
                                        return;
3461
                                }
3462
                                $( this ).removeClass( activeClass );
3463
                        })
3464
                        .bind( "click" + this.eventNamespace, function( event ) {
3465
                                if ( options.disabled ) {
3466
                                        event.preventDefault();
3467
                                        event.stopImmediatePropagation();
3468
                                }
3469
                        });
3470

    
3471
                // Can't use _focusable() because the element that receives focus
3472
                // and the element that gets the ui-state-focus class are different
3473
                this._on({
3474
                        focus: function() {
3475
                                this.buttonElement.addClass( "ui-state-focus" );
3476
                        },
3477
                        blur: function() {
3478
                                this.buttonElement.removeClass( "ui-state-focus" );
3479
                        }
3480
                });
3481

    
3482
                if ( toggleButton ) {
3483
                        this.element.bind( "change" + this.eventNamespace, function() {
3484
                                that.refresh();
3485
                        });
3486
                }
3487

    
3488
                if ( this.type === "checkbox" ) {
3489
                        this.buttonElement.bind( "click" + this.eventNamespace, function() {
3490
                                if ( options.disabled ) {
3491
                                        return false;
3492
                                }
3493
                        });
3494
                } else if ( this.type === "radio" ) {
3495
                        this.buttonElement.bind( "click" + this.eventNamespace, function() {
3496
                                if ( options.disabled ) {
3497
                                        return false;
3498
                                }
3499
                                $( this ).addClass( "ui-state-active" );
3500
                                that.buttonElement.attr( "aria-pressed", "true" );
3501

    
3502
                                var radio = that.element[ 0 ];
3503
                                radioGroup( radio )
3504
                                        .not( radio )
3505
                                        .map(function() {
3506
                                                return $( this ).button( "widget" )[ 0 ];
3507
                                        })
3508
                                        .removeClass( "ui-state-active" )
3509
                                        .attr( "aria-pressed", "false" );
3510
                        });
3511
                } else {
3512
                        this.buttonElement
3513
                                .bind( "mousedown" + this.eventNamespace, function() {
3514
                                        if ( options.disabled ) {
3515
                                                return false;
3516
                                        }
3517
                                        $( this ).addClass( "ui-state-active" );
3518
                                        lastActive = this;
3519
                                        that.document.one( "mouseup", function() {
3520
                                                lastActive = null;
3521
                                        });
3522
                                })
3523
                                .bind( "mouseup" + this.eventNamespace, function() {
3524
                                        if ( options.disabled ) {
3525
                                                return false;
3526
                                        }
3527
                                        $( this ).removeClass( "ui-state-active" );
3528
                                })
3529
                                .bind( "keydown" + this.eventNamespace, function(event) {
3530
                                        if ( options.disabled ) {
3531
                                                return false;
3532
                                        }
3533
                                        if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
3534
                                                $( this ).addClass( "ui-state-active" );
3535
                                        }
3536
                                })
3537
                                // see #8559, we bind to blur here in case the button element loses
3538
                                // focus between keydown and keyup, it would be left in an "active" state
3539
                                .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
3540
                                        $( this ).removeClass( "ui-state-active" );
3541
                                });
3542

    
3543
                        if ( this.buttonElement.is("a") ) {
3544
                                this.buttonElement.keyup(function(event) {
3545
                                        if ( event.keyCode === $.ui.keyCode.SPACE ) {
3546
                                                // TODO pass through original event correctly (just as 2nd argument doesn't work)
3547
                                                $( this ).click();
3548
                                        }
3549
                                });
3550
                        }
3551
                }
3552

    
3553
                this._setOption( "disabled", options.disabled );
3554
                this._resetButton();
3555
        },
3556

    
3557
        _determineButtonType: function() {
3558
                var ancestor, labelSelector, checked;
3559

    
3560
                if ( this.element.is("[type=checkbox]") ) {
3561
                        this.type = "checkbox";
3562
                } else if ( this.element.is("[type=radio]") ) {
3563
                        this.type = "radio";
3564
                } else if ( this.element.is("input") ) {
3565
                        this.type = "input";
3566
                } else {
3567
                        this.type = "button";
3568
                }
3569

    
3570
                if ( this.type === "checkbox" || this.type === "radio" ) {
3571
                        // we don't search against the document in case the element
3572
                        // is disconnected from the DOM
3573
                        ancestor = this.element.parents().last();
3574
                        labelSelector = "label[for='" + this.element.attr("id") + "']";
3575
                        this.buttonElement = ancestor.find( labelSelector );
3576
                        if ( !this.buttonElement.length ) {
3577
                                ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
3578
                                this.buttonElement = ancestor.filter( labelSelector );
3579
                                if ( !this.buttonElement.length ) {
3580
                                        this.buttonElement = ancestor.find( labelSelector );
3581
                                }
3582
                        }
3583
                        this.element.addClass( "ui-helper-hidden-accessible" );
3584

    
3585
                        checked = this.element.is( ":checked" );
3586
                        if ( checked ) {
3587
                                this.buttonElement.addClass( "ui-state-active" );
3588
                        }
3589
                        this.buttonElement.prop( "aria-pressed", checked );
3590
                } else {
3591
                        this.buttonElement = this.element;
3592
                }
3593
        },
3594

    
3595
        widget: function() {
3596
                return this.buttonElement;
3597
        },
3598

    
3599
        _destroy: function() {
3600
                this.element
3601
                        .removeClass( "ui-helper-hidden-accessible" );
3602
                this.buttonElement
3603
                        .removeClass( baseClasses + " ui-state-active " + typeClasses )
3604
                        .removeAttr( "role" )
3605
                        .removeAttr( "aria-pressed" )
3606
                        .html( this.buttonElement.find(".ui-button-text").html() );
3607

    
3608
                if ( !this.hasTitle ) {
3609
                        this.buttonElement.removeAttr( "title" );
3610
                }
3611
        },
3612

    
3613
        _setOption: function( key, value ) {
3614
                this._super( key, value );
3615
                if ( key === "disabled" ) {
3616
                        this.widget().toggleClass( "ui-state-disabled", !!value );
3617
                        this.element.prop( "disabled", !!value );
3618
                        if ( value ) {
3619
                                if ( this.type === "checkbox" || this.type === "radio" ) {
3620
                                        this.buttonElement.removeClass( "ui-state-focus" );
3621
                                } else {
3622
                                        this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
3623
                                }
3624
                        }
3625
                        return;
3626
                }
3627
                this._resetButton();
3628
        },
3629

    
3630
        refresh: function() {
3631
                //See #8237 & #8828
3632
                var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
3633

    
3634
                if ( isDisabled !== this.options.disabled ) {
3635
                        this._setOption( "disabled", isDisabled );
3636
                }
3637
                if ( this.type === "radio" ) {
3638
                        radioGroup( this.element[0] ).each(function() {
3639
                                if ( $( this ).is( ":checked" ) ) {
3640
                                        $( this ).button( "widget" )
3641
                                                .addClass( "ui-state-active" )
3642
                                                .attr( "aria-pressed", "true" );
3643
                                } else {
3644
                                        $( this ).button( "widget" )
3645
                                                .removeClass( "ui-state-active" )
3646
                                                .attr( "aria-pressed", "false" );
3647
                                }
3648
                        });
3649
                } else if ( this.type === "checkbox" ) {
3650
                        if ( this.element.is( ":checked" ) ) {
3651
                                this.buttonElement
3652
                                        .addClass( "ui-state-active" )
3653
                                        .attr( "aria-pressed", "true" );
3654
                        } else {
3655
                                this.buttonElement
3656
                                        .removeClass( "ui-state-active" )
3657
                                        .attr( "aria-pressed", "false" );
3658
                        }
3659
                }
3660
        },
3661

    
3662
        _resetButton: function() {
3663
                if ( this.type === "input" ) {
3664
                        if ( this.options.label ) {
3665
                                this.element.val( this.options.label );
3666
                        }
3667
                        return;
3668
                }
3669
                var buttonElement = this.buttonElement.removeClass( typeClasses ),
3670
                        buttonText = $( "<span></span>", this.document[0] )
3671
                                .addClass( "ui-button-text" )
3672
                                .html( this.options.label )
3673
                                .appendTo( buttonElement.empty() )
3674
                                .text(),
3675
                        icons = this.options.icons,
3676
                        multipleIcons = icons.primary && icons.secondary,
3677
                        buttonClasses = [];
3678

    
3679
                if ( icons.primary || icons.secondary ) {
3680
                        if ( this.options.text ) {
3681
                                buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
3682
                        }
3683

    
3684
                        if ( icons.primary ) {
3685
                                buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
3686
                        }
3687

    
3688
                        if ( icons.secondary ) {
3689
                                buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
3690
                        }
3691

    
3692
                        if ( !this.options.text ) {
3693
                                buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
3694

    
3695
                                if ( !this.hasTitle ) {
3696
                                        buttonElement.attr( "title", $.trim( buttonText ) );
3697
                                }
3698
                        }
3699
                } else {
3700
                        buttonClasses.push( "ui-button-text-only" );
3701
                }
3702
                buttonElement.addClass( buttonClasses.join( " " ) );
3703
        }
3704
});
3705

    
3706
$.widget( "ui.buttonset", {
3707
        version: "1.11.4",
3708
        options: {
3709
                items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
3710
        },
3711

    
3712
        _create: function() {
3713
                this.element.addClass( "ui-buttonset" );
3714
        },
3715

    
3716
        _init: function() {
3717
                this.refresh();
3718
        },
3719

    
3720
        _setOption: function( key, value ) {
3721
                if ( key === "disabled" ) {
3722
                        this.buttons.button( "option", key, value );
3723
                }
3724

    
3725
                this._super( key, value );
3726
        },
3727

    
3728
        refresh: function() {
3729
                var rtl = this.element.css( "direction" ) === "rtl",
3730
                        allButtons = this.element.find( this.options.items ),
3731
                        existingButtons = allButtons.filter( ":ui-button" );
3732

    
3733
                // Initialize new buttons
3734
                allButtons.not( ":ui-button" ).button();
3735

    
3736
                // Refresh existing buttons
3737
                existingButtons.button( "refresh" );
3738

    
3739
                this.buttons = allButtons
3740
                        .map(function() {
3741
                                return $( this ).button( "widget" )[ 0 ];
3742
                        })
3743
                                .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
3744
                                .filter( ":first" )
3745
                                        .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
3746
                                .end()
3747
                                .filter( ":last" )
3748
                                        .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
3749
                                .end()
3750
                        .end();
3751
        },
3752

    
3753
        _destroy: function() {
3754
                this.element.removeClass( "ui-buttonset" );
3755
                this.buttons
3756
                        .map(function() {
3757
                                return $( this ).button( "widget" )[ 0 ];
3758
                        })
3759
                                .removeClass( "ui-corner-left ui-corner-right" )
3760
                        .end()
3761
                        .button( "destroy" );
3762
        }
3763
});
3764

    
3765
var button = $.ui.button;
3766

    
3767

    
3768
/*!
3769
 * jQuery UI Datepicker 1.11.4
3770
 * http://jqueryui.com
3771
 *
3772
 * Copyright jQuery Foundation and other contributors
3773
 * Released under the MIT license.
3774
 * http://jquery.org/license
3775
 *
3776
 * http://api.jqueryui.com/datepicker/
3777
 */
3778

    
3779

    
3780
$.extend($.ui, { datepicker: { version: "1.11.4" } });
3781

    
3782
var datepicker_instActive;
3783

    
3784
function datepicker_getZindex( elem ) {
3785
        var position, value;
3786
        while ( elem.length && elem[ 0 ] !== document ) {
3787
                // Ignore z-index if position is set to a value where z-index is ignored by the browser
3788
                // This makes behavior of this function consistent across browsers
3789
                // WebKit always returns auto if the element is positioned
3790
                position = elem.css( "position" );
3791
                if ( position === "absolute" || position === "relative" || position === "fixed" ) {
3792
                        // IE returns 0 when zIndex is not specified
3793
                        // other browsers return a string
3794
                        // we ignore the case of nested elements with an explicit value of 0
3795
                        // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
3796
                        value = parseInt( elem.css( "zIndex" ), 10 );
3797
                        if ( !isNaN( value ) && value !== 0 ) {
3798
                                return value;
3799
                        }
3800
                }
3801
                elem = elem.parent();
3802
        }
3803

    
3804
        return 0;
3805
}
3806
/* Date picker manager.
3807
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
3808
   Settings for (groups of) date pickers are maintained in an instance object,
3809
   allowing multiple different settings on the same page. */
3810

    
3811
function Datepicker() {
3812
        this._curInst = null; // The current instance in use
3813
        this._keyEvent = false; // If the last event was a key event
3814
        this._disabledInputs = []; // List of date picker inputs that have been disabled
3815
        this._datepickerShowing = false; // True if the popup picker is showing , false if not
3816
        this._inDialog = false; // True if showing within a "dialog", false if not
3817
        this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
3818
        this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
3819
        this._appendClass = "ui-datepicker-append"; // The name of the append marker class
3820
        this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
3821
        this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
3822
        this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
3823
        this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
3824
        this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
3825
        this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
3826
        this.regional = []; // Available regional settings, indexed by language code
3827
        this.regional[""] = { // Default regional settings
3828
                closeText: "Done", // Display text for close link
3829
                prevText: "Prev", // Display text for previous month link
3830
                nextText: "Next", // Display text for next month link
3831
                currentText: "Today", // Display text for current month link
3832
                monthNames: ["January","February","March","April","May","June",
3833
                        "July","August","September","October","November","December"], // Names of months for drop-down and formatting
3834
                monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
3835
                dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
3836
                dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
3837
                dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
3838
                weekHeader: "Wk", // Column header for week of the year
3839
                dateFormat: "mm/dd/yy", // See format options on parseDate
3840
                firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
3841
                isRTL: false, // True if right-to-left language, false if left-to-right
3842
                showMonthAfterYear: false, // True if the year select precedes month, false for month then year
3843
                yearSuffix: "" // Additional text to append to the year in the month headers
3844
        };
3845
        this._defaults = { // Global defaults for all the date picker instances
3846
                showOn: "focus", // "focus" for popup on focus,
3847
                        // "button" for trigger button, or "both" for either
3848
                showAnim: "fadeIn", // Name of jQuery animation for popup
3849
                showOptions: {}, // Options for enhanced animations
3850
                defaultDate: null, // Used when field is blank: actual date,
3851
                        // +/-number for offset from today, null for today
3852
                appendText: "", // Display text following the input box, e.g. showing the format
3853
                buttonText: "...", // Text for trigger button
3854
                buttonImage: "", // URL for trigger button image
3855
                buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
3856
                hideIfNoPrevNext: false, // True to hide next/previous month links
3857
                        // if not applicable, false to just disable them
3858
                navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
3859
                gotoCurrent: false, // True if today link goes back to current selection instead
3860
                changeMonth: false, // True if month can be selected directly, false if only prev/next
3861
                changeYear: false, // True if year can be selected directly, false if only prev/next
3862
                yearRange: "c-10:c+10", // Range of years to display in drop-down,
3863
                        // either relative to today's year (-nn:+nn), relative to currently displayed year
3864
                        // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
3865
                showOtherMonths: false, // True to show dates in other months, false to leave blank
3866
                selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
3867
                showWeek: false, // True to show week of the year, false to not show it
3868
                calculateWeek: this.iso8601Week, // How to calculate the week of the year,
3869
                        // takes a Date and returns the number of the week for it
3870
                shortYearCutoff: "+10", // Short year values < this are in the current century,
3871
                        // > this are in the previous century,
3872
                        // string value starting with "+" for current year + value
3873
                minDate: null, // The earliest selectable date, or null for no limit
3874
                maxDate: null, // The latest selectable date, or null for no limit
3875
                duration: "fast", // Duration of display/closure
3876
                beforeShowDay: null, // Function that takes a date and returns an array with
3877
                        // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
3878
                        // [2] = cell title (optional), e.g. $.datepicker.noWeekends
3879
                beforeShow: null, // Function that takes an input field and
3880
                        // returns a set of custom settings for the date picker
3881
                onSelect: null, // Define a callback function when a date is selected
3882
                onChangeMonthYear: null, // Define a callback function when the month or year is changed
3883
                onClose: null, // Define a callback function when the datepicker is closed
3884
                numberOfMonths: 1, // Number of months to show at a time
3885
                showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
3886
                stepMonths: 1, // Number of months to step back/forward
3887
                stepBigMonths: 12, // Number of months to step back/forward for the big links
3888
                altField: "", // Selector for an alternate field to store selected dates into
3889
                altFormat: "", // The date format to use for the alternate field
3890
                constrainInput: true, // The input is constrained by the current date format
3891
                showButtonPanel: false, // True to show button panel, false to not show it
3892
                autoSize: false, // True to size the input for the date format, false to leave as is
3893
                disabled: false // The initial disabled state
3894
        };
3895
        $.extend(this._defaults, this.regional[""]);
3896
        this.regional.en = $.extend( true, {}, this.regional[ "" ]);
3897
        this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
3898
        this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
3899
}
3900

    
3901
$.extend(Datepicker.prototype, {
3902
        /* Class name added to elements to indicate already configured with a date picker. */
3903
        markerClassName: "hasDatepicker",
3904

    
3905
        //Keep track of the maximum number of rows displayed (see #7043)
3906
        maxRows: 4,
3907

    
3908
        // TODO rename to "widget" when switching to widget factory
3909
        _widgetDatepicker: function() {
3910
                return this.dpDiv;
3911
        },
3912

    
3913
        /* Override the default settings for all instances of the date picker.
3914
         * @param  settings  object - the new settings to use as defaults (anonymous object)
3915
         * @return the manager object
3916
         */
3917
        setDefaults: function(settings) {
3918
                datepicker_extendRemove(this._defaults, settings || {});
3919
                return this;
3920
        },
3921

    
3922
        /* Attach the date picker to a jQuery selection.
3923
         * @param  target        element - the target input field or division or span
3924
         * @param  settings  object - the new settings to use for this date picker instance (anonymous)
3925
         */
3926
        _attachDatepicker: function(target, settings) {
3927
                var nodeName, inline, inst;
3928
                nodeName = target.nodeName.toLowerCase();
3929
                inline = (nodeName === "div" || nodeName === "span");
3930
                if (!target.id) {
3931
                        this.uuid += 1;
3932
                        target.id = "dp" + this.uuid;
3933
                }
3934
                inst = this._newInst($(target), inline);
3935
                inst.settings = $.extend({}, settings || {});
3936
                if (nodeName === "input") {
3937
                        this._connectDatepicker(target, inst);
3938
                } else if (inline) {
3939
                        this._inlineDatepicker(target, inst);
3940
                }
3941
        },
3942

    
3943
        /* Create a new instance object. */
3944
        _newInst: function(target, inline) {
3945
                var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
3946
                return {id: id, input: target, // associated target
3947
                        selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
3948
                        drawMonth: 0, drawYear: 0, // month being drawn
3949
                        inline: inline, // is datepicker inline or not
3950
                        dpDiv: (!inline ? this.dpDiv : // presentation div
3951
                        datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
3952
        },
3953

    
3954
        /* Attach the date picker to an input field. */
3955
        _connectDatepicker: function(target, inst) {
3956
                var input = $(target);
3957
                inst.append = $([]);
3958
                inst.trigger = $([]);
3959
                if (input.hasClass(this.markerClassName)) {
3960
                        return;
3961
                }
3962
                this._attachments(input, inst);
3963
                input.addClass(this.markerClassName).keydown(this._doKeyDown).
3964
                        keypress(this._doKeyPress).keyup(this._doKeyUp);
3965
                this._autoSize(inst);
3966
                $.data(target, "datepicker", inst);
3967
                //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
3968
                if( inst.settings.disabled ) {
3969
                        this._disableDatepicker( target );
3970
                }
3971
        },
3972

    
3973
        /* Make attachments based on settings. */
3974
        _attachments: function(input, inst) {
3975
                var showOn, buttonText, buttonImage,
3976
                        appendText = this._get(inst, "appendText"),
3977
                        isRTL = this._get(inst, "isRTL");
3978

    
3979
                if (inst.append) {
3980
                        inst.append.remove();
3981
                }
3982
                if (appendText) {
3983
                        inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
3984
                        input[isRTL ? "before" : "after"](inst.append);
3985
                }
3986

    
3987
                input.unbind("focus", this._showDatepicker);
3988

    
3989
                if (inst.trigger) {
3990
                        inst.trigger.remove();
3991
                }
3992

    
3993
                showOn = this._get(inst, "showOn");
3994
                if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
3995
                        input.focus(this._showDatepicker);
3996
                }
3997
                if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
3998
                        buttonText = this._get(inst, "buttonText");
3999
                        buttonImage = this._get(inst, "buttonImage");
4000
                        inst.trigger = $(this._get(inst, "buttonImageOnly") ?
4001
                                $("<img/>").addClass(this._triggerClass).
4002
                                        attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
4003
                                $("<button type='button'></button>").addClass(this._triggerClass).
4004
                                        html(!buttonImage ? buttonText : $("<img/>").attr(
4005
                                        { src:buttonImage, alt:buttonText, title:buttonText })));
4006
                        input[isRTL ? "before" : "after"](inst.trigger);
4007
                        inst.trigger.click(function() {
4008
                                if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
4009
                                        $.datepicker._hideDatepicker();
4010
                                } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
4011
                                        $.datepicker._hideDatepicker();
4012
                                        $.datepicker._showDatepicker(input[0]);
4013
                                } else {
4014
                                        $.datepicker._showDatepicker(input[0]);
4015
                                }
4016
                                return false;
4017
                        });
4018
                }
4019
        },
4020

    
4021
        /* Apply the maximum length for the date format. */
4022
        _autoSize: function(inst) {
4023
                if (this._get(inst, "autoSize") && !inst.inline) {
4024
                        var findMax, max, maxI, i,
4025
                                date = new Date(2009, 12 - 1, 20), // Ensure double digits
4026
                                dateFormat = this._get(inst, "dateFormat");
4027

    
4028
                        if (dateFormat.match(/[DM]/)) {
4029
                                findMax = function(names) {
4030
                                        max = 0;
4031
                                        maxI = 0;
4032
                                        for (i = 0; i < names.length; i++) {
4033
                                                if (names[i].length > max) {
4034
                                                        max = names[i].length;
4035
                                                        maxI = i;
4036
                                                }
4037
                                        }
4038
                                        return maxI;
4039
                                };
4040
                                date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
4041
                                        "monthNames" : "monthNamesShort"))));
4042
                                date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
4043
                                        "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
4044
                        }
4045
                        inst.input.attr("size", this._formatDate(inst, date).length);
4046
                }
4047
        },
4048

    
4049
        /* Attach an inline date picker to a div. */
4050
        _inlineDatepicker: function(target, inst) {
4051
                var divSpan = $(target);
4052
                if (divSpan.hasClass(this.markerClassName)) {
4053
                        return;
4054
                }
4055
                divSpan.addClass(this.markerClassName).append(inst.dpDiv);
4056
                $.data(target, "datepicker", inst);
4057
                this._setDate(inst, this._getDefaultDate(inst), true);
4058
                this._updateDatepicker(inst);
4059
                this._updateAlternate(inst);
4060
                //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
4061
                if( inst.settings.disabled ) {
4062
                        this._disableDatepicker( target );
4063
                }
4064
                // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
4065
                // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
4066
                inst.dpDiv.css( "display", "block" );
4067
        },
4068

    
4069
        /* Pop-up the date picker in a "dialog" box.
4070
         * @param  input element - ignored
4071
         * @param  date        string or Date - the initial date to display
4072
         * @param  onSelect  function - the function to call when a date is selected
4073
         * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
4074
         * @param  pos int[2] - coordinates for the dialog's position within the screen or
4075
         *                                        event - with x/y coordinates or
4076
         *                                        leave empty for default (screen centre)
4077
         * @return the manager object
4078
         */
4079
        _dialogDatepicker: function(input, date, onSelect, settings, pos) {
4080
                var id, browserWidth, browserHeight, scrollX, scrollY,
4081
                        inst = this._dialogInst; // internal instance
4082

    
4083
                if (!inst) {
4084
                        this.uuid += 1;
4085
                        id = "dp" + this.uuid;
4086
                        this._dialogInput = $("<input type='text' id='" + id +
4087
                                "' style='position: absolute; top: -100px; width: 0px;'/>");
4088
                        this._dialogInput.keydown(this._doKeyDown);
4089
                        $("body").append(this._dialogInput);
4090
                        inst = this._dialogInst = this._newInst(this._dialogInput, false);
4091
                        inst.settings = {};
4092
                        $.data(this._dialogInput[0], "datepicker", inst);
4093
                }
4094
                datepicker_extendRemove(inst.settings, settings || {});
4095
                date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
4096
                this._dialogInput.val(date);
4097

    
4098
                this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
4099
                if (!this._pos) {
4100
                        browserWidth = document.documentElement.clientWidth;
4101
                        browserHeight = document.documentElement.clientHeight;
4102
                        scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
4103
                        scrollY = document.documentElement.scrollTop || document.body.scrollTop;
4104
                        this._pos = // should use actual width/height below
4105
                                [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
4106
                }
4107

    
4108
                // move input on screen for focus, but hidden behind dialog
4109
                this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
4110
                inst.settings.onSelect = onSelect;
4111
                this._inDialog = true;
4112
                this.dpDiv.addClass(this._dialogClass);
4113
                this._showDatepicker(this._dialogInput[0]);
4114
                if ($.blockUI) {
4115
                        $.blockUI(this.dpDiv);
4116
                }
4117
                $.data(this._dialogInput[0], "datepicker", inst);
4118
                return this;
4119
        },
4120

    
4121
        /* Detach a datepicker from its control.
4122
         * @param  target        element - the target input field or division or span
4123
         */
4124
        _destroyDatepicker: function(target) {
4125
                var nodeName,
4126
                        $target = $(target),
4127
                        inst = $.data(target, "datepicker");
4128

    
4129
                if (!$target.hasClass(this.markerClassName)) {
4130
                        return;
4131
                }
4132

    
4133
                nodeName = target.nodeName.toLowerCase();
4134
                $.removeData(target, "datepicker");
4135
                if (nodeName === "input") {
4136
                        inst.append.remove();
4137
                        inst.trigger.remove();
4138
                        $target.removeClass(this.markerClassName).
4139
                                unbind("focus", this._showDatepicker).
4140
                                unbind("keydown", this._doKeyDown).
4141
                                unbind("keypress", this._doKeyPress).
4142
                                unbind("keyup", this._doKeyUp);
4143
                } else if (nodeName === "div" || nodeName === "span") {
4144
                        $target.removeClass(this.markerClassName).empty();
4145
                }
4146

    
4147
                if ( datepicker_instActive === inst ) {
4148
                        datepicker_instActive = null;
4149
                }
4150
        },
4151

    
4152
        /* Enable the date picker to a jQuery selection.
4153
         * @param  target        element - the target input field or division or span
4154
         */
4155
        _enableDatepicker: function(target) {
4156
                var nodeName, inline,
4157
                        $target = $(target),
4158
                        inst = $.data(target, "datepicker");
4159

    
4160
                if (!$target.hasClass(this.markerClassName)) {
4161
                        return;
4162
                }
4163

    
4164
                nodeName = target.nodeName.toLowerCase();
4165
                if (nodeName === "input") {
4166
                        target.disabled = false;
4167
                        inst.trigger.filter("button").
4168
                                each(function() { this.disabled = false; }).end().
4169
                                filter("img").css({opacity: "1.0", cursor: ""});
4170
                } else if (nodeName === "div" || nodeName === "span") {
4171
                        inline = $target.children("." + this._inlineClass);
4172
                        inline.children().removeClass("ui-state-disabled");
4173
                        inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4174
                                prop("disabled", false);
4175
                }
4176
                this._disabledInputs = $.map(this._disabledInputs,
4177
                        function(value) { return (value === target ? null : value); }); // delete entry
4178
        },
4179

    
4180
        /* Disable the date picker to a jQuery selection.
4181
         * @param  target        element - the target input field or division or span
4182
         */
4183
        _disableDatepicker: function(target) {
4184
                var nodeName, inline,
4185
                        $target = $(target),
4186
                        inst = $.data(target, "datepicker");
4187

    
4188
                if (!$target.hasClass(this.markerClassName)) {
4189
                        return;
4190
                }
4191

    
4192
                nodeName = target.nodeName.toLowerCase();
4193
                if (nodeName === "input") {
4194
                        target.disabled = true;
4195
                        inst.trigger.filter("button").
4196
                                each(function() { this.disabled = true; }).end().
4197
                                filter("img").css({opacity: "0.5", cursor: "default"});
4198
                } else if (nodeName === "div" || nodeName === "span") {
4199
                        inline = $target.children("." + this._inlineClass);
4200
                        inline.children().addClass("ui-state-disabled");
4201
                        inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4202
                                prop("disabled", true);
4203
                }
4204
                this._disabledInputs = $.map(this._disabledInputs,
4205
                        function(value) { return (value === target ? null : value); }); // delete entry
4206
                this._disabledInputs[this._disabledInputs.length] = target;
4207
        },
4208

    
4209
        /* Is the first field in a jQuery collection disabled as a datepicker?
4210
         * @param  target        element - the target input field or division or span
4211
         * @return boolean - true if disabled, false if enabled
4212
         */
4213
        _isDisabledDatepicker: function(target) {
4214
                if (!target) {
4215
                        return false;
4216
                }
4217
                for (var i = 0; i < this._disabledInputs.length; i++) {
4218
                        if (this._disabledInputs[i] === target) {
4219
                                return true;
4220
                        }
4221
                }
4222
                return false;
4223
        },
4224

    
4225
        /* Retrieve the instance data for the target control.
4226
         * @param  target  element - the target input field or division or span
4227
         * @return  object - the associated instance data
4228
         * @throws  error if a jQuery problem getting data
4229
         */
4230
        _getInst: function(target) {
4231
                try {
4232
                        return $.data(target, "datepicker");
4233
                }
4234
                catch (err) {
4235
                        throw "Missing instance data for this datepicker";
4236
                }
4237
        },
4238

    
4239
        /* Update or retrieve the settings for a date picker attached to an input field or division.
4240
         * @param  target  element - the target input field or division or span
4241
         * @param  name        object - the new settings to update or
4242
         *                                string - the name of the setting to change or retrieve,
4243
         *                                when retrieving also "all" for all instance settings or
4244
         *                                "defaults" for all global defaults
4245
         * @param  value   any - the new value for the setting
4246
         *                                (omit if above is an object or to retrieve a value)
4247
         */
4248
        _optionDatepicker: function(target, name, value) {
4249
                var settings, date, minDate, maxDate,
4250
                        inst = this._getInst(target);
4251

    
4252
                if (arguments.length === 2 && typeof name === "string") {
4253
                        return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
4254
                                (inst ? (name === "all" ? $.extend({}, inst.settings) :
4255
                                this._get(inst, name)) : null));
4256
                }
4257

    
4258
                settings = name || {};
4259
                if (typeof name === "string") {
4260
                        settings = {};
4261
                        settings[name] = value;
4262
                }
4263

    
4264
                if (inst) {
4265
                        if (this._curInst === inst) {
4266
                                this._hideDatepicker();
4267
                        }
4268

    
4269
                        date = this._getDateDatepicker(target, true);
4270
                        minDate = this._getMinMaxDate(inst, "min");
4271
                        maxDate = this._getMinMaxDate(inst, "max");
4272
                        datepicker_extendRemove(inst.settings, settings);
4273
                        // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
4274
                        if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
4275
                                inst.settings.minDate = this._formatDate(inst, minDate);
4276
                        }
4277
                        if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
4278
                                inst.settings.maxDate = this._formatDate(inst, maxDate);
4279
                        }
4280
                        if ( "disabled" in settings ) {
4281
                                if ( settings.disabled ) {
4282
                                        this._disableDatepicker(target);
4283
                                } else {
4284
                                        this._enableDatepicker(target);
4285
                                }
4286
                        }
4287
                        this._attachments($(target), inst);
4288
                        this._autoSize(inst);
4289
                        this._setDate(inst, date);
4290
                        this._updateAlternate(inst);
4291
                        this._updateDatepicker(inst);
4292
                }
4293
        },
4294

    
4295
        // change method deprecated
4296
        _changeDatepicker: function(target, name, value) {
4297
                this._optionDatepicker(target, name, value);
4298
        },
4299

    
4300
        /* Redraw the date picker attached to an input field or division.
4301
         * @param  target  element - the target input field or division or span
4302
         */
4303
        _refreshDatepicker: function(target) {
4304
                var inst = this._getInst(target);
4305
                if (inst) {
4306
                        this._updateDatepicker(inst);
4307
                }
4308
        },
4309

    
4310
        /* Set the dates for a jQuery selection.
4311
         * @param  target element - the target input field or division or span
4312
         * @param  date        Date - the new date
4313
         */
4314
        _setDateDatepicker: function(target, date) {
4315
                var inst = this._getInst(target);
4316
                if (inst) {
4317
                        this._setDate(inst, date);
4318
                        this._updateDatepicker(inst);
4319
                        this._updateAlternate(inst);
4320
                }
4321
        },
4322

    
4323
        /* Get the date(s) for the first entry in a jQuery selection.
4324
         * @param  target element - the target input field or division or span
4325
         * @param  noDefault boolean - true if no default date is to be used
4326
         * @return Date - the current date
4327
         */
4328
        _getDateDatepicker: function(target, noDefault) {
4329
                var inst = this._getInst(target);
4330
                if (inst && !inst.inline) {
4331
                        this._setDateFromField(inst, noDefault);
4332
                }
4333
                return (inst ? this._getDate(inst) : null);
4334
        },
4335

    
4336
        /* Handle keystrokes. */
4337
        _doKeyDown: function(event) {
4338
                var onSelect, dateStr, sel,
4339
                        inst = $.datepicker._getInst(event.target),
4340
                        handled = true,
4341
                        isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
4342

    
4343
                inst._keyEvent = true;
4344
                if ($.datepicker._datepickerShowing) {
4345
                        switch (event.keyCode) {
4346
                                case 9: $.datepicker._hideDatepicker();
4347
                                                handled = false;
4348
                                                break; // hide on tab out
4349
                                case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
4350
                                                                        $.datepicker._currentClass + ")", inst.dpDiv);
4351
                                                if (sel[0]) {
4352
                                                        $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
4353
                                                }
4354

    
4355
                                                onSelect = $.datepicker._get(inst, "onSelect");
4356
                                                if (onSelect) {
4357
                                                        dateStr = $.datepicker._formatDate(inst);
4358

    
4359
                                                        // trigger custom callback
4360
                                                        onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
4361
                                                } else {
4362
                                                        $.datepicker._hideDatepicker();
4363
                                                }
4364

    
4365
                                                return false; // don't submit the form
4366
                                case 27: $.datepicker._hideDatepicker();
4367
                                                break; // hide on escape
4368
                                case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4369
                                                        -$.datepicker._get(inst, "stepBigMonths") :
4370
                                                        -$.datepicker._get(inst, "stepMonths")), "M");
4371
                                                break; // previous month/year on page up/+ ctrl
4372
                                case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4373
                                                        +$.datepicker._get(inst, "stepBigMonths") :
4374
                                                        +$.datepicker._get(inst, "stepMonths")), "M");
4375
                                                break; // next month/year on page down/+ ctrl
4376
                                case 35: if (event.ctrlKey || event.metaKey) {
4377
                                                        $.datepicker._clearDate(event.target);
4378
                                                }
4379
                                                handled = event.ctrlKey || event.metaKey;
4380
                                                break; // clear on ctrl or command +end
4381
                                case 36: if (event.ctrlKey || event.metaKey) {
4382
                                                        $.datepicker._gotoToday(event.target);
4383
                                                }
4384
                                                handled = event.ctrlKey || event.metaKey;
4385
                                                break; // current on ctrl or command +home
4386
                                case 37: if (event.ctrlKey || event.metaKey) {
4387
                                                        $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
4388
                                                }
4389
                                                handled = event.ctrlKey || event.metaKey;
4390
                                                // -1 day on ctrl or command +left
4391
                                                if (event.originalEvent.altKey) {
4392
                                                        $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4393
                                                                -$.datepicker._get(inst, "stepBigMonths") :
4394
                                                                -$.datepicker._get(inst, "stepMonths")), "M");
4395
                                                }
4396
                                                // next month/year on alt +left on Mac
4397
                                                break;
4398
                                case 38: if (event.ctrlKey || event.metaKey) {
4399
                                                        $.datepicker._adjustDate(event.target, -7, "D");
4400
                                                }
4401
                                                handled = event.ctrlKey || event.metaKey;
4402
                                                break; // -1 week on ctrl or command +up
4403
                                case 39: if (event.ctrlKey || event.metaKey) {
4404
                                                        $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
4405
                                                }
4406
                                                handled = event.ctrlKey || event.metaKey;
4407
                                                // +1 day on ctrl or command +right
4408
                                                if (event.originalEvent.altKey) {
4409
                                                        $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4410
                                                                +$.datepicker._get(inst, "stepBigMonths") :
4411
                                                                +$.datepicker._get(inst, "stepMonths")), "M");
4412
                                                }
4413
                                                // next month/year on alt +right
4414
                                                break;
4415
                                case 40: if (event.ctrlKey || event.metaKey) {
4416
                                                        $.datepicker._adjustDate(event.target, +7, "D");
4417
                                                }
4418
                                                handled = event.ctrlKey || event.metaKey;
4419
                                                break; // +1 week on ctrl or command +down
4420
                                default: handled = false;
4421
                        }
4422
                } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
4423
                        $.datepicker._showDatepicker(this);
4424
                } else {
4425
                        handled = false;
4426
                }
4427

    
4428
                if (handled) {
4429
                        event.preventDefault();
4430
                        event.stopPropagation();
4431
                }
4432
        },
4433

    
4434
        /* Filter entered characters - based on date format. */
4435
        _doKeyPress: function(event) {
4436
                var chars, chr,
4437
                        inst = $.datepicker._getInst(event.target);
4438

    
4439
                if ($.datepicker._get(inst, "constrainInput")) {
4440
                        chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
4441
                        chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
4442
                        return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
4443
                }
4444
        },
4445

    
4446
        /* Synchronise manual entry and field/alternate field. */
4447
        _doKeyUp: function(event) {
4448
                var date,
4449
                        inst = $.datepicker._getInst(event.target);
4450

    
4451
                if (inst.input.val() !== inst.lastVal) {
4452
                        try {
4453
                                date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
4454
                                        (inst.input ? inst.input.val() : null),
4455
                                        $.datepicker._getFormatConfig(inst));
4456

    
4457
                                if (date) { // only if valid
4458
                                        $.datepicker._setDateFromField(inst);
4459
                                        $.datepicker._updateAlternate(inst);
4460
                                        $.datepicker._updateDatepicker(inst);
4461
                                }
4462
                        }
4463
                        catch (err) {
4464
                        }
4465
                }
4466
                return true;
4467
        },
4468

    
4469
        /* Pop-up the date picker for a given input field.
4470
         * If false returned from beforeShow event handler do not show.
4471
         * @param  input  element - the input field attached to the date picker or
4472
         *                                        event - if triggered by focus
4473
         */
4474
        _showDatepicker: function(input) {
4475
                input = input.target || input;
4476
                if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
4477
                        input = $("input", input.parentNode)[0];
4478
                }
4479

    
4480
                if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
4481
                        return;
4482
                }
4483

    
4484
                var inst, beforeShow, beforeShowSettings, isFixed,
4485
                        offset, showAnim, duration;
4486

    
4487
                inst = $.datepicker._getInst(input);
4488
                if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
4489
                        $.datepicker._curInst.dpDiv.stop(true, true);
4490
                        if ( inst && $.datepicker._datepickerShowing ) {
4491
                                $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
4492
                        }
4493
                }
4494

    
4495
                beforeShow = $.datepicker._get(inst, "beforeShow");
4496
                beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
4497
                if(beforeShowSettings === false){
4498
                        return;
4499
                }
4500
                datepicker_extendRemove(inst.settings, beforeShowSettings);
4501

    
4502
                inst.lastVal = null;
4503
                $.datepicker._lastInput = input;
4504
                $.datepicker._setDateFromField(inst);
4505

    
4506
                if ($.datepicker._inDialog) { // hide cursor
4507
                        input.value = "";
4508
                }
4509
                if (!$.datepicker._pos) { // position below input
4510
                        $.datepicker._pos = $.datepicker._findPos(input);
4511
                        $.datepicker._pos[1] += input.offsetHeight; // add the height
4512
                }
4513

    
4514
                isFixed = false;
4515
                $(input).parents().each(function() {
4516
                        isFixed |= $(this).css("position") === "fixed";
4517
                        return !isFixed;
4518
                });
4519

    
4520
                offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
4521
                $.datepicker._pos = null;
4522
                //to avoid flashes on Firefox
4523
                inst.dpDiv.empty();
4524
                // determine sizing offscreen
4525
                inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
4526
                $.datepicker._updateDatepicker(inst);
4527
                // fix width for dynamic number of date pickers
4528
                // and adjust position before showing
4529
                offset = $.datepicker._checkOffset(inst, offset, isFixed);
4530
                inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
4531
                        "static" : (isFixed ? "fixed" : "absolute")), display: "none",
4532
                        left: offset.left + "px", top: offset.top + "px"});
4533

    
4534
                if (!inst.inline) {
4535
                        showAnim = $.datepicker._get(inst, "showAnim");
4536
                        duration = $.datepicker._get(inst, "duration");
4537
                        inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
4538
                        $.datepicker._datepickerShowing = true;
4539

    
4540
                        if ( $.effects && $.effects.effect[ showAnim ] ) {
4541
                                inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
4542
                        } else {
4543
                                inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
4544
                        }
4545

    
4546
                        if ( $.datepicker._shouldFocusInput( inst ) ) {
4547
                                inst.input.focus();
4548
                        }
4549

    
4550
                        $.datepicker._curInst = inst;
4551
                }
4552
        },
4553

    
4554
        /* Generate the date picker content. */
4555
        _updateDatepicker: function(inst) {
4556
                this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
4557
                datepicker_instActive = inst; // for delegate hover events
4558
                inst.dpDiv.empty().append(this._generateHTML(inst));
4559
                this._attachHandlers(inst);
4560

    
4561
                var origyearshtml,
4562
                        numMonths = this._getNumberOfMonths(inst),
4563
                        cols = numMonths[1],
4564
                        width = 17,
4565
                        activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
4566

    
4567
                if ( activeCell.length > 0 ) {
4568
                        datepicker_handleMouseover.apply( activeCell.get( 0 ) );
4569
                }
4570

    
4571
                inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
4572
                if (cols > 1) {
4573
                        inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
4574
                }
4575
                inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
4576
                        "Class"]("ui-datepicker-multi");
4577
                inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
4578
                        "Class"]("ui-datepicker-rtl");
4579

    
4580
                if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
4581
                        inst.input.focus();
4582
                }
4583

    
4584
                // deffered render of the years select (to avoid flashes on Firefox)
4585
                if( inst.yearshtml ){
4586
                        origyearshtml = inst.yearshtml;
4587
                        setTimeout(function(){
4588
                                //assure that inst.yearshtml didn't change.
4589
                                if( origyearshtml === inst.yearshtml && inst.yearshtml ){
4590
                                        inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
4591
                                }
4592
                                origyearshtml = inst.yearshtml = null;
4593
                        }, 0);
4594
                }
4595
        },
4596

    
4597
        // #6694 - don't focus the input if it's already focused
4598
        // this breaks the change event in IE
4599
        // Support: IE and jQuery <1.9
4600
        _shouldFocusInput: function( inst ) {
4601
                return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
4602
        },
4603

    
4604
        /* Check positioning to remain on screen. */
4605
        _checkOffset: function(inst, offset, isFixed) {
4606
                var dpWidth = inst.dpDiv.outerWidth(),
4607
                        dpHeight = inst.dpDiv.outerHeight(),
4608
                        inputWidth = inst.input ? inst.input.outerWidth() : 0,
4609
                        inputHeight = inst.input ? inst.input.outerHeight() : 0,
4610
                        viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
4611
                        viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
4612

    
4613
                offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
4614
                offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
4615
                offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
4616

    
4617
                // now check if datepicker is showing outside window viewport - move to a better place if so.
4618
                offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
4619
                        Math.abs(offset.left + dpWidth - viewWidth) : 0);
4620
                offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
4621
                        Math.abs(dpHeight + inputHeight) : 0);
4622

    
4623
                return offset;
4624
        },
4625

    
4626
        /* Find an object's position on the screen. */
4627
        _findPos: function(obj) {
4628
                var position,
4629
                        inst = this._getInst(obj),
4630
                        isRTL = this._get(inst, "isRTL");
4631

    
4632
                while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
4633
                        obj = obj[isRTL ? "previousSibling" : "nextSibling"];
4634
                }
4635

    
4636
                position = $(obj).offset();
4637
                return [position.left, position.top];
4638
        },
4639

    
4640
        /* Hide the date picker from view.
4641
         * @param  input  element - the input field attached to the date picker
4642
         */
4643
        _hideDatepicker: function(input) {
4644
                var showAnim, duration, postProcess, onClose,
4645
                        inst = this._curInst;
4646

    
4647
                if (!inst || (input && inst !== $.data(input, "datepicker"))) {
4648
                        return;
4649
                }
4650

    
4651
                if (this._datepickerShowing) {
4652
                        showAnim = this._get(inst, "showAnim");
4653
                        duration = this._get(inst, "duration");
4654
                        postProcess = function() {
4655
                                $.datepicker._tidyDialog(inst);
4656
                        };
4657

    
4658
                        // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
4659
                        if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
4660
                                inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
4661
                        } else {
4662
                                inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
4663
                                        (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
4664
                        }
4665

    
4666
                        if (!showAnim) {
4667
                                postProcess();
4668
                        }
4669
                        this._datepickerShowing = false;
4670

    
4671
                        onClose = this._get(inst, "onClose");
4672
                        if (onClose) {
4673
                                onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
4674
                        }
4675

    
4676
                        this._lastInput = null;
4677
                        if (this._inDialog) {
4678
                                this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
4679
                                if ($.blockUI) {
4680
                                        $.unblockUI();
4681
                                        $("body").append(this.dpDiv);
4682
                                }
4683
                        }
4684
                        this._inDialog = false;
4685
                }
4686
        },
4687

    
4688
        /* Tidy up after a dialog display. */
4689
        _tidyDialog: function(inst) {
4690
                inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
4691
        },
4692

    
4693
        /* Close date picker if clicked elsewhere. */
4694
        _checkExternalClick: function(event) {
4695
                if (!$.datepicker._curInst) {
4696
                        return;
4697
                }
4698

    
4699
                var $target = $(event.target),
4700
                        inst = $.datepicker._getInst($target[0]);
4701

    
4702
                if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
4703
                                $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
4704
                                !$target.hasClass($.datepicker.markerClassName) &&
4705
                                !$target.closest("." + $.datepicker._triggerClass).length &&
4706
                                $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
4707
                        ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
4708
                                $.datepicker._hideDatepicker();
4709
                }
4710
        },
4711

    
4712
        /* Adjust one of the date sub-fields. */
4713
        _adjustDate: function(id, offset, period) {
4714
                var target = $(id),
4715
                        inst = this._getInst(target[0]);
4716

    
4717
                if (this._isDisabledDatepicker(target[0])) {
4718
                        return;
4719
                }
4720
                this._adjustInstDate(inst, offset +
4721
                        (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
4722
                        period);
4723
                this._updateDatepicker(inst);
4724
        },
4725

    
4726
        /* Action for current link. */
4727
        _gotoToday: function(id) {
4728
                var date,
4729
                        target = $(id),
4730
                        inst = this._getInst(target[0]);
4731

    
4732
                if (this._get(inst, "gotoCurrent") && inst.currentDay) {
4733
                        inst.selectedDay = inst.currentDay;
4734
                        inst.drawMonth = inst.selectedMonth = inst.currentMonth;
4735
                        inst.drawYear = inst.selectedYear = inst.currentYear;
4736
                } else {
4737
                        date = new Date();
4738
                        inst.selectedDay = date.getDate();
4739
                        inst.drawMonth = inst.selectedMonth = date.getMonth();
4740
                        inst.drawYear = inst.selectedYear = date.getFullYear();
4741
                }
4742
                this._notifyChange(inst);
4743
                this._adjustDate(target);
4744
        },
4745

    
4746
        /* Action for selecting a new month/year. */
4747
        _selectMonthYear: function(id, select, period) {
4748
                var target = $(id),
4749
                        inst = this._getInst(target[0]);
4750

    
4751
                inst["selected" + (period === "M" ? "Month" : "Year")] =
4752
                inst["draw" + (period === "M" ? "Month" : "Year")] =
4753
                        parseInt(select.options[select.selectedIndex].value,10);
4754

    
4755
                this._notifyChange(inst);
4756
                this._adjustDate(target);
4757
        },
4758

    
4759
        /* Action for selecting a day. */
4760
        _selectDay: function(id, month, year, td) {
4761
                var inst,
4762
                        target = $(id);
4763

    
4764
                if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
4765
                        return;
4766
                }
4767

    
4768
                inst = this._getInst(target[0]);
4769
                inst.selectedDay = inst.currentDay = $("a", td).html();
4770
                inst.selectedMonth = inst.currentMonth = month;
4771
                inst.selectedYear = inst.currentYear = year;
4772
                this._selectDate(id, this._formatDate(inst,
4773
                        inst.currentDay, inst.currentMonth, inst.currentYear));
4774
        },
4775

    
4776
        /* Erase the input field and hide the date picker. */
4777
        _clearDate: function(id) {
4778
                var target = $(id);
4779
                this._selectDate(target, "");
4780
        },
4781

    
4782
        /* Update the input field with the selected date. */
4783
        _selectDate: function(id, dateStr) {
4784
                var onSelect,
4785
                        target = $(id),
4786
                        inst = this._getInst(target[0]);
4787

    
4788
                dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
4789
                if (inst.input) {
4790
                        inst.input.val(dateStr);
4791
                }
4792
                this._updateAlternate(inst);
4793

    
4794
                onSelect = this._get(inst, "onSelect");
4795
                if (onSelect) {
4796
                        onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
4797
                } else if (inst.input) {
4798
                        inst.input.trigger("change"); // fire the change event
4799
                }
4800

    
4801
                if (inst.inline){
4802
                        this._updateDatepicker(inst);
4803
                } else {
4804
                        this._hideDatepicker();
4805
                        this._lastInput = inst.input[0];
4806
                        if (typeof(inst.input[0]) !== "object") {
4807
                                inst.input.focus(); // restore focus
4808
                        }
4809
                        this._lastInput = null;
4810
                }
4811
        },
4812

    
4813
        /* Update any alternate field to synchronise with the main field. */
4814
        _updateAlternate: function(inst) {
4815
                var altFormat, date, dateStr,
4816
                        altField = this._get(inst, "altField");
4817

    
4818
                if (altField) { // update alternate field too
4819
                        altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
4820
                        date = this._getDate(inst);
4821
                        dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
4822
                        $(altField).each(function() { $(this).val(dateStr); });
4823
                }
4824
        },
4825

    
4826
        /* Set as beforeShowDay function to prevent selection of weekends.
4827
         * @param  date  Date - the date to customise
4828
         * @return [boolean, string] - is this date selectable?, what is its CSS class?
4829
         */
4830
        noWeekends: function(date) {
4831
                var day = date.getDay();
4832
                return [(day > 0 && day < 6), ""];
4833
        },
4834

    
4835
        /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
4836
         * @param  date  Date - the date to get the week for
4837
         * @return  number - the number of the week within the year that contains this date
4838
         */
4839
        iso8601Week: function(date) {
4840
                var time,
4841
                        checkDate = new Date(date.getTime());
4842

    
4843
                // Find Thursday of this week starting on Monday
4844
                checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
4845

    
4846
                time = checkDate.getTime();
4847
                checkDate.setMonth(0); // Compare with Jan 1
4848
                checkDate.setDate(1);
4849
                return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
4850
        },
4851

    
4852
        /* Parse a string value into a date object.
4853
         * See formatDate below for the possible formats.
4854
         *
4855
         * @param  format string - the expected format of the date
4856
         * @param  value string - the date in the above format
4857
         * @param  settings Object - attributes include:
4858
         *                                        shortYearCutoff  number - the cutoff year for determining the century (optional)
4859
         *                                        dayNamesShort        string[7] - abbreviated names of the days from Sunday (optional)
4860
         *                                        dayNames                string[7] - names of the days from Sunday (optional)
4861
         *                                        monthNamesShort string[12] - abbreviated names of the months (optional)
4862
         *                                        monthNames                string[12] - names of the months (optional)
4863
         * @return  Date - the extracted date value or null if value is blank
4864
         */
4865
        parseDate: function (format, value, settings) {
4866
                if (format == null || value == null) {
4867
                        throw "Invalid arguments";
4868
                }
4869

    
4870
                value = (typeof value === "object" ? value.toString() : value + "");
4871
                if (value === "") {
4872
                        return null;
4873
                }
4874

    
4875
                var iFormat, dim, extra,
4876
                        iValue = 0,
4877
                        shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
4878
                        shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
4879
                                new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
4880
                        dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
4881
                        dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
4882
                        monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
4883
                        monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
4884
                        year = -1,
4885
                        month = -1,
4886
                        day = -1,
4887
                        doy = -1,
4888
                        literal = false,
4889
                        date,
4890
                        // Check whether a format character is doubled
4891
                        lookAhead = function(match) {
4892
                                var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
4893
                                if (matches) {
4894
                                        iFormat++;
4895
                                }
4896
                                return matches;
4897
                        },
4898
                        // Extract a number from the string value
4899
                        getNumber = function(match) {
4900
                                var isDoubled = lookAhead(match),
4901
                                        size = (match === "@" ? 14 : (match === "!" ? 20 :
4902
                                        (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
4903
                                        minSize = (match === "y" ? size : 1),
4904
                                        digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
4905
                                        num = value.substring(iValue).match(digits);
4906
                                if (!num) {
4907
                                        throw "Missing number at position " + iValue;
4908
                                }
4909
                                iValue += num[0].length;
4910
                                return parseInt(num[0], 10);
4911
                        },
4912
                        // Extract a name from the string value and convert to an index
4913
                        getName = function(match, shortNames, longNames) {
4914
                                var index = -1,
4915
                                        names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
4916
                                                return [ [k, v] ];
4917
                                        }).sort(function (a, b) {
4918
                                                return -(a[1].length - b[1].length);
4919
                                        });
4920

    
4921
                                $.each(names, function (i, pair) {
4922
                                        var name = pair[1];
4923
                                        if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
4924
                                                index = pair[0];
4925
                                                iValue += name.length;
4926
                                                return false;
4927
                                        }
4928
                                });
4929
                                if (index !== -1) {
4930
                                        return index + 1;
4931
                                } else {
4932
                                        throw "Unknown name at position " + iValue;
4933
                                }
4934
                        },
4935
                        // Confirm that a literal character matches the string value
4936
                        checkLiteral = function() {
4937
                                if (value.charAt(iValue) !== format.charAt(iFormat)) {
4938
                                        throw "Unexpected literal at position " + iValue;
4939
                                }
4940
                                iValue++;
4941
                        };
4942

    
4943
                for (iFormat = 0; iFormat < format.length; iFormat++) {
4944
                        if (literal) {
4945
                                if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
4946
                                        literal = false;
4947
                                } else {
4948
                                        checkLiteral();
4949
                                }
4950
                        } else {
4951
                                switch (format.charAt(iFormat)) {
4952
                                        case "d":
4953
                                                day = getNumber("d");
4954
                                                break;
4955
                                        case "D":
4956
                                                getName("D", dayNamesShort, dayNames);
4957
                                                break;
4958
                                        case "o":
4959
                                                doy = getNumber("o");
4960
                                                break;
4961
                                        case "m":
4962
                                                month = getNumber("m");
4963
                                                break;
4964
                                        case "M":
4965
                                                month = getName("M", monthNamesShort, monthNames);
4966
                                                break;
4967
                                        case "y":
4968
                                                year = getNumber("y");
4969
                                                break;
4970
                                        case "@":
4971
                                                date = new Date(getNumber("@"));
4972
                                                year = date.getFullYear();
4973
                                                month = date.getMonth() + 1;
4974
                                                day = date.getDate();
4975
                                                break;
4976
                                        case "!":
4977
                                                date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
4978
                                                year = date.getFullYear();
4979
                                                month = date.getMonth() + 1;
4980
                                                day = date.getDate();
4981
                                                break;
4982
                                        case "'":
4983
                                                if (lookAhead("'")){
4984
                                                        checkLiteral();
4985
                                                } else {
4986
                                                        literal = true;
4987
                                                }
4988
                                                break;
4989
                                        default:
4990
                                                checkLiteral();
4991
                                }
4992
                        }
4993
                }
4994

    
4995
                if (iValue < value.length){
4996
                        extra = value.substr(iValue);
4997
                        if (!/^\s+/.test(extra)) {
4998
                                throw "Extra/unparsed characters found in date: " + extra;
4999
                        }
5000
                }
5001

    
5002
                if (year === -1) {
5003
                        year = new Date().getFullYear();
5004
                } else if (year < 100) {
5005
                        year += new Date().getFullYear() - new Date().getFullYear() % 100 +
5006
                                (year <= shortYearCutoff ? 0 : -100);
5007
                }
5008

    
5009
                if (doy > -1) {
5010
                        month = 1;
5011
                        day = doy;
5012
                        do {
5013
                                dim = this._getDaysInMonth(year, month - 1);
5014
                                if (day <= dim) {
5015
                                        break;
5016
                                }
5017
                                month++;
5018
                                day -= dim;
5019
                        } while (true);
5020
                }
5021

    
5022
                date = this._daylightSavingAdjust(new Date(year, month - 1, day));
5023
                if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
5024
                        throw "Invalid date"; // E.g. 31/02/00
5025
                }
5026
                return date;
5027
        },
5028

    
5029
        /* Standard date formats. */
5030
        ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
5031
        COOKIE: "D, dd M yy",
5032
        ISO_8601: "yy-mm-dd",
5033
        RFC_822: "D, d M y",
5034
        RFC_850: "DD, dd-M-y",
5035
        RFC_1036: "D, d M y",
5036
        RFC_1123: "D, d M yy",
5037
        RFC_2822: "D, d M yy",
5038
        RSS: "D, d M y", // RFC 822
5039
        TICKS: "!",
5040
        TIMESTAMP: "@",
5041
        W3C: "yy-mm-dd", // ISO 8601
5042

    
5043
        _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
5044
                Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
5045

    
5046
        /* Format a date object into a string value.
5047
         * The format can be combinations of the following:
5048
         * d  - day of month (no leading zero)
5049
         * dd - day of month (two digit)
5050
         * o  - day of year (no leading zeros)
5051
         * oo - day of year (three digit)
5052
         * D  - day name short
5053
         * DD - day name long
5054
         * m  - month of year (no leading zero)
5055
         * mm - month of year (two digit)
5056
         * M  - month name short
5057
         * MM - month name long
5058
         * y  - year (two digit)
5059
         * yy - year (four digit)
5060
         * @ - Unix timestamp (ms since 01/01/1970)
5061
         * ! - Windows ticks (100ns since 01/01/0001)
5062
         * "..." - literal text
5063
         * '' - single quote
5064
         *
5065
         * @param  format string - the desired format of the date
5066
         * @param  date Date - the date value to format
5067
         * @param  settings Object - attributes include:
5068
         *                                        dayNamesShort        string[7] - abbreviated names of the days from Sunday (optional)
5069
         *                                        dayNames                string[7] - names of the days from Sunday (optional)
5070
         *                                        monthNamesShort string[12] - abbreviated names of the months (optional)
5071
         *                                        monthNames                string[12] - names of the months (optional)
5072
         * @return  string - the date in the above format
5073
         */
5074
        formatDate: function (format, date, settings) {
5075
                if (!date) {
5076
                        return "";
5077
                }
5078

    
5079
                var iFormat,
5080
                        dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
5081
                        dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
5082
                        monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
5083
                        monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
5084
                        // Check whether a format character is doubled
5085
                        lookAhead = function(match) {
5086
                                var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5087
                                if (matches) {
5088
                                        iFormat++;
5089
                                }
5090
                                return matches;
5091
                        },
5092
                        // Format a number, with leading zero if necessary
5093
                        formatNumber = function(match, value, len) {
5094
                                var num = "" + value;
5095
                                if (lookAhead(match)) {
5096
                                        while (num.length < len) {
5097
                                                num = "0" + num;
5098
                                        }
5099
                                }
5100
                                return num;
5101
                        },
5102
                        // Format a name, short or long as requested
5103
                        formatName = function(match, value, shortNames, longNames) {
5104
                                return (lookAhead(match) ? longNames[value] : shortNames[value]);
5105
                        },
5106
                        output = "",
5107
                        literal = false;
5108

    
5109
                if (date) {
5110
                        for (iFormat = 0; iFormat < format.length; iFormat++) {
5111
                                if (literal) {
5112
                                        if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5113
                                                literal = false;
5114
                                        } else {
5115
                                                output += format.charAt(iFormat);
5116
                                        }
5117
                                } else {
5118
                                        switch (format.charAt(iFormat)) {
5119
                                                case "d":
5120
                                                        output += formatNumber("d", date.getDate(), 2);
5121
                                                        break;
5122
                                                case "D":
5123
                                                        output += formatName("D", date.getDay(), dayNamesShort, dayNames);
5124
                                                        break;
5125
                                                case "o":
5126
                                                        output += formatNumber("o",
5127
                                                                Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
5128
                                                        break;
5129
                                                case "m":
5130
                                                        output += formatNumber("m", date.getMonth() + 1, 2);
5131
                                                        break;
5132
                                                case "M":
5133
                                                        output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
5134
                                                        break;
5135
                                                case "y":
5136
                                                        output += (lookAhead("y") ? date.getFullYear() :
5137
                                                                (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
5138
                                                        break;
5139
                                                case "@":
5140
                                                        output += date.getTime();
5141
                                                        break;
5142
                                                case "!":
5143
                                                        output += date.getTime() * 10000 + this._ticksTo1970;
5144
                                                        break;
5145
                                                case "'":
5146
                                                        if (lookAhead("'")) {
5147
                                                                output += "'";
5148
                                                        } else {
5149
                                                                literal = true;
5150
                                                        }
5151
                                                        break;
5152
                                                default:
5153
                                                        output += format.charAt(iFormat);
5154
                                        }
5155
                                }
5156
                        }
5157
                }
5158
                return output;
5159
        },
5160

    
5161
        /* Extract all possible characters from the date format. */
5162
        _possibleChars: function (format) {
5163
                var iFormat,
5164
                        chars = "",
5165
                        literal = false,
5166
                        // Check whether a format character is doubled
5167
                        lookAhead = function(match) {
5168
                                var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5169
                                if (matches) {
5170
                                        iFormat++;
5171
                                }
5172
                                return matches;
5173
                        };
5174

    
5175
                for (iFormat = 0; iFormat < format.length; iFormat++) {
5176
                        if (literal) {
5177
                                if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5178
                                        literal = false;
5179
                                } else {
5180
                                        chars += format.charAt(iFormat);
5181
                                }
5182
                        } else {
5183
                                switch (format.charAt(iFormat)) {
5184
                                        case "d": case "m": case "y": case "@":
5185
                                                chars += "0123456789";
5186
                                                break;
5187
                                        case "D": case "M":
5188
                                                return null; // Accept anything
5189
                                        case "'":
5190
                                                if (lookAhead("'")) {
5191
                                                        chars += "'";
5192
                                                } else {
5193
                                                        literal = true;
5194
                                                }
5195
                                                break;
5196
                                        default:
5197
                                                chars += format.charAt(iFormat);
5198
                                }
5199
                        }
5200
                }
5201
                return chars;
5202
        },
5203

    
5204
        /* Get a setting value, defaulting if necessary. */
5205
        _get: function(inst, name) {
5206
                return inst.settings[name] !== undefined ?
5207
                        inst.settings[name] : this._defaults[name];
5208
        },
5209

    
5210
        /* Parse existing date and initialise date picker. */
5211
        _setDateFromField: function(inst, noDefault) {
5212
                if (inst.input.val() === inst.lastVal) {
5213
                        return;
5214
                }
5215

    
5216
                var dateFormat = this._get(inst, "dateFormat"),
5217
                        dates = inst.lastVal = inst.input ? inst.input.val() : null,
5218
                        defaultDate = this._getDefaultDate(inst),
5219
                        date = defaultDate,
5220
                        settings = this._getFormatConfig(inst);
5221

    
5222
                try {
5223
                        date = this.parseDate(dateFormat, dates, settings) || defaultDate;
5224
                } catch (event) {
5225
                        dates = (noDefault ? "" : dates);
5226
                }
5227
                inst.selectedDay = date.getDate();
5228
                inst.drawMonth = inst.selectedMonth = date.getMonth();
5229
                inst.drawYear = inst.selectedYear = date.getFullYear();
5230
                inst.currentDay = (dates ? date.getDate() : 0);
5231
                inst.currentMonth = (dates ? date.getMonth() : 0);
5232
                inst.currentYear = (dates ? date.getFullYear() : 0);
5233
                this._adjustInstDate(inst);
5234
        },
5235

    
5236
        /* Retrieve the default date shown on opening. */
5237
        _getDefaultDate: function(inst) {
5238
                return this._restrictMinMax(inst,
5239
                        this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
5240
        },
5241

    
5242
        /* A date may be specified as an exact value or a relative one. */
5243
        _determineDate: function(inst, date, defaultDate) {
5244
                var offsetNumeric = function(offset) {
5245
                                var date = new Date();
5246
                                date.setDate(date.getDate() + offset);
5247
                                return date;
5248
                        },
5249
                        offsetString = function(offset) {
5250
                                try {
5251
                                        return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
5252
                                                offset, $.datepicker._getFormatConfig(inst));
5253
                                }
5254
                                catch (e) {
5255
                                        // Ignore
5256
                                }
5257

    
5258
                                var date = (offset.toLowerCase().match(/^c/) ?
5259
                                        $.datepicker._getDate(inst) : null) || new Date(),
5260
                                        year = date.getFullYear(),
5261
                                        month = date.getMonth(),
5262
                                        day = date.getDate(),
5263
                                        pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
5264
                                        matches = pattern.exec(offset);
5265

    
5266
                                while (matches) {
5267
                                        switch (matches[2] || "d") {
5268
                                                case "d" : case "D" :
5269
                                                        day += parseInt(matches[1],10); break;
5270
                                                case "w" : case "W" :
5271
                                                        day += parseInt(matches[1],10) * 7; break;
5272
                                                case "m" : case "M" :
5273
                                                        month += parseInt(matches[1],10);
5274
                                                        day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5275
                                                        break;
5276
                                                case "y": case "Y" :
5277
                                                        year += parseInt(matches[1],10);
5278
                                                        day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5279
                                                        break;
5280
                                        }
5281
                                        matches = pattern.exec(offset);
5282
                                }
5283
                                return new Date(year, month, day);
5284
                        },
5285
                        newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
5286
                                (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
5287

    
5288
                newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
5289
                if (newDate) {
5290
                        newDate.setHours(0);
5291
                        newDate.setMinutes(0);
5292
                        newDate.setSeconds(0);
5293
                        newDate.setMilliseconds(0);
5294
                }
5295
                return this._daylightSavingAdjust(newDate);
5296
        },
5297

    
5298
        /* Handle switch to/from daylight saving.
5299
         * Hours may be non-zero on daylight saving cut-over:
5300
         * > 12 when midnight changeover, but then cannot generate
5301
         * midnight datetime, so jump to 1AM, otherwise reset.
5302
         * @param  date  (Date) the date to check
5303
         * @return  (Date) the corrected date
5304
         */
5305
        _daylightSavingAdjust: function(date) {
5306
                if (!date) {
5307
                        return null;
5308
                }
5309
                date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
5310
                return date;
5311
        },
5312

    
5313
        /* Set the date(s) directly. */
5314
        _setDate: function(inst, date, noChange) {
5315
                var clear = !date,
5316
                        origMonth = inst.selectedMonth,
5317
                        origYear = inst.selectedYear,
5318
                        newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
5319

    
5320
                inst.selectedDay = inst.currentDay = newDate.getDate();
5321
                inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
5322
                inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
5323
                if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
5324
                        this._notifyChange(inst);
5325
                }
5326
                this._adjustInstDate(inst);
5327
                if (inst.input) {
5328
                        inst.input.val(clear ? "" : this._formatDate(inst));
5329
                }
5330
        },
5331

    
5332
        /* Retrieve the date(s) directly. */
5333
        _getDate: function(inst) {
5334
                var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
5335
                        this._daylightSavingAdjust(new Date(
5336
                        inst.currentYear, inst.currentMonth, inst.currentDay)));
5337
                        return startDate;
5338
        },
5339

    
5340
        /* Attach the onxxx handlers.  These are declared statically so
5341
         * they work with static code transformers like Caja.
5342
         */
5343
        _attachHandlers: function(inst) {
5344
                var stepMonths = this._get(inst, "stepMonths"),
5345
                        id = "#" + inst.id.replace( /\\\\/g, "\\" );
5346
                inst.dpDiv.find("[data-handler]").map(function () {
5347
                        var handler = {
5348
                                prev: function () {
5349
                                        $.datepicker._adjustDate(id, -stepMonths, "M");
5350
                                },
5351
                                next: function () {
5352
                                        $.datepicker._adjustDate(id, +stepMonths, "M");
5353
                                },
5354
                                hide: function () {
5355
                                        $.datepicker._hideDatepicker();
5356
                                },
5357
                                today: function () {
5358
                                        $.datepicker._gotoToday(id);
5359
                                },
5360
                                selectDay: function () {
5361
                                        $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
5362
                                        return false;
5363
                                },
5364
                                selectMonth: function () {
5365
                                        $.datepicker._selectMonthYear(id, this, "M");
5366
                                        return false;
5367
                                },
5368
                                selectYear: function () {
5369
                                        $.datepicker._selectMonthYear(id, this, "Y");
5370
                                        return false;
5371
                                }
5372
                        };
5373
                        $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
5374
                });
5375
        },
5376

    
5377
        /* Generate the HTML for the current state of the date picker. */
5378
        _generateHTML: function(inst) {
5379
                var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
5380
                        controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
5381
                        monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
5382
                        selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
5383
                        cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
5384
                        printDate, dRow, tbody, daySettings, otherMonth, unselectable,
5385
                        tempDate = new Date(),
5386
                        today = this._daylightSavingAdjust(
5387
                                new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
5388
                        isRTL = this._get(inst, "isRTL"),
5389
                        showButtonPanel = this._get(inst, "showButtonPanel"),
5390
                        hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
5391
                        navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
5392
                        numMonths = this._getNumberOfMonths(inst),
5393
                        showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
5394
                        stepMonths = this._get(inst, "stepMonths"),
5395
                        isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
5396
                        currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
5397
                                new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
5398
                        minDate = this._getMinMaxDate(inst, "min"),
5399
                        maxDate = this._getMinMaxDate(inst, "max"),
5400
                        drawMonth = inst.drawMonth - showCurrentAtPos,
5401
                        drawYear = inst.drawYear;
5402

    
5403
                if (drawMonth < 0) {
5404
                        drawMonth += 12;
5405
                        drawYear--;
5406
                }
5407
                if (maxDate) {
5408
                        maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
5409
                                maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
5410
                        maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
5411
                        while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
5412
                                drawMonth--;
5413
                                if (drawMonth < 0) {
5414
                                        drawMonth = 11;
5415
                                        drawYear--;
5416
                                }
5417
                        }
5418
                }
5419
                inst.drawMonth = drawMonth;
5420
                inst.drawYear = drawYear;
5421

    
5422
                prevText = this._get(inst, "prevText");
5423
                prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
5424
                        this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
5425
                        this._getFormatConfig(inst)));
5426

    
5427
                prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
5428
                        "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
5429
                        " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
5430
                        (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>"));
5431

    
5432
                nextText = this._get(inst, "nextText");
5433
                nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
5434
                        this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
5435
                        this._getFormatConfig(inst)));
5436

    
5437
                next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
5438
                        "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
5439
                        " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
5440
                        (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>"));
5441

    
5442
                currentText = this._get(inst, "currentText");
5443
                gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
5444
                currentText = (!navigationAsDateFormat ? currentText :
5445
                        this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
5446

    
5447
                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'>" +
5448
                        this._get(inst, "closeText") + "</button>" : "");
5449

    
5450
                buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
5451
                        (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'" +
5452
                        ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
5453

    
5454
                firstDay = parseInt(this._get(inst, "firstDay"),10);
5455
                firstDay = (isNaN(firstDay) ? 0 : firstDay);
5456

    
5457
                showWeek = this._get(inst, "showWeek");
5458
                dayNames = this._get(inst, "dayNames");
5459
                dayNamesMin = this._get(inst, "dayNamesMin");
5460
                monthNames = this._get(inst, "monthNames");
5461
                monthNamesShort = this._get(inst, "monthNamesShort");
5462
                beforeShowDay = this._get(inst, "beforeShowDay");
5463
                showOtherMonths = this._get(inst, "showOtherMonths");
5464
                selectOtherMonths = this._get(inst, "selectOtherMonths");
5465
                defaultDate = this._getDefaultDate(inst);
5466
                html = "";
5467
                dow;
5468
                for (row = 0; row < numMonths[0]; row++) {
5469
                        group = "";
5470
                        this.maxRows = 4;
5471
                        for (col = 0; col < numMonths[1]; col++) {
5472
                                selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
5473
                                cornerClass = " ui-corner-all";
5474
                                calender = "";
5475
                                if (isMultiMonth) {
5476
                                        calender += "<div class='ui-datepicker-group";
5477
                                        if (numMonths[1] > 1) {
5478
                                                switch (col) {
5479
                                                        case 0: calender += " ui-datepicker-group-first";
5480
                                                                cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
5481
                                                        case numMonths[1]-1: calender += " ui-datepicker-group-last";
5482
                                                                cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
5483
                                                        default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
5484
                                                }
5485
                                        }
5486
                                        calender += "'>";
5487
                                }
5488
                                calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
5489
                                        (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
5490
                                        (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
5491
                                        this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
5492
                                        row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
5493
                                        "</div><table class='ui-datepicker-calendar'><thead>" +
5494
                                        "<tr>";
5495
                                thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
5496
                                for (dow = 0; dow < 7; dow++) { // days of the week
5497
                                        day = (dow + firstDay) % 7;
5498
                                        thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
5499
                                                "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
5500
                                }
5501
                                calender += thead + "</tr></thead><tbody>";
5502
                                daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
5503
                                if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
5504
                                        inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
5505
                                }
5506
                                leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
5507
                                curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
5508
                                numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
5509
                                this.maxRows = numRows;
5510
                                printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
5511
                                for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
5512
                                        calender += "<tr>";
5513
                                        tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
5514
                                                this._get(inst, "calculateWeek")(printDate) + "</td>");
5515
                                        for (dow = 0; dow < 7; dow++) { // create date picker days
5516
                                                daySettings = (beforeShowDay ?
5517
                                                        beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
5518
                                                otherMonth = (printDate.getMonth() !== drawMonth);
5519
                                                unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
5520
                                                        (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
5521
                                                tbody += "<td class='" +
5522
                                                        ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
5523
                                                        (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
5524
                                                        ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
5525
                                                        (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
5526
                                                        // or defaultDate is current printedDate and defaultDate is selectedDate
5527
                                                        " " + this._dayOverClass : "") + // highlight selected day
5528
                                                        (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
5529
                                                        (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
5530
                                                        (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
5531
                                                        (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
5532
                                                        ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
5533
                                                        (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
5534
                                                        (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
5535
                                                        (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
5536
                                                        (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
5537
                                                        (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
5538
                                                        (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
5539
                                                        "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
5540
                                                printDate.setDate(printDate.getDate() + 1);
5541
                                                printDate = this._daylightSavingAdjust(printDate);
5542
                                        }
5543
                                        calender += tbody + "</tr>";
5544
                                }
5545
                                drawMonth++;
5546
                                if (drawMonth > 11) {
5547
                                        drawMonth = 0;
5548
                                        drawYear++;
5549
                                }
5550
                                calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
5551
                                                        ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
5552
                                group += calender;
5553
                        }
5554
                        html += group;
5555
                }
5556
                html += buttonPanel;
5557
                inst._keyEvent = false;
5558
                return html;
5559
        },
5560

    
5561
        /* Generate the month and year header. */
5562
        _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
5563
                        secondary, monthNames, monthNamesShort) {
5564

    
5565
                var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
5566
                        changeMonth = this._get(inst, "changeMonth"),
5567
                        changeYear = this._get(inst, "changeYear"),
5568
                        showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
5569
                        html = "<div class='ui-datepicker-title'>",
5570
                        monthHtml = "";
5571

    
5572
                // month selection
5573
                if (secondary || !changeMonth) {
5574
                        monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
5575
                } else {
5576
                        inMinYear = (minDate && minDate.getFullYear() === drawYear);
5577
                        inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
5578
                        monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
5579
                        for ( month = 0; month < 12; month++) {
5580
                                if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
5581
                                        monthHtml += "<option value='" + month + "'" +
5582
                                                (month === drawMonth ? " selected='selected'" : "") +
5583
                                                ">" + monthNamesShort[month] + "</option>";
5584
                                }
5585
                        }
5586
                        monthHtml += "</select>";
5587
                }
5588

    
5589
                if (!showMonthAfterYear) {
5590
                        html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
5591
                }
5592

    
5593
                // year selection
5594
                if ( !inst.yearshtml ) {
5595
                        inst.yearshtml = "";
5596
                        if (secondary || !changeYear) {
5597
                                html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
5598
                        } else {
5599
                                // determine range of years to display
5600
                                years = this._get(inst, "yearRange").split(":");
5601
                                thisYear = new Date().getFullYear();
5602
                                determineYear = function(value) {
5603
                                        var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
5604
                                                (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
5605
                                                parseInt(value, 10)));
5606
                                        return (isNaN(year) ? thisYear : year);
5607
                                };
5608
                                year = determineYear(years[0]);
5609
                                endYear = Math.max(year, determineYear(years[1] || ""));
5610
                                year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
5611
                                endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
5612
                                inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
5613
                                for (; year <= endYear; year++) {
5614
                                        inst.yearshtml += "<option value='" + year + "'" +
5615
                                                (year === drawYear ? " selected='selected'" : "") +
5616
                                                ">" + year + "</option>";
5617
                                }
5618
                                inst.yearshtml += "</select>";
5619

    
5620
                                html += inst.yearshtml;
5621
                                inst.yearshtml = null;
5622
                        }
5623
                }
5624

    
5625
                html += this._get(inst, "yearSuffix");
5626
                if (showMonthAfterYear) {
5627
                        html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
5628
                }
5629
                html += "</div>"; // Close datepicker_header
5630
                return html;
5631
        },
5632

    
5633
        /* Adjust one of the date sub-fields. */
5634
        _adjustInstDate: function(inst, offset, period) {
5635
                var year = inst.drawYear + (period === "Y" ? offset : 0),
5636
                        month = inst.drawMonth + (period === "M" ? offset : 0),
5637
                        day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
5638
                        date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
5639

    
5640
                inst.selectedDay = date.getDate();
5641
                inst.drawMonth = inst.selectedMonth = date.getMonth();
5642
                inst.drawYear = inst.selectedYear = date.getFullYear();
5643
                if (period === "M" || period === "Y") {
5644
                        this._notifyChange(inst);
5645
                }
5646
        },
5647

    
5648
        /* Ensure a date is within any min/max bounds. */
5649
        _restrictMinMax: function(inst, date) {
5650
                var minDate = this._getMinMaxDate(inst, "min"),
5651
                        maxDate = this._getMinMaxDate(inst, "max"),
5652
                        newDate = (minDate && date < minDate ? minDate : date);
5653
                return (maxDate && newDate > maxDate ? maxDate : newDate);
5654
        },
5655

    
5656
        /* Notify change of month/year. */
5657
        _notifyChange: function(inst) {
5658
                var onChange = this._get(inst, "onChangeMonthYear");
5659
                if (onChange) {
5660
                        onChange.apply((inst.input ? inst.input[0] : null),
5661
                                [inst.selectedYear, inst.selectedMonth + 1, inst]);
5662
                }
5663
        },
5664

    
5665
        /* Determine the number of months to show. */
5666
        _getNumberOfMonths: function(inst) {
5667
                var numMonths = this._get(inst, "numberOfMonths");
5668
                return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
5669
        },
5670

    
5671
        /* Determine the current maximum date - ensure no time components are set. */
5672
        _getMinMaxDate: function(inst, minMax) {
5673
                return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
5674
        },
5675

    
5676
        /* Find the number of days in a given month. */
5677
        _getDaysInMonth: function(year, month) {
5678
                return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
5679
        },
5680

    
5681
        /* Find the day of the week of the first of a month. */
5682
        _getFirstDayOfMonth: function(year, month) {
5683
                return new Date(year, month, 1).getDay();
5684
        },
5685

    
5686
        /* Determines if we should allow a "next/prev" month display change. */
5687
        _canAdjustMonth: function(inst, offset, curYear, curMonth) {
5688
                var numMonths = this._getNumberOfMonths(inst),
5689
                        date = this._daylightSavingAdjust(new Date(curYear,
5690
                        curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
5691

    
5692
                if (offset < 0) {
5693
                        date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
5694
                }
5695
                return this._isInRange(inst, date);
5696
        },
5697

    
5698
        /* Is the given date in the accepted range? */
5699
        _isInRange: function(inst, date) {
5700
                var yearSplit, currentYear,
5701
                        minDate = this._getMinMaxDate(inst, "min"),
5702
                        maxDate = this._getMinMaxDate(inst, "max"),
5703
                        minYear = null,
5704
                        maxYear = null,
5705
                        years = this._get(inst, "yearRange");
5706
                        if (years){
5707
                                yearSplit = years.split(":");
5708
                                currentYear = new Date().getFullYear();
5709
                                minYear = parseInt(yearSplit[0], 10);
5710
                                maxYear = parseInt(yearSplit[1], 10);
5711
                                if ( yearSplit[0].match(/[+\-].*/) ) {
5712
                                        minYear += currentYear;
5713
                                }
5714
                                if ( yearSplit[1].match(/[+\-].*/) ) {
5715
                                        maxYear += currentYear;
5716
                                }
5717
                        }
5718

    
5719
                return ((!minDate || date.getTime() >= minDate.getTime()) &&
5720
                        (!maxDate || date.getTime() <= maxDate.getTime()) &&
5721
                        (!minYear || date.getFullYear() >= minYear) &&
5722
                        (!maxYear || date.getFullYear() <= maxYear));
5723
        },
5724

    
5725
        /* Provide the configuration settings for formatting/parsing. */
5726
        _getFormatConfig: function(inst) {
5727
                var shortYearCutoff = this._get(inst, "shortYearCutoff");
5728
                shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
5729
                        new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
5730
                return {shortYearCutoff: shortYearCutoff,
5731
                        dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
5732
                        monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
5733
        },
5734

    
5735
        /* Format the given date for display. */
5736
        _formatDate: function(inst, day, month, year) {
5737
                if (!day) {
5738
                        inst.currentDay = inst.selectedDay;
5739
                        inst.currentMonth = inst.selectedMonth;
5740
                        inst.currentYear = inst.selectedYear;
5741
                }
5742
                var date = (day ? (typeof day === "object" ? day :
5743
                        this._daylightSavingAdjust(new Date(year, month, day))) :
5744
                        this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
5745
                return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
5746
        }
5747
});
5748

    
5749
/*
5750
 * Bind hover events for datepicker elements.
5751
 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
5752
 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
5753
 */
5754
function datepicker_bindHover(dpDiv) {
5755
        var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
5756
        return dpDiv.delegate(selector, "mouseout", function() {
5757
                        $(this).removeClass("ui-state-hover");
5758
                        if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5759
                                $(this).removeClass("ui-datepicker-prev-hover");
5760
                        }
5761
                        if (this.className.indexOf("ui-datepicker-next") !== -1) {
5762
                                $(this).removeClass("ui-datepicker-next-hover");
5763
                        }
5764
                })
5765
                .delegate( selector, "mouseover", datepicker_handleMouseover );
5766
}
5767

    
5768
function datepicker_handleMouseover() {
5769
        if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
5770
                $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
5771
                $(this).addClass("ui-state-hover");
5772
                if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5773
                        $(this).addClass("ui-datepicker-prev-hover");
5774
                }
5775
                if (this.className.indexOf("ui-datepicker-next") !== -1) {
5776
                        $(this).addClass("ui-datepicker-next-hover");
5777
                }
5778
        }
5779
}
5780

    
5781
/* jQuery extend now ignores nulls! */
5782
function datepicker_extendRemove(target, props) {
5783
        $.extend(target, props);
5784
        for (var name in props) {
5785
                if (props[name] == null) {
5786
                        target[name] = props[name];
5787
                }
5788
        }
5789
        return target;
5790
}
5791

    
5792
/* Invoke the datepicker functionality.
5793
   @param  options  string - a command, optionally followed by additional parameters or
5794
                                        Object - settings for attaching new datepicker functionality
5795
   @return  jQuery object */
5796
$.fn.datepicker = function(options){
5797

    
5798
        /* Verify an empty collection wasn't passed - Fixes #6976 */
5799
        if ( !this.length ) {
5800
                return this;
5801
        }
5802

    
5803
        /* Initialise the date picker. */
5804
        if (!$.datepicker.initialized) {
5805
                $(document).mousedown($.datepicker._checkExternalClick);
5806
                $.datepicker.initialized = true;
5807
        }
5808

    
5809
        /* Append datepicker main container to body if not exist. */
5810
        if ($("#"+$.datepicker._mainDivId).length === 0) {
5811
                $("body").append($.datepicker.dpDiv);
5812
        }
5813

    
5814
        var otherArgs = Array.prototype.slice.call(arguments, 1);
5815
        if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
5816
                return $.datepicker["_" + options + "Datepicker"].
5817
                        apply($.datepicker, [this[0]].concat(otherArgs));
5818
        }
5819
        if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
5820
                return $.datepicker["_" + options + "Datepicker"].
5821
                        apply($.datepicker, [this[0]].concat(otherArgs));
5822
        }
5823
        return this.each(function() {
5824
                typeof options === "string" ?
5825
                        $.datepicker["_" + options + "Datepicker"].
5826
                                apply($.datepicker, [this].concat(otherArgs)) :
5827
                        $.datepicker._attachDatepicker(this, options);
5828
        });
5829
};
5830

    
5831
$.datepicker = new Datepicker(); // singleton instance
5832
$.datepicker.initialized = false;
5833
$.datepicker.uuid = new Date().getTime();
5834
$.datepicker.version = "1.11.4";
5835

    
5836
var datepicker = $.datepicker;
5837

    
5838

    
5839
/*!
5840
 * jQuery UI Draggable 1.11.4
5841
 * http://jqueryui.com
5842
 *
5843
 * Copyright jQuery Foundation and other contributors
5844
 * Released under the MIT license.
5845
 * http://jquery.org/license
5846
 *
5847
 * http://api.jqueryui.com/draggable/
5848
 */
5849

    
5850

    
5851
$.widget("ui.draggable", $.ui.mouse, {
5852
        version: "1.11.4",
5853
        widgetEventPrefix: "drag",
5854
        options: {
5855
                addClasses: true,
5856
                appendTo: "parent",
5857
                axis: false,
5858
                connectToSortable: false,
5859
                containment: false,
5860
                cursor: "auto",
5861
                cursorAt: false,
5862
                grid: false,
5863
                handle: false,
5864
                helper: "original",
5865
                iframeFix: false,
5866
                opacity: false,
5867
                refreshPositions: false,
5868
                revert: false,
5869
                revertDuration: 500,
5870
                scope: "default",
5871
                scroll: true,
5872
                scrollSensitivity: 20,
5873
                scrollSpeed: 20,
5874
                snap: false,
5875
                snapMode: "both",
5876
                snapTolerance: 20,
5877
                stack: false,
5878
                zIndex: false,
5879

    
5880
                // callbacks
5881
                drag: null,
5882
                start: null,
5883
                stop: null
5884
        },
5885
        _create: function() {
5886

    
5887
                if ( this.options.helper === "original" ) {
5888
                        this._setPositionRelative();
5889
                }
5890
                if (this.options.addClasses){
5891
                        this.element.addClass("ui-draggable");
5892
                }
5893
                if (this.options.disabled){
5894
                        this.element.addClass("ui-draggable-disabled");
5895
                }
5896
                this._setHandleClassName();
5897

    
5898
                this._mouseInit();
5899
        },
5900

    
5901
        _setOption: function( key, value ) {
5902
                this._super( key, value );
5903
                if ( key === "handle" ) {
5904
                        this._removeHandleClassName();
5905
                        this._setHandleClassName();
5906
                }
5907
        },
5908

    
5909
        _destroy: function() {
5910
                if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
5911
                        this.destroyOnClear = true;
5912
                        return;
5913
                }
5914
                this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
5915
                this._removeHandleClassName();
5916
                this._mouseDestroy();
5917
        },
5918

    
5919
        _mouseCapture: function(event) {
5920
                var o = this.options;
5921

    
5922
                this._blurActiveElement( event );
5923

    
5924
                // among others, prevent a drag on a resizable-handle
5925
                if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
5926
                        return false;
5927
                }
5928

    
5929
                //Quit if we're not on a valid handle
5930
                this.handle = this._getHandle(event);
5931
                if (!this.handle) {
5932
                        return false;
5933
                }
5934

    
5935
                this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
5936

    
5937
                return true;
5938

    
5939
        },
5940

    
5941
        _blockFrames: function( selector ) {
5942
                this.iframeBlocks = this.document.find( selector ).map(function() {
5943
                        var iframe = $( this );
5944

    
5945
                        return $( "<div>" )
5946
                                .css( "position", "absolute" )
5947
                                .appendTo( iframe.parent() )
5948
                                .outerWidth( iframe.outerWidth() )
5949
                                .outerHeight( iframe.outerHeight() )
5950
                                .offset( iframe.offset() )[ 0 ];
5951
                });
5952
        },
5953

    
5954
        _unblockFrames: function() {
5955
                if ( this.iframeBlocks ) {
5956
                        this.iframeBlocks.remove();
5957
                        delete this.iframeBlocks;
5958
                }
5959
        },
5960

    
5961
        _blurActiveElement: function( event ) {
5962
                var document = this.document[ 0 ];
5963

    
5964
                // Only need to blur if the event occurred on the draggable itself, see #10527
5965
                if ( !this.handleElement.is( event.target ) ) {
5966
                        return;
5967
                }
5968

    
5969
                // support: IE9
5970
                // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
5971
                try {
5972

    
5973
                        // Support: IE9, IE10
5974
                        // If the <body> is blurred, IE will switch windows, see #9520
5975
                        if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
5976

    
5977
                                // Blur any element that currently has focus, see #4261
5978
                                $( document.activeElement ).blur();
5979
                        }
5980
                } catch ( error ) {}
5981
        },
5982

    
5983
        _mouseStart: function(event) {
5984

    
5985
                var o = this.options;
5986

    
5987
                //Create and append the visible helper
5988
                this.helper = this._createHelper(event);
5989

    
5990
                this.helper.addClass("ui-draggable-dragging");
5991

    
5992
                //Cache the helper size
5993
                this._cacheHelperProportions();
5994

    
5995
                //If ddmanager is used for droppables, set the global draggable
5996
                if ($.ui.ddmanager) {
5997
                        $.ui.ddmanager.current = this;
5998
                }
5999

    
6000
                /*
6001
                 * - Position generation -
6002
                 * This block generates everything position related - it's the core of draggables.
6003
                 */
6004

    
6005
                //Cache the margins of the original element
6006
                this._cacheMargins();
6007

    
6008
                //Store the helper's css position
6009
                this.cssPosition = this.helper.css( "position" );
6010
                this.scrollParent = this.helper.scrollParent( true );
6011
                this.offsetParent = this.helper.offsetParent();
6012
                this.hasFixedAncestor = this.helper.parents().filter(function() {
6013
                                return $( this ).css( "position" ) === "fixed";
6014
                        }).length > 0;
6015

    
6016
                //The element's absolute position on the page minus margins
6017
                this.positionAbs = this.element.offset();
6018
                this._refreshOffsets( event );
6019

    
6020
                //Generate the original position
6021
                this.originalPosition = this.position = this._generatePosition( event, false );
6022
                this.originalPageX = event.pageX;
6023
                this.originalPageY = event.pageY;
6024

    
6025
                //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
6026
                (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
6027

    
6028
                //Set a containment if given in the options
6029
                this._setContainment();
6030

    
6031
                //Trigger event + callbacks
6032
                if (this._trigger("start", event) === false) {
6033
                        this._clear();
6034
                        return false;
6035
                }
6036

    
6037
                //Recache the helper size
6038
                this._cacheHelperProportions();
6039

    
6040
                //Prepare the droppable offsets
6041
                if ($.ui.ddmanager && !o.dropBehaviour) {
6042
                        $.ui.ddmanager.prepareOffsets(this, event);
6043
                }
6044

    
6045
                // Reset helper's right/bottom css if they're set and set explicit width/height instead
6046
                // as this prevents resizing of elements with right/bottom set (see #7772)
6047
                this._normalizeRightBottom();
6048

    
6049
                this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
6050

    
6051
                //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
6052
                if ( $.ui.ddmanager ) {
6053
                        $.ui.ddmanager.dragStart(this, event);
6054
                }
6055

    
6056
                return true;
6057
        },
6058

    
6059
        _refreshOffsets: function( event ) {
6060
                this.offset = {
6061
                        top: this.positionAbs.top - this.margins.top,
6062
                        left: this.positionAbs.left - this.margins.left,
6063
                        scroll: false,
6064
                        parent: this._getParentOffset(),
6065
                        relative: this._getRelativeOffset()
6066
                };
6067

    
6068
                this.offset.click = {
6069
                        left: event.pageX - this.offset.left,
6070
                        top: event.pageY - this.offset.top
6071
                };
6072
        },
6073

    
6074
        _mouseDrag: function(event, noPropagation) {
6075
                // reset any necessary cached properties (see #5009)
6076
                if ( this.hasFixedAncestor ) {
6077
                        this.offset.parent = this._getParentOffset();
6078
                }
6079

    
6080
                //Compute the helpers position
6081
                this.position = this._generatePosition( event, true );
6082
                this.positionAbs = this._convertPositionTo("absolute");
6083

    
6084
                //Call plugins and callbacks and use the resulting position if something is returned
6085
                if (!noPropagation) {
6086
                        var ui = this._uiHash();
6087
                        if (this._trigger("drag", event, ui) === false) {
6088
                                this._mouseUp({});
6089
                                return false;
6090
                        }
6091
                        this.position = ui.position;
6092
                }
6093

    
6094
                this.helper[ 0 ].style.left = this.position.left + "px";
6095
                this.helper[ 0 ].style.top = this.position.top + "px";
6096

    
6097
                if ($.ui.ddmanager) {
6098
                        $.ui.ddmanager.drag(this, event);
6099
                }
6100

    
6101
                return false;
6102
        },
6103

    
6104
        _mouseStop: function(event) {
6105

    
6106
                //If we are using droppables, inform the manager about the drop
6107
                var that = this,
6108
                        dropped = false;
6109
                if ($.ui.ddmanager && !this.options.dropBehaviour) {
6110
                        dropped = $.ui.ddmanager.drop(this, event);
6111
                }
6112

    
6113
                //if a drop comes from outside (a sortable)
6114
                if (this.dropped) {
6115
                        dropped = this.dropped;
6116
                        this.dropped = false;
6117
                }
6118

    
6119
                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))) {
6120
                        $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
6121
                                if (that._trigger("stop", event) !== false) {
6122
                                        that._clear();
6123
                                }
6124
                        });
6125
                } else {
6126
                        if (this._trigger("stop", event) !== false) {
6127
                                this._clear();
6128
                        }
6129
                }
6130

    
6131
                return false;
6132
        },
6133

    
6134
        _mouseUp: function( event ) {
6135
                this._unblockFrames();
6136

    
6137
                //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
6138
                if ( $.ui.ddmanager ) {
6139
                        $.ui.ddmanager.dragStop(this, event);
6140
                }
6141

    
6142
                // Only need to focus if the event occurred on the draggable itself, see #10527
6143
                if ( this.handleElement.is( event.target ) ) {
6144
                        // The interaction is over; whether or not the click resulted in a drag, focus the element
6145
                        this.element.focus();
6146
                }
6147

    
6148
                return $.ui.mouse.prototype._mouseUp.call(this, event);
6149
        },
6150

    
6151
        cancel: function() {
6152

    
6153
                if (this.helper.is(".ui-draggable-dragging")) {
6154
                        this._mouseUp({});
6155
                } else {
6156
                        this._clear();
6157
                }
6158

    
6159
                return this;
6160

    
6161
        },
6162

    
6163
        _getHandle: function(event) {
6164
                return this.options.handle ?
6165
                        !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
6166
                        true;
6167
        },
6168

    
6169
        _setHandleClassName: function() {
6170
                this.handleElement = this.options.handle ?
6171
                        this.element.find( this.options.handle ) : this.element;
6172
                this.handleElement.addClass( "ui-draggable-handle" );
6173
        },
6174

    
6175
        _removeHandleClassName: function() {
6176
                this.handleElement.removeClass( "ui-draggable-handle" );
6177
        },
6178

    
6179
        _createHelper: function(event) {
6180

    
6181
                var o = this.options,
6182
                        helperIsFunction = $.isFunction( o.helper ),
6183
                        helper = helperIsFunction ?
6184
                                $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
6185
                                ( o.helper === "clone" ?
6186
                                        this.element.clone().removeAttr( "id" ) :
6187
                                        this.element );
6188

    
6189
                if (!helper.parents("body").length) {
6190
                        helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
6191
                }
6192

    
6193
                // http://bugs.jqueryui.com/ticket/9446
6194
                // a helper function can return the original element
6195
                // which wouldn't have been set to relative in _create
6196
                if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
6197
                        this._setPositionRelative();
6198
                }
6199

    
6200
                if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
6201
                        helper.css("position", "absolute");
6202
                }
6203

    
6204
                return helper;
6205

    
6206
        },
6207

    
6208
        _setPositionRelative: function() {
6209
                if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
6210
                        this.element[ 0 ].style.position = "relative";
6211
                }
6212
        },
6213

    
6214
        _adjustOffsetFromHelper: function(obj) {
6215
                if (typeof obj === "string") {
6216
                        obj = obj.split(" ");
6217
                }
6218
                if ($.isArray(obj)) {
6219
                        obj = { left: +obj[0], top: +obj[1] || 0 };
6220
                }
6221
                if ("left" in obj) {
6222
                        this.offset.click.left = obj.left + this.margins.left;
6223
                }
6224
                if ("right" in obj) {
6225
                        this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6226
                }
6227
                if ("top" in obj) {
6228
                        this.offset.click.top = obj.top + this.margins.top;
6229
                }
6230
                if ("bottom" in obj) {
6231
                        this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6232
                }
6233
        },
6234

    
6235
        _isRootNode: function( element ) {
6236
                return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
6237
        },
6238

    
6239
        _getParentOffset: function() {
6240

    
6241
                //Get the offsetParent and cache its position
6242
                var po = this.offsetParent.offset(),
6243
                        document = this.document[ 0 ];
6244

    
6245
                // This is a special case where we need to modify a offset calculated on start, since the following happened:
6246
                // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
6247
                // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
6248
                //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
6249
                if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
6250
                        po.left += this.scrollParent.scrollLeft();
6251
                        po.top += this.scrollParent.scrollTop();
6252
                }
6253

    
6254
                if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
6255
                        po = { top: 0, left: 0 };
6256
                }
6257

    
6258
                return {
6259
                        top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
6260
                        left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
6261
                };
6262

    
6263
        },
6264

    
6265
        _getRelativeOffset: function() {
6266
                if ( this.cssPosition !== "relative" ) {
6267
                        return { top: 0, left: 0 };
6268
                }
6269

    
6270
                var p = this.element.position(),
6271
                        scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6272

    
6273
                return {
6274
                        top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
6275
                        left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
6276
                };
6277

    
6278
        },
6279

    
6280
        _cacheMargins: function() {
6281
                this.margins = {
6282
                        left: (parseInt(this.element.css("marginLeft"), 10) || 0),
6283
                        top: (parseInt(this.element.css("marginTop"), 10) || 0),
6284
                        right: (parseInt(this.element.css("marginRight"), 10) || 0),
6285
                        bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
6286
                };
6287
        },
6288

    
6289
        _cacheHelperProportions: function() {
6290
                this.helperProportions = {
6291
                        width: this.helper.outerWidth(),
6292
                        height: this.helper.outerHeight()
6293
                };
6294
        },
6295

    
6296
        _setContainment: function() {
6297

    
6298
                var isUserScrollable, c, ce,
6299
                        o = this.options,
6300
                        document = this.document[ 0 ];
6301

    
6302
                this.relativeContainer = null;
6303

    
6304
                if ( !o.containment ) {
6305
                        this.containment = null;
6306
                        return;
6307
                }
6308

    
6309
                if ( o.containment === "window" ) {
6310
                        this.containment = [
6311
                                $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
6312
                                $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
6313
                                $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
6314
                                $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6315
                        ];
6316
                        return;
6317
                }
6318

    
6319
                if ( o.containment === "document") {
6320
                        this.containment = [
6321
                                0,
6322
                                0,
6323
                                $( document ).width() - this.helperProportions.width - this.margins.left,
6324
                                ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6325
                        ];
6326
                        return;
6327
                }
6328

    
6329
                if ( o.containment.constructor === Array ) {
6330
                        this.containment = o.containment;
6331
                        return;
6332
                }
6333

    
6334
                if ( o.containment === "parent" ) {
6335
                        o.containment = this.helper[ 0 ].parentNode;
6336
                }
6337

    
6338
                c = $( o.containment );
6339
                ce = c[ 0 ];
6340

    
6341
                if ( !ce ) {
6342
                        return;
6343
                }
6344

    
6345
                isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
6346

    
6347
                this.containment = [
6348
                        ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
6349
                        ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
6350
                        ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
6351
                                ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
6352
                                ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
6353
                                this.helperProportions.width -
6354
                                this.margins.left -
6355
                                this.margins.right,
6356
                        ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
6357
                                ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
6358
                                ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
6359
                                this.helperProportions.height -
6360
                                this.margins.top -
6361
                                this.margins.bottom
6362
                ];
6363
                this.relativeContainer = c;
6364
        },
6365

    
6366
        _convertPositionTo: function(d, pos) {
6367

    
6368
                if (!pos) {
6369
                        pos = this.position;
6370
                }
6371

    
6372
                var mod = d === "absolute" ? 1 : -1,
6373
                        scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6374

    
6375
                return {
6376
                        top: (
6377
                                pos.top        +                                                                                                                                // The absolute mouse position
6378
                                this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6379
                                this.offset.parent.top * mod -                                                                                // The offsetParent's offset without borders (offset + border)
6380
                                ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
6381
                        ),
6382
                        left: (
6383
                                pos.left +                                                                                                                                // The absolute mouse position
6384
                                this.offset.relative.left * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6385
                                this.offset.parent.left * mod        -                                                                                // The offsetParent's offset without borders (offset + border)
6386
                                ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
6387
                        )
6388
                };
6389

    
6390
        },
6391

    
6392
        _generatePosition: function( event, constrainPosition ) {
6393

    
6394
                var containment, co, top, left,
6395
                        o = this.options,
6396
                        scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
6397
                        pageX = event.pageX,
6398
                        pageY = event.pageY;
6399

    
6400
                // Cache the scroll
6401
                if ( !scrollIsRootNode || !this.offset.scroll ) {
6402
                        this.offset.scroll = {
6403
                                top: this.scrollParent.scrollTop(),
6404
                                left: this.scrollParent.scrollLeft()
6405
                        };
6406
                }
6407

    
6408
                /*
6409
                 * - Position constraining -
6410
                 * Constrain the position to a mix of grid, containment.
6411
                 */
6412

    
6413
                // If we are not dragging yet, we won't check for options
6414
                if ( constrainPosition ) {
6415
                        if ( this.containment ) {
6416
                                if ( this.relativeContainer ){
6417
                                        co = this.relativeContainer.offset();
6418
                                        containment = [
6419
                                                this.containment[ 0 ] + co.left,
6420
                                                this.containment[ 1 ] + co.top,
6421
                                                this.containment[ 2 ] + co.left,
6422
                                                this.containment[ 3 ] + co.top
6423
                                        ];
6424
                                } else {
6425
                                        containment = this.containment;
6426
                                }
6427

    
6428
                                if (event.pageX - this.offset.click.left < containment[0]) {
6429
                                        pageX = containment[0] + this.offset.click.left;
6430
                                }
6431
                                if (event.pageY - this.offset.click.top < containment[1]) {
6432
                                        pageY = containment[1] + this.offset.click.top;
6433
                                }
6434
                                if (event.pageX - this.offset.click.left > containment[2]) {
6435
                                        pageX = containment[2] + this.offset.click.left;
6436
                                }
6437
                                if (event.pageY - this.offset.click.top > containment[3]) {
6438
                                        pageY = containment[3] + this.offset.click.top;
6439
                                }
6440
                        }
6441

    
6442
                        if (o.grid) {
6443
                                //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
6444
                                top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
6445
                                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;
6446

    
6447
                                left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
6448
                                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;
6449
                        }
6450

    
6451
                        if ( o.axis === "y" ) {
6452
                                pageX = this.originalPageX;
6453
                        }
6454

    
6455
                        if ( o.axis === "x" ) {
6456
                                pageY = this.originalPageY;
6457
                        }
6458
                }
6459

    
6460
                return {
6461
                        top: (
6462
                                pageY -                                                                                                                                        // The absolute mouse position
6463
                                this.offset.click.top        -                                                                                                // Click offset (relative to the element)
6464
                                this.offset.relative.top -                                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6465
                                this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
6466
                                ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
6467
                        ),
6468
                        left: (
6469
                                pageX -                                                                                                                                        // The absolute mouse position
6470
                                this.offset.click.left -                                                                                                // Click offset (relative to the element)
6471
                                this.offset.relative.left -                                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6472
                                this.offset.parent.left +                                                                                                // The offsetParent's offset without borders (offset + border)
6473
                                ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
6474
                        )
6475
                };
6476

    
6477
        },
6478

    
6479
        _clear: function() {
6480
                this.helper.removeClass("ui-draggable-dragging");
6481
                if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
6482
                        this.helper.remove();
6483
                }
6484
                this.helper = null;
6485
                this.cancelHelperRemoval = false;
6486
                if ( this.destroyOnClear ) {
6487
                        this.destroy();
6488
                }
6489
        },
6490

    
6491
        _normalizeRightBottom: function() {
6492
                if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
6493
                        this.helper.width( this.helper.width() );
6494
                        this.helper.css( "right", "auto" );
6495
                }
6496
                if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
6497
                        this.helper.height( this.helper.height() );
6498
                        this.helper.css( "bottom", "auto" );
6499
                }
6500
        },
6501

    
6502
        // From now on bulk stuff - mainly helpers
6503

    
6504
        _trigger: function( type, event, ui ) {
6505
                ui = ui || this._uiHash();
6506
                $.ui.plugin.call( this, type, [ event, ui, this ], true );
6507

    
6508
                // Absolute position and offset (see #6884 ) have to be recalculated after plugins
6509
                if ( /^(drag|start|stop)/.test( type ) ) {
6510
                        this.positionAbs = this._convertPositionTo( "absolute" );
6511
                        ui.offset = this.positionAbs;
6512
                }
6513
                return $.Widget.prototype._trigger.call( this, type, event, ui );
6514
        },
6515

    
6516
        plugins: {},
6517

    
6518
        _uiHash: function() {
6519
                return {
6520
                        helper: this.helper,
6521
                        position: this.position,
6522
                        originalPosition: this.originalPosition,
6523
                        offset: this.positionAbs
6524
                };
6525
        }
6526

    
6527
});
6528

    
6529
$.ui.plugin.add( "draggable", "connectToSortable", {
6530
        start: function( event, ui, draggable ) {
6531
                var uiSortable = $.extend( {}, ui, {
6532
                        item: draggable.element
6533
                });
6534

    
6535
                draggable.sortables = [];
6536
                $( draggable.options.connectToSortable ).each(function() {
6537
                        var sortable = $( this ).sortable( "instance" );
6538

    
6539
                        if ( sortable && !sortable.options.disabled ) {
6540
                                draggable.sortables.push( sortable );
6541

    
6542
                                // refreshPositions is called at drag start to refresh the containerCache
6543
                                // which is used in drag. This ensures it's initialized and synchronized
6544
                                // with any changes that might have happened on the page since initialization.
6545
                                sortable.refreshPositions();
6546
                                sortable._trigger("activate", event, uiSortable);
6547
                        }
6548
                });
6549
        },
6550
        stop: function( event, ui, draggable ) {
6551
                var uiSortable = $.extend( {}, ui, {
6552
                        item: draggable.element
6553
                });
6554

    
6555
                draggable.cancelHelperRemoval = false;
6556

    
6557
                $.each( draggable.sortables, function() {
6558
                        var sortable = this;
6559

    
6560
                        if ( sortable.isOver ) {
6561
                                sortable.isOver = 0;
6562

    
6563
                                // Allow this sortable to handle removing the helper
6564
                                draggable.cancelHelperRemoval = true;
6565
                                sortable.cancelHelperRemoval = false;
6566

    
6567
                                // Use _storedCSS To restore properties in the sortable,
6568
                                // as this also handles revert (#9675) since the draggable
6569
                                // may have modified them in unexpected ways (#8809)
6570
                                sortable._storedCSS = {
6571
                                        position: sortable.placeholder.css( "position" ),
6572
                                        top: sortable.placeholder.css( "top" ),
6573
                                        left: sortable.placeholder.css( "left" )
6574
                                };
6575

    
6576
                                sortable._mouseStop(event);
6577

    
6578
                                // Once drag has ended, the sortable should return to using
6579
                                // its original helper, not the shared helper from draggable
6580
                                sortable.options.helper = sortable.options._helper;
6581
                        } else {
6582
                                // Prevent this Sortable from removing the helper.
6583
                                // However, don't set the draggable to remove the helper
6584
                                // either as another connected Sortable may yet handle the removal.
6585
                                sortable.cancelHelperRemoval = true;
6586

    
6587
                                sortable._trigger( "deactivate", event, uiSortable );
6588
                        }
6589
                });
6590
        },
6591
        drag: function( event, ui, draggable ) {
6592
                $.each( draggable.sortables, function() {
6593
                        var innermostIntersecting = false,
6594
                                sortable = this;
6595

    
6596
                        // Copy over variables that sortable's _intersectsWith uses
6597
                        sortable.positionAbs = draggable.positionAbs;
6598
                        sortable.helperProportions = draggable.helperProportions;
6599
                        sortable.offset.click = draggable.offset.click;
6600

    
6601
                        if ( sortable._intersectsWith( sortable.containerCache ) ) {
6602
                                innermostIntersecting = true;
6603

    
6604
                                $.each( draggable.sortables, function() {
6605
                                        // Copy over variables that sortable's _intersectsWith uses
6606
                                        this.positionAbs = draggable.positionAbs;
6607
                                        this.helperProportions = draggable.helperProportions;
6608
                                        this.offset.click = draggable.offset.click;
6609

    
6610
                                        if ( this !== sortable &&
6611
                                                        this._intersectsWith( this.containerCache ) &&
6612
                                                        $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
6613
                                                innermostIntersecting = false;
6614
                                        }
6615

    
6616
                                        return innermostIntersecting;
6617
                                });
6618
                        }
6619

    
6620
                        if ( innermostIntersecting ) {
6621
                                // If it intersects, we use a little isOver variable and set it once,
6622
                                // so that the move-in stuff gets fired only once.
6623
                                if ( !sortable.isOver ) {
6624
                                        sortable.isOver = 1;
6625

    
6626
                                        // Store draggable's parent in case we need to reappend to it later.
6627
                                        draggable._parent = ui.helper.parent();
6628

    
6629
                                        sortable.currentItem = ui.helper
6630
                                                .appendTo( sortable.element )
6631
                                                .data( "ui-sortable-item", true );
6632

    
6633
                                        // Store helper option to later restore it
6634
                                        sortable.options._helper = sortable.options.helper;
6635

    
6636
                                        sortable.options.helper = function() {
6637
                                                return ui.helper[ 0 ];
6638
                                        };
6639

    
6640
                                        // Fire the start events of the sortable with our passed browser event,
6641
                                        // and our own helper (so it doesn't create a new one)
6642
                                        event.target = sortable.currentItem[ 0 ];
6643
                                        sortable._mouseCapture( event, true );
6644
                                        sortable._mouseStart( event, true, true );
6645

    
6646
                                        // Because the browser event is way off the new appended portlet,
6647
                                        // modify necessary variables to reflect the changes
6648
                                        sortable.offset.click.top = draggable.offset.click.top;
6649
                                        sortable.offset.click.left = draggable.offset.click.left;
6650
                                        sortable.offset.parent.left -= draggable.offset.parent.left -
6651
                                                sortable.offset.parent.left;
6652
                                        sortable.offset.parent.top -= draggable.offset.parent.top -
6653
                                                sortable.offset.parent.top;
6654

    
6655
                                        draggable._trigger( "toSortable", event );
6656

    
6657
                                        // Inform draggable that the helper is in a valid drop zone,
6658
                                        // used solely in the revert option to handle "valid/invalid".
6659
                                        draggable.dropped = sortable.element;
6660

    
6661
                                        // Need to refreshPositions of all sortables in the case that
6662
                                        // adding to one sortable changes the location of the other sortables (#9675)
6663
                                        $.each( draggable.sortables, function() {
6664
                                                this.refreshPositions();
6665
                                        });
6666

    
6667
                                        // hack so receive/update callbacks work (mostly)
6668
                                        draggable.currentItem = draggable.element;
6669
                                        sortable.fromOutside = draggable;
6670
                                }
6671

    
6672
                                if ( sortable.currentItem ) {
6673
                                        sortable._mouseDrag( event );
6674
                                        // Copy the sortable's position because the draggable's can potentially reflect
6675
                                        // a relative position, while sortable is always absolute, which the dragged
6676
                                        // element has now become. (#8809)
6677
                                        ui.position = sortable.position;
6678
                                }
6679
                        } else {
6680
                                // If it doesn't intersect with the sortable, and it intersected before,
6681
                                // we fake the drag stop of the sortable, but make sure it doesn't remove
6682
                                // the helper by using cancelHelperRemoval.
6683
                                if ( sortable.isOver ) {
6684

    
6685
                                        sortable.isOver = 0;
6686
                                        sortable.cancelHelperRemoval = true;
6687

    
6688
                                        // Calling sortable's mouseStop would trigger a revert,
6689
                                        // so revert must be temporarily false until after mouseStop is called.
6690
                                        sortable.options._revert = sortable.options.revert;
6691
                                        sortable.options.revert = false;
6692

    
6693
                                        sortable._trigger( "out", event, sortable._uiHash( sortable ) );
6694
                                        sortable._mouseStop( event, true );
6695

    
6696
                                        // restore sortable behaviors that were modfied
6697
                                        // when the draggable entered the sortable area (#9481)
6698
                                        sortable.options.revert = sortable.options._revert;
6699
                                        sortable.options.helper = sortable.options._helper;
6700

    
6701
                                        if ( sortable.placeholder ) {
6702
                                                sortable.placeholder.remove();
6703
                                        }
6704

    
6705
                                        // Restore and recalculate the draggable's offset considering the sortable
6706
                                        // may have modified them in unexpected ways. (#8809, #10669)
6707
                                        ui.helper.appendTo( draggable._parent );
6708
                                        draggable._refreshOffsets( event );
6709
                                        ui.position = draggable._generatePosition( event, true );
6710

    
6711
                                        draggable._trigger( "fromSortable", event );
6712

    
6713
                                        // Inform draggable that the helper is no longer in a valid drop zone
6714
                                        draggable.dropped = false;
6715

    
6716
                                        // Need to refreshPositions of all sortables just in case removing
6717
                                        // from one sortable changes the location of other sortables (#9675)
6718
                                        $.each( draggable.sortables, function() {
6719
                                                this.refreshPositions();
6720
                                        });
6721
                                }
6722
                        }
6723
                });
6724
        }
6725
});
6726

    
6727
$.ui.plugin.add("draggable", "cursor", {
6728
        start: function( event, ui, instance ) {
6729
                var t = $( "body" ),
6730
                        o = instance.options;
6731

    
6732
                if (t.css("cursor")) {
6733
                        o._cursor = t.css("cursor");
6734
                }
6735
                t.css("cursor", o.cursor);
6736
        },
6737
        stop: function( event, ui, instance ) {
6738
                var o = instance.options;
6739
                if (o._cursor) {
6740
                        $("body").css("cursor", o._cursor);
6741
                }
6742
        }
6743
});
6744

    
6745
$.ui.plugin.add("draggable", "opacity", {
6746
        start: function( event, ui, instance ) {
6747
                var t = $( ui.helper ),
6748
                        o = instance.options;
6749
                if (t.css("opacity")) {
6750
                        o._opacity = t.css("opacity");
6751
                }
6752
                t.css("opacity", o.opacity);
6753
        },
6754
        stop: function( event, ui, instance ) {
6755
                var o = instance.options;
6756
                if (o._opacity) {
6757
                        $(ui.helper).css("opacity", o._opacity);
6758
                }
6759
        }
6760
});
6761

    
6762
$.ui.plugin.add("draggable", "scroll", {
6763
        start: function( event, ui, i ) {
6764
                if ( !i.scrollParentNotHidden ) {
6765
                        i.scrollParentNotHidden = i.helper.scrollParent( false );
6766
                }
6767

    
6768
                if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
6769
                        i.overflowOffset = i.scrollParentNotHidden.offset();
6770
                }
6771
        },
6772
        drag: function( event, ui, i  ) {
6773

    
6774
                var o = i.options,
6775
                        scrolled = false,
6776
                        scrollParent = i.scrollParentNotHidden[ 0 ],
6777
                        document = i.document[ 0 ];
6778

    
6779
                if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
6780
                        if ( !o.axis || o.axis !== "x" ) {
6781
                                if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
6782
                                        scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
6783
                                } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
6784
                                        scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
6785
                                }
6786
                        }
6787

    
6788
                        if ( !o.axis || o.axis !== "y" ) {
6789
                                if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
6790
                                        scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
6791
                                } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
6792
                                        scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
6793
                                }
6794
                        }
6795

    
6796
                } else {
6797

    
6798
                        if (!o.axis || o.axis !== "x") {
6799
                                if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
6800
                                        scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
6801
                                } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
6802
                                        scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
6803
                                }
6804
                        }
6805

    
6806
                        if (!o.axis || o.axis !== "y") {
6807
                                if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
6808
                                        scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
6809
                                } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
6810
                                        scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
6811
                                }
6812
                        }
6813

    
6814
                }
6815

    
6816
                if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
6817
                        $.ui.ddmanager.prepareOffsets(i, event);
6818
                }
6819

    
6820
        }
6821
});
6822

    
6823
$.ui.plugin.add("draggable", "snap", {
6824
        start: function( event, ui, i ) {
6825

    
6826
                var o = i.options;
6827

    
6828
                i.snapElements = [];
6829

    
6830
                $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
6831
                        var $t = $(this),
6832
                                $o = $t.offset();
6833
                        if (this !== i.element[0]) {
6834
                                i.snapElements.push({
6835
                                        item: this,
6836
                                        width: $t.outerWidth(), height: $t.outerHeight(),
6837
                                        top: $o.top, left: $o.left
6838
                                });
6839
                        }
6840
                });
6841

    
6842
        },
6843
        drag: function( event, ui, inst ) {
6844

    
6845
                var ts, bs, ls, rs, l, r, t, b, i, first,
6846
                        o = inst.options,
6847
                        d = o.snapTolerance,
6848
                        x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
6849
                        y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
6850

    
6851
                for (i = inst.snapElements.length - 1; i >= 0; i--){
6852

    
6853
                        l = inst.snapElements[i].left - inst.margins.left;
6854
                        r = l + inst.snapElements[i].width;
6855
                        t = inst.snapElements[i].top - inst.margins.top;
6856
                        b = t + inst.snapElements[i].height;
6857

    
6858
                        if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
6859
                                if (inst.snapElements[i].snapping) {
6860
                                        (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6861
                                }
6862
                                inst.snapElements[i].snapping = false;
6863
                                continue;
6864
                        }
6865

    
6866
                        if (o.snapMode !== "inner") {
6867
                                ts = Math.abs(t - y2) <= d;
6868
                                bs = Math.abs(b - y1) <= d;
6869
                                ls = Math.abs(l - x2) <= d;
6870
                                rs = Math.abs(r - x1) <= d;
6871
                                if (ts) {
6872
                                        ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
6873
                                }
6874
                                if (bs) {
6875
                                        ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
6876
                                }
6877
                                if (ls) {
6878
                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
6879
                                }
6880
                                if (rs) {
6881
                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
6882
                                }
6883
                        }
6884

    
6885
                        first = (ts || bs || ls || rs);
6886

    
6887
                        if (o.snapMode !== "outer") {
6888
                                ts = Math.abs(t - y1) <= d;
6889
                                bs = Math.abs(b - y2) <= d;
6890
                                ls = Math.abs(l - x1) <= d;
6891
                                rs = Math.abs(r - x2) <= d;
6892
                                if (ts) {
6893
                                        ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
6894
                                }
6895
                                if (bs) {
6896
                                        ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
6897
                                }
6898
                                if (ls) {
6899
                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
6900
                                }
6901
                                if (rs) {
6902
                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
6903
                                }
6904
                        }
6905

    
6906
                        if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
6907
                                (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6908
                        }
6909
                        inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
6910

    
6911
                }
6912

    
6913
        }
6914
});
6915

    
6916
$.ui.plugin.add("draggable", "stack", {
6917
        start: function( event, ui, instance ) {
6918
                var min,
6919
                        o = instance.options,
6920
                        group = $.makeArray($(o.stack)).sort(function(a, b) {
6921
                                return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
6922
                        });
6923

    
6924
                if (!group.length) { return; }
6925

    
6926
                min = parseInt($(group[0]).css("zIndex"), 10) || 0;
6927
                $(group).each(function(i) {
6928
                        $(this).css("zIndex", min + i);
6929
                });
6930
                this.css("zIndex", (min + group.length));
6931
        }
6932
});
6933

    
6934
$.ui.plugin.add("draggable", "zIndex", {
6935
        start: function( event, ui, instance ) {
6936
                var t = $( ui.helper ),
6937
                        o = instance.options;
6938

    
6939
                if (t.css("zIndex")) {
6940
                        o._zIndex = t.css("zIndex");
6941
                }
6942
                t.css("zIndex", o.zIndex);
6943
        },
6944
        stop: function( event, ui, instance ) {
6945
                var o = instance.options;
6946

    
6947
                if (o._zIndex) {
6948
                        $(ui.helper).css("zIndex", o._zIndex);
6949
                }
6950
        }
6951
});
6952

    
6953
var draggable = $.ui.draggable;
6954

    
6955

    
6956
/*!
6957
 * jQuery UI Resizable 1.11.4
6958
 * http://jqueryui.com
6959
 *
6960
 * Copyright jQuery Foundation and other contributors
6961
 * Released under the MIT license.
6962
 * http://jquery.org/license
6963
 *
6964
 * http://api.jqueryui.com/resizable/
6965
 */
6966

    
6967

    
6968
$.widget("ui.resizable", $.ui.mouse, {
6969
        version: "1.11.4",
6970
        widgetEventPrefix: "resize",
6971
        options: {
6972
                alsoResize: false,
6973
                animate: false,
6974
                animateDuration: "slow",
6975
                animateEasing: "swing",
6976
                aspectRatio: false,
6977
                autoHide: false,
6978
                containment: false,
6979
                ghost: false,
6980
                grid: false,
6981
                handles: "e,s,se",
6982
                helper: false,
6983
                maxHeight: null,
6984
                maxWidth: null,
6985
                minHeight: 10,
6986
                minWidth: 10,
6987
                // See #7960
6988
                zIndex: 90,
6989

    
6990
                // callbacks
6991
                resize: null,
6992
                start: null,
6993
                stop: null
6994
        },
6995

    
6996
        _num: function( value ) {
6997
                return parseInt( value, 10 ) || 0;
6998
        },
6999

    
7000
        _isNumber: function( value ) {
7001
                return !isNaN( parseInt( value, 10 ) );
7002
        },
7003

    
7004
        _hasScroll: function( el, a ) {
7005

    
7006
                if ( $( el ).css( "overflow" ) === "hidden") {
7007
                        return false;
7008
                }
7009

    
7010
                var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
7011
                        has = false;
7012

    
7013
                if ( el[ scroll ] > 0 ) {
7014
                        return true;
7015
                }
7016

    
7017
                // TODO: determine which cases actually cause this to happen
7018
                // if the element doesn't have the scroll set, see if it's possible to
7019
                // set the scroll
7020
                el[ scroll ] = 1;
7021
                has = ( el[ scroll ] > 0 );
7022
                el[ scroll ] = 0;
7023
                return has;
7024
        },
7025

    
7026
        _create: function() {
7027

    
7028
                var n, i, handle, axis, hname,
7029
                        that = this,
7030
                        o = this.options;
7031
                this.element.addClass("ui-resizable");
7032

    
7033
                $.extend(this, {
7034
                        _aspectRatio: !!(o.aspectRatio),
7035
                        aspectRatio: o.aspectRatio,
7036
                        originalElement: this.element,
7037
                        _proportionallyResizeElements: [],
7038
                        _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
7039
                });
7040

    
7041
                // Wrap the element if it cannot hold child nodes
7042
                if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
7043

    
7044
                        this.element.wrap(
7045
                                $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
7046
                                        position: this.element.css("position"),
7047
                                        width: this.element.outerWidth(),
7048
                                        height: this.element.outerHeight(),
7049
                                        top: this.element.css("top"),
7050
                                        left: this.element.css("left")
7051
                                })
7052
                        );
7053

    
7054
                        this.element = this.element.parent().data(
7055
                                "ui-resizable", this.element.resizable( "instance" )
7056
                        );
7057

    
7058
                        this.elementIsWrapper = true;
7059

    
7060
                        this.element.css({
7061
                                marginLeft: this.originalElement.css("marginLeft"),
7062
                                marginTop: this.originalElement.css("marginTop"),
7063
                                marginRight: this.originalElement.css("marginRight"),
7064
                                marginBottom: this.originalElement.css("marginBottom")
7065
                        });
7066
                        this.originalElement.css({
7067
                                marginLeft: 0,
7068
                                marginTop: 0,
7069
                                marginRight: 0,
7070
                                marginBottom: 0
7071
                        });
7072
                        // support: Safari
7073
                        // Prevent Safari textarea resize
7074
                        this.originalResizeStyle = this.originalElement.css("resize");
7075
                        this.originalElement.css("resize", "none");
7076

    
7077
                        this._proportionallyResizeElements.push( this.originalElement.css({
7078
                                position: "static",
7079
                                zoom: 1,
7080
                                display: "block"
7081
                        }) );
7082

    
7083
                        // support: IE9
7084
                        // avoid IE jump (hard set the margin)
7085
                        this.originalElement.css({ margin: this.originalElement.css("margin") });
7086

    
7087
                        this._proportionallyResize();
7088
                }
7089

    
7090
                this.handles = o.handles ||
7091
                        ( !$(".ui-resizable-handle", this.element).length ?
7092
                                "e,s,se" : {
7093
                                        n: ".ui-resizable-n",
7094
                                        e: ".ui-resizable-e",
7095
                                        s: ".ui-resizable-s",
7096
                                        w: ".ui-resizable-w",
7097
                                        se: ".ui-resizable-se",
7098
                                        sw: ".ui-resizable-sw",
7099
                                        ne: ".ui-resizable-ne",
7100
                                        nw: ".ui-resizable-nw"
7101
                                } );
7102

    
7103
                this._handles = $();
7104
                if ( this.handles.constructor === String ) {
7105

    
7106
                        if ( this.handles === "all") {
7107
                                this.handles = "n,e,s,w,se,sw,ne,nw";
7108
                        }
7109

    
7110
                        n = this.handles.split(",");
7111
                        this.handles = {};
7112

    
7113
                        for (i = 0; i < n.length; i++) {
7114

    
7115
                                handle = $.trim(n[i]);
7116
                                hname = "ui-resizable-" + handle;
7117
                                axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
7118

    
7119
                                axis.css({ zIndex: o.zIndex });
7120

    
7121
                                // TODO : What's going on here?
7122
                                if ("se" === handle) {
7123
                                        axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
7124
                                }
7125

    
7126
                                this.handles[handle] = ".ui-resizable-" + handle;
7127
                                this.element.append(axis);
7128
                        }
7129

    
7130
                }
7131

    
7132
                this._renderAxis = function(target) {
7133

    
7134
                        var i, axis, padPos, padWrapper;
7135

    
7136
                        target = target || this.element;
7137

    
7138
                        for (i in this.handles) {
7139

    
7140
                                if (this.handles[i].constructor === String) {
7141
                                        this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
7142
                                } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
7143
                                        this.handles[ i ] = $( this.handles[ i ] );
7144
                                        this._on( this.handles[ i ], { "mousedown": that._mouseDown });
7145
                                }
7146

    
7147
                                if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
7148

    
7149
                                        axis = $(this.handles[i], this.element);
7150

    
7151
                                        padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
7152

    
7153
                                        padPos = [ "padding",
7154
                                                /ne|nw|n/.test(i) ? "Top" :
7155
                                                /se|sw|s/.test(i) ? "Bottom" :
7156
                                                /^e$/.test(i) ? "Right" : "Left" ].join("");
7157

    
7158
                                        target.css(padPos, padWrapper);
7159

    
7160
                                        this._proportionallyResize();
7161
                                }
7162

    
7163
                                this._handles = this._handles.add( this.handles[ i ] );
7164
                        }
7165
                };
7166

    
7167
                // TODO: make renderAxis a prototype function
7168
                this._renderAxis(this.element);
7169

    
7170
                this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
7171
                this._handles.disableSelection();
7172

    
7173
                this._handles.mouseover(function() {
7174
                        if (!that.resizing) {
7175
                                if (this.className) {
7176
                                        axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
7177
                                }
7178
                                that.axis = axis && axis[1] ? axis[1] : "se";
7179
                        }
7180
                });
7181

    
7182
                if (o.autoHide) {
7183
                        this._handles.hide();
7184
                        $(this.element)
7185
                                .addClass("ui-resizable-autohide")
7186
                                .mouseenter(function() {
7187
                                        if (o.disabled) {
7188
                                                return;
7189
                                        }
7190
                                        $(this).removeClass("ui-resizable-autohide");
7191
                                        that._handles.show();
7192
                                })
7193
                                .mouseleave(function() {
7194
                                        if (o.disabled) {
7195
                                                return;
7196
                                        }
7197
                                        if (!that.resizing) {
7198
                                                $(this).addClass("ui-resizable-autohide");
7199
                                                that._handles.hide();
7200
                                        }
7201
                                });
7202
                }
7203

    
7204
                this._mouseInit();
7205
        },
7206

    
7207
        _destroy: function() {
7208

    
7209
                this._mouseDestroy();
7210

    
7211
                var wrapper,
7212
                        _destroy = function(exp) {
7213
                                $(exp)
7214
                                        .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
7215
                                        .removeData("resizable")
7216
                                        .removeData("ui-resizable")
7217
                                        .unbind(".resizable")
7218
                                        .find(".ui-resizable-handle")
7219
                                                .remove();
7220
                        };
7221

    
7222
                // TODO: Unwrap at same DOM position
7223
                if (this.elementIsWrapper) {
7224
                        _destroy(this.element);
7225
                        wrapper = this.element;
7226
                        this.originalElement.css({
7227
                                position: wrapper.css("position"),
7228
                                width: wrapper.outerWidth(),
7229
                                height: wrapper.outerHeight(),
7230
                                top: wrapper.css("top"),
7231
                                left: wrapper.css("left")
7232
                        }).insertAfter( wrapper );
7233
                        wrapper.remove();
7234
                }
7235

    
7236
                this.originalElement.css("resize", this.originalResizeStyle);
7237
                _destroy(this.originalElement);
7238

    
7239
                return this;
7240
        },
7241

    
7242
        _mouseCapture: function(event) {
7243
                var i, handle,
7244
                        capture = false;
7245

    
7246
                for (i in this.handles) {
7247
                        handle = $(this.handles[i])[0];
7248
                        if (handle === event.target || $.contains(handle, event.target)) {
7249
                                capture = true;
7250
                        }
7251
                }
7252

    
7253
                return !this.options.disabled && capture;
7254
        },
7255

    
7256
        _mouseStart: function(event) {
7257

    
7258
                var curleft, curtop, cursor,
7259
                        o = this.options,
7260
                        el = this.element;
7261

    
7262
                this.resizing = true;
7263

    
7264
                this._renderProxy();
7265

    
7266
                curleft = this._num(this.helper.css("left"));
7267
                curtop = this._num(this.helper.css("top"));
7268

    
7269
                if (o.containment) {
7270
                        curleft += $(o.containment).scrollLeft() || 0;
7271
                        curtop += $(o.containment).scrollTop() || 0;
7272
                }
7273

    
7274
                this.offset = this.helper.offset();
7275
                this.position = { left: curleft, top: curtop };
7276

    
7277
                this.size = this._helper ? {
7278
                                width: this.helper.width(),
7279
                                height: this.helper.height()
7280
                        } : {
7281
                                width: el.width(),
7282
                                height: el.height()
7283
                        };
7284

    
7285
                this.originalSize = this._helper ? {
7286
                                width: el.outerWidth(),
7287
                                height: el.outerHeight()
7288
                        } : {
7289
                                width: el.width(),
7290
                                height: el.height()
7291
                        };
7292

    
7293
                this.sizeDiff = {
7294
                        width: el.outerWidth() - el.width(),
7295
                        height: el.outerHeight() - el.height()
7296
                };
7297

    
7298
                this.originalPosition = { left: curleft, top: curtop };
7299
                this.originalMousePosition = { left: event.pageX, top: event.pageY };
7300

    
7301
                this.aspectRatio = (typeof o.aspectRatio === "number") ?
7302
                        o.aspectRatio :
7303
                        ((this.originalSize.width / this.originalSize.height) || 1);
7304

    
7305
                cursor = $(".ui-resizable-" + this.axis).css("cursor");
7306
                $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
7307

    
7308
                el.addClass("ui-resizable-resizing");
7309
                this._propagate("start", event);
7310
                return true;
7311
        },
7312

    
7313
        _mouseDrag: function(event) {
7314

    
7315
                var data, props,
7316
                        smp = this.originalMousePosition,
7317
                        a = this.axis,
7318
                        dx = (event.pageX - smp.left) || 0,
7319
                        dy = (event.pageY - smp.top) || 0,
7320
                        trigger = this._change[a];
7321

    
7322
                this._updatePrevProperties();
7323

    
7324
                if (!trigger) {
7325
                        return false;
7326
                }
7327

    
7328
                data = trigger.apply(this, [ event, dx, dy ]);
7329

    
7330
                this._updateVirtualBoundaries(event.shiftKey);
7331
                if (this._aspectRatio || event.shiftKey) {
7332
                        data = this._updateRatio(data, event);
7333
                }
7334

    
7335
                data = this._respectSize(data, event);
7336

    
7337
                this._updateCache(data);
7338

    
7339
                this._propagate("resize", event);
7340

    
7341
                props = this._applyChanges();
7342

    
7343
                if ( !this._helper && this._proportionallyResizeElements.length ) {
7344
                        this._proportionallyResize();
7345
                }
7346

    
7347
                if ( !$.isEmptyObject( props ) ) {
7348
                        this._updatePrevProperties();
7349
                        this._trigger( "resize", event, this.ui() );
7350
                        this._applyChanges();
7351
                }
7352

    
7353
                return false;
7354
        },
7355

    
7356
        _mouseStop: function(event) {
7357

    
7358
                this.resizing = false;
7359
                var pr, ista, soffseth, soffsetw, s, left, top,
7360
                        o = this.options, that = this;
7361

    
7362
                if (this._helper) {
7363

    
7364
                        pr = this._proportionallyResizeElements;
7365
                        ista = pr.length && (/textarea/i).test(pr[0].nodeName);
7366
                        soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
7367
                        soffsetw = ista ? 0 : that.sizeDiff.width;
7368

    
7369
                        s = {
7370
                                width: (that.helper.width()  - soffsetw),
7371
                                height: (that.helper.height() - soffseth)
7372
                        };
7373
                        left = (parseInt(that.element.css("left"), 10) +
7374
                                (that.position.left - that.originalPosition.left)) || null;
7375
                        top = (parseInt(that.element.css("top"), 10) +
7376
                                (that.position.top - that.originalPosition.top)) || null;
7377

    
7378
                        if (!o.animate) {
7379
                                this.element.css($.extend(s, { top: top, left: left }));
7380
                        }
7381

    
7382
                        that.helper.height(that.size.height);
7383
                        that.helper.width(that.size.width);
7384

    
7385
                        if (this._helper && !o.animate) {
7386
                                this._proportionallyResize();
7387
                        }
7388
                }
7389

    
7390
                $("body").css("cursor", "auto");
7391

    
7392
                this.element.removeClass("ui-resizable-resizing");
7393

    
7394
                this._propagate("stop", event);
7395

    
7396
                if (this._helper) {
7397
                        this.helper.remove();
7398
                }
7399

    
7400
                return false;
7401

    
7402
        },
7403

    
7404
        _updatePrevProperties: function() {
7405
                this.prevPosition = {
7406
                        top: this.position.top,
7407
                        left: this.position.left
7408
                };
7409
                this.prevSize = {
7410
                        width: this.size.width,
7411
                        height: this.size.height
7412
                };
7413
        },
7414

    
7415
        _applyChanges: function() {
7416
                var props = {};
7417

    
7418
                if ( this.position.top !== this.prevPosition.top ) {
7419
                        props.top = this.position.top + "px";
7420
                }
7421
                if ( this.position.left !== this.prevPosition.left ) {
7422
                        props.left = this.position.left + "px";
7423
                }
7424
                if ( this.size.width !== this.prevSize.width ) {
7425
                        props.width = this.size.width + "px";
7426
                }
7427
                if ( this.size.height !== this.prevSize.height ) {
7428
                        props.height = this.size.height + "px";
7429
                }
7430

    
7431
                this.helper.css( props );
7432

    
7433
                return props;
7434
        },
7435

    
7436
        _updateVirtualBoundaries: function(forceAspectRatio) {
7437
                var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
7438
                        o = this.options;
7439

    
7440
                b = {
7441
                        minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
7442
                        maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
7443
                        minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
7444
                        maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
7445
                };
7446

    
7447
                if (this._aspectRatio || forceAspectRatio) {
7448
                        pMinWidth = b.minHeight * this.aspectRatio;
7449
                        pMinHeight = b.minWidth / this.aspectRatio;
7450
                        pMaxWidth = b.maxHeight * this.aspectRatio;
7451
                        pMaxHeight = b.maxWidth / this.aspectRatio;
7452

    
7453
                        if (pMinWidth > b.minWidth) {
7454
                                b.minWidth = pMinWidth;
7455
                        }
7456
                        if (pMinHeight > b.minHeight) {
7457
                                b.minHeight = pMinHeight;
7458
                        }
7459
                        if (pMaxWidth < b.maxWidth) {
7460
                                b.maxWidth = pMaxWidth;
7461
                        }
7462
                        if (pMaxHeight < b.maxHeight) {
7463
                                b.maxHeight = pMaxHeight;
7464
                        }
7465
                }
7466
                this._vBoundaries = b;
7467
        },
7468

    
7469
        _updateCache: function(data) {
7470
                this.offset = this.helper.offset();
7471
                if (this._isNumber(data.left)) {
7472
                        this.position.left = data.left;
7473
                }
7474
                if (this._isNumber(data.top)) {
7475
                        this.position.top = data.top;
7476
                }
7477
                if (this._isNumber(data.height)) {
7478
                        this.size.height = data.height;
7479
                }
7480
                if (this._isNumber(data.width)) {
7481
                        this.size.width = data.width;
7482
                }
7483
        },
7484

    
7485
        _updateRatio: function( data ) {
7486

    
7487
                var cpos = this.position,
7488
                        csize = this.size,
7489
                        a = this.axis;
7490

    
7491
                if (this._isNumber(data.height)) {
7492
                        data.width = (data.height * this.aspectRatio);
7493
                } else if (this._isNumber(data.width)) {
7494
                        data.height = (data.width / this.aspectRatio);
7495
                }
7496

    
7497
                if (a === "sw") {
7498
                        data.left = cpos.left + (csize.width - data.width);
7499
                        data.top = null;
7500
                }
7501
                if (a === "nw") {
7502
                        data.top = cpos.top + (csize.height - data.height);
7503
                        data.left = cpos.left + (csize.width - data.width);
7504
                }
7505

    
7506
                return data;
7507
        },
7508

    
7509
        _respectSize: function( data ) {
7510

    
7511
                var o = this._vBoundaries,
7512
                        a = this.axis,
7513
                        ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
7514
                        ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
7515
                        isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
7516
                        isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
7517
                        dw = this.originalPosition.left + this.originalSize.width,
7518
                        dh = this.position.top + this.size.height,
7519
                        cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
7520
                if (isminw) {
7521
                        data.width = o.minWidth;
7522
                }
7523
                if (isminh) {
7524
                        data.height = o.minHeight;
7525
                }
7526
                if (ismaxw) {
7527
                        data.width = o.maxWidth;
7528
                }
7529
                if (ismaxh) {
7530
                        data.height = o.maxHeight;
7531
                }
7532

    
7533
                if (isminw && cw) {
7534
                        data.left = dw - o.minWidth;
7535
                }
7536
                if (ismaxw && cw) {
7537
                        data.left = dw - o.maxWidth;
7538
                }
7539
                if (isminh && ch) {
7540
                        data.top = dh - o.minHeight;
7541
                }
7542
                if (ismaxh && ch) {
7543
                        data.top = dh - o.maxHeight;
7544
                }
7545

    
7546
                // Fixing jump error on top/left - bug #2330
7547
                if (!data.width && !data.height && !data.left && data.top) {
7548
                        data.top = null;
7549
                } else if (!data.width && !data.height && !data.top && data.left) {
7550
                        data.left = null;
7551
                }
7552

    
7553
                return data;
7554
        },
7555

    
7556
        _getPaddingPlusBorderDimensions: function( element ) {
7557
                var i = 0,
7558
                        widths = [],
7559
                        borders = [
7560
                                element.css( "borderTopWidth" ),
7561
                                element.css( "borderRightWidth" ),
7562
                                element.css( "borderBottomWidth" ),
7563
                                element.css( "borderLeftWidth" )
7564
                        ],
7565
                        paddings = [
7566
                                element.css( "paddingTop" ),
7567
                                element.css( "paddingRight" ),
7568
                                element.css( "paddingBottom" ),
7569
                                element.css( "paddingLeft" )
7570
                        ];
7571

    
7572
                for ( ; i < 4; i++ ) {
7573
                        widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
7574
                        widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
7575
                }
7576

    
7577
                return {
7578
                        height: widths[ 0 ] + widths[ 2 ],
7579
                        width: widths[ 1 ] + widths[ 3 ]
7580
                };
7581
        },
7582

    
7583
        _proportionallyResize: function() {
7584

    
7585
                if (!this._proportionallyResizeElements.length) {
7586
                        return;
7587
                }
7588

    
7589
                var prel,
7590
                        i = 0,
7591
                        element = this.helper || this.element;
7592

    
7593
                for ( ; i < this._proportionallyResizeElements.length; i++) {
7594

    
7595
                        prel = this._proportionallyResizeElements[i];
7596

    
7597
                        // TODO: Seems like a bug to cache this.outerDimensions
7598
                        // considering that we are in a loop.
7599
                        if (!this.outerDimensions) {
7600
                                this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
7601
                        }
7602

    
7603
                        prel.css({
7604
                                height: (element.height() - this.outerDimensions.height) || 0,
7605
                                width: (element.width() - this.outerDimensions.width) || 0
7606
                        });
7607

    
7608
                }
7609

    
7610
        },
7611

    
7612
        _renderProxy: function() {
7613

    
7614
                var el = this.element, o = this.options;
7615
                this.elementOffset = el.offset();
7616

    
7617
                if (this._helper) {
7618

    
7619
                        this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
7620

    
7621
                        this.helper.addClass(this._helper).css({
7622
                                width: this.element.outerWidth() - 1,
7623
                                height: this.element.outerHeight() - 1,
7624
                                position: "absolute",
7625
                                left: this.elementOffset.left + "px",
7626
                                top: this.elementOffset.top + "px",
7627
                                zIndex: ++o.zIndex //TODO: Don't modify option
7628
                        });
7629

    
7630
                        this.helper
7631
                                .appendTo("body")
7632
                                .disableSelection();
7633

    
7634
                } else {
7635
                        this.helper = this.element;
7636
                }
7637

    
7638
        },
7639

    
7640
        _change: {
7641
                e: function(event, dx) {
7642
                        return { width: this.originalSize.width + dx };
7643
                },
7644
                w: function(event, dx) {
7645
                        var cs = this.originalSize, sp = this.originalPosition;
7646
                        return { left: sp.left + dx, width: cs.width - dx };
7647
                },
7648
                n: function(event, dx, dy) {
7649
                        var cs = this.originalSize, sp = this.originalPosition;
7650
                        return { top: sp.top + dy, height: cs.height - dy };
7651
                },
7652
                s: function(event, dx, dy) {
7653
                        return { height: this.originalSize.height + dy };
7654
                },
7655
                se: function(event, dx, dy) {
7656
                        return $.extend(this._change.s.apply(this, arguments),
7657
                                this._change.e.apply(this, [ event, dx, dy ]));
7658
                },
7659
                sw: function(event, dx, dy) {
7660
                        return $.extend(this._change.s.apply(this, arguments),
7661
                                this._change.w.apply(this, [ event, dx, dy ]));
7662
                },
7663
                ne: function(event, dx, dy) {
7664
                        return $.extend(this._change.n.apply(this, arguments),
7665
                                this._change.e.apply(this, [ event, dx, dy ]));
7666
                },
7667
                nw: function(event, dx, dy) {
7668
                        return $.extend(this._change.n.apply(this, arguments),
7669
                                this._change.w.apply(this, [ event, dx, dy ]));
7670
                }
7671
        },
7672

    
7673
        _propagate: function(n, event) {
7674
                $.ui.plugin.call(this, n, [ event, this.ui() ]);
7675
                (n !== "resize" && this._trigger(n, event, this.ui()));
7676
        },
7677

    
7678
        plugins: {},
7679

    
7680
        ui: function() {
7681
                return {
7682
                        originalElement: this.originalElement,
7683
                        element: this.element,
7684
                        helper: this.helper,
7685
                        position: this.position,
7686
                        size: this.size,
7687
                        originalSize: this.originalSize,
7688
                        originalPosition: this.originalPosition
7689
                };
7690
        }
7691

    
7692
});
7693

    
7694
/*
7695
 * Resizable Extensions
7696
 */
7697

    
7698
$.ui.plugin.add("resizable", "animate", {
7699

    
7700
        stop: function( event ) {
7701
                var that = $(this).resizable( "instance" ),
7702
                        o = that.options,
7703
                        pr = that._proportionallyResizeElements,
7704
                        ista = pr.length && (/textarea/i).test(pr[0].nodeName),
7705
                        soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
7706
                        soffsetw = ista ? 0 : that.sizeDiff.width,
7707
                        style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
7708
                        left = (parseInt(that.element.css("left"), 10) +
7709
                                (that.position.left - that.originalPosition.left)) || null,
7710
                        top = (parseInt(that.element.css("top"), 10) +
7711
                                (that.position.top - that.originalPosition.top)) || null;
7712

    
7713
                that.element.animate(
7714
                        $.extend(style, top && left ? { top: top, left: left } : {}), {
7715
                                duration: o.animateDuration,
7716
                                easing: o.animateEasing,
7717
                                step: function() {
7718

    
7719
                                        var data = {
7720
                                                width: parseInt(that.element.css("width"), 10),
7721
                                                height: parseInt(that.element.css("height"), 10),
7722
                                                top: parseInt(that.element.css("top"), 10),
7723
                                                left: parseInt(that.element.css("left"), 10)
7724
                                        };
7725

    
7726
                                        if (pr && pr.length) {
7727
                                                $(pr[0]).css({ width: data.width, height: data.height });
7728
                                        }
7729

    
7730
                                        // propagating resize, and updating values for each animation step
7731
                                        that._updateCache(data);
7732
                                        that._propagate("resize", event);
7733

    
7734
                                }
7735
                        }
7736
                );
7737
        }
7738

    
7739
});
7740

    
7741
$.ui.plugin.add( "resizable", "containment", {
7742

    
7743
        start: function() {
7744
                var element, p, co, ch, cw, width, height,
7745
                        that = $( this ).resizable( "instance" ),
7746
                        o = that.options,
7747
                        el = that.element,
7748
                        oc = o.containment,
7749
                        ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
7750

    
7751
                if ( !ce ) {
7752
                        return;
7753
                }
7754

    
7755
                that.containerElement = $( ce );
7756

    
7757
                if ( /document/.test( oc ) || oc === document ) {
7758
                        that.containerOffset = {
7759
                                left: 0,
7760
                                top: 0
7761
                        };
7762
                        that.containerPosition = {
7763
                                left: 0,
7764
                                top: 0
7765
                        };
7766

    
7767
                        that.parentData = {
7768
                                element: $( document ),
7769
                                left: 0,
7770
                                top: 0,
7771
                                width: $( document ).width(),
7772
                                height: $( document ).height() || document.body.parentNode.scrollHeight
7773
                        };
7774
                } else {
7775
                        element = $( ce );
7776
                        p = [];
7777
                        $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
7778
                                p[ i ] = that._num( element.css( "padding" + name ) );
7779
                        });
7780

    
7781
                        that.containerOffset = element.offset();
7782
                        that.containerPosition = element.position();
7783
                        that.containerSize = {
7784
                                height: ( element.innerHeight() - p[ 3 ] ),
7785
                                width: ( element.innerWidth() - p[ 1 ] )
7786
                        };
7787

    
7788
                        co = that.containerOffset;
7789
                        ch = that.containerSize.height;
7790
                        cw = that.containerSize.width;
7791
                        width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
7792
                        height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
7793

    
7794
                        that.parentData = {
7795
                                element: ce,
7796
                                left: co.left,
7797
                                top: co.top,
7798
                                width: width,
7799
                                height: height
7800
                        };
7801
                }
7802
        },
7803

    
7804
        resize: function( event ) {
7805
                var woset, hoset, isParent, isOffsetRelative,
7806
                        that = $( this ).resizable( "instance" ),
7807
                        o = that.options,
7808
                        co = that.containerOffset,
7809
                        cp = that.position,
7810
                        pRatio = that._aspectRatio || event.shiftKey,
7811
                        cop = {
7812
                                top: 0,
7813
                                left: 0
7814
                        },
7815
                        ce = that.containerElement,
7816
                        continueResize = true;
7817

    
7818
                if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
7819
                        cop = co;
7820
                }
7821

    
7822
                if ( cp.left < ( that._helper ? co.left : 0 ) ) {
7823
                        that.size.width = that.size.width +
7824
                                ( that._helper ?
7825
                                        ( that.position.left - co.left ) :
7826
                                        ( that.position.left - cop.left ) );
7827

    
7828
                        if ( pRatio ) {
7829
                                that.size.height = that.size.width / that.aspectRatio;
7830
                                continueResize = false;
7831
                        }
7832
                        that.position.left = o.helper ? co.left : 0;
7833
                }
7834

    
7835
                if ( cp.top < ( that._helper ? co.top : 0 ) ) {
7836
                        that.size.height = that.size.height +
7837
                                ( that._helper ?
7838
                                        ( that.position.top - co.top ) :
7839
                                        that.position.top );
7840

    
7841
                        if ( pRatio ) {
7842
                                that.size.width = that.size.height * that.aspectRatio;
7843
                                continueResize = false;
7844
                        }
7845
                        that.position.top = that._helper ? co.top : 0;
7846
                }
7847

    
7848
                isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
7849
                isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
7850

    
7851
                if ( isParent && isOffsetRelative ) {
7852
                        that.offset.left = that.parentData.left + that.position.left;
7853
                        that.offset.top = that.parentData.top + that.position.top;
7854
                } else {
7855
                        that.offset.left = that.element.offset().left;
7856
                        that.offset.top = that.element.offset().top;
7857
                }
7858

    
7859
                woset = Math.abs( that.sizeDiff.width +
7860
                        (that._helper ?
7861
                                that.offset.left - cop.left :
7862
                                (that.offset.left - co.left)) );
7863

    
7864
                hoset = Math.abs( that.sizeDiff.height +
7865
                        (that._helper ?
7866
                                that.offset.top - cop.top :
7867
                                (that.offset.top - co.top)) );
7868

    
7869
                if ( woset + that.size.width >= that.parentData.width ) {
7870
                        that.size.width = that.parentData.width - woset;
7871
                        if ( pRatio ) {
7872
                                that.size.height = that.size.width / that.aspectRatio;
7873
                                continueResize = false;
7874
                        }
7875
                }
7876

    
7877
                if ( hoset + that.size.height >= that.parentData.height ) {
7878
                        that.size.height = that.parentData.height - hoset;
7879
                        if ( pRatio ) {
7880
                                that.size.width = that.size.height * that.aspectRatio;
7881
                                continueResize = false;
7882
                        }
7883
                }
7884

    
7885
                if ( !continueResize ) {
7886
                        that.position.left = that.prevPosition.left;
7887
                        that.position.top = that.prevPosition.top;
7888
                        that.size.width = that.prevSize.width;
7889
                        that.size.height = that.prevSize.height;
7890
                }
7891
        },
7892

    
7893
        stop: function() {
7894
                var that = $( this ).resizable( "instance" ),
7895
                        o = that.options,
7896
                        co = that.containerOffset,
7897
                        cop = that.containerPosition,
7898
                        ce = that.containerElement,
7899
                        helper = $( that.helper ),
7900
                        ho = helper.offset(),
7901
                        w = helper.outerWidth() - that.sizeDiff.width,
7902
                        h = helper.outerHeight() - that.sizeDiff.height;
7903

    
7904
                if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
7905
                        $( this ).css({
7906
                                left: ho.left - cop.left - co.left,
7907
                                width: w,
7908
                                height: h
7909
                        });
7910
                }
7911

    
7912
                if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
7913
                        $( this ).css({
7914
                                left: ho.left - cop.left - co.left,
7915
                                width: w,
7916
                                height: h
7917
                        });
7918
                }
7919
        }
7920
});
7921

    
7922
$.ui.plugin.add("resizable", "alsoResize", {
7923

    
7924
        start: function() {
7925
                var that = $(this).resizable( "instance" ),
7926
                        o = that.options;
7927

    
7928
                $(o.alsoResize).each(function() {
7929
                        var el = $(this);
7930
                        el.data("ui-resizable-alsoresize", {
7931
                                width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
7932
                                left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
7933
                        });
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
                        $(o.alsoResize).each(function() {
7950
                                var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
7951
                                        css = el.parents(ui.originalElement[0]).length ?
7952
                                                        [ "width", "height" ] :
7953
                                                        [ "width", "height", "top", "left" ];
7954

    
7955
                                $.each(css, function(i, prop) {
7956
                                        var sum = (start[prop] || 0) + (delta[prop] || 0);
7957
                                        if (sum && sum >= 0) {
7958
                                                style[prop] = sum || null;
7959
                                        }
7960
                                });
7961

    
7962
                                el.css(style);
7963
                        });
7964
        },
7965

    
7966
        stop: function() {
7967
                $(this).removeData("resizable-alsoresize");
7968
        }
7969
});
7970

    
7971
$.ui.plugin.add("resizable", "ghost", {
7972

    
7973
        start: function() {
7974

    
7975
                var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
7976

    
7977
                that.ghost = that.originalElement.clone();
7978
                that.ghost
7979
                        .css({
7980
                                opacity: 0.25,
7981
                                display: "block",
7982
                                position: "relative",
7983
                                height: cs.height,
7984
                                width: cs.width,
7985
                                margin: 0,
7986
                                left: 0,
7987
                                top: 0
7988
                        })
7989
                        .addClass("ui-resizable-ghost")
7990
                        .addClass(typeof o.ghost === "string" ? o.ghost : "");
7991

    
7992
                that.ghost.appendTo(that.helper);
7993

    
7994
        },
7995

    
7996
        resize: function() {
7997
                var that = $(this).resizable( "instance" );
7998
                if (that.ghost) {
7999
                        that.ghost.css({
8000
                                position: "relative",
8001
                                height: that.size.height,
8002
                                width: that.size.width
8003
                        });
8004
                }
8005
        },
8006

    
8007
        stop: function() {
8008
                var that = $(this).resizable( "instance" );
8009
                if (that.ghost && that.helper) {
8010
                        that.helper.get(0).removeChild(that.ghost.get(0));
8011
                }
8012
        }
8013

    
8014
});
8015

    
8016
$.ui.plugin.add("resizable", "grid", {
8017

    
8018
        resize: function() {
8019
                var outerDimensions,
8020
                        that = $(this).resizable( "instance" ),
8021
                        o = that.options,
8022
                        cs = that.size,
8023
                        os = that.originalSize,
8024
                        op = that.originalPosition,
8025
                        a = that.axis,
8026
                        grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
8027
                        gridX = (grid[0] || 1),
8028
                        gridY = (grid[1] || 1),
8029
                        ox = Math.round((cs.width - os.width) / gridX) * gridX,
8030
                        oy = Math.round((cs.height - os.height) / gridY) * gridY,
8031
                        newWidth = os.width + ox,
8032
                        newHeight = os.height + oy,
8033
                        isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
8034
                        isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
8035
                        isMinWidth = o.minWidth && (o.minWidth > newWidth),
8036
                        isMinHeight = o.minHeight && (o.minHeight > newHeight);
8037

    
8038
                o.grid = grid;
8039

    
8040
                if (isMinWidth) {
8041
                        newWidth += gridX;
8042
                }
8043
                if (isMinHeight) {
8044
                        newHeight += gridY;
8045
                }
8046
                if (isMaxWidth) {
8047
                        newWidth -= gridX;
8048
                }
8049
                if (isMaxHeight) {
8050
                        newHeight -= gridY;
8051
                }
8052

    
8053
                if (/^(se|s|e)$/.test(a)) {
8054
                        that.size.width = newWidth;
8055
                        that.size.height = newHeight;
8056
                } else if (/^(ne)$/.test(a)) {
8057
                        that.size.width = newWidth;
8058
                        that.size.height = newHeight;
8059
                        that.position.top = op.top - oy;
8060
                } else if (/^(sw)$/.test(a)) {
8061
                        that.size.width = newWidth;
8062
                        that.size.height = newHeight;
8063
                        that.position.left = op.left - ox;
8064
                } else {
8065
                        if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
8066
                                outerDimensions = that._getPaddingPlusBorderDimensions( this );
8067
                        }
8068

    
8069
                        if ( newHeight - gridY > 0 ) {
8070
                                that.size.height = newHeight;
8071
                                that.position.top = op.top - oy;
8072
                        } else {
8073
                                newHeight = gridY - outerDimensions.height;
8074
                                that.size.height = newHeight;
8075
                                that.position.top = op.top + os.height - newHeight;
8076
                        }
8077
                        if ( newWidth - gridX > 0 ) {
8078
                                that.size.width = newWidth;
8079
                                that.position.left = op.left - ox;
8080
                        } else {
8081
                                newWidth = gridX - outerDimensions.width;
8082
                                that.size.width = newWidth;
8083
                                that.position.left = op.left + os.width - newWidth;
8084
                        }
8085
                }
8086
        }
8087

    
8088
});
8089

    
8090
var resizable = $.ui.resizable;
8091

    
8092

    
8093
/*!
8094
 * jQuery UI Dialog 1.11.4
8095
 * http://jqueryui.com
8096
 *
8097
 * Copyright jQuery Foundation and other contributors
8098
 * Released under the MIT license.
8099
 * http://jquery.org/license
8100
 *
8101
 * http://api.jqueryui.com/dialog/
8102
 */
8103

    
8104

    
8105
var dialog = $.widget( "ui.dialog", {
8106
        version: "1.11.4",
8107
        options: {
8108
                appendTo: "body",
8109
                autoOpen: true,
8110
                buttons: [],
8111
                closeOnEscape: true,
8112
                closeText: "Close",
8113
                dialogClass: "",
8114
                draggable: true,
8115
                hide: null,
8116
                height: "auto",
8117
                maxHeight: null,
8118
                maxWidth: null,
8119
                minHeight: 150,
8120
                minWidth: 150,
8121
                modal: false,
8122
                position: {
8123
                        my: "center",
8124
                        at: "center",
8125
                        of: window,
8126
                        collision: "fit",
8127
                        // Ensure the titlebar is always visible
8128
                        using: function( pos ) {
8129
                                var topOffset = $( this ).css( pos ).offset().top;
8130
                                if ( topOffset < 0 ) {
8131
                                        $( this ).css( "top", pos.top - topOffset );
8132
                                }
8133
                        }
8134
                },
8135
                resizable: true,
8136
                show: null,
8137
                title: null,
8138
                width: 300,
8139

    
8140
                // callbacks
8141
                beforeClose: null,
8142
                close: null,
8143
                drag: null,
8144
                dragStart: null,
8145
                dragStop: null,
8146
                focus: null,
8147
                open: null,
8148
                resize: null,
8149
                resizeStart: null,
8150
                resizeStop: null
8151
        },
8152

    
8153
        sizeRelatedOptions: {
8154
                buttons: true,
8155
                height: true,
8156
                maxHeight: true,
8157
                maxWidth: true,
8158
                minHeight: true,
8159
                minWidth: true,
8160
                width: true
8161
        },
8162

    
8163
        resizableRelatedOptions: {
8164
                maxHeight: true,
8165
                maxWidth: true,
8166
                minHeight: true,
8167
                minWidth: true
8168
        },
8169

    
8170
        _create: function() {
8171
                this.originalCss = {
8172
                        display: this.element[ 0 ].style.display,
8173
                        width: this.element[ 0 ].style.width,
8174
                        minHeight: this.element[ 0 ].style.minHeight,
8175
                        maxHeight: this.element[ 0 ].style.maxHeight,
8176
                        height: this.element[ 0 ].style.height
8177
                };
8178
                this.originalPosition = {
8179
                        parent: this.element.parent(),
8180
                        index: this.element.parent().children().index( this.element )
8181
                };
8182
                this.originalTitle = this.element.attr( "title" );
8183
                this.options.title = this.options.title || this.originalTitle;
8184

    
8185
                this._createWrapper();
8186

    
8187
                this.element
8188
                        .show()
8189
                        .removeAttr( "title" )
8190
                        .addClass( "ui-dialog-content ui-widget-content" )
8191
                        .appendTo( this.uiDialog );
8192

    
8193
                this._createTitlebar();
8194
                this._createButtonPane();
8195

    
8196
                if ( this.options.draggable && $.fn.draggable ) {
8197
                        this._makeDraggable();
8198
                }
8199
                if ( this.options.resizable && $.fn.resizable ) {
8200
                        this._makeResizable();
8201
                }
8202

    
8203
                this._isOpen = false;
8204

    
8205
                this._trackFocus();
8206
        },
8207

    
8208
        _init: function() {
8209
                if ( this.options.autoOpen ) {
8210
                        this.open();
8211
                }
8212
        },
8213

    
8214
        _appendTo: function() {
8215
                var element = this.options.appendTo;
8216
                if ( element && (element.jquery || element.nodeType) ) {
8217
                        return $( element );
8218
                }
8219
                return this.document.find( element || "body" ).eq( 0 );
8220
        },
8221

    
8222
        _destroy: function() {
8223
                var next,
8224
                        originalPosition = this.originalPosition;
8225

    
8226
                this._untrackInstance();
8227
                this._destroyOverlay();
8228

    
8229
                this.element
8230
                        .removeUniqueId()
8231
                        .removeClass( "ui-dialog-content ui-widget-content" )
8232
                        .css( this.originalCss )
8233
                        // Without detaching first, the following becomes really slow
8234
                        .detach();
8235

    
8236
                this.uiDialog.stop( true, true ).remove();
8237

    
8238
                if ( this.originalTitle ) {
8239
                        this.element.attr( "title", this.originalTitle );
8240
                }
8241

    
8242
                next = originalPosition.parent.children().eq( originalPosition.index );
8243
                // Don't try to place the dialog next to itself (#8613)
8244
                if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
8245
                        next.before( this.element );
8246
                } else {
8247
                        originalPosition.parent.append( this.element );
8248
                }
8249
        },
8250

    
8251
        widget: function() {
8252
                return this.uiDialog;
8253
        },
8254

    
8255
        disable: $.noop,
8256
        enable: $.noop,
8257

    
8258
        close: function( event ) {
8259
                var activeElement,
8260
                        that = this;
8261

    
8262
                if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
8263
                        return;
8264
                }
8265

    
8266
                this._isOpen = false;
8267
                this._focusedElement = null;
8268
                this._destroyOverlay();
8269
                this._untrackInstance();
8270

    
8271
                if ( !this.opener.filter( ":focusable" ).focus().length ) {
8272

    
8273
                        // support: IE9
8274
                        // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
8275
                        try {
8276
                                activeElement = this.document[ 0 ].activeElement;
8277

    
8278
                                // Support: IE9, IE10
8279
                                // If the <body> is blurred, IE will switch windows, see #4520
8280
                                if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
8281

    
8282
                                        // Hiding a focused element doesn't trigger blur in WebKit
8283
                                        // so in case we have nothing to focus on, explicitly blur the active element
8284
                                        // https://bugs.webkit.org/show_bug.cgi?id=47182
8285
                                        $( activeElement ).blur();
8286
                                }
8287
                        } catch ( error ) {}
8288
                }
8289

    
8290
                this._hide( this.uiDialog, this.options.hide, function() {
8291
                        that._trigger( "close", event );
8292
                });
8293
        },
8294

    
8295
        isOpen: function() {
8296
                return this._isOpen;
8297
        },
8298

    
8299
        moveToTop: function() {
8300
                this._moveToTop();
8301
        },
8302

    
8303
        _moveToTop: function( event, silent ) {
8304
                var moved = false,
8305
                        zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
8306
                                return +$( this ).css( "z-index" );
8307
                        }).get(),
8308
                        zIndexMax = Math.max.apply( null, zIndices );
8309

    
8310
                if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
8311
                        this.uiDialog.css( "z-index", zIndexMax + 1 );
8312
                        moved = true;
8313
                }
8314

    
8315
                if ( moved && !silent ) {
8316
                        this._trigger( "focus", event );
8317
                }
8318
                return moved;
8319
        },
8320

    
8321
        open: function() {
8322
                var that = this;
8323
                if ( this._isOpen ) {
8324
                        if ( this._moveToTop() ) {
8325
                                this._focusTabbable();
8326
                        }
8327
                        return;
8328
                }
8329

    
8330
                this._isOpen = true;
8331
                this.opener = $( this.document[ 0 ].activeElement );
8332

    
8333
                this._size();
8334
                this._position();
8335
                this._createOverlay();
8336
                this._moveToTop( null, true );
8337

    
8338
                // Ensure the overlay is moved to the top with the dialog, but only when
8339
                // opening. The overlay shouldn't move after the dialog is open so that
8340
                // modeless dialogs opened after the modal dialog stack properly.
8341
                if ( this.overlay ) {
8342
                        this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
8343
                }
8344

    
8345
                this._show( this.uiDialog, this.options.show, function() {
8346
                        that._focusTabbable();
8347
                        that._trigger( "focus" );
8348
                });
8349

    
8350
                // Track the dialog immediately upon openening in case a focus event
8351
                // somehow occurs outside of the dialog before an element inside the
8352
                // dialog is focused (#10152)
8353
                this._makeFocusTarget();
8354

    
8355
                this._trigger( "open" );
8356
        },
8357

    
8358
        _focusTabbable: function() {
8359
                // Set focus to the first match:
8360
                // 1. An element that was focused previously
8361
                // 2. First element inside the dialog matching [autofocus]
8362
                // 3. Tabbable element inside the content element
8363
                // 4. Tabbable element inside the buttonpane
8364
                // 5. The close button
8365
                // 6. The dialog itself
8366
                var hasFocus = this._focusedElement;
8367
                if ( !hasFocus ) {
8368
                        hasFocus = this.element.find( "[autofocus]" );
8369
                }
8370
                if ( !hasFocus.length ) {
8371
                        hasFocus = this.element.find( ":tabbable" );
8372
                }
8373
                if ( !hasFocus.length ) {
8374
                        hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
8375
                }
8376
                if ( !hasFocus.length ) {
8377
                        hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
8378
                }
8379
                if ( !hasFocus.length ) {
8380
                        hasFocus = this.uiDialog;
8381
                }
8382
                hasFocus.eq( 0 ).focus();
8383
        },
8384

    
8385
        _keepFocus: function( event ) {
8386
                function checkFocus() {
8387
                        var activeElement = this.document[0].activeElement,
8388
                                isActive = this.uiDialog[0] === activeElement ||
8389
                                        $.contains( this.uiDialog[0], activeElement );
8390
                        if ( !isActive ) {
8391
                                this._focusTabbable();
8392
                        }
8393
                }
8394
                event.preventDefault();
8395
                checkFocus.call( this );
8396
                // support: IE
8397
                // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
8398
                // so we check again later
8399
                this._delay( checkFocus );
8400
        },
8401

    
8402
        _createWrapper: function() {
8403
                this.uiDialog = $("<div>")
8404
                        .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
8405
                                this.options.dialogClass )
8406
                        .hide()
8407
                        .attr({
8408
                                // Setting tabIndex makes the div focusable
8409
                                tabIndex: -1,
8410
                                role: "dialog"
8411
                        })
8412
                        .appendTo( this._appendTo() );
8413

    
8414
                this._on( this.uiDialog, {
8415
                        keydown: function( event ) {
8416
                                if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
8417
                                                event.keyCode === $.ui.keyCode.ESCAPE ) {
8418
                                        event.preventDefault();
8419
                                        this.close( event );
8420
                                        return;
8421
                                }
8422

    
8423
                                // prevent tabbing out of dialogs
8424
                                if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
8425
                                        return;
8426
                                }
8427
                                var tabbables = this.uiDialog.find( ":tabbable" ),
8428
                                        first = tabbables.filter( ":first" ),
8429
                                        last = tabbables.filter( ":last" );
8430

    
8431
                                if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
8432
                                        this._delay(function() {
8433
                                                first.focus();
8434
                                        });
8435
                                        event.preventDefault();
8436
                                } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
8437
                                        this._delay(function() {
8438
                                                last.focus();
8439
                                        });
8440
                                        event.preventDefault();
8441
                                }
8442
                        },
8443
                        mousedown: function( event ) {
8444
                                if ( this._moveToTop( event ) ) {
8445
                                        this._focusTabbable();
8446
                                }
8447
                        }
8448
                });
8449

    
8450
                // We assume that any existing aria-describedby attribute means
8451
                // that the dialog content is marked up properly
8452
                // otherwise we brute force the content as the description
8453
                if ( !this.element.find( "[aria-describedby]" ).length ) {
8454
                        this.uiDialog.attr({
8455
                                "aria-describedby": this.element.uniqueId().attr( "id" )
8456
                        });
8457
                }
8458
        },
8459

    
8460
        _createTitlebar: function() {
8461
                var uiDialogTitle;
8462

    
8463
                this.uiDialogTitlebar = $( "<div>" )
8464
                        .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
8465
                        .prependTo( this.uiDialog );
8466
                this._on( this.uiDialogTitlebar, {
8467
                        mousedown: function( event ) {
8468
                                // Don't prevent click on close button (#8838)
8469
                                // Focusing a dialog that is partially scrolled out of view
8470
                                // causes the browser to scroll it into view, preventing the click event
8471
                                if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
8472
                                        // Dialog isn't getting focus when dragging (#8063)
8473
                                        this.uiDialog.focus();
8474
                                }
8475
                        }
8476
                });
8477

    
8478
                // support: IE
8479
                // Use type="button" to prevent enter keypresses in textboxes from closing the
8480
                // dialog in IE (#9312)
8481
                this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
8482
                        .button({
8483
                                label: this.options.closeText,
8484
                                icons: {
8485
                                        primary: "ui-icon-closethick"
8486
                                },
8487
                                text: false
8488
                        })
8489
                        .addClass( "ui-dialog-titlebar-close" )
8490
                        .appendTo( this.uiDialogTitlebar );
8491
                this._on( this.uiDialogTitlebarClose, {
8492
                        click: function( event ) {
8493
                                event.preventDefault();
8494
                                this.close( event );
8495
                        }
8496
                });
8497

    
8498
                uiDialogTitle = $( "<span>" )
8499
                        .uniqueId()
8500
                        .addClass( "ui-dialog-title" )
8501
                        .prependTo( this.uiDialogTitlebar );
8502
                this._title( uiDialogTitle );
8503

    
8504
                this.uiDialog.attr({
8505
                        "aria-labelledby": uiDialogTitle.attr( "id" )
8506
                });
8507
        },
8508

    
8509
        _title: function( title ) {
8510
                if ( !this.options.title ) {
8511
                        title.html( "&#160;" );
8512
                }
8513
                title.text( this.options.title );
8514
        },
8515

    
8516
        _createButtonPane: function() {
8517
                this.uiDialogButtonPane = $( "<div>" )
8518
                        .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
8519

    
8520
                this.uiButtonSet = $( "<div>" )
8521
                        .addClass( "ui-dialog-buttonset" )
8522
                        .appendTo( this.uiDialogButtonPane );
8523

    
8524
                this._createButtons();
8525
        },
8526

    
8527
        _createButtons: function() {
8528
                var that = this,
8529
                        buttons = this.options.buttons;
8530

    
8531
                // if we already have a button pane, remove it
8532
                this.uiDialogButtonPane.remove();
8533
                this.uiButtonSet.empty();
8534

    
8535
                if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
8536
                        this.uiDialog.removeClass( "ui-dialog-buttons" );
8537
                        return;
8538
                }
8539

    
8540
                $.each( buttons, function( name, props ) {
8541
                        var click, buttonOptions;
8542
                        props = $.isFunction( props ) ?
8543
                                { click: props, text: name } :
8544
                                props;
8545
                        // Default to a non-submitting button
8546
                        props = $.extend( { type: "button" }, props );
8547
                        // Change the context for the click callback to be the main element
8548
                        click = props.click;
8549
                        props.click = function() {
8550
                                click.apply( that.element[ 0 ], arguments );
8551
                        };
8552
                        buttonOptions = {
8553
                                icons: props.icons,
8554
                                text: props.showText
8555
                        };
8556
                        delete props.icons;
8557
                        delete props.showText;
8558
                        $( "<button></button>", props )
8559
                                .button( buttonOptions )
8560
                                .appendTo( that.uiButtonSet );
8561
                });
8562
                this.uiDialog.addClass( "ui-dialog-buttons" );
8563
                this.uiDialogButtonPane.appendTo( this.uiDialog );
8564
        },
8565

    
8566
        _makeDraggable: function() {
8567
                var that = this,
8568
                        options = this.options;
8569

    
8570
                function filteredUi( ui ) {
8571
                        return {
8572
                                position: ui.position,
8573
                                offset: ui.offset
8574
                        };
8575
                }
8576

    
8577
                this.uiDialog.draggable({
8578
                        cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
8579
                        handle: ".ui-dialog-titlebar",
8580
                        containment: "document",
8581
                        start: function( event, ui ) {
8582
                                $( this ).addClass( "ui-dialog-dragging" );
8583
                                that._blockFrames();
8584
                                that._trigger( "dragStart", event, filteredUi( ui ) );
8585
                        },
8586
                        drag: function( event, ui ) {
8587
                                that._trigger( "drag", event, filteredUi( ui ) );
8588
                        },
8589
                        stop: function( event, ui ) {
8590
                                var left = ui.offset.left - that.document.scrollLeft(),
8591
                                        top = ui.offset.top - that.document.scrollTop();
8592

    
8593
                                options.position = {
8594
                                        my: "left top",
8595
                                        at: "left" + (left >= 0 ? "+" : "") + left + " " +
8596
                                                "top" + (top >= 0 ? "+" : "") + top,
8597
                                        of: that.window
8598
                                };
8599
                                $( this ).removeClass( "ui-dialog-dragging" );
8600
                                that._unblockFrames();
8601
                                that._trigger( "dragStop", event, filteredUi( ui ) );
8602
                        }
8603
                });
8604
        },
8605

    
8606
        _makeResizable: function() {
8607
                var that = this,
8608
                        options = this.options,
8609
                        handles = options.resizable,
8610
                        // .ui-resizable has position: relative defined in the stylesheet
8611
                        // but dialogs have to use absolute or fixed positioning
8612
                        position = this.uiDialog.css("position"),
8613
                        resizeHandles = typeof handles === "string" ?
8614
                                handles        :
8615
                                "n,e,s,w,se,sw,ne,nw";
8616

    
8617
                function filteredUi( ui ) {
8618
                        return {
8619
                                originalPosition: ui.originalPosition,
8620
                                originalSize: ui.originalSize,
8621
                                position: ui.position,
8622
                                size: ui.size
8623
                        };
8624
                }
8625

    
8626
                this.uiDialog.resizable({
8627
                        cancel: ".ui-dialog-content",
8628
                        containment: "document",
8629
                        alsoResize: this.element,
8630
                        maxWidth: options.maxWidth,
8631
                        maxHeight: options.maxHeight,
8632
                        minWidth: options.minWidth,
8633
                        minHeight: this._minHeight(),
8634
                        handles: resizeHandles,
8635
                        start: function( event, ui ) {
8636
                                $( this ).addClass( "ui-dialog-resizing" );
8637
                                that._blockFrames();
8638
                                that._trigger( "resizeStart", event, filteredUi( ui ) );
8639
                        },
8640
                        resize: function( event, ui ) {
8641
                                that._trigger( "resize", event, filteredUi( ui ) );
8642
                        },
8643
                        stop: function( event, ui ) {
8644
                                var offset = that.uiDialog.offset(),
8645
                                        left = offset.left - that.document.scrollLeft(),
8646
                                        top = offset.top - that.document.scrollTop();
8647

    
8648
                                options.height = that.uiDialog.height();
8649
                                options.width = that.uiDialog.width();
8650
                                options.position = {
8651
                                        my: "left top",
8652
                                        at: "left" + (left >= 0 ? "+" : "") + left + " " +
8653
                                                "top" + (top >= 0 ? "+" : "") + top,
8654
                                        of: that.window
8655
                                };
8656
                                $( this ).removeClass( "ui-dialog-resizing" );
8657
                                that._unblockFrames();
8658
                                that._trigger( "resizeStop", event, filteredUi( ui ) );
8659
                        }
8660
                })
8661
                .css( "position", position );
8662
        },
8663

    
8664
        _trackFocus: function() {
8665
                this._on( this.widget(), {
8666
                        focusin: function( event ) {
8667
                                this._makeFocusTarget();
8668
                                this._focusedElement = $( event.target );
8669
                        }
8670
                });
8671
        },
8672

    
8673
        _makeFocusTarget: function() {
8674
                this._untrackInstance();
8675
                this._trackingInstances().unshift( this );
8676
        },
8677

    
8678
        _untrackInstance: function() {
8679
                var instances = this._trackingInstances(),
8680
                        exists = $.inArray( this, instances );
8681
                if ( exists !== -1 ) {
8682
                        instances.splice( exists, 1 );
8683
                }
8684
        },
8685

    
8686
        _trackingInstances: function() {
8687
                var instances = this.document.data( "ui-dialog-instances" );
8688
                if ( !instances ) {
8689
                        instances = [];
8690
                        this.document.data( "ui-dialog-instances", instances );
8691
                }
8692
                return instances;
8693
        },
8694

    
8695
        _minHeight: function() {
8696
                var options = this.options;
8697

    
8698
                return options.height === "auto" ?
8699
                        options.minHeight :
8700
                        Math.min( options.minHeight, options.height );
8701
        },
8702

    
8703
        _position: function() {
8704
                // Need to show the dialog to get the actual offset in the position plugin
8705
                var isVisible = this.uiDialog.is( ":visible" );
8706
                if ( !isVisible ) {
8707
                        this.uiDialog.show();
8708
                }
8709
                this.uiDialog.position( this.options.position );
8710
                if ( !isVisible ) {
8711
                        this.uiDialog.hide();
8712
                }
8713
        },
8714

    
8715
        _setOptions: function( options ) {
8716
                var that = this,
8717
                        resize = false,
8718
                        resizableOptions = {};
8719

    
8720
                $.each( options, function( key, value ) {
8721
                        that._setOption( key, value );
8722

    
8723
                        if ( key in that.sizeRelatedOptions ) {
8724
                                resize = true;
8725
                        }
8726
                        if ( key in that.resizableRelatedOptions ) {
8727
                                resizableOptions[ key ] = value;
8728
                        }
8729
                });
8730

    
8731
                if ( resize ) {
8732
                        this._size();
8733
                        this._position();
8734
                }
8735
                if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8736
                        this.uiDialog.resizable( "option", resizableOptions );
8737
                }
8738
        },
8739

    
8740
        _setOption: function( key, value ) {
8741
                var isDraggable, isResizable,
8742
                        uiDialog = this.uiDialog;
8743

    
8744
                if ( key === "dialogClass" ) {
8745
                        uiDialog
8746
                                .removeClass( this.options.dialogClass )
8747
                                .addClass( value );
8748
                }
8749

    
8750
                if ( key === "disabled" ) {
8751
                        return;
8752
                }
8753

    
8754
                this._super( key, value );
8755

    
8756
                if ( key === "appendTo" ) {
8757
                        this.uiDialog.appendTo( this._appendTo() );
8758
                }
8759

    
8760
                if ( key === "buttons" ) {
8761
                        this._createButtons();
8762
                }
8763

    
8764
                if ( key === "closeText" ) {
8765
                        this.uiDialogTitlebarClose.button({
8766
                                // Ensure that we always pass a string
8767
                                label: "" + value
8768
                        });
8769
                }
8770

    
8771
                if ( key === "draggable" ) {
8772
                        isDraggable = uiDialog.is( ":data(ui-draggable)" );
8773
                        if ( isDraggable && !value ) {
8774
                                uiDialog.draggable( "destroy" );
8775
                        }
8776

    
8777
                        if ( !isDraggable && value ) {
8778
                                this._makeDraggable();
8779
                        }
8780
                }
8781

    
8782
                if ( key === "position" ) {
8783
                        this._position();
8784
                }
8785

    
8786
                if ( key === "resizable" ) {
8787
                        // currently resizable, becoming non-resizable
8788
                        isResizable = uiDialog.is( ":data(ui-resizable)" );
8789
                        if ( isResizable && !value ) {
8790
                                uiDialog.resizable( "destroy" );
8791
                        }
8792

    
8793
                        // currently resizable, changing handles
8794
                        if ( isResizable && typeof value === "string" ) {
8795
                                uiDialog.resizable( "option", "handles", value );
8796
                        }
8797

    
8798
                        // currently non-resizable, becoming resizable
8799
                        if ( !isResizable && value !== false ) {
8800
                                this._makeResizable();
8801
                        }
8802
                }
8803

    
8804
                if ( key === "title" ) {
8805
                        this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
8806
                }
8807
        },
8808

    
8809
        _size: function() {
8810
                // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
8811
                // divs will both have width and height set, so we need to reset them
8812
                var nonContentHeight, minContentHeight, maxContentHeight,
8813
                        options = this.options;
8814

    
8815
                // Reset content sizing
8816
                this.element.show().css({
8817
                        width: "auto",
8818
                        minHeight: 0,
8819
                        maxHeight: "none",
8820
                        height: 0
8821
                });
8822

    
8823
                if ( options.minWidth > options.width ) {
8824
                        options.width = options.minWidth;
8825
                }
8826

    
8827
                // reset wrapper sizing
8828
                // determine the height of all the non-content elements
8829
                nonContentHeight = this.uiDialog.css({
8830
                                height: "auto",
8831
                                width: options.width
8832
                        })
8833
                        .outerHeight();
8834
                minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
8835
                maxContentHeight = typeof options.maxHeight === "number" ?
8836
                        Math.max( 0, options.maxHeight - nonContentHeight ) :
8837
                        "none";
8838

    
8839
                if ( options.height === "auto" ) {
8840
                        this.element.css({
8841
                                minHeight: minContentHeight,
8842
                                maxHeight: maxContentHeight,
8843
                                height: "auto"
8844
                        });
8845
                } else {
8846
                        this.element.height( Math.max( 0, options.height - nonContentHeight ) );
8847
                }
8848

    
8849
                if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8850
                        this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
8851
                }
8852
        },
8853

    
8854
        _blockFrames: function() {
8855
                this.iframeBlocks = this.document.find( "iframe" ).map(function() {
8856
                        var iframe = $( this );
8857

    
8858
                        return $( "<div>" )
8859
                                .css({
8860
                                        position: "absolute",
8861
                                        width: iframe.outerWidth(),
8862
                                        height: iframe.outerHeight()
8863
                                })
8864
                                .appendTo( iframe.parent() )
8865
                                .offset( iframe.offset() )[0];
8866
                });
8867
        },
8868

    
8869
        _unblockFrames: function() {
8870
                if ( this.iframeBlocks ) {
8871
                        this.iframeBlocks.remove();
8872
                        delete this.iframeBlocks;
8873
                }
8874
        },
8875

    
8876
        _allowInteraction: function( event ) {
8877
                if ( $( event.target ).closest( ".ui-dialog" ).length ) {
8878
                        return true;
8879
                }
8880

    
8881
                // TODO: Remove hack when datepicker implements
8882
                // the .ui-front logic (#8989)
8883
                return !!$( event.target ).closest( ".ui-datepicker" ).length;
8884
        },
8885

    
8886
        _createOverlay: function() {
8887
                if ( !this.options.modal ) {
8888
                        return;
8889
                }
8890

    
8891
                // We use a delay in case the overlay is created from an
8892
                // event that we're going to be cancelling (#2804)
8893
                var isOpening = true;
8894
                this._delay(function() {
8895
                        isOpening = false;
8896
                });
8897

    
8898
                if ( !this.document.data( "ui-dialog-overlays" ) ) {
8899

    
8900
                        // Prevent use of anchors and inputs
8901
                        // Using _on() for an event handler shared across many instances is
8902
                        // safe because the dialogs stack and must be closed in reverse order
8903
                        this._on( this.document, {
8904
                                focusin: function( event ) {
8905
                                        if ( isOpening ) {
8906
                                                return;
8907
                                        }
8908

    
8909
                                        if ( !this._allowInteraction( event ) ) {
8910
                                                event.preventDefault();
8911
                                                this._trackingInstances()[ 0 ]._focusTabbable();
8912
                                        }
8913
                                }
8914
                        });
8915
                }
8916

    
8917
                this.overlay = $( "<div>" )
8918
                        .addClass( "ui-widget-overlay ui-front" )
8919
                        .appendTo( this._appendTo() );
8920
                this._on( this.overlay, {
8921
                        mousedown: "_keepFocus"
8922
                });
8923
                this.document.data( "ui-dialog-overlays",
8924
                        (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
8925
        },
8926

    
8927
        _destroyOverlay: function() {
8928
                if ( !this.options.modal ) {
8929
                        return;
8930
                }
8931

    
8932
                if ( this.overlay ) {
8933
                        var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
8934

    
8935
                        if ( !overlays ) {
8936
                                this.document
8937
                                        .unbind( "focusin" )
8938
                                        .removeData( "ui-dialog-overlays" );
8939
                        } else {
8940
                                this.document.data( "ui-dialog-overlays", overlays );
8941
                        }
8942

    
8943
                        this.overlay.remove();
8944
                        this.overlay = null;
8945
                }
8946
        }
8947
});
8948

    
8949

    
8950
/*!
8951
 * jQuery UI Droppable 1.11.4
8952
 * http://jqueryui.com
8953
 *
8954
 * Copyright jQuery Foundation and other contributors
8955
 * Released under the MIT license.
8956
 * http://jquery.org/license
8957
 *
8958
 * http://api.jqueryui.com/droppable/
8959
 */
8960

    
8961

    
8962
$.widget( "ui.droppable", {
8963
        version: "1.11.4",
8964
        widgetEventPrefix: "drop",
8965
        options: {
8966
                accept: "*",
8967
                activeClass: false,
8968
                addClasses: true,
8969
                greedy: false,
8970
                hoverClass: false,
8971
                scope: "default",
8972
                tolerance: "intersect",
8973

    
8974
                // callbacks
8975
                activate: null,
8976
                deactivate: null,
8977
                drop: null,
8978
                out: null,
8979
                over: null
8980
        },
8981
        _create: function() {
8982

    
8983
                var proportions,
8984
                        o = this.options,
8985
                        accept = o.accept;
8986

    
8987
                this.isover = false;
8988
                this.isout = true;
8989

    
8990
                this.accept = $.isFunction( accept ) ? accept : function( d ) {
8991
                        return d.is( accept );
8992
                };
8993

    
8994
                this.proportions = function( /* valueToWrite */ ) {
8995
                        if ( arguments.length ) {
8996
                                // Store the droppable's proportions
8997
                                proportions = arguments[ 0 ];
8998
                        } else {
8999
                                // Retrieve or derive the droppable's proportions
9000
                                return proportions ?
9001
                                        proportions :
9002
                                        proportions = {
9003
                                                width: this.element[ 0 ].offsetWidth,
9004
                                                height: this.element[ 0 ].offsetHeight
9005
                                        };
9006
                        }
9007
                };
9008

    
9009
                this._addToManager( o.scope );
9010

    
9011
                o.addClasses && this.element.addClass( "ui-droppable" );
9012

    
9013
        },
9014

    
9015
        _addToManager: function( scope ) {
9016
                // Add the reference and positions to the manager
9017
                $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
9018
                $.ui.ddmanager.droppables[ scope ].push( this );
9019
        },
9020

    
9021
        _splice: function( drop ) {
9022
                var i = 0;
9023
                for ( ; i < drop.length; i++ ) {
9024
                        if ( drop[ i ] === this ) {
9025
                                drop.splice( i, 1 );
9026
                        }
9027
                }
9028
        },
9029

    
9030
        _destroy: function() {
9031
                var drop = $.ui.ddmanager.droppables[ this.options.scope ];
9032

    
9033
                this._splice( drop );
9034

    
9035
                this.element.removeClass( "ui-droppable ui-droppable-disabled" );
9036
        },
9037

    
9038
        _setOption: function( key, value ) {
9039

    
9040
                if ( key === "accept" ) {
9041
                        this.accept = $.isFunction( value ) ? value : function( d ) {
9042
                                return d.is( value );
9043
                        };
9044
                } else if ( key === "scope" ) {
9045
                        var drop = $.ui.ddmanager.droppables[ this.options.scope ];
9046

    
9047
                        this._splice( drop );
9048
                        this._addToManager( value );
9049
                }
9050

    
9051
                this._super( key, value );
9052
        },
9053

    
9054
        _activate: function( event ) {
9055
                var draggable = $.ui.ddmanager.current;
9056
                if ( this.options.activeClass ) {
9057
                        this.element.addClass( this.options.activeClass );
9058
                }
9059
                if ( draggable ){
9060
                        this._trigger( "activate", event, this.ui( draggable ) );
9061
                }
9062
        },
9063

    
9064
        _deactivate: function( event ) {
9065
                var draggable = $.ui.ddmanager.current;
9066
                if ( this.options.activeClass ) {
9067
                        this.element.removeClass( this.options.activeClass );
9068
                }
9069
                if ( draggable ){
9070
                        this._trigger( "deactivate", event, this.ui( draggable ) );
9071
                }
9072
        },
9073

    
9074
        _over: function( event ) {
9075

    
9076
                var draggable = $.ui.ddmanager.current;
9077

    
9078
                // Bail if draggable and droppable are same element
9079
                if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9080
                        return;
9081
                }
9082

    
9083
                if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9084
                        if ( this.options.hoverClass ) {
9085
                                this.element.addClass( this.options.hoverClass );
9086
                        }
9087
                        this._trigger( "over", event, this.ui( draggable ) );
9088
                }
9089

    
9090
        },
9091

    
9092
        _out: function( event ) {
9093

    
9094
                var draggable = $.ui.ddmanager.current;
9095

    
9096
                // Bail if draggable and droppable are same element
9097
                if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9098
                        return;
9099
                }
9100

    
9101
                if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9102
                        if ( this.options.hoverClass ) {
9103
                                this.element.removeClass( this.options.hoverClass );
9104
                        }
9105
                        this._trigger( "out", event, this.ui( draggable ) );
9106
                }
9107

    
9108
        },
9109

    
9110
        _drop: function( event, custom ) {
9111

    
9112
                var draggable = custom || $.ui.ddmanager.current,
9113
                        childrenIntersection = false;
9114

    
9115
                // Bail if draggable and droppable are same element
9116
                if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9117
                        return false;
9118
                }
9119

    
9120
                this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
9121
                        var inst = $( this ).droppable( "instance" );
9122
                        if (
9123
                                inst.options.greedy &&
9124
                                !inst.options.disabled &&
9125
                                inst.options.scope === draggable.options.scope &&
9126
                                inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
9127
                                $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
9128
                        ) { childrenIntersection = true; return false; }
9129
                });
9130
                if ( childrenIntersection ) {
9131
                        return false;
9132
                }
9133

    
9134
                if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9135
                        if ( this.options.activeClass ) {
9136
                                this.element.removeClass( this.options.activeClass );
9137
                        }
9138
                        if ( this.options.hoverClass ) {
9139
                                this.element.removeClass( this.options.hoverClass );
9140
                        }
9141
                        this._trigger( "drop", event, this.ui( draggable ) );
9142
                        return this.element;
9143
                }
9144

    
9145
                return false;
9146

    
9147
        },
9148

    
9149
        ui: function( c ) {
9150
                return {
9151
                        draggable: ( c.currentItem || c.element ),
9152
                        helper: c.helper,
9153
                        position: c.position,
9154
                        offset: c.positionAbs
9155
                };
9156
        }
9157

    
9158
});
9159

    
9160
$.ui.intersect = (function() {
9161
        function isOverAxis( x, reference, size ) {
9162
                return ( x >= reference ) && ( x < ( reference + size ) );
9163
        }
9164

    
9165
        return function( draggable, droppable, toleranceMode, event ) {
9166

    
9167
                if ( !droppable.offset ) {
9168
                        return false;
9169
                }
9170

    
9171
                var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
9172
                        y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
9173
                        x2 = x1 + draggable.helperProportions.width,
9174
                        y2 = y1 + draggable.helperProportions.height,
9175
                        l = droppable.offset.left,
9176
                        t = droppable.offset.top,
9177
                        r = l + droppable.proportions().width,
9178
                        b = t + droppable.proportions().height;
9179

    
9180
                switch ( toleranceMode ) {
9181
                case "fit":
9182
                        return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
9183
                case "intersect":
9184
                        return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
9185
                                x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
9186
                                t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
9187
                                y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
9188
                case "pointer":
9189
                        return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
9190
                case "touch":
9191
                        return (
9192
                                ( y1 >= t && y1 <= b ) || // Top edge touching
9193
                                ( y2 >= t && y2 <= b ) || // Bottom edge touching
9194
                                ( y1 < t && y2 > b ) // Surrounded vertically
9195
                        ) && (
9196
                                ( x1 >= l && x1 <= r ) || // Left edge touching
9197
                                ( x2 >= l && x2 <= r ) || // Right edge touching
9198
                                ( x1 < l && x2 > r ) // Surrounded horizontally
9199
                        );
9200
                default:
9201
                        return false;
9202
                }
9203
        };
9204
})();
9205

    
9206
/*
9207
        This manager tracks offsets of draggables and droppables
9208
*/
9209
$.ui.ddmanager = {
9210
        current: null,
9211
        droppables: { "default": [] },
9212
        prepareOffsets: function( t, event ) {
9213

    
9214
                var i, j,
9215
                        m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
9216
                        type = event ? event.type : null, // workaround for #2317
9217
                        list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
9218

    
9219
                droppablesLoop: for ( i = 0; i < m.length; i++ ) {
9220

    
9221
                        // No disabled and non-accepted
9222
                        if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
9223
                                continue;
9224
                        }
9225

    
9226
                        // Filter out elements in the current dragged item
9227
                        for ( j = 0; j < list.length; j++ ) {
9228
                                if ( list[ j ] === m[ i ].element[ 0 ] ) {
9229
                                        m[ i ].proportions().height = 0;
9230
                                        continue droppablesLoop;
9231
                                }
9232
                        }
9233

    
9234
                        m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
9235
                        if ( !m[ i ].visible ) {
9236
                                continue;
9237
                        }
9238

    
9239
                        // Activate the droppable if used directly from draggables
9240
                        if ( type === "mousedown" ) {
9241
                                m[ i ]._activate.call( m[ i ], event );
9242
                        }
9243

    
9244
                        m[ i ].offset = m[ i ].element.offset();
9245
                        m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
9246

    
9247
                }
9248

    
9249
        },
9250
        drop: function( draggable, event ) {
9251

    
9252
                var dropped = false;
9253
                // Create a copy of the droppables in case the list changes during the drop (#9116)
9254
                $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
9255

    
9256
                        if ( !this.options ) {
9257
                                return;
9258
                        }
9259
                        if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
9260
                                dropped = this._drop.call( this, event ) || dropped;
9261
                        }
9262

    
9263
                        if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9264
                                this.isout = true;
9265
                                this.isover = false;
9266
                                this._deactivate.call( this, event );
9267
                        }
9268

    
9269
                });
9270
                return dropped;
9271

    
9272
        },
9273
        dragStart: function( draggable, event ) {
9274
                // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
9275
                draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
9276
                        if ( !draggable.options.refreshPositions ) {
9277
                                $.ui.ddmanager.prepareOffsets( draggable, event );
9278
                        }
9279
                });
9280
        },
9281
        drag: function( draggable, event ) {
9282

    
9283
                // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
9284
                if ( draggable.options.refreshPositions ) {
9285
                        $.ui.ddmanager.prepareOffsets( draggable, event );
9286
                }
9287

    
9288
                // Run through all droppables and check their positions based on specific tolerance options
9289
                $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
9290

    
9291
                        if ( this.options.disabled || this.greedyChild || !this.visible ) {
9292
                                return;
9293
                        }
9294

    
9295
                        var parentInstance, scope, parent,
9296
                                intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
9297
                                c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
9298
                        if ( !c ) {
9299
                                return;
9300
                        }
9301

    
9302
                        if ( this.options.greedy ) {
9303
                                // find droppable parents with same scope
9304
                                scope = this.options.scope;
9305
                                parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
9306
                                        return $( this ).droppable( "instance" ).options.scope === scope;
9307
                                });
9308

    
9309
                                if ( parent.length ) {
9310
                                        parentInstance = $( parent[ 0 ] ).droppable( "instance" );
9311
                                        parentInstance.greedyChild = ( c === "isover" );
9312
                                }
9313
                        }
9314

    
9315
                        // we just moved into a greedy child
9316
                        if ( parentInstance && c === "isover" ) {
9317
                                parentInstance.isover = false;
9318
                                parentInstance.isout = true;
9319
                                parentInstance._out.call( parentInstance, event );
9320
                        }
9321

    
9322
                        this[ c ] = true;
9323
                        this[c === "isout" ? "isover" : "isout"] = false;
9324
                        this[c === "isover" ? "_over" : "_out"].call( this, event );
9325

    
9326
                        // we just moved out of a greedy child
9327
                        if ( parentInstance && c === "isout" ) {
9328
                                parentInstance.isout = false;
9329
                                parentInstance.isover = true;
9330
                                parentInstance._over.call( parentInstance, event );
9331
                        }
9332
                });
9333

    
9334
        },
9335
        dragStop: function( draggable, event ) {
9336
                draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
9337
                // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
9338
                if ( !draggable.options.refreshPositions ) {
9339
                        $.ui.ddmanager.prepareOffsets( draggable, event );
9340
                }
9341
        }
9342
};
9343

    
9344
var droppable = $.ui.droppable;
9345

    
9346

    
9347
/*!
9348
 * jQuery UI Effects 1.11.4
9349
 * http://jqueryui.com
9350
 *
9351
 * Copyright jQuery Foundation and other contributors
9352
 * Released under the MIT license.
9353
 * http://jquery.org/license
9354
 *
9355
 * http://api.jqueryui.com/category/effects-core/
9356
 */
9357

    
9358

    
9359
var dataSpace = "ui-effects-",
9360

    
9361
        // Create a local jQuery because jQuery Color relies on it and the
9362
        // global may not exist with AMD and a custom build (#10199)
9363
        jQuery = $;
9364

    
9365
$.effects = {
9366
        effect: {}
9367
};
9368

    
9369
/*!
9370
 * jQuery Color Animations v2.1.2
9371
 * https://github.com/jquery/jquery-color
9372
 *
9373
 * Copyright 2014 jQuery Foundation and other contributors
9374
 * Released under the MIT license.
9375
 * http://jquery.org/license
9376
 *
9377
 * Date: Wed Jan 16 08:47:09 2013 -0600
9378
 */
9379
(function( jQuery, undefined ) {
9380

    
9381
        var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
9382

    
9383
        // plusequals test for += 100 -= 100
9384
        rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
9385
        // a set of RE's that can match strings and generate color tuples.
9386
        stringParsers = [ {
9387
                        re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9388
                        parse: function( execResult ) {
9389
                                return [
9390
                                        execResult[ 1 ],
9391
                                        execResult[ 2 ],
9392
                                        execResult[ 3 ],
9393
                                        execResult[ 4 ]
9394
                                ];
9395
                        }
9396
                }, {
9397
                        re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9398
                        parse: function( execResult ) {
9399
                                return [
9400
                                        execResult[ 1 ] * 2.55,
9401
                                        execResult[ 2 ] * 2.55,
9402
                                        execResult[ 3 ] * 2.55,
9403
                                        execResult[ 4 ]
9404
                                ];
9405
                        }
9406
                }, {
9407
                        // this regex ignores A-F because it's compared against an already lowercased string
9408
                        re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
9409
                        parse: function( execResult ) {
9410
                                return [
9411
                                        parseInt( execResult[ 1 ], 16 ),
9412
                                        parseInt( execResult[ 2 ], 16 ),
9413
                                        parseInt( execResult[ 3 ], 16 )
9414
                                ];
9415
                        }
9416
                }, {
9417
                        // this regex ignores A-F because it's compared against an already lowercased string
9418
                        re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
9419
                        parse: function( execResult ) {
9420
                                return [
9421
                                        parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
9422
                                        parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
9423
                                        parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
9424
                                ];
9425
                        }
9426
                }, {
9427
                        re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9428
                        space: "hsla",
9429
                        parse: function( execResult ) {
9430
                                return [
9431
                                        execResult[ 1 ],
9432
                                        execResult[ 2 ] / 100,
9433
                                        execResult[ 3 ] / 100,
9434
                                        execResult[ 4 ]
9435
                                ];
9436
                        }
9437
                } ],
9438

    
9439
        // jQuery.Color( )
9440
        color = jQuery.Color = function( color, green, blue, alpha ) {
9441
                return new jQuery.Color.fn.parse( color, green, blue, alpha );
9442
        },
9443
        spaces = {
9444
                rgba: {
9445
                        props: {
9446
                                red: {
9447
                                        idx: 0,
9448
                                        type: "byte"
9449
                                },
9450
                                green: {
9451
                                        idx: 1,
9452
                                        type: "byte"
9453
                                },
9454
                                blue: {
9455
                                        idx: 2,
9456
                                        type: "byte"
9457
                                }
9458
                        }
9459
                },
9460

    
9461
                hsla: {
9462
                        props: {
9463
                                hue: {
9464
                                        idx: 0,
9465
                                        type: "degrees"
9466
                                },
9467
                                saturation: {
9468
                                        idx: 1,
9469
                                        type: "percent"
9470
                                },
9471
                                lightness: {
9472
                                        idx: 2,
9473
                                        type: "percent"
9474
                                }
9475
                        }
9476
                }
9477
        },
9478
        propTypes = {
9479
                "byte": {
9480
                        floor: true,
9481
                        max: 255
9482
                },
9483
                "percent": {
9484
                        max: 1
9485
                },
9486
                "degrees": {
9487
                        mod: 360,
9488
                        floor: true
9489
                }
9490
        },
9491
        support = color.support = {},
9492

    
9493
        // element for support tests
9494
        supportElem = jQuery( "<p>" )[ 0 ],
9495

    
9496
        // colors = jQuery.Color.names
9497
        colors,
9498

    
9499
        // local aliases of functions called often
9500
        each = jQuery.each;
9501

    
9502
// determine rgba support immediately
9503
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
9504
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
9505

    
9506
// define cache name and alpha properties
9507
// for rgba and hsla spaces
9508
each( spaces, function( spaceName, space ) {
9509
        space.cache = "_" + spaceName;
9510
        space.props.alpha = {
9511
                idx: 3,
9512
                type: "percent",
9513
                def: 1
9514
        };
9515
});
9516

    
9517
function clamp( value, prop, allowEmpty ) {
9518
        var type = propTypes[ prop.type ] || {};
9519

    
9520
        if ( value == null ) {
9521
                return (allowEmpty || !prop.def) ? null : prop.def;
9522
        }
9523

    
9524
        // ~~ is an short way of doing floor for positive numbers
9525
        value = type.floor ? ~~value : parseFloat( value );
9526

    
9527
        // IE will pass in empty strings as value for alpha,
9528
        // which will hit this case
9529
        if ( isNaN( value ) ) {
9530
                return prop.def;
9531
        }
9532

    
9533
        if ( type.mod ) {
9534
                // we add mod before modding to make sure that negatives values
9535
                // get converted properly: -10 -> 350
9536
                return (value + type.mod) % type.mod;
9537
        }
9538

    
9539
        // for now all property types without mod have min and max
9540
        return 0 > value ? 0 : type.max < value ? type.max : value;
9541
}
9542

    
9543
function stringParse( string ) {
9544
        var inst = color(),
9545
                rgba = inst._rgba = [];
9546

    
9547
        string = string.toLowerCase();
9548

    
9549
        each( stringParsers, function( i, parser ) {
9550
                var parsed,
9551
                        match = parser.re.exec( string ),
9552
                        values = match && parser.parse( match ),
9553
                        spaceName = parser.space || "rgba";
9554

    
9555
                if ( values ) {
9556
                        parsed = inst[ spaceName ]( values );
9557

    
9558
                        // if this was an rgba parse the assignment might happen twice
9559
                        // oh well....
9560
                        inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
9561
                        rgba = inst._rgba = parsed._rgba;
9562

    
9563
                        // exit each( stringParsers ) here because we matched
9564
                        return false;
9565
                }
9566
        });
9567

    
9568
        // Found a stringParser that handled it
9569
        if ( rgba.length ) {
9570

    
9571
                // if this came from a parsed string, force "transparent" when alpha is 0
9572
                // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
9573
                if ( rgba.join() === "0,0,0,0" ) {
9574
                        jQuery.extend( rgba, colors.transparent );
9575
                }
9576
                return inst;
9577
        }
9578

    
9579
        // named colors
9580
        return colors[ string ];
9581
}
9582

    
9583
color.fn = jQuery.extend( color.prototype, {
9584
        parse: function( red, green, blue, alpha ) {
9585
                if ( red === undefined ) {
9586
                        this._rgba = [ null, null, null, null ];
9587
                        return this;
9588
                }
9589
                if ( red.jquery || red.nodeType ) {
9590
                        red = jQuery( red ).css( green );
9591
                        green = undefined;
9592
                }
9593

    
9594
                var inst = this,
9595
                        type = jQuery.type( red ),
9596
                        rgba = this._rgba = [];
9597

    
9598
                // more than 1 argument specified - assume ( red, green, blue, alpha )
9599
                if ( green !== undefined ) {
9600
                        red = [ red, green, blue, alpha ];
9601
                        type = "array";
9602
                }
9603

    
9604
                if ( type === "string" ) {
9605
                        return this.parse( stringParse( red ) || colors._default );
9606
                }
9607

    
9608
                if ( type === "array" ) {
9609
                        each( spaces.rgba.props, function( key, prop ) {
9610
                                rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
9611
                        });
9612
                        return this;
9613
                }
9614

    
9615
                if ( type === "object" ) {
9616
                        if ( red instanceof color ) {
9617
                                each( spaces, function( spaceName, space ) {
9618
                                        if ( red[ space.cache ] ) {
9619
                                                inst[ space.cache ] = red[ space.cache ].slice();
9620
                                        }
9621
                                });
9622
                        } else {
9623
                                each( spaces, function( spaceName, space ) {
9624
                                        var cache = space.cache;
9625
                                        each( space.props, function( key, prop ) {
9626

    
9627
                                                // if the cache doesn't exist, and we know how to convert
9628
                                                if ( !inst[ cache ] && space.to ) {
9629

    
9630
                                                        // if the value was null, we don't need to copy it
9631
                                                        // if the key was alpha, we don't need to copy it either
9632
                                                        if ( key === "alpha" || red[ key ] == null ) {
9633
                                                                return;
9634
                                                        }
9635
                                                        inst[ cache ] = space.to( inst._rgba );
9636
                                                }
9637

    
9638
                                                // this is the only case where we allow nulls for ALL properties.
9639
                                                // call clamp with alwaysAllowEmpty
9640
                                                inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
9641
                                        });
9642

    
9643
                                        // everything defined but alpha?
9644
                                        if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
9645
                                                // use the default of 1
9646
                                                inst[ cache ][ 3 ] = 1;
9647
                                                if ( space.from ) {
9648
                                                        inst._rgba = space.from( inst[ cache ] );
9649
                                                }
9650
                                        }
9651
                                });
9652
                        }
9653
                        return this;
9654
                }
9655
        },
9656
        is: function( compare ) {
9657
                var is = color( compare ),
9658
                        same = true,
9659
                        inst = this;
9660

    
9661
                each( spaces, function( _, space ) {
9662
                        var localCache,
9663
                                isCache = is[ space.cache ];
9664
                        if (isCache) {
9665
                                localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
9666
                                each( space.props, function( _, prop ) {
9667
                                        if ( isCache[ prop.idx ] != null ) {
9668
                                                same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
9669
                                                return same;
9670
                                        }
9671
                                });
9672
                        }
9673
                        return same;
9674
                });
9675
                return same;
9676
        },
9677
        _space: function() {
9678
                var used = [],
9679
                        inst = this;
9680
                each( spaces, function( spaceName, space ) {
9681
                        if ( inst[ space.cache ] ) {
9682
                                used.push( spaceName );
9683
                        }
9684
                });
9685
                return used.pop();
9686
        },
9687
        transition: function( other, distance ) {
9688
                var end = color( other ),
9689
                        spaceName = end._space(),
9690
                        space = spaces[ spaceName ],
9691
                        startColor = this.alpha() === 0 ? color( "transparent" ) : this,
9692
                        start = startColor[ space.cache ] || space.to( startColor._rgba ),
9693
                        result = start.slice();
9694

    
9695
                end = end[ space.cache ];
9696
                each( space.props, function( key, prop ) {
9697
                        var index = prop.idx,
9698
                                startValue = start[ index ],
9699
                                endValue = end[ index ],
9700
                                type = propTypes[ prop.type ] || {};
9701

    
9702
                        // if null, don't override start value
9703
                        if ( endValue === null ) {
9704
                                return;
9705
                        }
9706
                        // if null - use end
9707
                        if ( startValue === null ) {
9708
                                result[ index ] = endValue;
9709
                        } else {
9710
                                if ( type.mod ) {
9711
                                        if ( endValue - startValue > type.mod / 2 ) {
9712
                                                startValue += type.mod;
9713
                                        } else if ( startValue - endValue > type.mod / 2 ) {
9714
                                                startValue -= type.mod;
9715
                                        }
9716
                                }
9717
                                result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
9718
                        }
9719
                });
9720
                return this[ spaceName ]( result );
9721
        },
9722
        blend: function( opaque ) {
9723
                // if we are already opaque - return ourself
9724
                if ( this._rgba[ 3 ] === 1 ) {
9725
                        return this;
9726
                }
9727

    
9728
                var rgb = this._rgba.slice(),
9729
                        a = rgb.pop(),
9730
                        blend = color( opaque )._rgba;
9731

    
9732
                return color( jQuery.map( rgb, function( v, i ) {
9733
                        return ( 1 - a ) * blend[ i ] + a * v;
9734
                }));
9735
        },
9736
        toRgbaString: function() {
9737
                var prefix = "rgba(",
9738
                        rgba = jQuery.map( this._rgba, function( v, i ) {
9739
                                return v == null ? ( i > 2 ? 1 : 0 ) : v;
9740
                        });
9741

    
9742
                if ( rgba[ 3 ] === 1 ) {
9743
                        rgba.pop();
9744
                        prefix = "rgb(";
9745
                }
9746

    
9747
                return prefix + rgba.join() + ")";
9748
        },
9749
        toHslaString: function() {
9750
                var prefix = "hsla(",
9751
                        hsla = jQuery.map( this.hsla(), function( v, i ) {
9752
                                if ( v == null ) {
9753
                                        v = i > 2 ? 1 : 0;
9754
                                }
9755

    
9756
                                // catch 1 and 2
9757
                                if ( i && i < 3 ) {
9758
                                        v = Math.round( v * 100 ) + "%";
9759
                                }
9760
                                return v;
9761
                        });
9762

    
9763
                if ( hsla[ 3 ] === 1 ) {
9764
                        hsla.pop();
9765
                        prefix = "hsl(";
9766
                }
9767
                return prefix + hsla.join() + ")";
9768
        },
9769
        toHexString: function( includeAlpha ) {
9770
                var rgba = this._rgba.slice(),
9771
                        alpha = rgba.pop();
9772

    
9773
                if ( includeAlpha ) {
9774
                        rgba.push( ~~( alpha * 255 ) );
9775
                }
9776

    
9777
                return "#" + jQuery.map( rgba, function( v ) {
9778

    
9779
                        // default to 0 when nulls exist
9780
                        v = ( v || 0 ).toString( 16 );
9781
                        return v.length === 1 ? "0" + v : v;
9782
                }).join("");
9783
        },
9784
        toString: function() {
9785
                return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
9786
        }
9787
});
9788
color.fn.parse.prototype = color.fn;
9789

    
9790
// hsla conversions adapted from:
9791
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
9792

    
9793
function hue2rgb( p, q, h ) {
9794
        h = ( h + 1 ) % 1;
9795
        if ( h * 6 < 1 ) {
9796
                return p + ( q - p ) * h * 6;
9797
        }
9798
        if ( h * 2 < 1) {
9799
                return q;
9800
        }
9801
        if ( h * 3 < 2 ) {
9802
                return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
9803
        }
9804
        return p;
9805
}
9806

    
9807
spaces.hsla.to = function( rgba ) {
9808
        if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
9809
                return [ null, null, null, rgba[ 3 ] ];
9810
        }
9811
        var r = rgba[ 0 ] / 255,
9812
                g = rgba[ 1 ] / 255,
9813
                b = rgba[ 2 ] / 255,
9814
                a = rgba[ 3 ],
9815
                max = Math.max( r, g, b ),
9816
                min = Math.min( r, g, b ),
9817
                diff = max - min,
9818
                add = max + min,
9819
                l = add * 0.5,
9820
                h, s;
9821

    
9822
        if ( min === max ) {
9823
                h = 0;
9824
        } else if ( r === max ) {
9825
                h = ( 60 * ( g - b ) / diff ) + 360;
9826
        } else if ( g === max ) {
9827
                h = ( 60 * ( b - r ) / diff ) + 120;
9828
        } else {
9829
                h = ( 60 * ( r - g ) / diff ) + 240;
9830
        }
9831

    
9832
        // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
9833
        // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
9834
        if ( diff === 0 ) {
9835
                s = 0;
9836
        } else if ( l <= 0.5 ) {
9837
                s = diff / add;
9838
        } else {
9839
                s = diff / ( 2 - add );
9840
        }
9841
        return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
9842
};
9843

    
9844
spaces.hsla.from = function( hsla ) {
9845
        if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
9846
                return [ null, null, null, hsla[ 3 ] ];
9847
        }
9848
        var h = hsla[ 0 ] / 360,
9849
                s = hsla[ 1 ],
9850
                l = hsla[ 2 ],
9851
                a = hsla[ 3 ],
9852
                q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
9853
                p = 2 * l - q;
9854

    
9855
        return [
9856
                Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
9857
                Math.round( hue2rgb( p, q, h ) * 255 ),
9858
                Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
9859
                a
9860
        ];
9861
};
9862

    
9863
each( spaces, function( spaceName, space ) {
9864
        var props = space.props,
9865
                cache = space.cache,
9866
                to = space.to,
9867
                from = space.from;
9868

    
9869
        // makes rgba() and hsla()
9870
        color.fn[ spaceName ] = function( value ) {
9871

    
9872
                // generate a cache for this space if it doesn't exist
9873
                if ( to && !this[ cache ] ) {
9874
                        this[ cache ] = to( this._rgba );
9875
                }
9876
                if ( value === undefined ) {
9877
                        return this[ cache ].slice();
9878
                }
9879

    
9880
                var ret,
9881
                        type = jQuery.type( value ),
9882
                        arr = ( type === "array" || type === "object" ) ? value : arguments,
9883
                        local = this[ cache ].slice();
9884

    
9885
                each( props, function( key, prop ) {
9886
                        var val = arr[ type === "object" ? key : prop.idx ];
9887
                        if ( val == null ) {
9888
                                val = local[ prop.idx ];
9889
                        }
9890
                        local[ prop.idx ] = clamp( val, prop );
9891
                });
9892

    
9893
                if ( from ) {
9894
                        ret = color( from( local ) );
9895
                        ret[ cache ] = local;
9896
                        return ret;
9897
                } else {
9898
                        return color( local );
9899
                }
9900
        };
9901

    
9902
        // makes red() green() blue() alpha() hue() saturation() lightness()
9903
        each( props, function( key, prop ) {
9904
                // alpha is included in more than one space
9905
                if ( color.fn[ key ] ) {
9906
                        return;
9907
                }
9908
                color.fn[ key ] = function( value ) {
9909
                        var vtype = jQuery.type( value ),
9910
                                fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
9911
                                local = this[ fn ](),
9912
                                cur = local[ prop.idx ],
9913
                                match;
9914

    
9915
                        if ( vtype === "undefined" ) {
9916
                                return cur;
9917
                        }
9918

    
9919
                        if ( vtype === "function" ) {
9920
                                value = value.call( this, cur );
9921
                                vtype = jQuery.type( value );
9922
                        }
9923
                        if ( value == null && prop.empty ) {
9924
                                return this;
9925
                        }
9926
                        if ( vtype === "string" ) {
9927
                                match = rplusequals.exec( value );
9928
                                if ( match ) {
9929
                                        value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
9930
                                }
9931
                        }
9932
                        local[ prop.idx ] = value;
9933
                        return this[ fn ]( local );
9934
                };
9935
        });
9936
});
9937

    
9938
// add cssHook and .fx.step function for each named hook.
9939
// accept a space separated string of properties
9940
color.hook = function( hook ) {
9941
        var hooks = hook.split( " " );
9942
        each( hooks, function( i, hook ) {
9943
                jQuery.cssHooks[ hook ] = {
9944
                        set: function( elem, value ) {
9945
                                var parsed, curElem,
9946
                                        backgroundColor = "";
9947

    
9948
                                if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
9949
                                        value = color( parsed || value );
9950
                                        if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
9951
                                                curElem = hook === "backgroundColor" ? elem.parentNode : elem;
9952
                                                while (
9953
                                                        (backgroundColor === "" || backgroundColor === "transparent") &&
9954
                                                        curElem && curElem.style
9955
                                                ) {
9956
                                                        try {
9957
                                                                backgroundColor = jQuery.css( curElem, "backgroundColor" );
9958
                                                                curElem = curElem.parentNode;
9959
                                                        } catch ( e ) {
9960
                                                        }
9961
                                                }
9962

    
9963
                                                value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
9964
                                                        backgroundColor :
9965
                                                        "_default" );
9966
                                        }
9967

    
9968
                                        value = value.toRgbaString();
9969
                                }
9970
                                try {
9971
                                        elem.style[ hook ] = value;
9972
                                } catch ( e ) {
9973
                                        // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
9974
                                }
9975
                        }
9976
                };
9977
                jQuery.fx.step[ hook ] = function( fx ) {
9978
                        if ( !fx.colorInit ) {
9979
                                fx.start = color( fx.elem, hook );
9980
                                fx.end = color( fx.end );
9981
                                fx.colorInit = true;
9982
                        }
9983
                        jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
9984
                };
9985
        });
9986

    
9987
};
9988

    
9989
color.hook( stepHooks );
9990

    
9991
jQuery.cssHooks.borderColor = {
9992
        expand: function( value ) {
9993
                var expanded = {};
9994

    
9995
                each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
9996
                        expanded[ "border" + part + "Color" ] = value;
9997
                });
9998
                return expanded;
9999
        }
10000
};
10001

    
10002
// Basic color names only.
10003
// Usage of any of the other color names requires adding yourself or including
10004
// jquery.color.svg-names.js.
10005
colors = jQuery.Color.names = {
10006
        // 4.1. Basic color keywords
10007
        aqua: "#00ffff",
10008
        black: "#000000",
10009
        blue: "#0000ff",
10010
        fuchsia: "#ff00ff",
10011
        gray: "#808080",
10012
        green: "#008000",
10013
        lime: "#00ff00",
10014
        maroon: "#800000",
10015
        navy: "#000080",
10016
        olive: "#808000",
10017
        purple: "#800080",
10018
        red: "#ff0000",
10019
        silver: "#c0c0c0",
10020
        teal: "#008080",
10021
        white: "#ffffff",
10022
        yellow: "#ffff00",
10023

    
10024
        // 4.2.3. "transparent" color keyword
10025
        transparent: [ null, null, null, 0 ],
10026

    
10027
        _default: "#ffffff"
10028
};
10029

    
10030
})( jQuery );
10031

    
10032
/******************************************************************************/
10033
/****************************** CLASS ANIMATIONS ******************************/
10034
/******************************************************************************/
10035
(function() {
10036

    
10037
var classAnimationActions = [ "add", "remove", "toggle" ],
10038
        shorthandStyles = {
10039
                border: 1,
10040
                borderBottom: 1,
10041
                borderColor: 1,
10042
                borderLeft: 1,
10043
                borderRight: 1,
10044
                borderTop: 1,
10045
                borderWidth: 1,
10046
                margin: 1,
10047
                padding: 1
10048
        };
10049

    
10050
$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
10051
        $.fx.step[ prop ] = function( fx ) {
10052
                if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
10053
                        jQuery.style( fx.elem, prop, fx.end );
10054
                        fx.setAttr = true;
10055
                }
10056
        };
10057
});
10058

    
10059
function getElementStyles( elem ) {
10060
        var key, len,
10061
                style = elem.ownerDocument.defaultView ?
10062
                        elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
10063
                        elem.currentStyle,
10064
                styles = {};
10065

    
10066
        if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
10067
                len = style.length;
10068
                while ( len-- ) {
10069
                        key = style[ len ];
10070
                        if ( typeof style[ key ] === "string" ) {
10071
                                styles[ $.camelCase( key ) ] = style[ key ];
10072
                        }
10073
                }
10074
        // support: Opera, IE <9
10075
        } else {
10076
                for ( key in style ) {
10077
                        if ( typeof style[ key ] === "string" ) {
10078
                                styles[ key ] = style[ key ];
10079
                        }
10080
                }
10081
        }
10082

    
10083
        return styles;
10084
}
10085

    
10086
function styleDifference( oldStyle, newStyle ) {
10087
        var diff = {},
10088
                name, value;
10089

    
10090
        for ( name in newStyle ) {
10091
                value = newStyle[ name ];
10092
                if ( oldStyle[ name ] !== value ) {
10093
                        if ( !shorthandStyles[ name ] ) {
10094
                                if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
10095
                                        diff[ name ] = value;
10096
                                }
10097
                        }
10098
                }
10099
        }
10100

    
10101
        return diff;
10102
}
10103

    
10104
// support: jQuery <1.8
10105
if ( !$.fn.addBack ) {
10106
        $.fn.addBack = function( selector ) {
10107
                return this.add( selector == null ?
10108
                        this.prevObject : this.prevObject.filter( selector )
10109
                );
10110
        };
10111
}
10112

    
10113
$.effects.animateClass = function( value, duration, easing, callback ) {
10114
        var o = $.speed( duration, easing, callback );
10115

    
10116
        return this.queue( function() {
10117
                var animated = $( this ),
10118
                        baseClass = animated.attr( "class" ) || "",
10119
                        applyClassChange,
10120
                        allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
10121

    
10122
                // map the animated objects to store the original styles.
10123
                allAnimations = allAnimations.map(function() {
10124
                        var el = $( this );
10125
                        return {
10126
                                el: el,
10127
                                start: getElementStyles( this )
10128
                        };
10129
                });
10130

    
10131
                // apply class change
10132
                applyClassChange = function() {
10133
                        $.each( classAnimationActions, function(i, action) {
10134
                                if ( value[ action ] ) {
10135
                                        animated[ action + "Class" ]( value[ action ] );
10136
                                }
10137
                        });
10138
                };
10139
                applyClassChange();
10140

    
10141
                // map all animated objects again - calculate new styles and diff
10142
                allAnimations = allAnimations.map(function() {
10143
                        this.end = getElementStyles( this.el[ 0 ] );
10144
                        this.diff = styleDifference( this.start, this.end );
10145
                        return this;
10146
                });
10147

    
10148
                // apply original class
10149
                animated.attr( "class", baseClass );
10150

    
10151
                // map all animated objects again - this time collecting a promise
10152
                allAnimations = allAnimations.map(function() {
10153
                        var styleInfo = this,
10154
                                dfd = $.Deferred(),
10155
                                opts = $.extend({}, o, {
10156
                                        queue: false,
10157
                                        complete: function() {
10158
                                                dfd.resolve( styleInfo );
10159
                                        }
10160
                                });
10161

    
10162
                        this.el.animate( this.diff, opts );
10163
                        return dfd.promise();
10164
                });
10165

    
10166
                // once all animations have completed:
10167
                $.when.apply( $, allAnimations.get() ).done(function() {
10168

    
10169
                        // set the final class
10170
                        applyClassChange();
10171

    
10172
                        // for each animated element,
10173
                        // clear all css properties that were animated
10174
                        $.each( arguments, function() {
10175
                                var el = this.el;
10176
                                $.each( this.diff, function(key) {
10177
                                        el.css( key, "" );
10178
                                });
10179
                        });
10180

    
10181
                        // this is guarnteed to be there if you use jQuery.speed()
10182
                        // it also handles dequeuing the next anim...
10183
                        o.complete.call( animated[ 0 ] );
10184
                });
10185
        });
10186
};
10187

    
10188
$.fn.extend({
10189
        addClass: (function( orig ) {
10190
                return function( classNames, speed, easing, callback ) {
10191
                        return speed ?
10192
                                $.effects.animateClass.call( this,
10193
                                        { add: classNames }, speed, easing, callback ) :
10194
                                orig.apply( this, arguments );
10195
                };
10196
        })( $.fn.addClass ),
10197

    
10198
        removeClass: (function( orig ) {
10199
                return function( classNames, speed, easing, callback ) {
10200
                        return arguments.length > 1 ?
10201
                                $.effects.animateClass.call( this,
10202
                                        { remove: classNames }, speed, easing, callback ) :
10203
                                orig.apply( this, arguments );
10204
                };
10205
        })( $.fn.removeClass ),
10206

    
10207
        toggleClass: (function( orig ) {
10208
                return function( classNames, force, speed, easing, callback ) {
10209
                        if ( typeof force === "boolean" || force === undefined ) {
10210
                                if ( !speed ) {
10211
                                        // without speed parameter
10212
                                        return orig.apply( this, arguments );
10213
                                } else {
10214
                                        return $.effects.animateClass.call( this,
10215
                                                (force ? { add: classNames } : { remove: classNames }),
10216
                                                speed, easing, callback );
10217
                                }
10218
                        } else {
10219
                                // without force parameter
10220
                                return $.effects.animateClass.call( this,
10221
                                        { toggle: classNames }, force, speed, easing );
10222
                        }
10223
                };
10224
        })( $.fn.toggleClass ),
10225

    
10226
        switchClass: function( remove, add, speed, easing, callback) {
10227
                return $.effects.animateClass.call( this, {
10228
                        add: add,
10229
                        remove: remove
10230
                }, speed, easing, callback );
10231
        }
10232
});
10233

    
10234
})();
10235

    
10236
/******************************************************************************/
10237
/*********************************** EFFECTS **********************************/
10238
/******************************************************************************/
10239

    
10240
(function() {
10241

    
10242
$.extend( $.effects, {
10243
        version: "1.11.4",
10244

    
10245
        // Saves a set of properties in a data storage
10246
        save: function( element, set ) {
10247
                for ( var i = 0; i < set.length; i++ ) {
10248
                        if ( set[ i ] !== null ) {
10249
                                element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
10250
                        }
10251
                }
10252
        },
10253

    
10254
        // Restores a set of previously saved properties from a data storage
10255
        restore: function( element, set ) {
10256
                var val, i;
10257
                for ( i = 0; i < set.length; i++ ) {
10258
                        if ( set[ i ] !== null ) {
10259
                                val = element.data( dataSpace + set[ i ] );
10260
                                // support: jQuery 1.6.2
10261
                                // http://bugs.jquery.com/ticket/9917
10262
                                // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
10263
                                // We can't differentiate between "" and 0 here, so we just assume
10264
                                // empty string since it's likely to be a more common value...
10265
                                if ( val === undefined ) {
10266
                                        val = "";
10267
                                }
10268
                                element.css( set[ i ], val );
10269
                        }
10270
                }
10271
        },
10272

    
10273
        setMode: function( el, mode ) {
10274
                if (mode === "toggle") {
10275
                        mode = el.is( ":hidden" ) ? "show" : "hide";
10276
                }
10277
                return mode;
10278
        },
10279

    
10280
        // Translates a [top,left] array into a baseline value
10281
        // this should be a little more flexible in the future to handle a string & hash
10282
        getBaseline: function( origin, original ) {
10283
                var y, x;
10284
                switch ( origin[ 0 ] ) {
10285
                        case "top": y = 0; break;
10286
                        case "middle": y = 0.5; break;
10287
                        case "bottom": y = 1; break;
10288
                        default: y = origin[ 0 ] / original.height;
10289
                }
10290
                switch ( origin[ 1 ] ) {
10291
                        case "left": x = 0; break;
10292
                        case "center": x = 0.5; break;
10293
                        case "right": x = 1; break;
10294
                        default: x = origin[ 1 ] / original.width;
10295
                }
10296
                return {
10297
                        x: x,
10298
                        y: y
10299
                };
10300
        },
10301

    
10302
        // Wraps the element around a wrapper that copies position properties
10303
        createWrapper: function( element ) {
10304

    
10305
                // if the element is already wrapped, return it
10306
                if ( element.parent().is( ".ui-effects-wrapper" )) {
10307
                        return element.parent();
10308
                }
10309

    
10310
                // wrap the element
10311
                var props = {
10312
                                width: element.outerWidth(true),
10313
                                height: element.outerHeight(true),
10314
                                "float": element.css( "float" )
10315
                        },
10316
                        wrapper = $( "<div></div>" )
10317
                                .addClass( "ui-effects-wrapper" )
10318
                                .css({
10319
                                        fontSize: "100%",
10320
                                        background: "transparent",
10321
                                        border: "none",
10322
                                        margin: 0,
10323
                                        padding: 0
10324
                                }),
10325
                        // Store the size in case width/height are defined in % - Fixes #5245
10326
                        size = {
10327
                                width: element.width(),
10328
                                height: element.height()
10329
                        },
10330
                        active = document.activeElement;
10331

    
10332
                // support: Firefox
10333
                // Firefox incorrectly exposes anonymous content
10334
                // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
10335
                try {
10336
                        active.id;
10337
                } catch ( e ) {
10338
                        active = document.body;
10339
                }
10340

    
10341
                element.wrap( wrapper );
10342

    
10343
                // Fixes #7595 - Elements lose focus when wrapped.
10344
                if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10345
                        $( active ).focus();
10346
                }
10347

    
10348
                wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
10349

    
10350
                // transfer positioning properties to the wrapper
10351
                if ( element.css( "position" ) === "static" ) {
10352
                        wrapper.css({ position: "relative" });
10353
                        element.css({ position: "relative" });
10354
                } else {
10355
                        $.extend( props, {
10356
                                position: element.css( "position" ),
10357
                                zIndex: element.css( "z-index" )
10358
                        });
10359
                        $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
10360
                                props[ pos ] = element.css( pos );
10361
                                if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
10362
                                        props[ pos ] = "auto";
10363
                                }
10364
                        });
10365
                        element.css({
10366
                                position: "relative",
10367
                                top: 0,
10368
                                left: 0,
10369
                                right: "auto",
10370
                                bottom: "auto"
10371
                        });
10372
                }
10373
                element.css(size);
10374

    
10375
                return wrapper.css( props ).show();
10376
        },
10377

    
10378
        removeWrapper: function( element ) {
10379
                var active = document.activeElement;
10380

    
10381
                if ( element.parent().is( ".ui-effects-wrapper" ) ) {
10382
                        element.parent().replaceWith( element );
10383

    
10384
                        // Fixes #7595 - Elements lose focus when wrapped.
10385
                        if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10386
                                $( active ).focus();
10387
                        }
10388
                }
10389

    
10390
                return element;
10391
        },
10392

    
10393
        setTransition: function( element, list, factor, value ) {
10394
                value = value || {};
10395
                $.each( list, function( i, x ) {
10396
                        var unit = element.cssUnit( x );
10397
                        if ( unit[ 0 ] > 0 ) {
10398
                                value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
10399
                        }
10400
                });
10401
                return value;
10402
        }
10403
});
10404

    
10405
// return an effect options object for the given parameters:
10406
function _normalizeArguments( effect, options, speed, callback ) {
10407

    
10408
        // allow passing all options as the first parameter
10409
        if ( $.isPlainObject( effect ) ) {
10410
                options = effect;
10411
                effect = effect.effect;
10412
        }
10413

    
10414
        // convert to an object
10415
        effect = { effect: effect };
10416

    
10417
        // catch (effect, null, ...)
10418
        if ( options == null ) {
10419
                options = {};
10420
        }
10421

    
10422
        // catch (effect, callback)
10423
        if ( $.isFunction( options ) ) {
10424
                callback = options;
10425
                speed = null;
10426
                options = {};
10427
        }
10428

    
10429
        // catch (effect, speed, ?)
10430
        if ( typeof options === "number" || $.fx.speeds[ options ] ) {
10431
                callback = speed;
10432
                speed = options;
10433
                options = {};
10434
        }
10435

    
10436
        // catch (effect, options, callback)
10437
        if ( $.isFunction( speed ) ) {
10438
                callback = speed;
10439
                speed = null;
10440
        }
10441

    
10442
        // add options to effect
10443
        if ( options ) {
10444
                $.extend( effect, options );
10445
        }
10446

    
10447
        speed = speed || options.duration;
10448
        effect.duration = $.fx.off ? 0 :
10449
                typeof speed === "number" ? speed :
10450
                speed in $.fx.speeds ? $.fx.speeds[ speed ] :
10451
                $.fx.speeds._default;
10452

    
10453
        effect.complete = callback || options.complete;
10454

    
10455
        return effect;
10456
}
10457

    
10458
function standardAnimationOption( option ) {
10459
        // Valid standard speeds (nothing, number, named speed)
10460
        if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
10461
                return true;
10462
        }
10463

    
10464
        // Invalid strings - treat as "normal" speed
10465
        if ( typeof option === "string" && !$.effects.effect[ option ] ) {
10466
                return true;
10467
        }
10468

    
10469
        // Complete callback
10470
        if ( $.isFunction( option ) ) {
10471
                return true;
10472
        }
10473

    
10474
        // Options hash (but not naming an effect)
10475
        if ( typeof option === "object" && !option.effect ) {
10476
                return true;
10477
        }
10478

    
10479
        // Didn't match any standard API
10480
        return false;
10481
}
10482

    
10483
$.fn.extend({
10484
        effect: function( /* effect, options, speed, callback */ ) {
10485
                var args = _normalizeArguments.apply( this, arguments ),
10486
                        mode = args.mode,
10487
                        queue = args.queue,
10488
                        effectMethod = $.effects.effect[ args.effect ];
10489

    
10490
                if ( $.fx.off || !effectMethod ) {
10491
                        // delegate to the original method (e.g., .show()) if possible
10492
                        if ( mode ) {
10493
                                return this[ mode ]( args.duration, args.complete );
10494
                        } else {
10495
                                return this.each( function() {
10496
                                        if ( args.complete ) {
10497
                                                args.complete.call( this );
10498
                                        }
10499
                                });
10500
                        }
10501
                }
10502

    
10503
                function run( next ) {
10504
                        var elem = $( this ),
10505
                                complete = args.complete,
10506
                                mode = args.mode;
10507

    
10508
                        function done() {
10509
                                if ( $.isFunction( complete ) ) {
10510
                                        complete.call( elem[0] );
10511
                                }
10512
                                if ( $.isFunction( next ) ) {
10513
                                        next();
10514
                                }
10515
                        }
10516

    
10517
                        // If the element already has the correct final state, delegate to
10518
                        // the core methods so the internal tracking of "olddisplay" works.
10519
                        if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
10520
                                elem[ mode ]();
10521
                                done();
10522
                        } else {
10523
                                effectMethod.call( elem[0], args, done );
10524
                        }
10525
                }
10526

    
10527
                return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
10528
        },
10529

    
10530
        show: (function( orig ) {
10531
                return function( option ) {
10532
                        if ( standardAnimationOption( option ) ) {
10533
                                return orig.apply( this, arguments );
10534
                        } else {
10535
                                var args = _normalizeArguments.apply( this, arguments );
10536
                                args.mode = "show";
10537
                                return this.effect.call( this, args );
10538
                        }
10539
                };
10540
        })( $.fn.show ),
10541

    
10542
        hide: (function( orig ) {
10543
                return function( option ) {
10544
                        if ( standardAnimationOption( option ) ) {
10545
                                return orig.apply( this, arguments );
10546
                        } else {
10547
                                var args = _normalizeArguments.apply( this, arguments );
10548
                                args.mode = "hide";
10549
                                return this.effect.call( this, args );
10550
                        }
10551
                };
10552
        })( $.fn.hide ),
10553

    
10554
        toggle: (function( orig ) {
10555
                return function( option ) {
10556
                        if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
10557
                                return orig.apply( this, arguments );
10558
                        } else {
10559
                                var args = _normalizeArguments.apply( this, arguments );
10560
                                args.mode = "toggle";
10561
                                return this.effect.call( this, args );
10562
                        }
10563
                };
10564
        })( $.fn.toggle ),
10565

    
10566
        // helper functions
10567
        cssUnit: function(key) {
10568
                var style = this.css( key ),
10569
                        val = [];
10570

    
10571
                $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
10572
                        if ( style.indexOf( unit ) > 0 ) {
10573
                                val = [ parseFloat( style ), unit ];
10574
                        }
10575
                });
10576
                return val;
10577
        }
10578
});
10579

    
10580
})();
10581

    
10582
/******************************************************************************/
10583
/*********************************** EASING ***********************************/
10584
/******************************************************************************/
10585

    
10586
(function() {
10587

    
10588
// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
10589

    
10590
var baseEasings = {};
10591

    
10592
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
10593
        baseEasings[ name ] = function( p ) {
10594
                return Math.pow( p, i + 2 );
10595
        };
10596
});
10597

    
10598
$.extend( baseEasings, {
10599
        Sine: function( p ) {
10600
                return 1 - Math.cos( p * Math.PI / 2 );
10601
        },
10602
        Circ: function( p ) {
10603
                return 1 - Math.sqrt( 1 - p * p );
10604
        },
10605
        Elastic: function( p ) {
10606
                return p === 0 || p === 1 ? p :
10607
                        -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
10608
        },
10609
        Back: function( p ) {
10610
                return p * p * ( 3 * p - 2 );
10611
        },
10612
        Bounce: function( p ) {
10613
                var pow2,
10614
                        bounce = 4;
10615

    
10616
                while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
10617
                return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
10618
        }
10619
});
10620

    
10621
$.each( baseEasings, function( name, easeIn ) {
10622
        $.easing[ "easeIn" + name ] = easeIn;
10623
        $.easing[ "easeOut" + name ] = function( p ) {
10624
                return 1 - easeIn( 1 - p );
10625
        };
10626
        $.easing[ "easeInOut" + name ] = function( p ) {
10627
                return p < 0.5 ?
10628
                        easeIn( p * 2 ) / 2 :
10629
                        1 - easeIn( p * -2 + 2 ) / 2;
10630
        };
10631
});
10632

    
10633
})();
10634

    
10635
var effect = $.effects;
10636

    
10637

    
10638
/*!
10639
 * jQuery UI Effects Blind 1.11.4
10640
 * http://jqueryui.com
10641
 *
10642
 * Copyright jQuery Foundation and other contributors
10643
 * Released under the MIT license.
10644
 * http://jquery.org/license
10645
 *
10646
 * http://api.jqueryui.com/blind-effect/
10647
 */
10648

    
10649

    
10650
var effectBlind = $.effects.effect.blind = function( o, done ) {
10651
        // Create element
10652
        var el = $( this ),
10653
                rvertical = /up|down|vertical/,
10654
                rpositivemotion = /up|left|vertical|horizontal/,
10655
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10656
                mode = $.effects.setMode( el, o.mode || "hide" ),
10657
                direction = o.direction || "up",
10658
                vertical = rvertical.test( direction ),
10659
                ref = vertical ? "height" : "width",
10660
                ref2 = vertical ? "top" : "left",
10661
                motion = rpositivemotion.test( direction ),
10662
                animation = {},
10663
                show = mode === "show",
10664
                wrapper, distance, margin;
10665

    
10666
        // if already wrapped, the wrapper's properties are my property. #6245
10667
        if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10668
                $.effects.save( el.parent(), props );
10669
        } else {
10670
                $.effects.save( el, props );
10671
        }
10672
        el.show();
10673
        wrapper = $.effects.createWrapper( el ).css({
10674
                overflow: "hidden"
10675
        });
10676

    
10677
        distance = wrapper[ ref ]();
10678
        margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10679

    
10680
        animation[ ref ] = show ? distance : 0;
10681
        if ( !motion ) {
10682
                el
10683
                        .css( vertical ? "bottom" : "right", 0 )
10684
                        .css( vertical ? "top" : "left", "auto" )
10685
                        .css({ position: "absolute" });
10686

    
10687
                animation[ ref2 ] = show ? margin : distance + margin;
10688
        }
10689

    
10690
        // start at 0 if we are showing
10691
        if ( show ) {
10692
                wrapper.css( ref, 0 );
10693
                if ( !motion ) {
10694
                        wrapper.css( ref2, margin + distance );
10695
                }
10696
        }
10697

    
10698
        // Animate
10699
        wrapper.animate( animation, {
10700
                duration: o.duration,
10701
                easing: o.easing,
10702
                queue: false,
10703
                complete: function() {
10704
                        if ( mode === "hide" ) {
10705
                                el.hide();
10706
                        }
10707
                        $.effects.restore( el, props );
10708
                        $.effects.removeWrapper( el );
10709
                        done();
10710
                }
10711
        });
10712
};
10713

    
10714

    
10715
/*!
10716
 * jQuery UI Effects Bounce 1.11.4
10717
 * http://jqueryui.com
10718
 *
10719
 * Copyright jQuery Foundation and other contributors
10720
 * Released under the MIT license.
10721
 * http://jquery.org/license
10722
 *
10723
 * http://api.jqueryui.com/bounce-effect/
10724
 */
10725

    
10726

    
10727
var effectBounce = $.effects.effect.bounce = function( o, done ) {
10728
        var el = $( this ),
10729
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10730

    
10731
                // defaults:
10732
                mode = $.effects.setMode( el, o.mode || "effect" ),
10733
                hide = mode === "hide",
10734
                show = mode === "show",
10735
                direction = o.direction || "up",
10736
                distance = o.distance,
10737
                times = o.times || 5,
10738

    
10739
                // number of internal animations
10740
                anims = times * 2 + ( show || hide ? 1 : 0 ),
10741
                speed = o.duration / anims,
10742
                easing = o.easing,
10743

    
10744
                // utility:
10745
                ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10746
                motion = ( direction === "up" || direction === "left" ),
10747
                i,
10748
                upAnim,
10749
                downAnim,
10750

    
10751
                // we will need to re-assemble the queue to stack our animations in place
10752
                queue = el.queue(),
10753
                queuelen = queue.length;
10754

    
10755
        // Avoid touching opacity to prevent clearType and PNG issues in IE
10756
        if ( show || hide ) {
10757
                props.push( "opacity" );
10758
        }
10759

    
10760
        $.effects.save( el, props );
10761
        el.show();
10762
        $.effects.createWrapper( el ); // Create Wrapper
10763

    
10764
        // default distance for the BIGGEST bounce is the outer Distance / 3
10765
        if ( !distance ) {
10766
                distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10767
        }
10768

    
10769
        if ( show ) {
10770
                downAnim = { opacity: 1 };
10771
                downAnim[ ref ] = 0;
10772

    
10773
                // if we are showing, force opacity 0 and set the initial position
10774
                // then do the "first" animation
10775
                el.css( "opacity", 0 )
10776
                        .css( ref, motion ? -distance * 2 : distance * 2 )
10777
                        .animate( downAnim, speed, easing );
10778
        }
10779

    
10780
        // start at the smallest distance if we are hiding
10781
        if ( hide ) {
10782
                distance = distance / Math.pow( 2, times - 1 );
10783
        }
10784

    
10785
        downAnim = {};
10786
        downAnim[ ref ] = 0;
10787
        // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10788
        for ( i = 0; i < times; i++ ) {
10789
                upAnim = {};
10790
                upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10791

    
10792
                el.animate( upAnim, speed, easing )
10793
                        .animate( downAnim, speed, easing );
10794

    
10795
                distance = hide ? distance * 2 : distance / 2;
10796
        }
10797

    
10798
        // Last Bounce when Hiding
10799
        if ( hide ) {
10800
                upAnim = { opacity: 0 };
10801
                upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10802

    
10803
                el.animate( upAnim, speed, easing );
10804
        }
10805

    
10806
        el.queue(function() {
10807
                if ( hide ) {
10808
                        el.hide();
10809
                }
10810
                $.effects.restore( el, props );
10811
                $.effects.removeWrapper( el );
10812
                done();
10813
        });
10814

    
10815
        // inject all the animations we just queued to be first in line (after "inprogress")
10816
        if ( queuelen > 1) {
10817
                queue.splice.apply( queue,
10818
                        [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10819
        }
10820
        el.dequeue();
10821

    
10822
};
10823

    
10824

    
10825
/*!
10826
 * jQuery UI Effects Clip 1.11.4
10827
 * http://jqueryui.com
10828
 *
10829
 * Copyright jQuery Foundation and other contributors
10830
 * Released under the MIT license.
10831
 * http://jquery.org/license
10832
 *
10833
 * http://api.jqueryui.com/clip-effect/
10834
 */
10835

    
10836

    
10837
var effectClip = $.effects.effect.clip = function( o, done ) {
10838
        // Create element
10839
        var el = $( this ),
10840
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10841
                mode = $.effects.setMode( el, o.mode || "hide" ),
10842
                show = mode === "show",
10843
                direction = o.direction || "vertical",
10844
                vert = direction === "vertical",
10845
                size = vert ? "height" : "width",
10846
                position = vert ? "top" : "left",
10847
                animation = {},
10848
                wrapper, animate, distance;
10849

    
10850
        // Save & Show
10851
        $.effects.save( el, props );
10852
        el.show();
10853

    
10854
        // Create Wrapper
10855
        wrapper = $.effects.createWrapper( el ).css({
10856
                overflow: "hidden"
10857
        });
10858
        animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10859
        distance = animate[ size ]();
10860

    
10861
        // Shift
10862
        if ( show ) {
10863
                animate.css( size, 0 );
10864
                animate.css( position, distance / 2 );
10865
        }
10866

    
10867
        // Create Animation Object:
10868
        animation[ size ] = show ? distance : 0;
10869
        animation[ position ] = show ? 0 : distance / 2;
10870

    
10871
        // Animate
10872
        animate.animate( animation, {
10873
                queue: false,
10874
                duration: o.duration,
10875
                easing: o.easing,
10876
                complete: function() {
10877
                        if ( !show ) {
10878
                                el.hide();
10879
                        }
10880
                        $.effects.restore( el, props );
10881
                        $.effects.removeWrapper( el );
10882
                        done();
10883
                }
10884
        });
10885

    
10886
};
10887

    
10888

    
10889
/*!
10890
 * jQuery UI Effects Drop 1.11.4
10891
 * http://jqueryui.com
10892
 *
10893
 * Copyright jQuery Foundation and other contributors
10894
 * Released under the MIT license.
10895
 * http://jquery.org/license
10896
 *
10897
 * http://api.jqueryui.com/drop-effect/
10898
 */
10899

    
10900

    
10901
var effectDrop = $.effects.effect.drop = function( o, done ) {
10902

    
10903
        var el = $( this ),
10904
                props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10905
                mode = $.effects.setMode( el, o.mode || "hide" ),
10906
                show = mode === "show",
10907
                direction = o.direction || "left",
10908
                ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10909
                motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10910
                animation = {
10911
                        opacity: show ? 1 : 0
10912
                },
10913
                distance;
10914

    
10915
        // Adjust
10916
        $.effects.save( el, props );
10917
        el.show();
10918
        $.effects.createWrapper( el );
10919

    
10920
        distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
10921

    
10922
        if ( show ) {
10923
                el
10924
                        .css( "opacity", 0 )
10925
                        .css( ref, motion === "pos" ? -distance : distance );
10926
        }
10927

    
10928
        // Animation
10929
        animation[ ref ] = ( show ?
10930
                ( motion === "pos" ? "+=" : "-=" ) :
10931
                ( motion === "pos" ? "-=" : "+=" ) ) +
10932
                distance;
10933

    
10934
        // Animate
10935
        el.animate( animation, {
10936
                queue: false,
10937
                duration: o.duration,
10938
                easing: o.easing,
10939
                complete: function() {
10940
                        if ( mode === "hide" ) {
10941
                                el.hide();
10942
                        }
10943
                        $.effects.restore( el, props );
10944
                        $.effects.removeWrapper( el );
10945
                        done();
10946
                }
10947
        });
10948
};
10949

    
10950

    
10951
/*!
10952
 * jQuery UI Effects Explode 1.11.4
10953
 * http://jqueryui.com
10954
 *
10955
 * Copyright jQuery Foundation and other contributors
10956
 * Released under the MIT license.
10957
 * http://jquery.org/license
10958
 *
10959
 * http://api.jqueryui.com/explode-effect/
10960
 */
10961

    
10962

    
10963
var effectExplode = $.effects.effect.explode = function( o, done ) {
10964

    
10965
        var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10966
                cells = rows,
10967
                el = $( this ),
10968
                mode = $.effects.setMode( el, o.mode || "hide" ),
10969
                show = mode === "show",
10970

    
10971
                // show and then visibility:hidden the element before calculating offset
10972
                offset = el.show().css( "visibility", "hidden" ).offset(),
10973

    
10974
                // width and height of a piece
10975
                width = Math.ceil( el.outerWidth() / cells ),
10976
                height = Math.ceil( el.outerHeight() / rows ),
10977
                pieces = [],
10978

    
10979
                // loop
10980
                i, j, left, top, mx, my;
10981

    
10982
        // children animate complete:
10983
        function childComplete() {
10984
                pieces.push( this );
10985
                if ( pieces.length === rows * cells ) {
10986
                        animComplete();
10987
                }
10988
        }
10989

    
10990
        // clone the element for each row and cell.
10991
        for ( i = 0; i < rows ; i++ ) { // ===>
10992
                top = offset.top + i * height;
10993
                my = i - ( rows - 1 ) / 2 ;
10994

    
10995
                for ( j = 0; j < cells ; j++ ) { // |||
10996
                        left = offset.left + j * width;
10997
                        mx = j - ( cells - 1 ) / 2 ;
10998

    
10999
                        // Create a clone of the now hidden main element that will be absolute positioned
11000
                        // within a wrapper div off the -left and -top equal to size of our pieces
11001
                        el
11002
                                .clone()
11003
                                .appendTo( "body" )
11004
                                .wrap( "<div></div>" )
11005
                                .css({
11006
                                        position: "absolute",
11007
                                        visibility: "visible",
11008
                                        left: -j * width,
11009
                                        top: -i * height
11010
                                })
11011

    
11012
                        // select the wrapper - make it overflow: hidden and absolute positioned based on
11013
                        // where the original was located +left and +top equal to the size of pieces
11014
                                .parent()
11015
                                .addClass( "ui-effects-explode" )
11016
                                .css({
11017
                                        position: "absolute",
11018
                                        overflow: "hidden",
11019
                                        width: width,
11020
                                        height: height,
11021
                                        left: left + ( show ? mx * width : 0 ),
11022
                                        top: top + ( show ? my * height : 0 ),
11023
                                        opacity: show ? 0 : 1
11024
                                }).animate({
11025
                                        left: left + ( show ? 0 : mx * width ),
11026
                                        top: top + ( show ? 0 : my * height ),
11027
                                        opacity: show ? 1 : 0
11028
                                }, o.duration || 500, o.easing, childComplete );
11029
                }
11030
        }
11031

    
11032
        function animComplete() {
11033
                el.css({
11034
                        visibility: "visible"
11035
                });
11036
                $( pieces ).remove();
11037
                if ( !show ) {
11038
                        el.hide();
11039
                }
11040
                done();
11041
        }
11042
};
11043

    
11044

    
11045
/*!
11046
 * jQuery UI Effects Fade 1.11.4
11047
 * http://jqueryui.com
11048
 *
11049
 * Copyright jQuery Foundation and other contributors
11050
 * Released under the MIT license.
11051
 * http://jquery.org/license
11052
 *
11053
 * http://api.jqueryui.com/fade-effect/
11054
 */
11055

    
11056

    
11057
var effectFade = $.effects.effect.fade = function( o, done ) {
11058
        var el = $( this ),
11059
                mode = $.effects.setMode( el, o.mode || "toggle" );
11060

    
11061
        el.animate({
11062
                opacity: mode
11063
        }, {
11064
                queue: false,
11065
                duration: o.duration,
11066
                easing: o.easing,
11067
                complete: done
11068
        });
11069
};
11070

    
11071

    
11072
/*!
11073
 * jQuery UI Effects Fold 1.11.4
11074
 * http://jqueryui.com
11075
 *
11076
 * Copyright jQuery Foundation and other contributors
11077
 * Released under the MIT license.
11078
 * http://jquery.org/license
11079
 *
11080
 * http://api.jqueryui.com/fold-effect/
11081
 */
11082

    
11083

    
11084
var effectFold = $.effects.effect.fold = function( o, done ) {
11085

    
11086
        // Create element
11087
        var el = $( this ),
11088
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11089
                mode = $.effects.setMode( el, o.mode || "hide" ),
11090
                show = mode === "show",
11091
                hide = mode === "hide",
11092
                size = o.size || 15,
11093
                percent = /([0-9]+)%/.exec( size ),
11094
                horizFirst = !!o.horizFirst,
11095
                widthFirst = show !== horizFirst,
11096
                ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
11097
                duration = o.duration / 2,
11098
                wrapper, distance,
11099
                animation1 = {},
11100
                animation2 = {};
11101

    
11102
        $.effects.save( el, props );
11103
        el.show();
11104

    
11105
        // Create Wrapper
11106
        wrapper = $.effects.createWrapper( el ).css({
11107
                overflow: "hidden"
11108
        });
11109
        distance = widthFirst ?
11110
                [ wrapper.width(), wrapper.height() ] :
11111
                [ wrapper.height(), wrapper.width() ];
11112

    
11113
        if ( percent ) {
11114
                size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
11115
        }
11116
        if ( show ) {
11117
                wrapper.css( horizFirst ? {
11118
                        height: 0,
11119
                        width: size
11120
                } : {
11121
                        height: size,
11122
                        width: 0
11123
                });
11124
        }
11125

    
11126
        // Animation
11127
        animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
11128
        animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
11129

    
11130
        // Animate
11131
        wrapper
11132
                .animate( animation1, duration, o.easing )
11133
                .animate( animation2, duration, o.easing, function() {
11134
                        if ( hide ) {
11135
                                el.hide();
11136
                        }
11137
                        $.effects.restore( el, props );
11138
                        $.effects.removeWrapper( el );
11139
                        done();
11140
                });
11141

    
11142
};
11143

    
11144

    
11145
/*!
11146
 * jQuery UI Effects Highlight 1.11.4
11147
 * http://jqueryui.com
11148
 *
11149
 * Copyright jQuery Foundation and other contributors
11150
 * Released under the MIT license.
11151
 * http://jquery.org/license
11152
 *
11153
 * http://api.jqueryui.com/highlight-effect/
11154
 */
11155

    
11156

    
11157
var effectHighlight = $.effects.effect.highlight = function( o, done ) {
11158
        var elem = $( this ),
11159
                props = [ "backgroundImage", "backgroundColor", "opacity" ],
11160
                mode = $.effects.setMode( elem, o.mode || "show" ),
11161
                animation = {
11162
                        backgroundColor: elem.css( "backgroundColor" )
11163
                };
11164

    
11165
        if (mode === "hide") {
11166
                animation.opacity = 0;
11167
        }
11168

    
11169
        $.effects.save( elem, props );
11170

    
11171
        elem
11172
                .show()
11173
                .css({
11174
                        backgroundImage: "none",
11175
                        backgroundColor: o.color || "#ffff99"
11176
                })
11177
                .animate( animation, {
11178
                        queue: false,
11179
                        duration: o.duration,
11180
                        easing: o.easing,
11181
                        complete: function() {
11182
                                if ( mode === "hide" ) {
11183
                                        elem.hide();
11184
                                }
11185
                                $.effects.restore( elem, props );
11186
                                done();
11187
                        }
11188
                });
11189
};
11190

    
11191

    
11192
/*!
11193
 * jQuery UI Effects Size 1.11.4
11194
 * http://jqueryui.com
11195
 *
11196
 * Copyright jQuery Foundation and other contributors
11197
 * Released under the MIT license.
11198
 * http://jquery.org/license
11199
 *
11200
 * http://api.jqueryui.com/size-effect/
11201
 */
11202

    
11203

    
11204
var effectSize = $.effects.effect.size = function( o, done ) {
11205

    
11206
        // Create element
11207
        var original, baseline, factor,
11208
                el = $( this ),
11209
                props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11210

    
11211
                // Always restore
11212
                props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11213

    
11214
                // Copy for children
11215
                props2 = [ "width", "height", "overflow" ],
11216
                cProps = [ "fontSize" ],
11217
                vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11218
                hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11219

    
11220
                // Set options
11221
                mode = $.effects.setMode( el, o.mode || "effect" ),
11222
                restore = o.restore || mode !== "effect",
11223
                scale = o.scale || "both",
11224
                origin = o.origin || [ "middle", "center" ],
11225
                position = el.css( "position" ),
11226
                props = restore ? props0 : props1,
11227
                zero = {
11228
                        height: 0,
11229
                        width: 0,
11230
                        outerHeight: 0,
11231
                        outerWidth: 0
11232
                };
11233

    
11234
        if ( mode === "show" ) {
11235
                el.show();
11236
        }
11237
        original = {
11238
                height: el.height(),
11239
                width: el.width(),
11240
                outerHeight: el.outerHeight(),
11241
                outerWidth: el.outerWidth()
11242
        };
11243

    
11244
        if ( o.mode === "toggle" && mode === "show" ) {
11245
                el.from = o.to || zero;
11246
                el.to = o.from || original;
11247
        } else {
11248
                el.from = o.from || ( mode === "show" ? zero : original );
11249
                el.to = o.to || ( mode === "hide" ? zero : original );
11250
        }
11251

    
11252
        // Set scaling factor
11253
        factor = {
11254
                from: {
11255
                        y: el.from.height / original.height,
11256
                        x: el.from.width / original.width
11257
                },
11258
                to: {
11259
                        y: el.to.height / original.height,
11260
                        x: el.to.width / original.width
11261
                }
11262
        };
11263

    
11264
        // Scale the css box
11265
        if ( scale === "box" || scale === "both" ) {
11266

    
11267
                // Vertical props scaling
11268
                if ( factor.from.y !== factor.to.y ) {
11269
                        props = props.concat( vProps );
11270
                        el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11271
                        el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11272
                }
11273

    
11274
                // Horizontal props scaling
11275
                if ( factor.from.x !== factor.to.x ) {
11276
                        props = props.concat( hProps );
11277
                        el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11278
                        el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11279
                }
11280
        }
11281

    
11282
        // Scale the content
11283
        if ( scale === "content" || scale === "both" ) {
11284

    
11285
                // Vertical props scaling
11286
                if ( factor.from.y !== factor.to.y ) {
11287
                        props = props.concat( cProps ).concat( props2 );
11288
                        el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11289
                        el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11290
                }
11291
        }
11292

    
11293
        $.effects.save( el, props );
11294
        el.show();
11295
        $.effects.createWrapper( el );
11296
        el.css( "overflow", "hidden" ).css( el.from );
11297

    
11298
        // Adjust
11299
        if (origin) { // Calculate baseline shifts
11300
                baseline = $.effects.getBaseline( origin, original );
11301
                el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11302
                el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11303
                el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11304
                el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11305
        }
11306
        el.css( el.from ); // set top & left
11307

    
11308
        // Animate
11309
        if ( scale === "content" || scale === "both" ) { // Scale the children
11310

    
11311
                // Add margins/font-size
11312
                vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11313
                hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11314
                props2 = props0.concat(vProps).concat(hProps);
11315

    
11316
                el.find( "*[width]" ).each( function() {
11317
                        var child = $( this ),
11318
                                c_original = {
11319
                                        height: child.height(),
11320
                                        width: child.width(),
11321
                                        outerHeight: child.outerHeight(),
11322
                                        outerWidth: child.outerWidth()
11323
                                };
11324
                        if (restore) {
11325
                                $.effects.save(child, props2);
11326
                        }
11327

    
11328
                        child.from = {
11329
                                height: c_original.height * factor.from.y,
11330
                                width: c_original.width * factor.from.x,
11331
                                outerHeight: c_original.outerHeight * factor.from.y,
11332
                                outerWidth: c_original.outerWidth * factor.from.x
11333
                        };
11334
                        child.to = {
11335
                                height: c_original.height * factor.to.y,
11336
                                width: c_original.width * factor.to.x,
11337
                                outerHeight: c_original.height * factor.to.y,
11338
                                outerWidth: c_original.width * factor.to.x
11339
                        };
11340

    
11341
                        // Vertical props scaling
11342
                        if ( factor.from.y !== factor.to.y ) {
11343
                                child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11344
                                child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11345
                        }
11346

    
11347
                        // Horizontal props scaling
11348
                        if ( factor.from.x !== factor.to.x ) {
11349
                                child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11350
                                child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11351
                        }
11352

    
11353
                        // Animate children
11354
                        child.css( child.from );
11355
                        child.animate( child.to, o.duration, o.easing, function() {
11356

    
11357
                                // Restore children
11358
                                if ( restore ) {
11359
                                        $.effects.restore( child, props2 );
11360
                                }
11361
                        });
11362
                });
11363
        }
11364

    
11365
        // Animate
11366
        el.animate( el.to, {
11367
                queue: false,
11368
                duration: o.duration,
11369
                easing: o.easing,
11370
                complete: function() {
11371
                        if ( el.to.opacity === 0 ) {
11372
                                el.css( "opacity", el.from.opacity );
11373
                        }
11374
                        if ( mode === "hide" ) {
11375
                                el.hide();
11376
                        }
11377
                        $.effects.restore( el, props );
11378
                        if ( !restore ) {
11379

    
11380
                                // we need to calculate our new positioning based on the scaling
11381
                                if ( position === "static" ) {
11382
                                        el.css({
11383
                                                position: "relative",
11384
                                                top: el.to.top,
11385
                                                left: el.to.left
11386
                                        });
11387
                                } else {
11388
                                        $.each([ "top", "left" ], function( idx, pos ) {
11389
                                                el.css( pos, function( _, str ) {
11390
                                                        var val = parseInt( str, 10 ),
11391
                                                                toRef = idx ? el.to.left : el.to.top;
11392

    
11393
                                                        // if original was "auto", recalculate the new value from wrapper
11394
                                                        if ( str === "auto" ) {
11395
                                                                return toRef + "px";
11396
                                                        }
11397

    
11398
                                                        return val + toRef + "px";
11399
                                                });
11400
                                        });
11401
                                }
11402
                        }
11403

    
11404
                        $.effects.removeWrapper( el );
11405
                        done();
11406
                }
11407
        });
11408

    
11409
};
11410

    
11411

    
11412
/*!
11413
 * jQuery UI Effects Scale 1.11.4
11414
 * http://jqueryui.com
11415
 *
11416
 * Copyright jQuery Foundation and other contributors
11417
 * Released under the MIT license.
11418
 * http://jquery.org/license
11419
 *
11420
 * http://api.jqueryui.com/scale-effect/
11421
 */
11422

    
11423

    
11424
var effectScale = $.effects.effect.scale = function( o, done ) {
11425

    
11426
        // Create element
11427
        var el = $( this ),
11428
                options = $.extend( true, {}, o ),
11429
                mode = $.effects.setMode( el, o.mode || "effect" ),
11430
                percent = parseInt( o.percent, 10 ) ||
11431
                        ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
11432
                direction = o.direction || "both",
11433
                origin = o.origin,
11434
                original = {
11435
                        height: el.height(),
11436
                        width: el.width(),
11437
                        outerHeight: el.outerHeight(),
11438
                        outerWidth: el.outerWidth()
11439
                },
11440
                factor = {
11441
                        y: direction !== "horizontal" ? (percent / 100) : 1,
11442
                        x: direction !== "vertical" ? (percent / 100) : 1
11443
                };
11444

    
11445
        // We are going to pass this effect to the size effect:
11446
        options.effect = "size";
11447
        options.queue = false;
11448
        options.complete = done;
11449

    
11450
        // Set default origin and restore for show/hide
11451
        if ( mode !== "effect" ) {
11452
                options.origin = origin || [ "middle", "center" ];
11453
                options.restore = true;
11454
        }
11455

    
11456
        options.from = o.from || ( mode === "show" ? {
11457
                height: 0,
11458
                width: 0,
11459
                outerHeight: 0,
11460
                outerWidth: 0
11461
        } : original );
11462
        options.to = {
11463
                height: original.height * factor.y,
11464
                width: original.width * factor.x,
11465
                outerHeight: original.outerHeight * factor.y,
11466
                outerWidth: original.outerWidth * factor.x
11467
        };
11468

    
11469
        // Fade option to support puff
11470
        if ( options.fade ) {
11471
                if ( mode === "show" ) {
11472
                        options.from.opacity = 0;
11473
                        options.to.opacity = 1;
11474
                }
11475
                if ( mode === "hide" ) {
11476
                        options.from.opacity = 1;
11477
                        options.to.opacity = 0;
11478
                }
11479
        }
11480

    
11481
        // Animate
11482
        el.effect( options );
11483

    
11484
};
11485

    
11486

    
11487
/*!
11488
 * jQuery UI Effects Puff 1.11.4
11489
 * http://jqueryui.com
11490
 *
11491
 * Copyright jQuery Foundation and other contributors
11492
 * Released under the MIT license.
11493
 * http://jquery.org/license
11494
 *
11495
 * http://api.jqueryui.com/puff-effect/
11496
 */
11497

    
11498

    
11499
var effectPuff = $.effects.effect.puff = function( o, done ) {
11500
        var elem = $( this ),
11501
                mode = $.effects.setMode( elem, o.mode || "hide" ),
11502
                hide = mode === "hide",
11503
                percent = parseInt( o.percent, 10 ) || 150,
11504
                factor = percent / 100,
11505
                original = {
11506
                        height: elem.height(),
11507
                        width: elem.width(),
11508
                        outerHeight: elem.outerHeight(),
11509
                        outerWidth: elem.outerWidth()
11510
                };
11511

    
11512
        $.extend( o, {
11513
                effect: "scale",
11514
                queue: false,
11515
                fade: true,
11516
                mode: mode,
11517
                complete: done,
11518
                percent: hide ? percent : 100,
11519
                from: hide ?
11520
                        original :
11521
                        {
11522
                                height: original.height * factor,
11523
                                width: original.width * factor,
11524
                                outerHeight: original.outerHeight * factor,
11525
                                outerWidth: original.outerWidth * factor
11526
                        }
11527
        });
11528

    
11529
        elem.effect( o );
11530
};
11531

    
11532

    
11533
/*!
11534
 * jQuery UI Effects Pulsate 1.11.4
11535
 * http://jqueryui.com
11536
 *
11537
 * Copyright jQuery Foundation and other contributors
11538
 * Released under the MIT license.
11539
 * http://jquery.org/license
11540
 *
11541
 * http://api.jqueryui.com/pulsate-effect/
11542
 */
11543

    
11544

    
11545
var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
11546
        var elem = $( this ),
11547
                mode = $.effects.setMode( elem, o.mode || "show" ),
11548
                show = mode === "show",
11549
                hide = mode === "hide",
11550
                showhide = ( show || mode === "hide" ),
11551

    
11552
                // showing or hiding leaves of the "last" animation
11553
                anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
11554
                duration = o.duration / anims,
11555
                animateTo = 0,
11556
                queue = elem.queue(),
11557
                queuelen = queue.length,
11558
                i;
11559

    
11560
        if ( show || !elem.is(":visible")) {
11561
                elem.css( "opacity", 0 ).show();
11562
                animateTo = 1;
11563
        }
11564

    
11565
        // anims - 1 opacity "toggles"
11566
        for ( i = 1; i < anims; i++ ) {
11567
                elem.animate({
11568
                        opacity: animateTo
11569
                }, duration, o.easing );
11570
                animateTo = 1 - animateTo;
11571
        }
11572

    
11573
        elem.animate({
11574
                opacity: animateTo
11575
        }, duration, o.easing);
11576

    
11577
        elem.queue(function() {
11578
                if ( hide ) {
11579
                        elem.hide();
11580
                }
11581
                done();
11582
        });
11583

    
11584
        // We just queued up "anims" animations, we need to put them next in the queue
11585
        if ( queuelen > 1 ) {
11586
                queue.splice.apply( queue,
11587
                        [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11588
        }
11589
        elem.dequeue();
11590
};
11591

    
11592

    
11593
/*!
11594
 * jQuery UI Effects Shake 1.11.4
11595
 * http://jqueryui.com
11596
 *
11597
 * Copyright jQuery Foundation and other contributors
11598
 * Released under the MIT license.
11599
 * http://jquery.org/license
11600
 *
11601
 * http://api.jqueryui.com/shake-effect/
11602
 */
11603

    
11604

    
11605
var effectShake = $.effects.effect.shake = function( o, done ) {
11606

    
11607
        var el = $( this ),
11608
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11609
                mode = $.effects.setMode( el, o.mode || "effect" ),
11610
                direction = o.direction || "left",
11611
                distance = o.distance || 20,
11612
                times = o.times || 3,
11613
                anims = times * 2 + 1,
11614
                speed = Math.round( o.duration / anims ),
11615
                ref = (direction === "up" || direction === "down") ? "top" : "left",
11616
                positiveMotion = (direction === "up" || direction === "left"),
11617
                animation = {},
11618
                animation1 = {},
11619
                animation2 = {},
11620
                i,
11621

    
11622
                // we will need to re-assemble the queue to stack our animations in place
11623
                queue = el.queue(),
11624
                queuelen = queue.length;
11625

    
11626
        $.effects.save( el, props );
11627
        el.show();
11628
        $.effects.createWrapper( el );
11629

    
11630
        // Animation
11631
        animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11632
        animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11633
        animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11634

    
11635
        // Animate
11636
        el.animate( animation, speed, o.easing );
11637

    
11638
        // Shakes
11639
        for ( i = 1; i < times; i++ ) {
11640
                el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11641
        }
11642
        el
11643
                .animate( animation1, speed, o.easing )
11644
                .animate( animation, speed / 2, o.easing )
11645
                .queue(function() {
11646
                        if ( mode === "hide" ) {
11647
                                el.hide();
11648
                        }
11649
                        $.effects.restore( el, props );
11650
                        $.effects.removeWrapper( el );
11651
                        done();
11652
                });
11653

    
11654
        // inject all the animations we just queued to be first in line (after "inprogress")
11655
        if ( queuelen > 1) {
11656
                queue.splice.apply( queue,
11657
                        [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11658
        }
11659
        el.dequeue();
11660

    
11661
};
11662

    
11663

    
11664
/*!
11665
 * jQuery UI Effects Slide 1.11.4
11666
 * http://jqueryui.com
11667
 *
11668
 * Copyright jQuery Foundation and other contributors
11669
 * Released under the MIT license.
11670
 * http://jquery.org/license
11671
 *
11672
 * http://api.jqueryui.com/slide-effect/
11673
 */
11674

    
11675

    
11676
var effectSlide = $.effects.effect.slide = function( o, done ) {
11677

    
11678
        // Create element
11679
        var el = $( this ),
11680
                props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11681
                mode = $.effects.setMode( el, o.mode || "show" ),
11682
                show = mode === "show",
11683
                direction = o.direction || "left",
11684
                ref = (direction === "up" || direction === "down") ? "top" : "left",
11685
                positiveMotion = (direction === "up" || direction === "left"),
11686
                distance,
11687
                animation = {};
11688

    
11689
        // Adjust
11690
        $.effects.save( el, props );
11691
        el.show();
11692
        distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11693

    
11694
        $.effects.createWrapper( el ).css({
11695
                overflow: "hidden"
11696
        });
11697

    
11698
        if ( show ) {
11699
                el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11700
        }
11701

    
11702
        // Animation
11703
        animation[ ref ] = ( show ?
11704
                ( positiveMotion ? "+=" : "-=") :
11705
                ( positiveMotion ? "-=" : "+=")) +
11706
                distance;
11707

    
11708
        // Animate
11709
        el.animate( animation, {
11710
                queue: false,
11711
                duration: o.duration,
11712
                easing: o.easing,
11713
                complete: function() {
11714
                        if ( mode === "hide" ) {
11715
                                el.hide();
11716
                        }
11717
                        $.effects.restore( el, props );
11718
                        $.effects.removeWrapper( el );
11719
                        done();
11720
                }
11721
        });
11722
};
11723

    
11724

    
11725
/*!
11726
 * jQuery UI Effects Transfer 1.11.4
11727
 * http://jqueryui.com
11728
 *
11729
 * Copyright jQuery Foundation and other contributors
11730
 * Released under the MIT license.
11731
 * http://jquery.org/license
11732
 *
11733
 * http://api.jqueryui.com/transfer-effect/
11734
 */
11735

    
11736

    
11737
var effectTransfer = $.effects.effect.transfer = function( o, done ) {
11738
        var elem = $( this ),
11739
                target = $( o.to ),
11740
                targetFixed = target.css( "position" ) === "fixed",
11741
                body = $("body"),
11742
                fixTop = targetFixed ? body.scrollTop() : 0,
11743
                fixLeft = targetFixed ? body.scrollLeft() : 0,
11744
                endPosition = target.offset(),
11745
                animation = {
11746
                        top: endPosition.top - fixTop,
11747
                        left: endPosition.left - fixLeft,
11748
                        height: target.innerHeight(),
11749
                        width: target.innerWidth()
11750
                },
11751
                startPosition = elem.offset(),
11752
                transfer = $( "<div class='ui-effects-transfer'></div>" )
11753
                        .appendTo( document.body )
11754
                        .addClass( o.className )
11755
                        .css({
11756
                                top: startPosition.top - fixTop,
11757
                                left: startPosition.left - fixLeft,
11758
                                height: elem.innerHeight(),
11759
                                width: elem.innerWidth(),
11760
                                position: targetFixed ? "fixed" : "absolute"
11761
                        })
11762
                        .animate( animation, o.duration, o.easing, function() {
11763
                                transfer.remove();
11764
                                done();
11765
                        });
11766
};
11767

    
11768

    
11769
/*!
11770
 * jQuery UI Progressbar 1.11.4
11771
 * http://jqueryui.com
11772
 *
11773
 * Copyright jQuery Foundation and other contributors
11774
 * Released under the MIT license.
11775
 * http://jquery.org/license
11776
 *
11777
 * http://api.jqueryui.com/progressbar/
11778
 */
11779

    
11780

    
11781
var progressbar = $.widget( "ui.progressbar", {
11782
        version: "1.11.4",
11783
        options: {
11784
                max: 100,
11785
                value: 0,
11786

    
11787
                change: null,
11788
                complete: null
11789
        },
11790

    
11791
        min: 0,
11792

    
11793
        _create: function() {
11794
                // Constrain initial value
11795
                this.oldValue = this.options.value = this._constrainedValue();
11796

    
11797
                this.element
11798
                        .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11799
                        .attr({
11800
                                // Only set static values, aria-valuenow and aria-valuemax are
11801
                                // set inside _refreshValue()
11802
                                role: "progressbar",
11803
                                "aria-valuemin": this.min
11804
                        });
11805

    
11806
                this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
11807
                        .appendTo( this.element );
11808

    
11809
                this._refreshValue();
11810
        },
11811

    
11812
        _destroy: function() {
11813
                this.element
11814
                        .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11815
                        .removeAttr( "role" )
11816
                        .removeAttr( "aria-valuemin" )
11817
                        .removeAttr( "aria-valuemax" )
11818
                        .removeAttr( "aria-valuenow" );
11819

    
11820
                this.valueDiv.remove();
11821
        },
11822

    
11823
        value: function( newValue ) {
11824
                if ( newValue === undefined ) {
11825
                        return this.options.value;
11826
                }
11827

    
11828
                this.options.value = this._constrainedValue( newValue );
11829
                this._refreshValue();
11830
        },
11831

    
11832
        _constrainedValue: function( newValue ) {
11833
                if ( newValue === undefined ) {
11834
                        newValue = this.options.value;
11835
                }
11836

    
11837
                this.indeterminate = newValue === false;
11838

    
11839
                // sanitize value
11840
                if ( typeof newValue !== "number" ) {
11841
                        newValue = 0;
11842
                }
11843

    
11844
                return this.indeterminate ? false :
11845
                        Math.min( this.options.max, Math.max( this.min, newValue ) );
11846
        },
11847

    
11848
        _setOptions: function( options ) {
11849
                // Ensure "value" option is set after other values (like max)
11850
                var value = options.value;
11851
                delete options.value;
11852

    
11853
                this._super( options );
11854

    
11855
                this.options.value = this._constrainedValue( value );
11856
                this._refreshValue();
11857
        },
11858

    
11859
        _setOption: function( key, value ) {
11860
                if ( key === "max" ) {
11861
                        // Don't allow a max less than min
11862
                        value = Math.max( this.min, value );
11863
                }
11864
                if ( key === "disabled" ) {
11865
                        this.element
11866
                                .toggleClass( "ui-state-disabled", !!value )
11867
                                .attr( "aria-disabled", value );
11868
                }
11869
                this._super( key, value );
11870
        },
11871

    
11872
        _percentage: function() {
11873
                return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
11874
        },
11875

    
11876
        _refreshValue: function() {
11877
                var value = this.options.value,
11878
                        percentage = this._percentage();
11879

    
11880
                this.valueDiv
11881
                        .toggle( this.indeterminate || value > this.min )
11882
                        .toggleClass( "ui-corner-right", value === this.options.max )
11883
                        .width( percentage.toFixed(0) + "%" );
11884

    
11885
                this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
11886

    
11887
                if ( this.indeterminate ) {
11888
                        this.element.removeAttr( "aria-valuenow" );
11889
                        if ( !this.overlayDiv ) {
11890
                                this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
11891
                        }
11892
                } else {
11893
                        this.element.attr({
11894
                                "aria-valuemax": this.options.max,
11895
                                "aria-valuenow": value
11896
                        });
11897
                        if ( this.overlayDiv ) {
11898
                                this.overlayDiv.remove();
11899
                                this.overlayDiv = null;
11900
                        }
11901
                }
11902

    
11903
                if ( this.oldValue !== value ) {
11904
                        this.oldValue = value;
11905
                        this._trigger( "change" );
11906
                }
11907
                if ( value === this.options.max ) {
11908
                        this._trigger( "complete" );
11909
                }
11910
        }
11911
});
11912

    
11913

    
11914
/*!
11915
 * jQuery UI Selectable 1.11.4
11916
 * http://jqueryui.com
11917
 *
11918
 * Copyright jQuery Foundation and other contributors
11919
 * Released under the MIT license.
11920
 * http://jquery.org/license
11921
 *
11922
 * http://api.jqueryui.com/selectable/
11923
 */
11924

    
11925

    
11926
var selectable = $.widget("ui.selectable", $.ui.mouse, {
11927
        version: "1.11.4",
11928
        options: {
11929
                appendTo: "body",
11930
                autoRefresh: true,
11931
                distance: 0,
11932
                filter: "*",
11933
                tolerance: "touch",
11934

    
11935
                // callbacks
11936
                selected: null,
11937
                selecting: null,
11938
                start: null,
11939
                stop: null,
11940
                unselected: null,
11941
                unselecting: null
11942
        },
11943
        _create: function() {
11944
                var selectees,
11945
                        that = this;
11946

    
11947
                this.element.addClass("ui-selectable");
11948

    
11949
                this.dragged = false;
11950

    
11951
                // cache selectee children based on filter
11952
                this.refresh = function() {
11953
                        selectees = $(that.options.filter, that.element[0]);
11954
                        selectees.addClass("ui-selectee");
11955
                        selectees.each(function() {
11956
                                var $this = $(this),
11957
                                        pos = $this.offset();
11958
                                $.data(this, "selectable-item", {
11959
                                        element: this,
11960
                                        $element: $this,
11961
                                        left: pos.left,
11962
                                        top: pos.top,
11963
                                        right: pos.left + $this.outerWidth(),
11964
                                        bottom: pos.top + $this.outerHeight(),
11965
                                        startselected: false,
11966
                                        selected: $this.hasClass("ui-selected"),
11967
                                        selecting: $this.hasClass("ui-selecting"),
11968
                                        unselecting: $this.hasClass("ui-unselecting")
11969
                                });
11970
                        });
11971
                };
11972
                this.refresh();
11973

    
11974
                this.selectees = selectees.addClass("ui-selectee");
11975

    
11976
                this._mouseInit();
11977

    
11978
                this.helper = $("<div class='ui-selectable-helper'></div>");
11979
        },
11980

    
11981
        _destroy: function() {
11982
                this.selectees
11983
                        .removeClass("ui-selectee")
11984
                        .removeData("selectable-item");
11985
                this.element
11986
                        .removeClass("ui-selectable ui-selectable-disabled");
11987
                this._mouseDestroy();
11988
        },
11989

    
11990
        _mouseStart: function(event) {
11991
                var that = this,
11992
                        options = this.options;
11993

    
11994
                this.opos = [ event.pageX, event.pageY ];
11995

    
11996
                if (this.options.disabled) {
11997
                        return;
11998
                }
11999

    
12000
                this.selectees = $(options.filter, this.element[0]);
12001

    
12002
                this._trigger("start", event);
12003

    
12004
                $(options.appendTo).append(this.helper);
12005
                // position helper (lasso)
12006
                this.helper.css({
12007
                        "left": event.pageX,
12008
                        "top": event.pageY,
12009
                        "width": 0,
12010
                        "height": 0
12011
                });
12012

    
12013
                if (options.autoRefresh) {
12014
                        this.refresh();
12015
                }
12016

    
12017
                this.selectees.filter(".ui-selected").each(function() {
12018
                        var selectee = $.data(this, "selectable-item");
12019
                        selectee.startselected = true;
12020
                        if (!event.metaKey && !event.ctrlKey) {
12021
                                selectee.$element.removeClass("ui-selected");
12022
                                selectee.selected = false;
12023
                                selectee.$element.addClass("ui-unselecting");
12024
                                selectee.unselecting = true;
12025
                                // selectable UNSELECTING callback
12026
                                that._trigger("unselecting", event, {
12027
                                        unselecting: selectee.element
12028
                                });
12029
                        }
12030
                });
12031

    
12032
                $(event.target).parents().addBack().each(function() {
12033
                        var doSelect,
12034
                                selectee = $.data(this, "selectable-item");
12035
                        if (selectee) {
12036
                                doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
12037
                                selectee.$element
12038
                                        .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
12039
                                        .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
12040
                                selectee.unselecting = !doSelect;
12041
                                selectee.selecting = doSelect;
12042
                                selectee.selected = doSelect;
12043
                                // selectable (UN)SELECTING callback
12044
                                if (doSelect) {
12045
                                        that._trigger("selecting", event, {
12046
                                                selecting: selectee.element
12047
                                        });
12048
                                } else {
12049
                                        that._trigger("unselecting", event, {
12050
                                                unselecting: selectee.element
12051
                                        });
12052
                                }
12053
                                return false;
12054
                        }
12055
                });
12056

    
12057
        },
12058

    
12059
        _mouseDrag: function(event) {
12060

    
12061
                this.dragged = true;
12062

    
12063
                if (this.options.disabled) {
12064
                        return;
12065
                }
12066

    
12067
                var tmp,
12068
                        that = this,
12069
                        options = this.options,
12070
                        x1 = this.opos[0],
12071
                        y1 = this.opos[1],
12072
                        x2 = event.pageX,
12073
                        y2 = event.pageY;
12074

    
12075
                if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
12076
                if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
12077
                this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
12078

    
12079
                this.selectees.each(function() {
12080
                        var selectee = $.data(this, "selectable-item"),
12081
                                hit = false;
12082

    
12083
                        //prevent helper from being selected if appendTo: selectable
12084
                        if (!selectee || selectee.element === that.element[0]) {
12085
                                return;
12086
                        }
12087

    
12088
                        if (options.tolerance === "touch") {
12089
                                hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
12090
                        } else if (options.tolerance === "fit") {
12091
                                hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
12092
                        }
12093

    
12094
                        if (hit) {
12095
                                // SELECT
12096
                                if (selectee.selected) {
12097
                                        selectee.$element.removeClass("ui-selected");
12098
                                        selectee.selected = false;
12099
                                }
12100
                                if (selectee.unselecting) {
12101
                                        selectee.$element.removeClass("ui-unselecting");
12102
                                        selectee.unselecting = false;
12103
                                }
12104
                                if (!selectee.selecting) {
12105
                                        selectee.$element.addClass("ui-selecting");
12106
                                        selectee.selecting = true;
12107
                                        // selectable SELECTING callback
12108
                                        that._trigger("selecting", event, {
12109
                                                selecting: selectee.element
12110
                                        });
12111
                                }
12112
                        } else {
12113
                                // UNSELECT
12114
                                if (selectee.selecting) {
12115
                                        if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
12116
                                                selectee.$element.removeClass("ui-selecting");
12117
                                                selectee.selecting = false;
12118
                                                selectee.$element.addClass("ui-selected");
12119
                                                selectee.selected = true;
12120
                                        } else {
12121
                                                selectee.$element.removeClass("ui-selecting");
12122
                                                selectee.selecting = false;
12123
                                                if (selectee.startselected) {
12124
                                                        selectee.$element.addClass("ui-unselecting");
12125
                                                        selectee.unselecting = true;
12126
                                                }
12127
                                                // selectable UNSELECTING callback
12128
                                                that._trigger("unselecting", event, {
12129
                                                        unselecting: selectee.element
12130
                                                });
12131
                                        }
12132
                                }
12133
                                if (selectee.selected) {
12134
                                        if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
12135
                                                selectee.$element.removeClass("ui-selected");
12136
                                                selectee.selected = false;
12137

    
12138
                                                selectee.$element.addClass("ui-unselecting");
12139
                                                selectee.unselecting = true;
12140
                                                // selectable UNSELECTING callback
12141
                                                that._trigger("unselecting", event, {
12142
                                                        unselecting: selectee.element
12143
                                                });
12144
                                        }
12145
                                }
12146
                        }
12147
                });
12148

    
12149
                return false;
12150
        },
12151

    
12152
        _mouseStop: function(event) {
12153
                var that = this;
12154

    
12155
                this.dragged = false;
12156

    
12157
                $(".ui-unselecting", this.element[0]).each(function() {
12158
                        var selectee = $.data(this, "selectable-item");
12159
                        selectee.$element.removeClass("ui-unselecting");
12160
                        selectee.unselecting = false;
12161
                        selectee.startselected = false;
12162
                        that._trigger("unselected", event, {
12163
                                unselected: selectee.element
12164
                        });
12165
                });
12166
                $(".ui-selecting", this.element[0]).each(function() {
12167
                        var selectee = $.data(this, "selectable-item");
12168
                        selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
12169
                        selectee.selecting = false;
12170
                        selectee.selected = true;
12171
                        selectee.startselected = true;
12172
                        that._trigger("selected", event, {
12173
                                selected: selectee.element
12174
                        });
12175
                });
12176
                this._trigger("stop", event);
12177

    
12178
                this.helper.remove();
12179

    
12180
                return false;
12181
        }
12182

    
12183
});
12184

    
12185

    
12186
/*!
12187
 * jQuery UI Selectmenu 1.11.4
12188
 * http://jqueryui.com
12189
 *
12190
 * Copyright jQuery Foundation and other contributors
12191
 * Released under the MIT license.
12192
 * http://jquery.org/license
12193
 *
12194
 * http://api.jqueryui.com/selectmenu
12195
 */
12196

    
12197

    
12198
var selectmenu = $.widget( "ui.selectmenu", {
12199
        version: "1.11.4",
12200
        defaultElement: "<select>",
12201
        options: {
12202
                appendTo: null,
12203
                disabled: null,
12204
                icons: {
12205
                        button: "ui-icon-triangle-1-s"
12206
                },
12207
                position: {
12208
                        my: "left top",
12209
                        at: "left bottom",
12210
                        collision: "none"
12211
                },
12212
                width: null,
12213

    
12214
                // callbacks
12215
                change: null,
12216
                close: null,
12217
                focus: null,
12218
                open: null,
12219
                select: null
12220
        },
12221

    
12222
        _create: function() {
12223
                var selectmenuId = this.element.uniqueId().attr( "id" );
12224
                this.ids = {
12225
                        element: selectmenuId,
12226
                        button: selectmenuId + "-button",
12227
                        menu: selectmenuId + "-menu"
12228
                };
12229

    
12230
                this._drawButton();
12231
                this._drawMenu();
12232

    
12233
                if ( this.options.disabled ) {
12234
                        this.disable();
12235
                }
12236
        },
12237

    
12238
        _drawButton: function() {
12239
                var that = this;
12240

    
12241
                // Associate existing label with the new button
12242
                this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
12243
                this._on( this.label, {
12244
                        click: function( event ) {
12245
                                this.button.focus();
12246
                                event.preventDefault();
12247
                        }
12248
                });
12249

    
12250
                // Hide original select element
12251
                this.element.hide();
12252

    
12253
                // Create button
12254
                this.button = $( "<span>", {
12255
                        "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
12256
                        tabindex: this.options.disabled ? -1 : 0,
12257
                        id: this.ids.button,
12258
                        role: "combobox",
12259
                        "aria-expanded": "false",
12260
                        "aria-autocomplete": "list",
12261
                        "aria-owns": this.ids.menu,
12262
                        "aria-haspopup": "true"
12263
                })
12264
                        .insertAfter( this.element );
12265

    
12266
                $( "<span>", {
12267
                        "class": "ui-icon " + this.options.icons.button
12268
                })
12269
                        .prependTo( this.button );
12270

    
12271
                this.buttonText = $( "<span>", {
12272
                        "class": "ui-selectmenu-text"
12273
                })
12274
                        .appendTo( this.button );
12275

    
12276
                this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
12277
                this._resizeButton();
12278

    
12279
                this._on( this.button, this._buttonEvents );
12280
                this.button.one( "focusin", function() {
12281

    
12282
                        // Delay rendering the menu items until the button receives focus.
12283
                        // The menu may have already been rendered via a programmatic open.
12284
                        if ( !that.menuItems ) {
12285
                                that._refreshMenu();
12286
                        }
12287
                });
12288
                this._hoverable( this.button );
12289
                this._focusable( this.button );
12290
        },
12291

    
12292
        _drawMenu: function() {
12293
                var that = this;
12294

    
12295
                // Create menu
12296
                this.menu = $( "<ul>", {
12297
                        "aria-hidden": "true",
12298
                        "aria-labelledby": this.ids.button,
12299
                        id: this.ids.menu
12300
                });
12301

    
12302
                // Wrap menu
12303
                this.menuWrap = $( "<div>", {
12304
                        "class": "ui-selectmenu-menu ui-front"
12305
                })
12306
                        .append( this.menu )
12307
                        .appendTo( this._appendTo() );
12308

    
12309
                // Initialize menu widget
12310
                this.menuInstance = this.menu
12311
                        .menu({
12312
                                role: "listbox",
12313
                                select: function( event, ui ) {
12314
                                        event.preventDefault();
12315

    
12316
                                        // support: IE8
12317
                                        // If the item was selected via a click, the text selection
12318
                                        // will be destroyed in IE
12319
                                        that._setSelection();
12320

    
12321
                                        that._select( ui.item.data( "ui-selectmenu-item" ), event );
12322
                                },
12323
                                focus: function( event, ui ) {
12324
                                        var item = ui.item.data( "ui-selectmenu-item" );
12325

    
12326
                                        // Prevent inital focus from firing and check if its a newly focused item
12327
                                        if ( that.focusIndex != null && item.index !== that.focusIndex ) {
12328
                                                that._trigger( "focus", event, { item: item } );
12329
                                                if ( !that.isOpen ) {
12330
                                                        that._select( item, event );
12331
                                                }
12332
                                        }
12333
                                        that.focusIndex = item.index;
12334

    
12335
                                        that.button.attr( "aria-activedescendant",
12336
                                                that.menuItems.eq( item.index ).attr( "id" ) );
12337
                                }
12338
                        })
12339
                        .menu( "instance" );
12340

    
12341
                // Adjust menu styles to dropdown
12342
                this.menu
12343
                        .addClass( "ui-corner-bottom" )
12344
                        .removeClass( "ui-corner-all" );
12345

    
12346
                // Don't close the menu on mouseleave
12347
                this.menuInstance._off( this.menu, "mouseleave" );
12348

    
12349
                // Cancel the menu's collapseAll on document click
12350
                this.menuInstance._closeOnDocumentClick = function() {
12351
                        return false;
12352
                };
12353

    
12354
                // Selects often contain empty items, but never contain dividers
12355
                this.menuInstance._isDivider = function() {
12356
                        return false;
12357
                };
12358
        },
12359

    
12360
        refresh: function() {
12361
                this._refreshMenu();
12362
                this._setText( this.buttonText, this._getSelectedItem().text() );
12363
                if ( !this.options.width ) {
12364
                        this._resizeButton();
12365
                }
12366
        },
12367

    
12368
        _refreshMenu: function() {
12369
                this.menu.empty();
12370

    
12371
                var item,
12372
                        options = this.element.find( "option" );
12373

    
12374
                if ( !options.length ) {
12375
                        return;
12376
                }
12377

    
12378
                this._parseOptions( options );
12379
                this._renderMenu( this.menu, this.items );
12380

    
12381
                this.menuInstance.refresh();
12382
                this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
12383

    
12384
                item = this._getSelectedItem();
12385

    
12386
                // Update the menu to have the correct item focused
12387
                this.menuInstance.focus( null, item );
12388
                this._setAria( item.data( "ui-selectmenu-item" ) );
12389

    
12390
                // Set disabled state
12391
                this._setOption( "disabled", this.element.prop( "disabled" ) );
12392
        },
12393

    
12394
        open: function( event ) {
12395
                if ( this.options.disabled ) {
12396
                        return;
12397
                }
12398

    
12399
                // If this is the first time the menu is being opened, render the items
12400
                if ( !this.menuItems ) {
12401
                        this._refreshMenu();
12402
                } else {
12403

    
12404
                        // Menu clears focus on close, reset focus to selected item
12405
                        this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
12406
                        this.menuInstance.focus( null, this._getSelectedItem() );
12407
                }
12408

    
12409
                this.isOpen = true;
12410
                this._toggleAttr();
12411
                this._resizeMenu();
12412
                this._position();
12413

    
12414
                this._on( this.document, this._documentClick );
12415

    
12416
                this._trigger( "open", event );
12417
        },
12418

    
12419
        _position: function() {
12420
                this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
12421
        },
12422

    
12423
        close: function( event ) {
12424
                if ( !this.isOpen ) {
12425
                        return;
12426
                }
12427

    
12428
                this.isOpen = false;
12429
                this._toggleAttr();
12430

    
12431
                this.range = null;
12432
                this._off( this.document );
12433

    
12434
                this._trigger( "close", event );
12435
        },
12436

    
12437
        widget: function() {
12438
                return this.button;
12439
        },
12440

    
12441
        menuWidget: function() {
12442
                return this.menu;
12443
        },
12444

    
12445
        _renderMenu: function( ul, items ) {
12446
                var that = this,
12447
                        currentOptgroup = "";
12448

    
12449
                $.each( items, function( index, item ) {
12450
                        if ( item.optgroup !== currentOptgroup ) {
12451
                                $( "<li>", {
12452
                                        "class": "ui-selectmenu-optgroup ui-menu-divider" +
12453
                                                ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
12454
                                                        " ui-state-disabled" :
12455
                                                        "" ),
12456
                                        text: item.optgroup
12457
                                })
12458
                                        .appendTo( ul );
12459

    
12460
                                currentOptgroup = item.optgroup;
12461
                        }
12462

    
12463
                        that._renderItemData( ul, item );
12464
                });
12465
        },
12466

    
12467
        _renderItemData: function( ul, item ) {
12468
                return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
12469
        },
12470

    
12471
        _renderItem: function( ul, item ) {
12472
                var li = $( "<li>" );
12473

    
12474
                if ( item.disabled ) {
12475
                        li.addClass( "ui-state-disabled" );
12476
                }
12477
                this._setText( li, item.label );
12478

    
12479
                return li.appendTo( ul );
12480
        },
12481

    
12482
        _setText: function( element, value ) {
12483
                if ( value ) {
12484
                        element.text( value );
12485
                } else {
12486
                        element.html( "&#160;" );
12487
                }
12488
        },
12489

    
12490
        _move: function( direction, event ) {
12491
                var item, next,
12492
                        filter = ".ui-menu-item";
12493

    
12494
                if ( this.isOpen ) {
12495
                        item = this.menuItems.eq( this.focusIndex );
12496
                } else {
12497
                        item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
12498
                        filter += ":not(.ui-state-disabled)";
12499
                }
12500

    
12501
                if ( direction === "first" || direction === "last" ) {
12502
                        next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
12503
                } else {
12504
                        next = item[ direction + "All" ]( filter ).eq( 0 );
12505
                }
12506

    
12507
                if ( next.length ) {
12508
                        this.menuInstance.focus( event, next );
12509
                }
12510
        },
12511

    
12512
        _getSelectedItem: function() {
12513
                return this.menuItems.eq( this.element[ 0 ].selectedIndex );
12514
        },
12515

    
12516
        _toggle: function( event ) {
12517
                this[ this.isOpen ? "close" : "open" ]( event );
12518
        },
12519

    
12520
        _setSelection: function() {
12521
                var selection;
12522

    
12523
                if ( !this.range ) {
12524
                        return;
12525
                }
12526

    
12527
                if ( window.getSelection ) {
12528
                        selection = window.getSelection();
12529
                        selection.removeAllRanges();
12530
                        selection.addRange( this.range );
12531

    
12532
                // support: IE8
12533
                } else {
12534
                        this.range.select();
12535
                }
12536

    
12537
                // support: IE
12538
                // Setting the text selection kills the button focus in IE, but
12539
                // restoring the focus doesn't kill the selection.
12540
                this.button.focus();
12541
        },
12542

    
12543
        _documentClick: {
12544
                mousedown: function( event ) {
12545
                        if ( !this.isOpen ) {
12546
                                return;
12547
                        }
12548

    
12549
                        if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
12550
                                this.close( event );
12551
                        }
12552
                }
12553
        },
12554

    
12555
        _buttonEvents: {
12556

    
12557
                // Prevent text selection from being reset when interacting with the selectmenu (#10144)
12558
                mousedown: function() {
12559
                        var selection;
12560

    
12561
                        if ( window.getSelection ) {
12562
                                selection = window.getSelection();
12563
                                if ( selection.rangeCount ) {
12564
                                        this.range = selection.getRangeAt( 0 );
12565
                                }
12566

    
12567
                        // support: IE8
12568
                        } else {
12569
                                this.range = document.selection.createRange();
12570
                        }
12571
                },
12572

    
12573
                click: function( event ) {
12574
                        this._setSelection();
12575
                        this._toggle( event );
12576
                },
12577

    
12578
                keydown: function( event ) {
12579
                        var preventDefault = true;
12580
                        switch ( event.keyCode ) {
12581
                                case $.ui.keyCode.TAB:
12582
                                case $.ui.keyCode.ESCAPE:
12583
                                        this.close( event );
12584
                                        preventDefault = false;
12585
                                        break;
12586
                                case $.ui.keyCode.ENTER:
12587
                                        if ( this.isOpen ) {
12588
                                                this._selectFocusedItem( event );
12589
                                        }
12590
                                        break;
12591
                                case $.ui.keyCode.UP:
12592
                                        if ( event.altKey ) {
12593
                                                this._toggle( event );
12594
                                        } else {
12595
                                                this._move( "prev", event );
12596
                                        }
12597
                                        break;
12598
                                case $.ui.keyCode.DOWN:
12599
                                        if ( event.altKey ) {
12600
                                                this._toggle( event );
12601
                                        } else {
12602
                                                this._move( "next", event );
12603
                                        }
12604
                                        break;
12605
                                case $.ui.keyCode.SPACE:
12606
                                        if ( this.isOpen ) {
12607
                                                this._selectFocusedItem( event );
12608
                                        } else {
12609
                                                this._toggle( event );
12610
                                        }
12611
                                        break;
12612
                                case $.ui.keyCode.LEFT:
12613
                                        this._move( "prev", event );
12614
                                        break;
12615
                                case $.ui.keyCode.RIGHT:
12616
                                        this._move( "next", event );
12617
                                        break;
12618
                                case $.ui.keyCode.HOME:
12619
                                case $.ui.keyCode.PAGE_UP:
12620
                                        this._move( "first", event );
12621
                                        break;
12622
                                case $.ui.keyCode.END:
12623
                                case $.ui.keyCode.PAGE_DOWN:
12624
                                        this._move( "last", event );
12625
                                        break;
12626
                                default:
12627
                                        this.menu.trigger( event );
12628
                                        preventDefault = false;
12629
                        }
12630

    
12631
                        if ( preventDefault ) {
12632
                                event.preventDefault();
12633
                        }
12634
                }
12635
        },
12636

    
12637
        _selectFocusedItem: function( event ) {
12638
                var item = this.menuItems.eq( this.focusIndex );
12639
                if ( !item.hasClass( "ui-state-disabled" ) ) {
12640
                        this._select( item.data( "ui-selectmenu-item" ), event );
12641
                }
12642
        },
12643

    
12644
        _select: function( item, event ) {
12645
                var oldIndex = this.element[ 0 ].selectedIndex;
12646

    
12647
                // Change native select element
12648
                this.element[ 0 ].selectedIndex = item.index;
12649
                this._setText( this.buttonText, item.label );
12650
                this._setAria( item );
12651
                this._trigger( "select", event, { item: item } );
12652

    
12653
                if ( item.index !== oldIndex ) {
12654
                        this._trigger( "change", event, { item: item } );
12655
                }
12656

    
12657
                this.close( event );
12658
        },
12659

    
12660
        _setAria: function( item ) {
12661
                var id = this.menuItems.eq( item.index ).attr( "id" );
12662

    
12663
                this.button.attr({
12664
                        "aria-labelledby": id,
12665
                        "aria-activedescendant": id
12666
                });
12667
                this.menu.attr( "aria-activedescendant", id );
12668
        },
12669

    
12670
        _setOption: function( key, value ) {
12671
                if ( key === "icons" ) {
12672
                        this.button.find( "span.ui-icon" )
12673
                                .removeClass( this.options.icons.button )
12674
                                .addClass( value.button );
12675
                }
12676

    
12677
                this._super( key, value );
12678

    
12679
                if ( key === "appendTo" ) {
12680
                        this.menuWrap.appendTo( this._appendTo() );
12681
                }
12682

    
12683
                if ( key === "disabled" ) {
12684
                        this.menuInstance.option( "disabled", value );
12685
                        this.button
12686
                                .toggleClass( "ui-state-disabled", value )
12687
                                .attr( "aria-disabled", value );
12688

    
12689
                        this.element.prop( "disabled", value );
12690
                        if ( value ) {
12691
                                this.button.attr( "tabindex", -1 );
12692
                                this.close();
12693
                        } else {
12694
                                this.button.attr( "tabindex", 0 );
12695
                        }
12696
                }
12697

    
12698
                if ( key === "width" ) {
12699
                        this._resizeButton();
12700
                }
12701
        },
12702

    
12703
        _appendTo: function() {
12704
                var element = this.options.appendTo;
12705

    
12706
                if ( element ) {
12707
                        element = element.jquery || element.nodeType ?
12708
                                $( element ) :
12709
                                this.document.find( element ).eq( 0 );
12710
                }
12711

    
12712
                if ( !element || !element[ 0 ] ) {
12713
                        element = this.element.closest( ".ui-front" );
12714
                }
12715

    
12716
                if ( !element.length ) {
12717
                        element = this.document[ 0 ].body;
12718
                }
12719

    
12720
                return element;
12721
        },
12722

    
12723
        _toggleAttr: function() {
12724
                this.button
12725
                        .toggleClass( "ui-corner-top", this.isOpen )
12726
                        .toggleClass( "ui-corner-all", !this.isOpen )
12727
                        .attr( "aria-expanded", this.isOpen );
12728
                this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
12729
                this.menu.attr( "aria-hidden", !this.isOpen );
12730
        },
12731

    
12732
        _resizeButton: function() {
12733
                var width = this.options.width;
12734

    
12735
                if ( !width ) {
12736
                        width = this.element.show().outerWidth();
12737
                        this.element.hide();
12738
                }
12739

    
12740
                this.button.outerWidth( width );
12741
        },
12742

    
12743
        _resizeMenu: function() {
12744
                this.menu.outerWidth( Math.max(
12745
                        this.button.outerWidth(),
12746

    
12747
                        // support: IE10
12748
                        // IE10 wraps long text (possibly a rounding bug)
12749
                        // so we add 1px to avoid the wrapping
12750
                        this.menu.width( "" ).outerWidth() + 1
12751
                ) );
12752
        },
12753

    
12754
        _getCreateOptions: function() {
12755
                return { disabled: this.element.prop( "disabled" ) };
12756
        },
12757

    
12758
        _parseOptions: function( options ) {
12759
                var data = [];
12760
                options.each(function( index, item ) {
12761
                        var option = $( item ),
12762
                                optgroup = option.parent( "optgroup" );
12763
                        data.push({
12764
                                element: option,
12765
                                index: index,
12766
                                value: option.val(),
12767
                                label: option.text(),
12768
                                optgroup: optgroup.attr( "label" ) || "",
12769
                                disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
12770
                        });
12771
                });
12772
                this.items = data;
12773
        },
12774

    
12775
        _destroy: function() {
12776
                this.menuWrap.remove();
12777
                this.button.remove();
12778
                this.element.show();
12779
                this.element.removeUniqueId();
12780
                this.label.attr( "for", this.ids.element );
12781
        }
12782
});
12783

    
12784

    
12785
/*!
12786
 * jQuery UI Slider 1.11.4
12787
 * http://jqueryui.com
12788
 *
12789
 * Copyright jQuery Foundation and other contributors
12790
 * Released under the MIT license.
12791
 * http://jquery.org/license
12792
 *
12793
 * http://api.jqueryui.com/slider/
12794
 */
12795

    
12796

    
12797
var slider = $.widget( "ui.slider", $.ui.mouse, {
12798
        version: "1.11.4",
12799
        widgetEventPrefix: "slide",
12800

    
12801
        options: {
12802
                animate: false,
12803
                distance: 0,
12804
                max: 100,
12805
                min: 0,
12806
                orientation: "horizontal",
12807
                range: false,
12808
                step: 1,
12809
                value: 0,
12810
                values: null,
12811

    
12812
                // callbacks
12813
                change: null,
12814
                slide: null,
12815
                start: null,
12816
                stop: null
12817
        },
12818

    
12819
        // number of pages in a slider
12820
        // (how many times can you page up/down to go through the whole range)
12821
        numPages: 5,
12822

    
12823
        _create: function() {
12824
                this._keySliding = false;
12825
                this._mouseSliding = false;
12826
                this._animateOff = true;
12827
                this._handleIndex = null;
12828
                this._detectOrientation();
12829
                this._mouseInit();
12830
                this._calculateNewMax();
12831

    
12832
                this.element
12833
                        .addClass( "ui-slider" +
12834
                                " ui-slider-" + this.orientation +
12835
                                " ui-widget" +
12836
                                " ui-widget-content" +
12837
                                " ui-corner-all");
12838

    
12839
                this._refresh();
12840
                this._setOption( "disabled", this.options.disabled );
12841

    
12842
                this._animateOff = false;
12843
        },
12844

    
12845
        _refresh: function() {
12846
                this._createRange();
12847
                this._createHandles();
12848
                this._setupEvents();
12849
                this._refreshValue();
12850
        },
12851

    
12852
        _createHandles: function() {
12853
                var i, handleCount,
12854
                        options = this.options,
12855
                        existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12856
                        handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
12857
                        handles = [];
12858

    
12859
                handleCount = ( options.values && options.values.length ) || 1;
12860

    
12861
                if ( existingHandles.length > handleCount ) {
12862
                        existingHandles.slice( handleCount ).remove();
12863
                        existingHandles = existingHandles.slice( 0, handleCount );
12864
                }
12865

    
12866
                for ( i = existingHandles.length; i < handleCount; i++ ) {
12867
                        handles.push( handle );
12868
                }
12869

    
12870
                this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12871

    
12872
                this.handle = this.handles.eq( 0 );
12873

    
12874
                this.handles.each(function( i ) {
12875
                        $( this ).data( "ui-slider-handle-index", i );
12876
                });
12877
        },
12878

    
12879
        _createRange: function() {
12880
                var options = this.options,
12881
                        classes = "";
12882

    
12883
                if ( options.range ) {
12884
                        if ( options.range === true ) {
12885
                                if ( !options.values ) {
12886
                                        options.values = [ this._valueMin(), this._valueMin() ];
12887
                                } else if ( options.values.length && options.values.length !== 2 ) {
12888
                                        options.values = [ options.values[0], options.values[0] ];
12889
                                } else if ( $.isArray( options.values ) ) {
12890
                                        options.values = options.values.slice(0);
12891
                                }
12892
                        }
12893

    
12894
                        if ( !this.range || !this.range.length ) {
12895
                                this.range = $( "<div></div>" )
12896
                                        .appendTo( this.element );
12897

    
12898
                                classes = "ui-slider-range" +
12899
                                // note: this isn't the most fittingly semantic framework class for this element,
12900
                                // but worked best visually with a variety of themes
12901
                                " ui-widget-header ui-corner-all";
12902
                        } else {
12903
                                this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12904
                                        // Handle range switching from true to min/max
12905
                                        .css({
12906
                                                "left": "",
12907
                                                "bottom": ""
12908
                                        });
12909
                        }
12910

    
12911
                        this.range.addClass( classes +
12912
                                ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12913
                } else {
12914
                        if ( this.range ) {
12915
                                this.range.remove();
12916
                        }
12917
                        this.range = null;
12918
                }
12919
        },
12920

    
12921
        _setupEvents: function() {
12922
                this._off( this.handles );
12923
                this._on( this.handles, this._handleEvents );
12924
                this._hoverable( this.handles );
12925
                this._focusable( this.handles );
12926
        },
12927

    
12928
        _destroy: function() {
12929
                this.handles.remove();
12930
                if ( this.range ) {
12931
                        this.range.remove();
12932
                }
12933

    
12934
                this.element
12935
                        .removeClass( "ui-slider" +
12936
                                " ui-slider-horizontal" +
12937
                                " ui-slider-vertical" +
12938
                                " ui-widget" +
12939
                                " ui-widget-content" +
12940
                                " ui-corner-all" );
12941

    
12942
                this._mouseDestroy();
12943
        },
12944

    
12945
        _mouseCapture: function( event ) {
12946
                var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12947
                        that = this,
12948
                        o = this.options;
12949

    
12950
                if ( o.disabled ) {
12951
                        return false;
12952
                }
12953

    
12954
                this.elementSize = {
12955
                        width: this.element.outerWidth(),
12956
                        height: this.element.outerHeight()
12957
                };
12958
                this.elementOffset = this.element.offset();
12959

    
12960
                position = { x: event.pageX, y: event.pageY };
12961
                normValue = this._normValueFromMouse( position );
12962
                distance = this._valueMax() - this._valueMin() + 1;
12963
                this.handles.each(function( i ) {
12964
                        var thisDistance = Math.abs( normValue - that.values(i) );
12965
                        if (( distance > thisDistance ) ||
12966
                                ( distance === thisDistance &&
12967
                                        (i === that._lastChangedValue || that.values(i) === o.min ))) {
12968
                                distance = thisDistance;
12969
                                closestHandle = $( this );
12970
                                index = i;
12971
                        }
12972
                });
12973

    
12974
                allowed = this._start( event, index );
12975
                if ( allowed === false ) {
12976
                        return false;
12977
                }
12978
                this._mouseSliding = true;
12979

    
12980
                this._handleIndex = index;
12981

    
12982
                closestHandle
12983
                        .addClass( "ui-state-active" )
12984
                        .focus();
12985

    
12986
                offset = closestHandle.offset();
12987
                mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12988
                this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12989
                        left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12990
                        top: event.pageY - offset.top -
12991
                                ( closestHandle.height() / 2 ) -
12992
                                ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12993
                                ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12994
                                ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12995
                };
12996

    
12997
                if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12998
                        this._slide( event, index, normValue );
12999
                }
13000
                this._animateOff = true;
13001
                return true;
13002
        },
13003

    
13004
        _mouseStart: function() {
13005
                return true;
13006
        },
13007

    
13008
        _mouseDrag: function( event ) {
13009
                var position = { x: event.pageX, y: event.pageY },
13010
                        normValue = this._normValueFromMouse( position );
13011

    
13012
                this._slide( event, this._handleIndex, normValue );
13013

    
13014
                return false;
13015
        },
13016

    
13017
        _mouseStop: function( event ) {
13018
                this.handles.removeClass( "ui-state-active" );
13019
                this._mouseSliding = false;
13020

    
13021
                this._stop( event, this._handleIndex );
13022
                this._change( event, this._handleIndex );
13023

    
13024
                this._handleIndex = null;
13025
                this._clickOffset = null;
13026
                this._animateOff = false;
13027

    
13028
                return false;
13029
        },
13030

    
13031
        _detectOrientation: function() {
13032
                this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
13033
        },
13034

    
13035
        _normValueFromMouse: function( position ) {
13036
                var pixelTotal,
13037
                        pixelMouse,
13038
                        percentMouse,
13039
                        valueTotal,
13040
                        valueMouse;
13041

    
13042
                if ( this.orientation === "horizontal" ) {
13043
                        pixelTotal = this.elementSize.width;
13044
                        pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
13045
                } else {
13046
                        pixelTotal = this.elementSize.height;
13047
                        pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
13048
                }
13049

    
13050
                percentMouse = ( pixelMouse / pixelTotal );
13051
                if ( percentMouse > 1 ) {
13052
                        percentMouse = 1;
13053
                }
13054
                if ( percentMouse < 0 ) {
13055
                        percentMouse = 0;
13056
                }
13057
                if ( this.orientation === "vertical" ) {
13058
                        percentMouse = 1 - percentMouse;
13059
                }
13060

    
13061
                valueTotal = this._valueMax() - this._valueMin();
13062
                valueMouse = this._valueMin() + percentMouse * valueTotal;
13063

    
13064
                return this._trimAlignValue( valueMouse );
13065
        },
13066

    
13067
        _start: function( event, index ) {
13068
                var uiHash = {
13069
                        handle: this.handles[ index ],
13070
                        value: this.value()
13071
                };
13072
                if ( this.options.values && this.options.values.length ) {
13073
                        uiHash.value = this.values( index );
13074
                        uiHash.values = this.values();
13075
                }
13076
                return this._trigger( "start", event, uiHash );
13077
        },
13078

    
13079
        _slide: function( event, index, newVal ) {
13080
                var otherVal,
13081
                        newValues,
13082
                        allowed;
13083

    
13084
                if ( this.options.values && this.options.values.length ) {
13085
                        otherVal = this.values( index ? 0 : 1 );
13086

    
13087
                        if ( ( this.options.values.length === 2 && this.options.range === true ) &&
13088
                                        ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
13089
                                ) {
13090
                                newVal = otherVal;
13091
                        }
13092

    
13093
                        if ( newVal !== this.values( index ) ) {
13094
                                newValues = this.values();
13095
                                newValues[ index ] = newVal;
13096
                                // A slide can be canceled by returning false from the slide callback
13097
                                allowed = this._trigger( "slide", event, {
13098
                                        handle: this.handles[ index ],
13099
                                        value: newVal,
13100
                                        values: newValues
13101
                                } );
13102
                                otherVal = this.values( index ? 0 : 1 );
13103
                                if ( allowed !== false ) {
13104
                                        this.values( index, newVal );
13105
                                }
13106
                        }
13107
                } else {
13108
                        if ( newVal !== this.value() ) {
13109
                                // A slide can be canceled by returning false from the slide callback
13110
                                allowed = this._trigger( "slide", event, {
13111
                                        handle: this.handles[ index ],
13112
                                        value: newVal
13113
                                } );
13114
                                if ( allowed !== false ) {
13115
                                        this.value( newVal );
13116
                                }
13117
                        }
13118
                }
13119
        },
13120

    
13121
        _stop: function( event, index ) {
13122
                var uiHash = {
13123
                        handle: this.handles[ index ],
13124
                        value: this.value()
13125
                };
13126
                if ( this.options.values && this.options.values.length ) {
13127
                        uiHash.value = this.values( index );
13128
                        uiHash.values = this.values();
13129
                }
13130

    
13131
                this._trigger( "stop", event, uiHash );
13132
        },
13133

    
13134
        _change: function( event, index ) {
13135
                if ( !this._keySliding && !this._mouseSliding ) {
13136
                        var uiHash = {
13137
                                handle: this.handles[ index ],
13138
                                value: this.value()
13139
                        };
13140
                        if ( this.options.values && this.options.values.length ) {
13141
                                uiHash.value = this.values( index );
13142
                                uiHash.values = this.values();
13143
                        }
13144

    
13145
                        //store the last changed value index for reference when handles overlap
13146
                        this._lastChangedValue = index;
13147

    
13148
                        this._trigger( "change", event, uiHash );
13149
                }
13150
        },
13151

    
13152
        value: function( newValue ) {
13153
                if ( arguments.length ) {
13154
                        this.options.value = this._trimAlignValue( newValue );
13155
                        this._refreshValue();
13156
                        this._change( null, 0 );
13157
                        return;
13158
                }
13159

    
13160
                return this._value();
13161
        },
13162

    
13163
        values: function( index, newValue ) {
13164
                var vals,
13165
                        newValues,
13166
                        i;
13167

    
13168
                if ( arguments.length > 1 ) {
13169
                        this.options.values[ index ] = this._trimAlignValue( newValue );
13170
                        this._refreshValue();
13171
                        this._change( null, index );
13172
                        return;
13173
                }
13174

    
13175
                if ( arguments.length ) {
13176
                        if ( $.isArray( arguments[ 0 ] ) ) {
13177
                                vals = this.options.values;
13178
                                newValues = arguments[ 0 ];
13179
                                for ( i = 0; i < vals.length; i += 1 ) {
13180
                                        vals[ i ] = this._trimAlignValue( newValues[ i ] );
13181
                                        this._change( null, i );
13182
                                }
13183
                                this._refreshValue();
13184
                        } else {
13185
                                if ( this.options.values && this.options.values.length ) {
13186
                                        return this._values( index );
13187
                                } else {
13188
                                        return this.value();
13189
                                }
13190
                        }
13191
                } else {
13192
                        return this._values();
13193
                }
13194
        },
13195

    
13196
        _setOption: function( key, value ) {
13197
                var i,
13198
                        valsLength = 0;
13199

    
13200
                if ( key === "range" && this.options.range === true ) {
13201
                        if ( value === "min" ) {
13202
                                this.options.value = this._values( 0 );
13203
                                this.options.values = null;
13204
                        } else if ( value === "max" ) {
13205
                                this.options.value = this._values( this.options.values.length - 1 );
13206
                                this.options.values = null;
13207
                        }
13208
                }
13209

    
13210
                if ( $.isArray( this.options.values ) ) {
13211
                        valsLength = this.options.values.length;
13212
                }
13213

    
13214
                if ( key === "disabled" ) {
13215
                        this.element.toggleClass( "ui-state-disabled", !!value );
13216
                }
13217

    
13218
                this._super( key, value );
13219

    
13220
                switch ( key ) {
13221
                        case "orientation":
13222
                                this._detectOrientation();
13223
                                this.element
13224
                                        .removeClass( "ui-slider-horizontal ui-slider-vertical" )
13225
                                        .addClass( "ui-slider-" + this.orientation );
13226
                                this._refreshValue();
13227

    
13228
                                // Reset positioning from previous orientation
13229
                                this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
13230
                                break;
13231
                        case "value":
13232
                                this._animateOff = true;
13233
                                this._refreshValue();
13234
                                this._change( null, 0 );
13235
                                this._animateOff = false;
13236
                                break;
13237
                        case "values":
13238
                                this._animateOff = true;
13239
                                this._refreshValue();
13240
                                for ( i = 0; i < valsLength; i += 1 ) {
13241
                                        this._change( null, i );
13242
                                }
13243
                                this._animateOff = false;
13244
                                break;
13245
                        case "step":
13246
                        case "min":
13247
                        case "max":
13248
                                this._animateOff = true;
13249
                                this._calculateNewMax();
13250
                                this._refreshValue();
13251
                                this._animateOff = false;
13252
                                break;
13253
                        case "range":
13254
                                this._animateOff = true;
13255
                                this._refresh();
13256
                                this._animateOff = false;
13257
                                break;
13258
                }
13259
        },
13260

    
13261
        //internal value getter
13262
        // _value() returns value trimmed by min and max, aligned by step
13263
        _value: function() {
13264
                var val = this.options.value;
13265
                val = this._trimAlignValue( val );
13266

    
13267
                return val;
13268
        },
13269

    
13270
        //internal values getter
13271
        // _values() returns array of values trimmed by min and max, aligned by step
13272
        // _values( index ) returns single value trimmed by min and max, aligned by step
13273
        _values: function( index ) {
13274
                var val,
13275
                        vals,
13276
                        i;
13277

    
13278
                if ( arguments.length ) {
13279
                        val = this.options.values[ index ];
13280
                        val = this._trimAlignValue( val );
13281

    
13282
                        return val;
13283
                } else if ( this.options.values && this.options.values.length ) {
13284
                        // .slice() creates a copy of the array
13285
                        // this copy gets trimmed by min and max and then returned
13286
                        vals = this.options.values.slice();
13287
                        for ( i = 0; i < vals.length; i += 1) {
13288
                                vals[ i ] = this._trimAlignValue( vals[ i ] );
13289
                        }
13290

    
13291
                        return vals;
13292
                } else {
13293
                        return [];
13294
                }
13295
        },
13296

    
13297
        // returns the step-aligned value that val is closest to, between (inclusive) min and max
13298
        _trimAlignValue: function( val ) {
13299
                if ( val <= this._valueMin() ) {
13300
                        return this._valueMin();
13301
                }
13302
                if ( val >= this._valueMax() ) {
13303
                        return this._valueMax();
13304
                }
13305
                var step = ( this.options.step > 0 ) ? this.options.step : 1,
13306
                        valModStep = (val - this._valueMin()) % step,
13307
                        alignValue = val - valModStep;
13308

    
13309
                if ( Math.abs(valModStep) * 2 >= step ) {
13310
                        alignValue += ( valModStep > 0 ) ? step : ( -step );
13311
                }
13312

    
13313
                // Since JavaScript has problems with large floats, round
13314
                // the final value to 5 digits after the decimal point (see #4124)
13315
                return parseFloat( alignValue.toFixed(5) );
13316
        },
13317

    
13318
        _calculateNewMax: function() {
13319
                var max = this.options.max,
13320
                        min = this._valueMin(),
13321
                        step = this.options.step,
13322
                        aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
13323
                max = aboveMin + min;
13324
                this.max = parseFloat( max.toFixed( this._precision() ) );
13325
        },
13326

    
13327
        _precision: function() {
13328
                var precision = this._precisionOf( this.options.step );
13329
                if ( this.options.min !== null ) {
13330
                        precision = Math.max( precision, this._precisionOf( this.options.min ) );
13331
                }
13332
                return precision;
13333
        },
13334

    
13335
        _precisionOf: function( num ) {
13336
                var str = num.toString(),
13337
                        decimal = str.indexOf( "." );
13338
                return decimal === -1 ? 0 : str.length - decimal - 1;
13339
        },
13340

    
13341
        _valueMin: function() {
13342
                return this.options.min;
13343
        },
13344

    
13345
        _valueMax: function() {
13346
                return this.max;
13347
        },
13348

    
13349
        _refreshValue: function() {
13350
                var lastValPercent, valPercent, value, valueMin, valueMax,
13351
                        oRange = this.options.range,
13352
                        o = this.options,
13353
                        that = this,
13354
                        animate = ( !this._animateOff ) ? o.animate : false,
13355
                        _set = {};
13356

    
13357
                if ( this.options.values && this.options.values.length ) {
13358
                        this.handles.each(function( i ) {
13359
                                valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13360
                                _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13361
                                $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13362
                                if ( that.options.range === true ) {
13363
                                        if ( that.orientation === "horizontal" ) {
13364
                                                if ( i === 0 ) {
13365
                                                        that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13366
                                                }
13367
                                                if ( i === 1 ) {
13368
                                                        that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13369
                                                }
13370
                                        } else {
13371
                                                if ( i === 0 ) {
13372
                                                        that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13373
                                                }
13374
                                                if ( i === 1 ) {
13375
                                                        that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13376
                                                }
13377
                                        }
13378
                                }
13379
                                lastValPercent = valPercent;
13380
                        });
13381
                } else {
13382
                        value = this.value();
13383
                        valueMin = this._valueMin();
13384
                        valueMax = this._valueMax();
13385
                        valPercent = ( valueMax !== valueMin ) ?
13386
                                        ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13387
                                        0;
13388
                        _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13389
                        this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13390

    
13391
                        if ( oRange === "min" && this.orientation === "horizontal" ) {
13392
                                this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13393
                        }
13394
                        if ( oRange === "max" && this.orientation === "horizontal" ) {
13395
                                this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13396
                        }
13397
                        if ( oRange === "min" && this.orientation === "vertical" ) {
13398
                                this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13399
                        }
13400
                        if ( oRange === "max" && this.orientation === "vertical" ) {
13401
                                this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13402
                        }
13403
                }
13404
        },
13405

    
13406
        _handleEvents: {
13407
                keydown: function( event ) {
13408
                        var allowed, curVal, newVal, step,
13409
                                index = $( event.target ).data( "ui-slider-handle-index" );
13410

    
13411
                        switch ( event.keyCode ) {
13412
                                case $.ui.keyCode.HOME:
13413
                                case $.ui.keyCode.END:
13414
                                case $.ui.keyCode.PAGE_UP:
13415
                                case $.ui.keyCode.PAGE_DOWN:
13416
                                case $.ui.keyCode.UP:
13417
                                case $.ui.keyCode.RIGHT:
13418
                                case $.ui.keyCode.DOWN:
13419
                                case $.ui.keyCode.LEFT:
13420
                                        event.preventDefault();
13421
                                        if ( !this._keySliding ) {
13422
                                                this._keySliding = true;
13423
                                                $( event.target ).addClass( "ui-state-active" );
13424
                                                allowed = this._start( event, index );
13425
                                                if ( allowed === false ) {
13426
                                                        return;
13427
                                                }
13428
                                        }
13429
                                        break;
13430
                        }
13431

    
13432
                        step = this.options.step;
13433
                        if ( this.options.values && this.options.values.length ) {
13434
                                curVal = newVal = this.values( index );
13435
                        } else {
13436
                                curVal = newVal = this.value();
13437
                        }
13438

    
13439
                        switch ( event.keyCode ) {
13440
                                case $.ui.keyCode.HOME:
13441
                                        newVal = this._valueMin();
13442
                                        break;
13443
                                case $.ui.keyCode.END:
13444
                                        newVal = this._valueMax();
13445
                                        break;
13446
                                case $.ui.keyCode.PAGE_UP:
13447
                                        newVal = this._trimAlignValue(
13448
                                                curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
13449
                                        );
13450
                                        break;
13451
                                case $.ui.keyCode.PAGE_DOWN:
13452
                                        newVal = this._trimAlignValue(
13453
                                                curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
13454
                                        break;
13455
                                case $.ui.keyCode.UP:
13456
                                case $.ui.keyCode.RIGHT:
13457
                                        if ( curVal === this._valueMax() ) {
13458
                                                return;
13459
                                        }
13460
                                        newVal = this._trimAlignValue( curVal + step );
13461
                                        break;
13462
                                case $.ui.keyCode.DOWN:
13463
                                case $.ui.keyCode.LEFT:
13464
                                        if ( curVal === this._valueMin() ) {
13465
                                                return;
13466
                                        }
13467
                                        newVal = this._trimAlignValue( curVal - step );
13468
                                        break;
13469
                        }
13470

    
13471
                        this._slide( event, index, newVal );
13472
                },
13473
                keyup: function( event ) {
13474
                        var index = $( event.target ).data( "ui-slider-handle-index" );
13475

    
13476
                        if ( this._keySliding ) {
13477
                                this._keySliding = false;
13478
                                this._stop( event, index );
13479
                                this._change( event, index );
13480
                                $( event.target ).removeClass( "ui-state-active" );
13481
                        }
13482
                }
13483
        }
13484
});
13485

    
13486

    
13487
/*!
13488
 * jQuery UI Sortable 1.11.4
13489
 * http://jqueryui.com
13490
 *
13491
 * Copyright jQuery Foundation and other contributors
13492
 * Released under the MIT license.
13493
 * http://jquery.org/license
13494
 *
13495
 * http://api.jqueryui.com/sortable/
13496
 */
13497

    
13498

    
13499
var sortable = $.widget("ui.sortable", $.ui.mouse, {
13500
        version: "1.11.4",
13501
        widgetEventPrefix: "sort",
13502
        ready: false,
13503
        options: {
13504
                appendTo: "parent",
13505
                axis: false,
13506
                connectWith: false,
13507
                containment: false,
13508
                cursor: "auto",
13509
                cursorAt: false,
13510
                dropOnEmpty: true,
13511
                forcePlaceholderSize: false,
13512
                forceHelperSize: false,
13513
                grid: false,
13514
                handle: false,
13515
                helper: "original",
13516
                items: "> *",
13517
                opacity: false,
13518
                placeholder: false,
13519
                revert: false,
13520
                scroll: true,
13521
                scrollSensitivity: 20,
13522
                scrollSpeed: 20,
13523
                scope: "default",
13524
                tolerance: "intersect",
13525
                zIndex: 1000,
13526

    
13527
                // callbacks
13528
                activate: null,
13529
                beforeStop: null,
13530
                change: null,
13531
                deactivate: null,
13532
                out: null,
13533
                over: null,
13534
                receive: null,
13535
                remove: null,
13536
                sort: null,
13537
                start: null,
13538
                stop: null,
13539
                update: null
13540
        },
13541

    
13542
        _isOverAxis: function( x, reference, size ) {
13543
                return ( x >= reference ) && ( x < ( reference + size ) );
13544
        },
13545

    
13546
        _isFloating: function( item ) {
13547
                return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
13548
        },
13549

    
13550
        _create: function() {
13551
                this.containerCache = {};
13552
                this.element.addClass("ui-sortable");
13553

    
13554
                //Get the items
13555
                this.refresh();
13556

    
13557
                //Let's determine the parent's offset
13558
                this.offset = this.element.offset();
13559

    
13560
                //Initialize mouse events for interaction
13561
                this._mouseInit();
13562

    
13563
                this._setHandleClassName();
13564

    
13565
                //We're ready to go
13566
                this.ready = true;
13567

    
13568
        },
13569

    
13570
        _setOption: function( key, value ) {
13571
                this._super( key, value );
13572

    
13573
                if ( key === "handle" ) {
13574
                        this._setHandleClassName();
13575
                }
13576
        },
13577

    
13578
        _setHandleClassName: function() {
13579
                this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
13580
                $.each( this.items, function() {
13581
                        ( this.instance.options.handle ?
13582
                                this.item.find( this.instance.options.handle ) : this.item )
13583
                                .addClass( "ui-sortable-handle" );
13584
                });
13585
        },
13586

    
13587
        _destroy: function() {
13588
                this.element
13589
                        .removeClass( "ui-sortable ui-sortable-disabled" )
13590
                        .find( ".ui-sortable-handle" )
13591
                                .removeClass( "ui-sortable-handle" );
13592
                this._mouseDestroy();
13593

    
13594
                for ( var i = this.items.length - 1; i >= 0; i-- ) {
13595
                        this.items[i].item.removeData(this.widgetName + "-item");
13596
                }
13597

    
13598
                return this;
13599
        },
13600

    
13601
        _mouseCapture: function(event, overrideHandle) {
13602
                var currentItem = null,
13603
                        validHandle = false,
13604
                        that = this;
13605

    
13606
                if (this.reverting) {
13607
                        return false;
13608
                }
13609

    
13610
                if(this.options.disabled || this.options.type === "static") {
13611
                        return false;
13612
                }
13613

    
13614
                //We have to refresh the items data once first
13615
                this._refreshItems(event);
13616

    
13617
                //Find out if the clicked node (or one of its parents) is a actual item in this.items
13618
                $(event.target).parents().each(function() {
13619
                        if($.data(this, that.widgetName + "-item") === that) {
13620
                                currentItem = $(this);
13621
                                return false;
13622
                        }
13623
                });
13624
                if($.data(event.target, that.widgetName + "-item") === that) {
13625
                        currentItem = $(event.target);
13626
                }
13627

    
13628
                if(!currentItem) {
13629
                        return false;
13630
                }
13631
                if(this.options.handle && !overrideHandle) {
13632
                        $(this.options.handle, currentItem).find("*").addBack().each(function() {
13633
                                if(this === event.target) {
13634
                                        validHandle = true;
13635
                                }
13636
                        });
13637
                        if(!validHandle) {
13638
                                return false;
13639
                        }
13640
                }
13641

    
13642
                this.currentItem = currentItem;
13643
                this._removeCurrentsFromItems();
13644
                return true;
13645

    
13646
        },
13647

    
13648
        _mouseStart: function(event, overrideHandle, noActivation) {
13649

    
13650
                var i, body,
13651
                        o = this.options;
13652

    
13653
                this.currentContainer = this;
13654

    
13655
                //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
13656
                this.refreshPositions();
13657

    
13658
                //Create and append the visible helper
13659
                this.helper = this._createHelper(event);
13660

    
13661
                //Cache the helper size
13662
                this._cacheHelperProportions();
13663

    
13664
                /*
13665
                 * - Position generation -
13666
                 * This block generates everything position related - it's the core of draggables.
13667
                 */
13668

    
13669
                //Cache the margins of the original element
13670
                this._cacheMargins();
13671

    
13672
                //Get the next scrolling parent
13673
                this.scrollParent = this.helper.scrollParent();
13674

    
13675
                //The element's absolute position on the page minus margins
13676
                this.offset = this.currentItem.offset();
13677
                this.offset = {
13678
                        top: this.offset.top - this.margins.top,
13679
                        left: this.offset.left - this.margins.left
13680
                };
13681

    
13682
                $.extend(this.offset, {
13683
                        click: { //Where the click happened, relative to the element
13684
                                left: event.pageX - this.offset.left,
13685
                                top: event.pageY - this.offset.top
13686
                        },
13687
                        parent: this._getParentOffset(),
13688
                        relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
13689
                });
13690

    
13691
                // Only after we got the offset, we can change the helper's position to absolute
13692
                // TODO: Still need to figure out a way to make relative sorting possible
13693
                this.helper.css("position", "absolute");
13694
                this.cssPosition = this.helper.css("position");
13695

    
13696
                //Generate the original position
13697
                this.originalPosition = this._generatePosition(event);
13698
                this.originalPageX = event.pageX;
13699
                this.originalPageY = event.pageY;
13700

    
13701
                //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
13702
                (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
13703

    
13704
                //Cache the former DOM position
13705
                this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
13706

    
13707
                //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
13708
                if(this.helper[0] !== this.currentItem[0]) {
13709
                        this.currentItem.hide();
13710
                }
13711

    
13712
                //Create the placeholder
13713
                this._createPlaceholder();
13714

    
13715
                //Set a containment if given in the options
13716
                if(o.containment) {
13717
                        this._setContainment();
13718
                }
13719

    
13720
                if( o.cursor && o.cursor !== "auto" ) { // cursor option
13721
                        body = this.document.find( "body" );
13722

    
13723
                        // support: IE
13724
                        this.storedCursor = body.css( "cursor" );
13725
                        body.css( "cursor", o.cursor );
13726

    
13727
                        this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
13728
                }
13729

    
13730
                if(o.opacity) { // opacity option
13731
                        if (this.helper.css("opacity")) {
13732
                                this._storedOpacity = this.helper.css("opacity");
13733
                        }
13734
                        this.helper.css("opacity", o.opacity);
13735
                }
13736

    
13737
                if(o.zIndex) { // zIndex option
13738
                        if (this.helper.css("zIndex")) {
13739
                                this._storedZIndex = this.helper.css("zIndex");
13740
                        }
13741
                        this.helper.css("zIndex", o.zIndex);
13742
                }
13743

    
13744
                //Prepare scrolling
13745
                if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
13746
                        this.overflowOffset = this.scrollParent.offset();
13747
                }
13748

    
13749
                //Call callbacks
13750
                this._trigger("start", event, this._uiHash());
13751

    
13752
                //Recache the helper size
13753
                if(!this._preserveHelperProportions) {
13754
                        this._cacheHelperProportions();
13755
                }
13756

    
13757

    
13758
                //Post "activate" events to possible containers
13759
                if( !noActivation ) {
13760
                        for ( i = this.containers.length - 1; i >= 0; i-- ) {
13761
                                this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
13762
                        }
13763
                }
13764

    
13765
                //Prepare possible droppables
13766
                if($.ui.ddmanager) {
13767
                        $.ui.ddmanager.current = this;
13768
                }
13769

    
13770
                if ($.ui.ddmanager && !o.dropBehaviour) {
13771
                        $.ui.ddmanager.prepareOffsets(this, event);
13772
                }
13773

    
13774
                this.dragging = true;
13775

    
13776
                this.helper.addClass("ui-sortable-helper");
13777
                this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
13778
                return true;
13779

    
13780
        },
13781

    
13782
        _mouseDrag: function(event) {
13783
                var i, item, itemElement, intersection,
13784
                        o = this.options,
13785
                        scrolled = false;
13786

    
13787
                //Compute the helpers position
13788
                this.position = this._generatePosition(event);
13789
                this.positionAbs = this._convertPositionTo("absolute");
13790

    
13791
                if (!this.lastPositionAbs) {
13792
                        this.lastPositionAbs = this.positionAbs;
13793
                }
13794

    
13795
                //Do scrolling
13796
                if(this.options.scroll) {
13797
                        if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
13798

    
13799
                                if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
13800
                                        this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
13801
                                } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
13802
                                        this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
13803
                                }
13804

    
13805
                                if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
13806
                                        this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
13807
                                } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
13808
                                        this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
13809
                                }
13810

    
13811
                        } else {
13812

    
13813
                                if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
13814
                                        scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
13815
                                } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
13816
                                        scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
13817
                                }
13818

    
13819
                                if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
13820
                                        scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
13821
                                } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
13822
                                        scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
13823
                                }
13824

    
13825
                        }
13826

    
13827
                        if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
13828
                                $.ui.ddmanager.prepareOffsets(this, event);
13829
                        }
13830
                }
13831

    
13832
                //Regenerate the absolute position used for position checks
13833
                this.positionAbs = this._convertPositionTo("absolute");
13834

    
13835
                //Set the helper position
13836
                if(!this.options.axis || this.options.axis !== "y") {
13837
                        this.helper[0].style.left = this.position.left+"px";
13838
                }
13839
                if(!this.options.axis || this.options.axis !== "x") {
13840
                        this.helper[0].style.top = this.position.top+"px";
13841
                }
13842

    
13843
                //Rearrange
13844
                for (i = this.items.length - 1; i >= 0; i--) {
13845

    
13846
                        //Cache variables and intersection, continue if no intersection
13847
                        item = this.items[i];
13848
                        itemElement = item.item[0];
13849
                        intersection = this._intersectsWithPointer(item);
13850
                        if (!intersection) {
13851
                                continue;
13852
                        }
13853

    
13854
                        // Only put the placeholder inside the current Container, skip all
13855
                        // items from other containers. This works because when moving
13856
                        // an item from one container to another the
13857
                        // currentContainer is switched before the placeholder is moved.
13858
                        //
13859
                        // Without this, moving items in "sub-sortables" can cause
13860
                        // the placeholder to jitter between the outer and inner container.
13861
                        if (item.instance !== this.currentContainer) {
13862
                                continue;
13863
                        }
13864

    
13865
                        // cannot intersect with itself
13866
                        // no useless actions that have been done before
13867
                        // no action if the item moved is the parent of the item checked
13868
                        if (itemElement !== this.currentItem[0] &&
13869
                                this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
13870
                                !$.contains(this.placeholder[0], itemElement) &&
13871
                                (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
13872
                        ) {
13873

    
13874
                                this.direction = intersection === 1 ? "down" : "up";
13875

    
13876
                                if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
13877
                                        this._rearrange(event, item);
13878
                                } else {
13879
                                        break;
13880
                                }
13881

    
13882
                                this._trigger("change", event, this._uiHash());
13883
                                break;
13884
                        }
13885
                }
13886

    
13887
                //Post events to containers
13888
                this._contactContainers(event);
13889

    
13890
                //Interconnect with droppables
13891
                if($.ui.ddmanager) {
13892
                        $.ui.ddmanager.drag(this, event);
13893
                }
13894

    
13895
                //Call callbacks
13896
                this._trigger("sort", event, this._uiHash());
13897

    
13898
                this.lastPositionAbs = this.positionAbs;
13899
                return false;
13900

    
13901
        },
13902

    
13903
        _mouseStop: function(event, noPropagation) {
13904

    
13905
                if(!event) {
13906
                        return;
13907
                }
13908

    
13909
                //If we are using droppables, inform the manager about the drop
13910
                if ($.ui.ddmanager && !this.options.dropBehaviour) {
13911
                        $.ui.ddmanager.drop(this, event);
13912
                }
13913

    
13914
                if(this.options.revert) {
13915
                        var that = this,
13916
                                cur = this.placeholder.offset(),
13917
                                axis = this.options.axis,
13918
                                animation = {};
13919

    
13920
                        if ( !axis || axis === "x" ) {
13921
                                animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
13922
                        }
13923
                        if ( !axis || axis === "y" ) {
13924
                                animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
13925
                        }
13926
                        this.reverting = true;
13927
                        $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
13928
                                that._clear(event);
13929
                        });
13930
                } else {
13931
                        this._clear(event, noPropagation);
13932
                }
13933

    
13934
                return false;
13935

    
13936
        },
13937

    
13938
        cancel: function() {
13939

    
13940
                if(this.dragging) {
13941

    
13942
                        this._mouseUp({ target: null });
13943

    
13944
                        if(this.options.helper === "original") {
13945
                                this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
13946
                        } else {
13947
                                this.currentItem.show();
13948
                        }
13949

    
13950
                        //Post deactivating events to containers
13951
                        for (var i = this.containers.length - 1; i >= 0; i--){
13952
                                this.containers[i]._trigger("deactivate", null, this._uiHash(this));
13953
                                if(this.containers[i].containerCache.over) {
13954
                                        this.containers[i]._trigger("out", null, this._uiHash(this));
13955
                                        this.containers[i].containerCache.over = 0;
13956
                                }
13957
                        }
13958

    
13959
                }
13960

    
13961
                if (this.placeholder) {
13962
                        //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
13963
                        if(this.placeholder[0].parentNode) {
13964
                                this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
13965
                        }
13966
                        if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
13967
                                this.helper.remove();
13968
                        }
13969

    
13970
                        $.extend(this, {
13971
                                helper: null,
13972
                                dragging: false,
13973
                                reverting: false,
13974
                                _noFinalSort: null
13975
                        });
13976

    
13977
                        if(this.domPosition.prev) {
13978
                                $(this.domPosition.prev).after(this.currentItem);
13979
                        } else {
13980
                                $(this.domPosition.parent).prepend(this.currentItem);
13981
                        }
13982
                }
13983

    
13984
                return this;
13985

    
13986
        },
13987

    
13988
        serialize: function(o) {
13989

    
13990
                var items = this._getItemsAsjQuery(o && o.connected),
13991
                        str = [];
13992
                o = o || {};
13993

    
13994
                $(items).each(function() {
13995
                        var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
13996
                        if (res) {
13997
                                str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
13998
                        }
13999
                });
14000

    
14001
                if(!str.length && o.key) {
14002
                        str.push(o.key + "=");
14003
                }
14004

    
14005
                return str.join("&");
14006

    
14007
        },
14008

    
14009
        toArray: function(o) {
14010

    
14011
                var items = this._getItemsAsjQuery(o && o.connected),
14012
                        ret = [];
14013

    
14014
                o = o || {};
14015

    
14016
                items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
14017
                return ret;
14018

    
14019
        },
14020

    
14021
        /* Be careful with the following core functions */
14022
        _intersectsWith: function(item) {
14023

    
14024
                var x1 = this.positionAbs.left,
14025
                        x2 = x1 + this.helperProportions.width,
14026
                        y1 = this.positionAbs.top,
14027
                        y2 = y1 + this.helperProportions.height,
14028
                        l = item.left,
14029
                        r = l + item.width,
14030
                        t = item.top,
14031
                        b = t + item.height,
14032
                        dyClick = this.offset.click.top,
14033
                        dxClick = this.offset.click.left,
14034
                        isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
14035
                        isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
14036
                        isOverElement = isOverElementHeight && isOverElementWidth;
14037

    
14038
                if ( this.options.tolerance === "pointer" ||
14039
                        this.options.forcePointerForContainers ||
14040
                        (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
14041
                ) {
14042
                        return isOverElement;
14043
                } else {
14044

    
14045
                        return (l < x1 + (this.helperProportions.width / 2) && // Right Half
14046
                                x2 - (this.helperProportions.width / 2) < r && // Left Half
14047
                                t < y1 + (this.helperProportions.height / 2) && // Bottom Half
14048
                                y2 - (this.helperProportions.height / 2) < b ); // Top Half
14049

    
14050
                }
14051
        },
14052

    
14053
        _intersectsWithPointer: function(item) {
14054

    
14055
                var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
14056
                        isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
14057
                        isOverElement = isOverElementHeight && isOverElementWidth,
14058
                        verticalDirection = this._getDragVerticalDirection(),
14059
                        horizontalDirection = this._getDragHorizontalDirection();
14060

    
14061
                if (!isOverElement) {
14062
                        return false;
14063
                }
14064

    
14065
                return this.floating ?
14066
                        ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
14067
                        : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
14068

    
14069
        },
14070

    
14071
        _intersectsWithSides: function(item) {
14072

    
14073
                var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
14074
                        isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
14075
                        verticalDirection = this._getDragVerticalDirection(),
14076
                        horizontalDirection = this._getDragHorizontalDirection();
14077

    
14078
                if (this.floating && horizontalDirection) {
14079
                        return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
14080
                } else {
14081
                        return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
14082
                }
14083

    
14084
        },
14085

    
14086
        _getDragVerticalDirection: function() {
14087
                var delta = this.positionAbs.top - this.lastPositionAbs.top;
14088
                return delta !== 0 && (delta > 0 ? "down" : "up");
14089
        },
14090

    
14091
        _getDragHorizontalDirection: function() {
14092
                var delta = this.positionAbs.left - this.lastPositionAbs.left;
14093
                return delta !== 0 && (delta > 0 ? "right" : "left");
14094
        },
14095

    
14096
        refresh: function(event) {
14097
                this._refreshItems(event);
14098
                this._setHandleClassName();
14099
                this.refreshPositions();
14100
                return this;
14101
        },
14102

    
14103
        _connectWith: function() {
14104
                var options = this.options;
14105
                return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
14106
        },
14107

    
14108
        _getItemsAsjQuery: function(connected) {
14109

    
14110
                var i, j, cur, inst,
14111
                        items = [],
14112
                        queries = [],
14113
                        connectWith = this._connectWith();
14114

    
14115
                if(connectWith && connected) {
14116
                        for (i = connectWith.length - 1; i >= 0; i--){
14117
                                cur = $(connectWith[i], this.document[0]);
14118
                                for ( j = cur.length - 1; j >= 0; j--){
14119
                                        inst = $.data(cur[j], this.widgetFullName);
14120
                                        if(inst && inst !== this && !inst.options.disabled) {
14121
                                                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]);
14122
                                        }
14123
                                }
14124
                        }
14125
                }
14126

    
14127
                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]);
14128

    
14129
                function addItems() {
14130
                        items.push( this );
14131
                }
14132
                for (i = queries.length - 1; i >= 0; i--){
14133
                        queries[i][0].each( addItems );
14134
                }
14135

    
14136
                return $(items);
14137

    
14138
        },
14139

    
14140
        _removeCurrentsFromItems: function() {
14141

    
14142
                var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
14143

    
14144
                this.items = $.grep(this.items, function (item) {
14145
                        for (var j=0; j < list.length; j++) {
14146
                                if(list[j] === item.item[0]) {
14147
                                        return false;
14148
                                }
14149
                        }
14150
                        return true;
14151
                });
14152

    
14153
        },
14154

    
14155
        _refreshItems: function(event) {
14156

    
14157
                this.items = [];
14158
                this.containers = [this];
14159

    
14160
                var i, j, cur, inst, targetData, _queries, item, queriesLength,
14161
                        items = this.items,
14162
                        queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
14163
                        connectWith = this._connectWith();
14164

    
14165
                if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
14166
                        for (i = connectWith.length - 1; i >= 0; i--){
14167
                                cur = $(connectWith[i], this.document[0]);
14168
                                for (j = cur.length - 1; j >= 0; j--){
14169
                                        inst = $.data(cur[j], this.widgetFullName);
14170
                                        if(inst && inst !== this && !inst.options.disabled) {
14171
                                                queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
14172
                                                this.containers.push(inst);
14173
                                        }
14174
                                }
14175
                        }
14176
                }
14177

    
14178
                for (i = queries.length - 1; i >= 0; i--) {
14179
                        targetData = queries[i][1];
14180
                        _queries = queries[i][0];
14181

    
14182
                        for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
14183
                                item = $(_queries[j]);
14184

    
14185
                                item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
14186

    
14187
                                items.push({
14188
                                        item: item,
14189
                                        instance: targetData,
14190
                                        width: 0, height: 0,
14191
                                        left: 0, top: 0
14192
                                });
14193
                        }
14194
                }
14195

    
14196
        },
14197

    
14198
        refreshPositions: function(fast) {
14199

    
14200
                // Determine whether items are being displayed horizontally
14201
                this.floating = this.items.length ?
14202
                        this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
14203
                        false;
14204

    
14205
                //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
14206
                if(this.offsetParent && this.helper) {
14207
                        this.offset.parent = this._getParentOffset();
14208
                }
14209

    
14210
                var i, item, t, p;
14211

    
14212
                for (i = this.items.length - 1; i >= 0; i--){
14213
                        item = this.items[i];
14214

    
14215
                        //We ignore calculating positions of all connected containers when we're not over them
14216
                        if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
14217
                                continue;
14218
                        }
14219

    
14220
                        t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
14221

    
14222
                        if (!fast) {
14223
                                item.width = t.outerWidth();
14224
                                item.height = t.outerHeight();
14225
                        }
14226

    
14227
                        p = t.offset();
14228
                        item.left = p.left;
14229
                        item.top = p.top;
14230
                }
14231

    
14232
                if(this.options.custom && this.options.custom.refreshContainers) {
14233
                        this.options.custom.refreshContainers.call(this);
14234
                } else {
14235
                        for (i = this.containers.length - 1; i >= 0; i--){
14236
                                p = this.containers[i].element.offset();
14237
                                this.containers[i].containerCache.left = p.left;
14238
                                this.containers[i].containerCache.top = p.top;
14239
                                this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
14240
                                this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
14241
                        }
14242
                }
14243

    
14244
                return this;
14245
        },
14246

    
14247
        _createPlaceholder: function(that) {
14248
                that = that || this;
14249
                var className,
14250
                        o = that.options;
14251

    
14252
                if(!o.placeholder || o.placeholder.constructor === String) {
14253
                        className = o.placeholder;
14254
                        o.placeholder = {
14255
                                element: function() {
14256

    
14257
                                        var nodeName = that.currentItem[0].nodeName.toLowerCase(),
14258
                                                element = $( "<" + nodeName + ">", that.document[0] )
14259
                                                        .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
14260
                                                        .removeClass("ui-sortable-helper");
14261

    
14262
                                        if ( nodeName === "tbody" ) {
14263
                                                that._createTrPlaceholder(
14264
                                                        that.currentItem.find( "tr" ).eq( 0 ),
14265
                                                        $( "<tr>", that.document[ 0 ] ).appendTo( element )
14266
                                                );
14267
                                        } else if ( nodeName === "tr" ) {
14268
                                                that._createTrPlaceholder( that.currentItem, element );
14269
                                        } else if ( nodeName === "img" ) {
14270
                                                element.attr( "src", that.currentItem.attr( "src" ) );
14271
                                        }
14272

    
14273
                                        if ( !className ) {
14274
                                                element.css( "visibility", "hidden" );
14275
                                        }
14276

    
14277
                                        return element;
14278
                                },
14279
                                update: function(container, p) {
14280

    
14281
                                        // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
14282
                                        // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
14283
                                        if(className && !o.forcePlaceholderSize) {
14284
                                                return;
14285
                                        }
14286

    
14287
                                        //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
14288
                                        if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
14289
                                        if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
14290
                                }
14291
                        };
14292
                }
14293

    
14294
                //Create the placeholder
14295
                that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
14296

    
14297
                //Append it after the actual current item
14298
                that.currentItem.after(that.placeholder);
14299

    
14300
                //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
14301
                o.placeholder.update(that, that.placeholder);
14302

    
14303
        },
14304

    
14305
        _createTrPlaceholder: function( sourceTr, targetTr ) {
14306
                var that = this;
14307

    
14308
                sourceTr.children().each(function() {
14309
                        $( "<td>&#160;</td>", that.document[ 0 ] )
14310
                                .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
14311
                                .appendTo( targetTr );
14312
                });
14313
        },
14314

    
14315
        _contactContainers: function(event) {
14316
                var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
14317
                        innermostContainer = null,
14318
                        innermostIndex = null;
14319

    
14320
                // get innermost container that intersects with item
14321
                for (i = this.containers.length - 1; i >= 0; i--) {
14322

    
14323
                        // never consider a container that's located within the item itself
14324
                        if($.contains(this.currentItem[0], this.containers[i].element[0])) {
14325
                                continue;
14326
                        }
14327

    
14328
                        if(this._intersectsWith(this.containers[i].containerCache)) {
14329

    
14330
                                // if we've already found a container and it's more "inner" than this, then continue
14331
                                if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
14332
                                        continue;
14333
                                }
14334

    
14335
                                innermostContainer = this.containers[i];
14336
                                innermostIndex = i;
14337

    
14338
                        } else {
14339
                                // container doesn't intersect. trigger "out" event if necessary
14340
                                if(this.containers[i].containerCache.over) {
14341
                                        this.containers[i]._trigger("out", event, this._uiHash(this));
14342
                                        this.containers[i].containerCache.over = 0;
14343
                                }
14344
                        }
14345

    
14346
                }
14347

    
14348
                // if no intersecting containers found, return
14349
                if(!innermostContainer) {
14350
                        return;
14351
                }
14352

    
14353
                // move the item into the container if it's not there already
14354
                if(this.containers.length === 1) {
14355
                        if (!this.containers[innermostIndex].containerCache.over) {
14356
                                this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14357
                                this.containers[innermostIndex].containerCache.over = 1;
14358
                        }
14359
                } else {
14360

    
14361
                        //When entering a new container, we will find the item with the least distance and append our item near it
14362
                        dist = 10000;
14363
                        itemWithLeastDistance = null;
14364
                        floating = innermostContainer.floating || this._isFloating(this.currentItem);
14365
                        posProperty = floating ? "left" : "top";
14366
                        sizeProperty = floating ? "width" : "height";
14367
                        axis = floating ? "clientX" : "clientY";
14368

    
14369
                        for (j = this.items.length - 1; j >= 0; j--) {
14370
                                if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
14371
                                        continue;
14372
                                }
14373
                                if(this.items[j].item[0] === this.currentItem[0]) {
14374
                                        continue;
14375
                                }
14376

    
14377
                                cur = this.items[j].item.offset()[posProperty];
14378
                                nearBottom = false;
14379
                                if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
14380
                                        nearBottom = true;
14381
                                }
14382

    
14383
                                if ( Math.abs( event[ axis ] - cur ) < dist ) {
14384
                                        dist = Math.abs( event[ axis ] - cur );
14385
                                        itemWithLeastDistance = this.items[ j ];
14386
                                        this.direction = nearBottom ? "up": "down";
14387
                                }
14388
                        }
14389

    
14390
                        //Check if dropOnEmpty is enabled
14391
                        if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
14392
                                return;
14393
                        }
14394

    
14395
                        if(this.currentContainer === this.containers[innermostIndex]) {
14396
                                if ( !this.currentContainer.containerCache.over ) {
14397
                                        this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
14398
                                        this.currentContainer.containerCache.over = 1;
14399
                                }
14400
                                return;
14401
                        }
14402

    
14403
                        itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
14404
                        this._trigger("change", event, this._uiHash());
14405
                        this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
14406
                        this.currentContainer = this.containers[innermostIndex];
14407

    
14408
                        //Update the placeholder
14409
                        this.options.placeholder.update(this.currentContainer, this.placeholder);
14410

    
14411
                        this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14412
                        this.containers[innermostIndex].containerCache.over = 1;
14413
                }
14414

    
14415

    
14416
        },
14417

    
14418
        _createHelper: function(event) {
14419

    
14420
                var o = this.options,
14421
                        helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
14422

    
14423
                //Add the helper to the DOM if that didn't happen already
14424
                if(!helper.parents("body").length) {
14425
                        $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
14426
                }
14427

    
14428
                if(helper[0] === this.currentItem[0]) {
14429
                        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") };
14430
                }
14431

    
14432
                if(!helper[0].style.width || o.forceHelperSize) {
14433
                        helper.width(this.currentItem.width());
14434
                }
14435
                if(!helper[0].style.height || o.forceHelperSize) {
14436
                        helper.height(this.currentItem.height());
14437
                }
14438

    
14439
                return helper;
14440

    
14441
        },
14442

    
14443
        _adjustOffsetFromHelper: function(obj) {
14444
                if (typeof obj === "string") {
14445
                        obj = obj.split(" ");
14446
                }
14447
                if ($.isArray(obj)) {
14448
                        obj = {left: +obj[0], top: +obj[1] || 0};
14449
                }
14450
                if ("left" in obj) {
14451
                        this.offset.click.left = obj.left + this.margins.left;
14452
                }
14453
                if ("right" in obj) {
14454
                        this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
14455
                }
14456
                if ("top" in obj) {
14457
                        this.offset.click.top = obj.top + this.margins.top;
14458
                }
14459
                if ("bottom" in obj) {
14460
                        this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
14461
                }
14462
        },
14463

    
14464
        _getParentOffset: function() {
14465

    
14466

    
14467
                //Get the offsetParent and cache its position
14468
                this.offsetParent = this.helper.offsetParent();
14469
                var po = this.offsetParent.offset();
14470

    
14471
                // This is a special case where we need to modify a offset calculated on start, since the following happened:
14472
                // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
14473
                // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
14474
                //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
14475
                if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
14476
                        po.left += this.scrollParent.scrollLeft();
14477
                        po.top += this.scrollParent.scrollTop();
14478
                }
14479

    
14480
                // This needs to be actually done for all browsers, since pageX/pageY includes this information
14481
                // with an ugly IE fix
14482
                if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
14483
                        po = { top: 0, left: 0 };
14484
                }
14485

    
14486
                return {
14487
                        top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
14488
                        left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
14489
                };
14490

    
14491
        },
14492

    
14493
        _getRelativeOffset: function() {
14494

    
14495
                if(this.cssPosition === "relative") {
14496
                        var p = this.currentItem.position();
14497
                        return {
14498
                                top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
14499
                                left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
14500
                        };
14501
                } else {
14502
                        return { top: 0, left: 0 };
14503
                }
14504

    
14505
        },
14506

    
14507
        _cacheMargins: function() {
14508
                this.margins = {
14509
                        left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
14510
                        top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
14511
                };
14512
        },
14513

    
14514
        _cacheHelperProportions: function() {
14515
                this.helperProportions = {
14516
                        width: this.helper.outerWidth(),
14517
                        height: this.helper.outerHeight()
14518
                };
14519
        },
14520

    
14521
        _setContainment: function() {
14522

    
14523
                var ce, co, over,
14524
                        o = this.options;
14525
                if(o.containment === "parent") {
14526
                        o.containment = this.helper[0].parentNode;
14527
                }
14528
                if(o.containment === "document" || o.containment === "window") {
14529
                        this.containment = [
14530
                                0 - this.offset.relative.left - this.offset.parent.left,
14531
                                0 - this.offset.relative.top - this.offset.parent.top,
14532
                                o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
14533
                                (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
14534
                        ];
14535
                }
14536

    
14537
                if(!(/^(document|window|parent)$/).test(o.containment)) {
14538
                        ce = $(o.containment)[0];
14539
                        co = $(o.containment).offset();
14540
                        over = ($(ce).css("overflow") !== "hidden");
14541

    
14542
                        this.containment = [
14543
                                co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
14544
                                co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
14545
                                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,
14546
                                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
14547
                        ];
14548
                }
14549

    
14550
        },
14551

    
14552
        _convertPositionTo: function(d, pos) {
14553

    
14554
                if(!pos) {
14555
                        pos = this.position;
14556
                }
14557
                var mod = d === "absolute" ? 1 : -1,
14558
                        scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
14559
                        scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14560

    
14561
                return {
14562
                        top: (
14563
                                pos.top        +                                                                                                                                // The absolute mouse position
14564
                                this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
14565
                                this.offset.parent.top * mod -                                                                                        // The offsetParent's offset without borders (offset + border)
14566
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
14567
                        ),
14568
                        left: (
14569
                                pos.left +                                                                                                                                // The absolute mouse position
14570
                                this.offset.relative.left * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
14571
                                this.offset.parent.left * mod        -                                                                                // The offsetParent's offset without borders (offset + border)
14572
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
14573
                        )
14574
                };
14575

    
14576
        },
14577

    
14578
        _generatePosition: function(event) {
14579

    
14580
                var top, left,
14581
                        o = this.options,
14582
                        pageX = event.pageX,
14583
                        pageY = event.pageY,
14584
                        scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14585

    
14586
                // This is another very weird special case that only happens for relative elements:
14587
                // 1. If the css position is relative
14588
                // 2. and the scroll parent is the document or similar to the offset parent
14589
                // we have to refresh the relative offset during the scroll so there are no jumps
14590
                if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
14591
                        this.offset.relative = this._getRelativeOffset();
14592
                }
14593

    
14594
                /*
14595
                 * - Position constraining -
14596
                 * Constrain the position to a mix of grid, containment.
14597
                 */
14598

    
14599
                if(this.originalPosition) { //If we are not dragging yet, we won't check for options
14600

    
14601
                        if(this.containment) {
14602
                                if(event.pageX - this.offset.click.left < this.containment[0]) {
14603
                                        pageX = this.containment[0] + this.offset.click.left;
14604
                                }
14605
                                if(event.pageY - this.offset.click.top < this.containment[1]) {
14606
                                        pageY = this.containment[1] + this.offset.click.top;
14607
                                }
14608
                                if(event.pageX - this.offset.click.left > this.containment[2]) {
14609
                                        pageX = this.containment[2] + this.offset.click.left;
14610
                                }
14611
                                if(event.pageY - this.offset.click.top > this.containment[3]) {
14612
                                        pageY = this.containment[3] + this.offset.click.top;
14613
                                }
14614
                        }
14615

    
14616
                        if(o.grid) {
14617
                                top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
14618
                                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;
14619

    
14620
                                left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
14621
                                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;
14622
                        }
14623

    
14624
                }
14625

    
14626
                return {
14627
                        top: (
14628
                                pageY -                                                                                                                                // The absolute mouse position
14629
                                this.offset.click.top -                                                                                                        // Click offset (relative to the element)
14630
                                this.offset.relative.top        -                                                                                        // Only for relative positioned nodes: Relative offset from element to offset parent
14631
                                this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
14632
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
14633
                        ),
14634
                        left: (
14635
                                pageX -                                                                                                                                // The absolute mouse position
14636
                                this.offset.click.left -                                                                                                // Click offset (relative to the element)
14637
                                this.offset.relative.left        -                                                                                        // Only for relative positioned nodes: Relative offset from element to offset parent
14638
                                this.offset.parent.left +                                                                                                // The offsetParent's offset without borders (offset + border)
14639
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
14640
                        )
14641
                };
14642

    
14643
        },
14644

    
14645
        _rearrange: function(event, i, a, hardRefresh) {
14646

    
14647
                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));
14648

    
14649
                //Various things done here to improve the performance:
14650
                // 1. we create a setTimeout, that calls refreshPositions
14651
                // 2. on the instance, we have a counter variable, that get's higher after every append
14652
                // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
14653
                // 4. this lets only the last addition to the timeout stack through
14654
                this.counter = this.counter ? ++this.counter : 1;
14655
                var counter = this.counter;
14656

    
14657
                this._delay(function() {
14658
                        if(counter === this.counter) {
14659
                                this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
14660
                        }
14661
                });
14662

    
14663
        },
14664

    
14665
        _clear: function(event, noPropagation) {
14666

    
14667
                this.reverting = false;
14668
                // We delay all events that have to be triggered to after the point where the placeholder has been removed and
14669
                // everything else normalized again
14670
                var i,
14671
                        delayedTriggers = [];
14672

    
14673
                // We first have to update the dom position of the actual currentItem
14674
                // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
14675
                if(!this._noFinalSort && this.currentItem.parent().length) {
14676
                        this.placeholder.before(this.currentItem);
14677
                }
14678
                this._noFinalSort = null;
14679

    
14680
                if(this.helper[0] === this.currentItem[0]) {
14681
                        for(i in this._storedCSS) {
14682
                                if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
14683
                                        this._storedCSS[i] = "";
14684
                                }
14685
                        }
14686
                        this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
14687
                } else {
14688
                        this.currentItem.show();
14689
                }
14690

    
14691
                if(this.fromOutside && !noPropagation) {
14692
                        delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
14693
                }
14694
                if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
14695
                        delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
14696
                }
14697

    
14698
                // Check if the items Container has Changed and trigger appropriate
14699
                // events.
14700
                if (this !== this.currentContainer) {
14701
                        if(!noPropagation) {
14702
                                delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
14703
                                delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
14704
                                delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
14705
                        }
14706
                }
14707

    
14708

    
14709
                //Post events to containers
14710
                function delayEvent( type, instance, container ) {
14711
                        return function( event ) {
14712
                                container._trigger( type, event, instance._uiHash( instance ) );
14713
                        };
14714
                }
14715
                for (i = this.containers.length - 1; i >= 0; i--){
14716
                        if (!noPropagation) {
14717
                                delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
14718
                        }
14719
                        if(this.containers[i].containerCache.over) {
14720
                                delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
14721
                                this.containers[i].containerCache.over = 0;
14722
                        }
14723
                }
14724

    
14725
                //Do what was originally in plugins
14726
                if ( this.storedCursor ) {
14727
                        this.document.find( "body" ).css( "cursor", this.storedCursor );
14728
                        this.storedStylesheet.remove();
14729
                }
14730
                if(this._storedOpacity) {
14731
                        this.helper.css("opacity", this._storedOpacity);
14732
                }
14733
                if(this._storedZIndex) {
14734
                        this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
14735
                }
14736

    
14737
                this.dragging = false;
14738

    
14739
                if(!noPropagation) {
14740
                        this._trigger("beforeStop", event, this._uiHash());
14741
                }
14742

    
14743
                //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
14744
                this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
14745

    
14746
                if ( !this.cancelHelperRemoval ) {
14747
                        if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
14748
                                this.helper.remove();
14749
                        }
14750
                        this.helper = null;
14751
                }
14752

    
14753
                if(!noPropagation) {
14754
                        for (i=0; i < delayedTriggers.length; i++) {
14755
                                delayedTriggers[i].call(this, event);
14756
                        } //Trigger all delayed events
14757
                        this._trigger("stop", event, this._uiHash());
14758
                }
14759

    
14760
                this.fromOutside = false;
14761
                return !this.cancelHelperRemoval;
14762

    
14763
        },
14764

    
14765
        _trigger: function() {
14766
                if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
14767
                        this.cancel();
14768
                }
14769
        },
14770

    
14771
        _uiHash: function(_inst) {
14772
                var inst = _inst || this;
14773
                return {
14774
                        helper: inst.helper,
14775
                        placeholder: inst.placeholder || $([]),
14776
                        position: inst.position,
14777
                        originalPosition: inst.originalPosition,
14778
                        offset: inst.positionAbs,
14779
                        item: inst.currentItem,
14780
                        sender: _inst ? _inst.element : null
14781
                };
14782
        }
14783

    
14784
});
14785

    
14786

    
14787
/*!
14788
 * jQuery UI Spinner 1.11.4
14789
 * http://jqueryui.com
14790
 *
14791
 * Copyright jQuery Foundation and other contributors
14792
 * Released under the MIT license.
14793
 * http://jquery.org/license
14794
 *
14795
 * http://api.jqueryui.com/spinner/
14796
 */
14797

    
14798

    
14799
function spinner_modifier( fn ) {
14800
        return function() {
14801
                var previous = this.element.val();
14802
                fn.apply( this, arguments );
14803
                this._refresh();
14804
                if ( previous !== this.element.val() ) {
14805
                        this._trigger( "change" );
14806
                }
14807
        };
14808
}
14809

    
14810
var spinner = $.widget( "ui.spinner", {
14811
        version: "1.11.4",
14812
        defaultElement: "<input>",
14813
        widgetEventPrefix: "spin",
14814
        options: {
14815
                culture: null,
14816
                icons: {
14817
                        down: "ui-icon-triangle-1-s",
14818
                        up: "ui-icon-triangle-1-n"
14819
                },
14820
                incremental: true,
14821
                max: null,
14822
                min: null,
14823
                numberFormat: null,
14824
                page: 10,
14825
                step: 1,
14826

    
14827
                change: null,
14828
                spin: null,
14829
                start: null,
14830
                stop: null
14831
        },
14832

    
14833
        _create: function() {
14834
                // handle string values that need to be parsed
14835
                this._setOption( "max", this.options.max );
14836
                this._setOption( "min", this.options.min );
14837
                this._setOption( "step", this.options.step );
14838

    
14839
                // Only format if there is a value, prevents the field from being marked
14840
                // as invalid in Firefox, see #9573.
14841
                if ( this.value() !== "" ) {
14842
                        // Format the value, but don't constrain.
14843
                        this._value( this.element.val(), true );
14844
                }
14845

    
14846
                this._draw();
14847
                this._on( this._events );
14848
                this._refresh();
14849

    
14850
                // turning off autocomplete prevents the browser from remembering the
14851
                // value when navigating through history, so we re-enable autocomplete
14852
                // if the page is unloaded before the widget is destroyed. #7790
14853
                this._on( this.window, {
14854
                        beforeunload: function() {
14855
                                this.element.removeAttr( "autocomplete" );
14856
                        }
14857
                });
14858
        },
14859

    
14860
        _getCreateOptions: function() {
14861
                var options = {},
14862
                        element = this.element;
14863

    
14864
                $.each( [ "min", "max", "step" ], function( i, option ) {
14865
                        var value = element.attr( option );
14866
                        if ( value !== undefined && value.length ) {
14867
                                options[ option ] = value;
14868
                        }
14869
                });
14870

    
14871
                return options;
14872
        },
14873

    
14874
        _events: {
14875
                keydown: function( event ) {
14876
                        if ( this._start( event ) && this._keydown( event ) ) {
14877
                                event.preventDefault();
14878
                        }
14879
                },
14880
                keyup: "_stop",
14881
                focus: function() {
14882
                        this.previous = this.element.val();
14883
                },
14884
                blur: function( event ) {
14885
                        if ( this.cancelBlur ) {
14886
                                delete this.cancelBlur;
14887
                                return;
14888
                        }
14889

    
14890
                        this._stop();
14891
                        this._refresh();
14892
                        if ( this.previous !== this.element.val() ) {
14893
                                this._trigger( "change", event );
14894
                        }
14895
                },
14896
                mousewheel: function( event, delta ) {
14897
                        if ( !delta ) {
14898
                                return;
14899
                        }
14900
                        if ( !this.spinning && !this._start( event ) ) {
14901
                                return false;
14902
                        }
14903

    
14904
                        this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
14905
                        clearTimeout( this.mousewheelTimer );
14906
                        this.mousewheelTimer = this._delay(function() {
14907
                                if ( this.spinning ) {
14908
                                        this._stop( event );
14909
                                }
14910
                        }, 100 );
14911
                        event.preventDefault();
14912
                },
14913
                "mousedown .ui-spinner-button": function( event ) {
14914
                        var previous;
14915

    
14916
                        // We never want the buttons to have focus; whenever the user is
14917
                        // interacting with the spinner, the focus should be on the input.
14918
                        // If the input is focused then this.previous is properly set from
14919
                        // when the input first received focus. If the input is not focused
14920
                        // then we need to set this.previous based on the value before spinning.
14921
                        previous = this.element[0] === this.document[0].activeElement ?
14922
                                this.previous : this.element.val();
14923
                        function checkFocus() {
14924
                                var isActive = this.element[0] === this.document[0].activeElement;
14925
                                if ( !isActive ) {
14926
                                        this.element.focus();
14927
                                        this.previous = previous;
14928
                                        // support: IE
14929
                                        // IE sets focus asynchronously, so we need to check if focus
14930
                                        // moved off of the input because the user clicked on the button.
14931
                                        this._delay(function() {
14932
                                                this.previous = previous;
14933
                                        });
14934
                                }
14935
                        }
14936

    
14937
                        // ensure focus is on (or stays on) the text field
14938
                        event.preventDefault();
14939
                        checkFocus.call( this );
14940

    
14941
                        // support: IE
14942
                        // IE doesn't prevent moving focus even with event.preventDefault()
14943
                        // so we set a flag to know when we should ignore the blur event
14944
                        // and check (again) if focus moved off of the input.
14945
                        this.cancelBlur = true;
14946
                        this._delay(function() {
14947
                                delete this.cancelBlur;
14948
                                checkFocus.call( this );
14949
                        });
14950

    
14951
                        if ( this._start( event ) === false ) {
14952
                                return;
14953
                        }
14954

    
14955
                        this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14956
                },
14957
                "mouseup .ui-spinner-button": "_stop",
14958
                "mouseenter .ui-spinner-button": function( event ) {
14959
                        // button will add ui-state-active if mouse was down while mouseleave and kept down
14960
                        if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
14961
                                return;
14962
                        }
14963

    
14964
                        if ( this._start( event ) === false ) {
14965
                                return false;
14966
                        }
14967
                        this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14968
                },
14969
                // TODO: do we really want to consider this a stop?
14970
                // shouldn't we just stop the repeater and wait until mouseup before
14971
                // we trigger the stop event?
14972
                "mouseleave .ui-spinner-button": "_stop"
14973
        },
14974

    
14975
        _draw: function() {
14976
                var uiSpinner = this.uiSpinner = this.element
14977
                        .addClass( "ui-spinner-input" )
14978
                        .attr( "autocomplete", "off" )
14979
                        .wrap( this._uiSpinnerHtml() )
14980
                        .parent()
14981
                                // add buttons
14982
                                .append( this._buttonHtml() );
14983

    
14984
                this.element.attr( "role", "spinbutton" );
14985

    
14986
                // button bindings
14987
                this.buttons = uiSpinner.find( ".ui-spinner-button" )
14988
                        .attr( "tabIndex", -1 )
14989
                        .button()
14990
                        .removeClass( "ui-corner-all" );
14991

    
14992
                // IE 6 doesn't understand height: 50% for the buttons
14993
                // unless the wrapper has an explicit height
14994
                if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
14995
                                uiSpinner.height() > 0 ) {
14996
                        uiSpinner.height( uiSpinner.height() );
14997
                }
14998

    
14999
                // disable spinner if element was already disabled
15000
                if ( this.options.disabled ) {
15001
                        this.disable();
15002
                }
15003
        },
15004

    
15005
        _keydown: function( event ) {
15006
                var options = this.options,
15007
                        keyCode = $.ui.keyCode;
15008

    
15009
                switch ( event.keyCode ) {
15010
                case keyCode.UP:
15011
                        this._repeat( null, 1, event );
15012
                        return true;
15013
                case keyCode.DOWN:
15014
                        this._repeat( null, -1, event );
15015
                        return true;
15016
                case keyCode.PAGE_UP:
15017
                        this._repeat( null, options.page, event );
15018
                        return true;
15019
                case keyCode.PAGE_DOWN:
15020
                        this._repeat( null, -options.page, event );
15021
                        return true;
15022
                }
15023

    
15024
                return false;
15025
        },
15026

    
15027
        _uiSpinnerHtml: function() {
15028
                return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
15029
        },
15030

    
15031
        _buttonHtml: function() {
15032
                return "" +
15033
                        "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
15034
                                "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
15035
                        "</a>" +
15036
                        "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
15037
                                "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
15038
                        "</a>";
15039
        },
15040

    
15041
        _start: function( event ) {
15042
                if ( !this.spinning && this._trigger( "start", event ) === false ) {
15043
                        return false;
15044
                }
15045

    
15046
                if ( !this.counter ) {
15047
                        this.counter = 1;
15048
                }
15049
                this.spinning = true;
15050
                return true;
15051
        },
15052

    
15053
        _repeat: function( i, steps, event ) {
15054
                i = i || 500;
15055

    
15056
                clearTimeout( this.timer );
15057
                this.timer = this._delay(function() {
15058
                        this._repeat( 40, steps, event );
15059
                }, i );
15060

    
15061
                this._spin( steps * this.options.step, event );
15062
        },
15063

    
15064
        _spin: function( step, event ) {
15065
                var value = this.value() || 0;
15066

    
15067
                if ( !this.counter ) {
15068
                        this.counter = 1;
15069
                }
15070

    
15071
                value = this._adjustValue( value + step * this._increment( this.counter ) );
15072

    
15073
                if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
15074
                        this._value( value );
15075
                        this.counter++;
15076
                }
15077
        },
15078

    
15079
        _increment: function( i ) {
15080
                var incremental = this.options.incremental;
15081

    
15082
                if ( incremental ) {
15083
                        return $.isFunction( incremental ) ?
15084
                                incremental( i ) :
15085
                                Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
15086
                }
15087

    
15088
                return 1;
15089
        },
15090

    
15091
        _precision: function() {
15092
                var precision = this._precisionOf( this.options.step );
15093
                if ( this.options.min !== null ) {
15094
                        precision = Math.max( precision, this._precisionOf( this.options.min ) );
15095
                }
15096
                return precision;
15097
        },
15098

    
15099
        _precisionOf: function( num ) {
15100
                var str = num.toString(),
15101
                        decimal = str.indexOf( "." );
15102
                return decimal === -1 ? 0 : str.length - decimal - 1;
15103
        },
15104

    
15105
        _adjustValue: function( value ) {
15106
                var base, aboveMin,
15107
                        options = this.options;
15108

    
15109
                // make sure we're at a valid step
15110
                // - find out where we are relative to the base (min or 0)
15111
                base = options.min !== null ? options.min : 0;
15112
                aboveMin = value - base;
15113
                // - round to the nearest step
15114
                aboveMin = Math.round(aboveMin / options.step) * options.step;
15115
                // - rounding is based on 0, so adjust back to our base
15116
                value = base + aboveMin;
15117

    
15118
                // fix precision from bad JS floating point math
15119
                value = parseFloat( value.toFixed( this._precision() ) );
15120

    
15121
                // clamp the value
15122
                if ( options.max !== null && value > options.max) {
15123
                        return options.max;
15124
                }
15125
                if ( options.min !== null && value < options.min ) {
15126
                        return options.min;
15127
                }
15128

    
15129
                return value;
15130
        },
15131

    
15132
        _stop: function( event ) {
15133
                if ( !this.spinning ) {
15134
                        return;
15135
                }
15136

    
15137
                clearTimeout( this.timer );
15138
                clearTimeout( this.mousewheelTimer );
15139
                this.counter = 0;
15140
                this.spinning = false;
15141
                this._trigger( "stop", event );
15142
        },
15143

    
15144
        _setOption: function( key, value ) {
15145
                if ( key === "culture" || key === "numberFormat" ) {
15146
                        var prevValue = this._parse( this.element.val() );
15147
                        this.options[ key ] = value;
15148
                        this.element.val( this._format( prevValue ) );
15149
                        return;
15150
                }
15151

    
15152
                if ( key === "max" || key === "min" || key === "step" ) {
15153
                        if ( typeof value === "string" ) {
15154
                                value = this._parse( value );
15155
                        }
15156
                }
15157
                if ( key === "icons" ) {
15158
                        this.buttons.first().find( ".ui-icon" )
15159
                                .removeClass( this.options.icons.up )
15160
                                .addClass( value.up );
15161
                        this.buttons.last().find( ".ui-icon" )
15162
                                .removeClass( this.options.icons.down )
15163
                                .addClass( value.down );
15164
                }
15165

    
15166
                this._super( key, value );
15167

    
15168
                if ( key === "disabled" ) {
15169
                        this.widget().toggleClass( "ui-state-disabled", !!value );
15170
                        this.element.prop( "disabled", !!value );
15171
                        this.buttons.button( value ? "disable" : "enable" );
15172
                }
15173
        },
15174

    
15175
        _setOptions: spinner_modifier(function( options ) {
15176
                this._super( options );
15177
        }),
15178

    
15179
        _parse: function( val ) {
15180
                if ( typeof val === "string" && val !== "" ) {
15181
                        val = window.Globalize && this.options.numberFormat ?
15182
                                Globalize.parseFloat( val, 10, this.options.culture ) : +val;
15183
                }
15184
                return val === "" || isNaN( val ) ? null : val;
15185
        },
15186

    
15187
        _format: function( value ) {
15188
                if ( value === "" ) {
15189
                        return "";
15190
                }
15191
                return window.Globalize && this.options.numberFormat ?
15192
                        Globalize.format( value, this.options.numberFormat, this.options.culture ) :
15193
                        value;
15194
        },
15195

    
15196
        _refresh: function() {
15197
                this.element.attr({
15198
                        "aria-valuemin": this.options.min,
15199
                        "aria-valuemax": this.options.max,
15200
                        // TODO: what should we do with values that can't be parsed?
15201
                        "aria-valuenow": this._parse( this.element.val() )
15202
                });
15203
        },
15204

    
15205
        isValid: function() {
15206
                var value = this.value();
15207

    
15208
                // null is invalid
15209
                if ( value === null ) {
15210
                        return false;
15211
                }
15212

    
15213
                // if value gets adjusted, it's invalid
15214
                return value === this._adjustValue( value );
15215
        },
15216

    
15217
        // update the value without triggering change
15218
        _value: function( value, allowAny ) {
15219
                var parsed;
15220
                if ( value !== "" ) {
15221
                        parsed = this._parse( value );
15222
                        if ( parsed !== null ) {
15223
                                if ( !allowAny ) {
15224
                                        parsed = this._adjustValue( parsed );
15225
                                }
15226
                                value = this._format( parsed );
15227
                        }
15228
                }
15229
                this.element.val( value );
15230
                this._refresh();
15231
        },
15232

    
15233
        _destroy: function() {
15234
                this.element
15235
                        .removeClass( "ui-spinner-input" )
15236
                        .prop( "disabled", false )
15237
                        .removeAttr( "autocomplete" )
15238
                        .removeAttr( "role" )
15239
                        .removeAttr( "aria-valuemin" )
15240
                        .removeAttr( "aria-valuemax" )
15241
                        .removeAttr( "aria-valuenow" );
15242
                this.uiSpinner.replaceWith( this.element );
15243
        },
15244

    
15245
        stepUp: spinner_modifier(function( steps ) {
15246
                this._stepUp( steps );
15247
        }),
15248
        _stepUp: function( steps ) {
15249
                if ( this._start() ) {
15250
                        this._spin( (steps || 1) * this.options.step );
15251
                        this._stop();
15252
                }
15253
        },
15254

    
15255
        stepDown: spinner_modifier(function( steps ) {
15256
                this._stepDown( steps );
15257
        }),
15258
        _stepDown: function( steps ) {
15259
                if ( this._start() ) {
15260
                        this._spin( (steps || 1) * -this.options.step );
15261
                        this._stop();
15262
                }
15263
        },
15264

    
15265
        pageUp: spinner_modifier(function( pages ) {
15266
                this._stepUp( (pages || 1) * this.options.page );
15267
        }),
15268

    
15269
        pageDown: spinner_modifier(function( pages ) {
15270
                this._stepDown( (pages || 1) * this.options.page );
15271
        }),
15272

    
15273
        value: function( newVal ) {
15274
                if ( !arguments.length ) {
15275
                        return this._parse( this.element.val() );
15276
                }
15277
                spinner_modifier( this._value ).call( this, newVal );
15278
        },
15279

    
15280
        widget: function() {
15281
                return this.uiSpinner;
15282
        }
15283
});
15284

    
15285

    
15286
/*!
15287
 * jQuery UI Tabs 1.11.4
15288
 * http://jqueryui.com
15289
 *
15290
 * Copyright jQuery Foundation and other contributors
15291
 * Released under the MIT license.
15292
 * http://jquery.org/license
15293
 *
15294
 * http://api.jqueryui.com/tabs/
15295
 */
15296

    
15297

    
15298
var tabs = $.widget( "ui.tabs", {
15299
        version: "1.11.4",
15300
        delay: 300,
15301
        options: {
15302
                active: null,
15303
                collapsible: false,
15304
                event: "click",
15305
                heightStyle: "content",
15306
                hide: null,
15307
                show: null,
15308

    
15309
                // callbacks
15310
                activate: null,
15311
                beforeActivate: null,
15312
                beforeLoad: null,
15313
                load: null
15314
        },
15315

    
15316
        _isLocal: (function() {
15317
                var rhash = /#.*$/;
15318

    
15319
                return function( anchor ) {
15320
                        var anchorUrl, locationUrl;
15321

    
15322
                        // support: IE7
15323
                        // IE7 doesn't normalize the href property when set via script (#9317)
15324
                        anchor = anchor.cloneNode( false );
15325

    
15326
                        anchorUrl = anchor.href.replace( rhash, "" );
15327
                        locationUrl = location.href.replace( rhash, "" );
15328

    
15329
                        // decoding may throw an error if the URL isn't UTF-8 (#9518)
15330
                        try {
15331
                                anchorUrl = decodeURIComponent( anchorUrl );
15332
                        } catch ( error ) {}
15333
                        try {
15334
                                locationUrl = decodeURIComponent( locationUrl );
15335
                        } catch ( error ) {}
15336

    
15337
                        return anchor.hash.length > 1 && anchorUrl === locationUrl;
15338
                };
15339
        })(),
15340

    
15341
        _create: function() {
15342
                var that = this,
15343
                        options = this.options;
15344

    
15345
                this.running = false;
15346

    
15347
                this.element
15348
                        .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
15349
                        .toggleClass( "ui-tabs-collapsible", options.collapsible );
15350

    
15351
                this._processTabs();
15352
                options.active = this._initialActive();
15353

    
15354
                // Take disabling tabs via class attribute from HTML
15355
                // into account and update option properly.
15356
                if ( $.isArray( options.disabled ) ) {
15357
                        options.disabled = $.unique( options.disabled.concat(
15358
                                $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
15359
                                        return that.tabs.index( li );
15360
                                })
15361
                        ) ).sort();
15362
                }
15363

    
15364
                // check for length avoids error when initializing empty list
15365
                if ( this.options.active !== false && this.anchors.length ) {
15366
                        this.active = this._findActive( options.active );
15367
                } else {
15368
                        this.active = $();
15369
                }
15370

    
15371
                this._refresh();
15372

    
15373
                if ( this.active.length ) {
15374
                        this.load( options.active );
15375
                }
15376
        },
15377

    
15378
        _initialActive: function() {
15379
                var active = this.options.active,
15380
                        collapsible = this.options.collapsible,
15381
                        locationHash = location.hash.substring( 1 );
15382

    
15383
                if ( active === null ) {
15384
                        // check the fragment identifier in the URL
15385
                        if ( locationHash ) {
15386
                                this.tabs.each(function( i, tab ) {
15387
                                        if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
15388
                                                active = i;
15389
                                                return false;
15390
                                        }
15391
                                });
15392
                        }
15393

    
15394
                        // check for a tab marked active via a class
15395
                        if ( active === null ) {
15396
                                active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
15397
                        }
15398

    
15399
                        // no active tab, set to false
15400
                        if ( active === null || active === -1 ) {
15401
                                active = this.tabs.length ? 0 : false;
15402
                        }
15403
                }
15404

    
15405
                // handle numbers: negative, out of range
15406
                if ( active !== false ) {
15407
                        active = this.tabs.index( this.tabs.eq( active ) );
15408
                        if ( active === -1 ) {
15409
                                active = collapsible ? false : 0;
15410
                        }
15411
                }
15412

    
15413
                // don't allow collapsible: false and active: false
15414
                if ( !collapsible && active === false && this.anchors.length ) {
15415
                        active = 0;
15416
                }
15417

    
15418
                return active;
15419
        },
15420

    
15421
        _getCreateEventData: function() {
15422
                return {
15423
                        tab: this.active,
15424
                        panel: !this.active.length ? $() : this._getPanelForTab( this.active )
15425
                };
15426
        },
15427

    
15428
        _tabKeydown: function( event ) {
15429
                var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
15430
                        selectedIndex = this.tabs.index( focusedTab ),
15431
                        goingForward = true;
15432

    
15433
                if ( this._handlePageNav( event ) ) {
15434
                        return;
15435
                }
15436

    
15437
                switch ( event.keyCode ) {
15438
                        case $.ui.keyCode.RIGHT:
15439
                        case $.ui.keyCode.DOWN:
15440
                                selectedIndex++;
15441
                                break;
15442
                        case $.ui.keyCode.UP:
15443
                        case $.ui.keyCode.LEFT:
15444
                                goingForward = false;
15445
                                selectedIndex--;
15446
                                break;
15447
                        case $.ui.keyCode.END:
15448
                                selectedIndex = this.anchors.length - 1;
15449
                                break;
15450
                        case $.ui.keyCode.HOME:
15451
                                selectedIndex = 0;
15452
                                break;
15453
                        case $.ui.keyCode.SPACE:
15454
                                // Activate only, no collapsing
15455
                                event.preventDefault();
15456
                                clearTimeout( this.activating );
15457
                                this._activate( selectedIndex );
15458
                                return;
15459
                        case $.ui.keyCode.ENTER:
15460
                                // Toggle (cancel delayed activation, allow collapsing)
15461
                                event.preventDefault();
15462
                                clearTimeout( this.activating );
15463
                                // Determine if we should collapse or activate
15464
                                this._activate( selectedIndex === this.options.active ? false : selectedIndex );
15465
                                return;
15466
                        default:
15467
                                return;
15468
                }
15469

    
15470
                // Focus the appropriate tab, based on which key was pressed
15471
                event.preventDefault();
15472
                clearTimeout( this.activating );
15473
                selectedIndex = this._focusNextTab( selectedIndex, goingForward );
15474

    
15475
                // Navigating with control/command key will prevent automatic activation
15476
                if ( !event.ctrlKey && !event.metaKey ) {
15477

    
15478
                        // Update aria-selected immediately so that AT think the tab is already selected.
15479
                        // Otherwise AT may confuse the user by stating that they need to activate the tab,
15480
                        // but the tab will already be activated by the time the announcement finishes.
15481
                        focusedTab.attr( "aria-selected", "false" );
15482
                        this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
15483

    
15484
                        this.activating = this._delay(function() {
15485
                                this.option( "active", selectedIndex );
15486
                        }, this.delay );
15487
                }
15488
        },
15489

    
15490
        _panelKeydown: function( event ) {
15491
                if ( this._handlePageNav( event ) ) {
15492
                        return;
15493
                }
15494

    
15495
                // Ctrl+up moves focus to the current tab
15496
                if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
15497
                        event.preventDefault();
15498
                        this.active.focus();
15499
                }
15500
        },
15501

    
15502
        // Alt+page up/down moves focus to the previous/next tab (and activates)
15503
        _handlePageNav: function( event ) {
15504
                if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
15505
                        this._activate( this._focusNextTab( this.options.active - 1, false ) );
15506
                        return true;
15507
                }
15508
                if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
15509
                        this._activate( this._focusNextTab( this.options.active + 1, true ) );
15510
                        return true;
15511
                }
15512
        },
15513

    
15514
        _findNextTab: function( index, goingForward ) {
15515
                var lastTabIndex = this.tabs.length - 1;
15516

    
15517
                function constrain() {
15518
                        if ( index > lastTabIndex ) {
15519
                                index = 0;
15520
                        }
15521
                        if ( index < 0 ) {
15522
                                index = lastTabIndex;
15523
                        }
15524
                        return index;
15525
                }
15526

    
15527
                while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
15528
                        index = goingForward ? index + 1 : index - 1;
15529
                }
15530

    
15531
                return index;
15532
        },
15533

    
15534
        _focusNextTab: function( index, goingForward ) {
15535
                index = this._findNextTab( index, goingForward );
15536
                this.tabs.eq( index ).focus();
15537
                return index;
15538
        },
15539

    
15540
        _setOption: function( key, value ) {
15541
                if ( key === "active" ) {
15542
                        // _activate() will handle invalid values and update this.options
15543
                        this._activate( value );
15544
                        return;
15545
                }
15546

    
15547
                if ( key === "disabled" ) {
15548
                        // don't use the widget factory's disabled handling
15549
                        this._setupDisabled( value );
15550
                        return;
15551
                }
15552

    
15553
                this._super( key, value);
15554

    
15555
                if ( key === "collapsible" ) {
15556
                        this.element.toggleClass( "ui-tabs-collapsible", value );
15557
                        // Setting collapsible: false while collapsed; open first panel
15558
                        if ( !value && this.options.active === false ) {
15559
                                this._activate( 0 );
15560
                        }
15561
                }
15562

    
15563
                if ( key === "event" ) {
15564
                        this._setupEvents( value );
15565
                }
15566

    
15567
                if ( key === "heightStyle" ) {
15568
                        this._setupHeightStyle( value );
15569
                }
15570
        },
15571

    
15572
        _sanitizeSelector: function( hash ) {
15573
                return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
15574
        },
15575

    
15576
        refresh: function() {
15577
                var options = this.options,
15578
                        lis = this.tablist.children( ":has(a[href])" );
15579

    
15580
                // get disabled tabs from class attribute from HTML
15581
                // this will get converted to a boolean if needed in _refresh()
15582
                options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
15583
                        return lis.index( tab );
15584
                });
15585

    
15586
                this._processTabs();
15587

    
15588
                // was collapsed or no tabs
15589
                if ( options.active === false || !this.anchors.length ) {
15590
                        options.active = false;
15591
                        this.active = $();
15592
                // was active, but active tab is gone
15593
                } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
15594
                        // all remaining tabs are disabled
15595
                        if ( this.tabs.length === options.disabled.length ) {
15596
                                options.active = false;
15597
                                this.active = $();
15598
                        // activate previous tab
15599
                        } else {
15600
                                this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
15601
                        }
15602
                // was active, active tab still exists
15603
                } else {
15604
                        // make sure active index is correct
15605
                        options.active = this.tabs.index( this.active );
15606
                }
15607

    
15608
                this._refresh();
15609
        },
15610

    
15611
        _refresh: function() {
15612
                this._setupDisabled( this.options.disabled );
15613
                this._setupEvents( this.options.event );
15614
                this._setupHeightStyle( this.options.heightStyle );
15615

    
15616
                this.tabs.not( this.active ).attr({
15617
                        "aria-selected": "false",
15618
                        "aria-expanded": "false",
15619
                        tabIndex: -1
15620
                });
15621
                this.panels.not( this._getPanelForTab( this.active ) )
15622
                        .hide()
15623
                        .attr({
15624
                                "aria-hidden": "true"
15625
                        });
15626

    
15627
                // Make sure one tab is in the tab order
15628
                if ( !this.active.length ) {
15629
                        this.tabs.eq( 0 ).attr( "tabIndex", 0 );
15630
                } else {
15631
                        this.active
15632
                                .addClass( "ui-tabs-active ui-state-active" )
15633
                                .attr({
15634
                                        "aria-selected": "true",
15635
                                        "aria-expanded": "true",
15636
                                        tabIndex: 0
15637
                                });
15638
                        this._getPanelForTab( this.active )
15639
                                .show()
15640
                                .attr({
15641
                                        "aria-hidden": "false"
15642
                                });
15643
                }
15644
        },
15645

    
15646
        _processTabs: function() {
15647
                var that = this,
15648
                        prevTabs = this.tabs,
15649
                        prevAnchors = this.anchors,
15650
                        prevPanels = this.panels;
15651

    
15652
                this.tablist = this._getList()
15653
                        .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15654
                        .attr( "role", "tablist" )
15655

    
15656
                        // Prevent users from focusing disabled tabs via click
15657
                        .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
15658
                                if ( $( this ).is( ".ui-state-disabled" ) ) {
15659
                                        event.preventDefault();
15660
                                }
15661
                        })
15662

    
15663
                        // support: IE <9
15664
                        // Preventing the default action in mousedown doesn't prevent IE
15665
                        // from focusing the element, so if the anchor gets focused, blur.
15666
                        // We don't have to worry about focusing the previously focused
15667
                        // element since clicking on a non-focusable element should focus
15668
                        // the body anyway.
15669
                        .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
15670
                                if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
15671
                                        this.blur();
15672
                                }
15673
                        });
15674

    
15675
                this.tabs = this.tablist.find( "> li:has(a[href])" )
15676
                        .addClass( "ui-state-default ui-corner-top" )
15677
                        .attr({
15678
                                role: "tab",
15679
                                tabIndex: -1
15680
                        });
15681

    
15682
                this.anchors = this.tabs.map(function() {
15683
                                return $( "a", this )[ 0 ];
15684
                        })
15685
                        .addClass( "ui-tabs-anchor" )
15686
                        .attr({
15687
                                role: "presentation",
15688
                                tabIndex: -1
15689
                        });
15690

    
15691
                this.panels = $();
15692

    
15693
                this.anchors.each(function( i, anchor ) {
15694
                        var selector, panel, panelId,
15695
                                anchorId = $( anchor ).uniqueId().attr( "id" ),
15696
                                tab = $( anchor ).closest( "li" ),
15697
                                originalAriaControls = tab.attr( "aria-controls" );
15698

    
15699
                        // inline tab
15700
                        if ( that._isLocal( anchor ) ) {
15701
                                selector = anchor.hash;
15702
                                panelId = selector.substring( 1 );
15703
                                panel = that.element.find( that._sanitizeSelector( selector ) );
15704
                        // remote tab
15705
                        } else {
15706
                                // If the tab doesn't already have aria-controls,
15707
                                // generate an id by using a throw-away element
15708
                                panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
15709
                                selector = "#" + panelId;
15710
                                panel = that.element.find( selector );
15711
                                if ( !panel.length ) {
15712
                                        panel = that._createPanel( panelId );
15713
                                        panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
15714
                                }
15715
                                panel.attr( "aria-live", "polite" );
15716
                        }
15717

    
15718
                        if ( panel.length) {
15719
                                that.panels = that.panels.add( panel );
15720
                        }
15721
                        if ( originalAriaControls ) {
15722
                                tab.data( "ui-tabs-aria-controls", originalAriaControls );
15723
                        }
15724
                        tab.attr({
15725
                                "aria-controls": panelId,
15726
                                "aria-labelledby": anchorId
15727
                        });
15728
                        panel.attr( "aria-labelledby", anchorId );
15729
                });
15730

    
15731
                this.panels
15732
                        .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15733
                        .attr( "role", "tabpanel" );
15734

    
15735
                // Avoid memory leaks (#10056)
15736
                if ( prevTabs ) {
15737
                        this._off( prevTabs.not( this.tabs ) );
15738
                        this._off( prevAnchors.not( this.anchors ) );
15739
                        this._off( prevPanels.not( this.panels ) );
15740
                }
15741
        },
15742

    
15743
        // allow overriding how to find the list for rare usage scenarios (#7715)
15744
        _getList: function() {
15745
                return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
15746
        },
15747

    
15748
        _createPanel: function( id ) {
15749
                return $( "<div>" )
15750
                        .attr( "id", id )
15751
                        .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15752
                        .data( "ui-tabs-destroy", true );
15753
        },
15754

    
15755
        _setupDisabled: function( disabled ) {
15756
                if ( $.isArray( disabled ) ) {
15757
                        if ( !disabled.length ) {
15758
                                disabled = false;
15759
                        } else if ( disabled.length === this.anchors.length ) {
15760
                                disabled = true;
15761
                        }
15762
                }
15763

    
15764
                // disable tabs
15765
                for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
15766
                        if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
15767
                                $( li )
15768
                                        .addClass( "ui-state-disabled" )
15769
                                        .attr( "aria-disabled", "true" );
15770
                        } else {
15771
                                $( li )
15772
                                        .removeClass( "ui-state-disabled" )
15773
                                        .removeAttr( "aria-disabled" );
15774
                        }
15775
                }
15776

    
15777
                this.options.disabled = disabled;
15778
        },
15779

    
15780
        _setupEvents: function( event ) {
15781
                var events = {};
15782
                if ( event ) {
15783
                        $.each( event.split(" "), function( index, eventName ) {
15784
                                events[ eventName ] = "_eventHandler";
15785
                        });
15786
                }
15787

    
15788
                this._off( this.anchors.add( this.tabs ).add( this.panels ) );
15789
                // Always prevent the default action, even when disabled
15790
                this._on( true, this.anchors, {
15791
                        click: function( event ) {
15792
                                event.preventDefault();
15793
                        }
15794
                });
15795
                this._on( this.anchors, events );
15796
                this._on( this.tabs, { keydown: "_tabKeydown" } );
15797
                this._on( this.panels, { keydown: "_panelKeydown" } );
15798

    
15799
                this._focusable( this.tabs );
15800
                this._hoverable( this.tabs );
15801
        },
15802

    
15803
        _setupHeightStyle: function( heightStyle ) {
15804
                var maxHeight,
15805
                        parent = this.element.parent();
15806

    
15807
                if ( heightStyle === "fill" ) {
15808
                        maxHeight = parent.height();
15809
                        maxHeight -= this.element.outerHeight() - this.element.height();
15810

    
15811
                        this.element.siblings( ":visible" ).each(function() {
15812
                                var elem = $( this ),
15813
                                        position = elem.css( "position" );
15814

    
15815
                                if ( position === "absolute" || position === "fixed" ) {
15816
                                        return;
15817
                                }
15818
                                maxHeight -= elem.outerHeight( true );
15819
                        });
15820

    
15821
                        this.element.children().not( this.panels ).each(function() {
15822
                                maxHeight -= $( this ).outerHeight( true );
15823
                        });
15824

    
15825
                        this.panels.each(function() {
15826
                                $( this ).height( Math.max( 0, maxHeight -
15827
                                        $( this ).innerHeight() + $( this ).height() ) );
15828
                        })
15829
                        .css( "overflow", "auto" );
15830
                } else if ( heightStyle === "auto" ) {
15831
                        maxHeight = 0;
15832
                        this.panels.each(function() {
15833
                                maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15834
                        }).height( maxHeight );
15835
                }
15836
        },
15837

    
15838
        _eventHandler: function( event ) {
15839
                var options = this.options,
15840
                        active = this.active,
15841
                        anchor = $( event.currentTarget ),
15842
                        tab = anchor.closest( "li" ),
15843
                        clickedIsActive = tab[ 0 ] === active[ 0 ],
15844
                        collapsing = clickedIsActive && options.collapsible,
15845
                        toShow = collapsing ? $() : this._getPanelForTab( tab ),
15846
                        toHide = !active.length ? $() : this._getPanelForTab( active ),
15847
                        eventData = {
15848
                                oldTab: active,
15849
                                oldPanel: toHide,
15850
                                newTab: collapsing ? $() : tab,
15851
                                newPanel: toShow
15852
                        };
15853

    
15854
                event.preventDefault();
15855

    
15856
                if ( tab.hasClass( "ui-state-disabled" ) ||
15857
                                // tab is already loading
15858
                                tab.hasClass( "ui-tabs-loading" ) ||
15859
                                // can't switch durning an animation
15860
                                this.running ||
15861
                                // click on active header, but not collapsible
15862
                                ( clickedIsActive && !options.collapsible ) ||
15863
                                // allow canceling activation
15864
                                ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
15865
                        return;
15866
                }
15867

    
15868
                options.active = collapsing ? false : this.tabs.index( tab );
15869

    
15870
                this.active = clickedIsActive ? $() : tab;
15871
                if ( this.xhr ) {
15872
                        this.xhr.abort();
15873
                }
15874

    
15875
                if ( !toHide.length && !toShow.length ) {
15876
                        $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
15877
                }
15878

    
15879
                if ( toShow.length ) {
15880
                        this.load( this.tabs.index( tab ), event );
15881
                }
15882
                this._toggle( event, eventData );
15883
        },
15884

    
15885
        // handles show/hide for selecting tabs
15886
        _toggle: function( event, eventData ) {
15887
                var that = this,
15888
                        toShow = eventData.newPanel,
15889
                        toHide = eventData.oldPanel;
15890

    
15891
                this.running = true;
15892

    
15893
                function complete() {
15894
                        that.running = false;
15895
                        that._trigger( "activate", event, eventData );
15896
                }
15897

    
15898
                function show() {
15899
                        eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
15900

    
15901
                        if ( toShow.length && that.options.show ) {
15902
                                that._show( toShow, that.options.show, complete );
15903
                        } else {
15904
                                toShow.show();
15905
                                complete();
15906
                        }
15907
                }
15908

    
15909
                // start out by hiding, then showing, then completing
15910
                if ( toHide.length && this.options.hide ) {
15911
                        this._hide( toHide, this.options.hide, function() {
15912
                                eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15913
                                show();
15914
                        });
15915
                } else {
15916
                        eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15917
                        toHide.hide();
15918
                        show();
15919
                }
15920

    
15921
                toHide.attr( "aria-hidden", "true" );
15922
                eventData.oldTab.attr({
15923
                        "aria-selected": "false",
15924
                        "aria-expanded": "false"
15925
                });
15926
                // If we're switching tabs, remove the old tab from the tab order.
15927
                // If we're opening from collapsed state, remove the previous tab from the tab order.
15928
                // If we're collapsing, then keep the collapsing tab in the tab order.
15929
                if ( toShow.length && toHide.length ) {
15930
                        eventData.oldTab.attr( "tabIndex", -1 );
15931
                } else if ( toShow.length ) {
15932
                        this.tabs.filter(function() {
15933
                                return $( this ).attr( "tabIndex" ) === 0;
15934
                        })
15935
                        .attr( "tabIndex", -1 );
15936
                }
15937

    
15938
                toShow.attr( "aria-hidden", "false" );
15939
                eventData.newTab.attr({
15940
                        "aria-selected": "true",
15941
                        "aria-expanded": "true",
15942
                        tabIndex: 0
15943
                });
15944
        },
15945

    
15946
        _activate: function( index ) {
15947
                var anchor,
15948
                        active = this._findActive( index );
15949

    
15950
                // trying to activate the already active panel
15951
                if ( active[ 0 ] === this.active[ 0 ] ) {
15952
                        return;
15953
                }
15954

    
15955
                // trying to collapse, simulate a click on the current active header
15956
                if ( !active.length ) {
15957
                        active = this.active;
15958
                }
15959

    
15960
                anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
15961
                this._eventHandler({
15962
                        target: anchor,
15963
                        currentTarget: anchor,
15964
                        preventDefault: $.noop
15965
                });
15966
        },
15967

    
15968
        _findActive: function( index ) {
15969
                return index === false ? $() : this.tabs.eq( index );
15970
        },
15971

    
15972
        _getIndex: function( index ) {
15973
                // meta-function to give users option to provide a href string instead of a numerical index.
15974
                if ( typeof index === "string" ) {
15975
                        index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
15976
                }
15977

    
15978
                return index;
15979
        },
15980

    
15981
        _destroy: function() {
15982
                if ( this.xhr ) {
15983
                        this.xhr.abort();
15984
                }
15985

    
15986
                this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
15987

    
15988
                this.tablist
15989
                        .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15990
                        .removeAttr( "role" );
15991

    
15992
                this.anchors
15993
                        .removeClass( "ui-tabs-anchor" )
15994
                        .removeAttr( "role" )
15995
                        .removeAttr( "tabIndex" )
15996
                        .removeUniqueId();
15997

    
15998
                this.tablist.unbind( this.eventNamespace );
15999

    
16000
                this.tabs.add( this.panels ).each(function() {
16001
                        if ( $.data( this, "ui-tabs-destroy" ) ) {
16002
                                $( this ).remove();
16003
                        } else {
16004
                                $( this )
16005
                                        .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
16006
                                                "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
16007
                                        .removeAttr( "tabIndex" )
16008
                                        .removeAttr( "aria-live" )
16009
                                        .removeAttr( "aria-busy" )
16010
                                        .removeAttr( "aria-selected" )
16011
                                        .removeAttr( "aria-labelledby" )
16012
                                        .removeAttr( "aria-hidden" )
16013
                                        .removeAttr( "aria-expanded" )
16014
                                        .removeAttr( "role" );
16015
                        }
16016
                });
16017

    
16018
                this.tabs.each(function() {
16019
                        var li = $( this ),
16020
                                prev = li.data( "ui-tabs-aria-controls" );
16021
                        if ( prev ) {
16022
                                li
16023
                                        .attr( "aria-controls", prev )
16024
                                        .removeData( "ui-tabs-aria-controls" );
16025
                        } else {
16026
                                li.removeAttr( "aria-controls" );
16027
                        }
16028
                });
16029

    
16030
                this.panels.show();
16031

    
16032
                if ( this.options.heightStyle !== "content" ) {
16033
                        this.panels.css( "height", "" );
16034
                }
16035
        },
16036

    
16037
        enable: function( index ) {
16038
                var disabled = this.options.disabled;
16039
                if ( disabled === false ) {
16040
                        return;
16041
                }
16042

    
16043
                if ( index === undefined ) {
16044
                        disabled = false;
16045
                } else {
16046
                        index = this._getIndex( index );
16047
                        if ( $.isArray( disabled ) ) {
16048
                                disabled = $.map( disabled, function( num ) {
16049
                                        return num !== index ? num : null;
16050
                                });
16051
                        } else {
16052
                                disabled = $.map( this.tabs, function( li, num ) {
16053
                                        return num !== index ? num : null;
16054
                                });
16055
                        }
16056
                }
16057
                this._setupDisabled( disabled );
16058
        },
16059

    
16060
        disable: function( index ) {
16061
                var disabled = this.options.disabled;
16062
                if ( disabled === true ) {
16063
                        return;
16064
                }
16065

    
16066
                if ( index === undefined ) {
16067
                        disabled = true;
16068
                } else {
16069
                        index = this._getIndex( index );
16070
                        if ( $.inArray( index, disabled ) !== -1 ) {
16071
                                return;
16072
                        }
16073
                        if ( $.isArray( disabled ) ) {
16074
                                disabled = $.merge( [ index ], disabled ).sort();
16075
                        } else {
16076
                                disabled = [ index ];
16077
                        }
16078
                }
16079
                this._setupDisabled( disabled );
16080
        },
16081

    
16082
        load: function( index, event ) {
16083
                index = this._getIndex( index );
16084
                var that = this,
16085
                        tab = this.tabs.eq( index ),
16086
                        anchor = tab.find( ".ui-tabs-anchor" ),
16087
                        panel = this._getPanelForTab( tab ),
16088
                        eventData = {
16089
                                tab: tab,
16090
                                panel: panel
16091
                        },
16092
                        complete = function( jqXHR, status ) {
16093
                                if ( status === "abort" ) {
16094
                                        that.panels.stop( false, true );
16095
                                }
16096

    
16097
                                tab.removeClass( "ui-tabs-loading" );
16098
                                panel.removeAttr( "aria-busy" );
16099

    
16100
                                if ( jqXHR === that.xhr ) {
16101
                                        delete that.xhr;
16102
                                }
16103
                        };
16104

    
16105
                // not remote
16106
                if ( this._isLocal( anchor[ 0 ] ) ) {
16107
                        return;
16108
                }
16109

    
16110
                this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
16111

    
16112
                // support: jQuery <1.8
16113
                // jQuery <1.8 returns false if the request is canceled in beforeSend,
16114
                // but as of 1.8, $.ajax() always returns a jqXHR object.
16115
                if ( this.xhr && this.xhr.statusText !== "canceled" ) {
16116
                        tab.addClass( "ui-tabs-loading" );
16117
                        panel.attr( "aria-busy", "true" );
16118

    
16119
                        this.xhr
16120
                                .done(function( response, status, jqXHR ) {
16121
                                        // support: jQuery <1.8
16122
                                        // http://bugs.jquery.com/ticket/11778
16123
                                        setTimeout(function() {
16124
                                                panel.html( response );
16125
                                                that._trigger( "load", event, eventData );
16126

    
16127
                                                complete( jqXHR, status );
16128
                                        }, 1 );
16129
                                })
16130
                                .fail(function( jqXHR, status ) {
16131
                                        // support: jQuery <1.8
16132
                                        // http://bugs.jquery.com/ticket/11778
16133
                                        setTimeout(function() {
16134
                                                complete( jqXHR, status );
16135
                                        }, 1 );
16136
                                });
16137
                }
16138
        },
16139

    
16140
        _ajaxSettings: function( anchor, event, eventData ) {
16141
                var that = this;
16142
                return {
16143
                        url: anchor.attr( "href" ),
16144
                        beforeSend: function( jqXHR, settings ) {
16145
                                return that._trigger( "beforeLoad", event,
16146
                                        $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
16147
                        }
16148
                };
16149
        },
16150

    
16151
        _getPanelForTab: function( tab ) {
16152
                var id = $( tab ).attr( "aria-controls" );
16153
                return this.element.find( this._sanitizeSelector( "#" + id ) );
16154
        }
16155
});
16156

    
16157

    
16158
/*!
16159
 * jQuery UI Tooltip 1.11.4
16160
 * http://jqueryui.com
16161
 *
16162
 * Copyright jQuery Foundation and other contributors
16163
 * Released under the MIT license.
16164
 * http://jquery.org/license
16165
 *
16166
 * http://api.jqueryui.com/tooltip/
16167
 */
16168

    
16169

    
16170
var tooltip = $.widget( "ui.tooltip", {
16171
        version: "1.11.4",
16172
        options: {
16173
                content: function() {
16174
                        // support: IE<9, Opera in jQuery <1.7
16175
                        // .text() can't accept undefined, so coerce to a string
16176
                        var title = $( this ).attr( "title" ) || "";
16177
                        // Escape title, since we're going from an attribute to raw HTML
16178
                        return $( "<a>" ).text( title ).html();
16179
                },
16180
                hide: true,
16181
                // Disabled elements have inconsistent behavior across browsers (#8661)
16182
                items: "[title]:not([disabled])",
16183
                position: {
16184
                        my: "left top+15",
16185
                        at: "left bottom",
16186
                        collision: "flipfit flip"
16187
                },
16188
                show: true,
16189
                tooltipClass: null,
16190
                track: false,
16191

    
16192
                // callbacks
16193
                close: null,
16194
                open: null
16195
        },
16196

    
16197
        _addDescribedBy: function( elem, id ) {
16198
                var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
16199
                describedby.push( id );
16200
                elem
16201
                        .data( "ui-tooltip-id", id )
16202
                        .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
16203
        },
16204

    
16205
        _removeDescribedBy: function( elem ) {
16206
                var id = elem.data( "ui-tooltip-id" ),
16207
                        describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
16208
                        index = $.inArray( id, describedby );
16209

    
16210
                if ( index !== -1 ) {
16211
                        describedby.splice( index, 1 );
16212
                }
16213

    
16214
                elem.removeData( "ui-tooltip-id" );
16215
                describedby = $.trim( describedby.join( " " ) );
16216
                if ( describedby ) {
16217
                        elem.attr( "aria-describedby", describedby );
16218
                } else {
16219
                        elem.removeAttr( "aria-describedby" );
16220
                }
16221
        },
16222

    
16223
        _create: function() {
16224
                this._on({
16225
                        mouseover: "open",
16226
                        focusin: "open"
16227
                });
16228

    
16229
                // IDs of generated tooltips, needed for destroy
16230
                this.tooltips = {};
16231

    
16232
                // IDs of parent tooltips where we removed the title attribute
16233
                this.parents = {};
16234

    
16235
                if ( this.options.disabled ) {
16236
                        this._disable();
16237
                }
16238

    
16239
                // Append the aria-live region so tooltips announce correctly
16240
                this.liveRegion = $( "<div>" )
16241
                        .attr({
16242
                                role: "log",
16243
                                "aria-live": "assertive",
16244
                                "aria-relevant": "additions"
16245
                        })
16246
                        .addClass( "ui-helper-hidden-accessible" )
16247
                        .appendTo( this.document[ 0 ].body );
16248
        },
16249

    
16250
        _setOption: function( key, value ) {
16251
                var that = this;
16252

    
16253
                if ( key === "disabled" ) {
16254
                        this[ value ? "_disable" : "_enable" ]();
16255
                        this.options[ key ] = value;
16256
                        // disable element style changes
16257
                        return;
16258
                }
16259

    
16260
                this._super( key, value );
16261

    
16262
                if ( key === "content" ) {
16263
                        $.each( this.tooltips, function( id, tooltipData ) {
16264
                                that._updateContent( tooltipData.element );
16265
                        });
16266
                }
16267
        },
16268

    
16269
        _disable: function() {
16270
                var that = this;
16271

    
16272
                // close open tooltips
16273
                $.each( this.tooltips, function( id, tooltipData ) {
16274
                        var event = $.Event( "blur" );
16275
                        event.target = event.currentTarget = tooltipData.element[ 0 ];
16276
                        that.close( event, true );
16277
                });
16278

    
16279
                // remove title attributes to prevent native tooltips
16280
                this.element.find( this.options.items ).addBack().each(function() {
16281
                        var element = $( this );
16282
                        if ( element.is( "[title]" ) ) {
16283
                                element
16284
                                        .data( "ui-tooltip-title", element.attr( "title" ) )
16285
                                        .removeAttr( "title" );
16286
                        }
16287
                });
16288
        },
16289

    
16290
        _enable: function() {
16291
                // restore title attributes
16292
                this.element.find( this.options.items ).addBack().each(function() {
16293
                        var element = $( this );
16294
                        if ( element.data( "ui-tooltip-title" ) ) {
16295
                                element.attr( "title", element.data( "ui-tooltip-title" ) );
16296
                        }
16297
                });
16298
        },
16299

    
16300
        open: function( event ) {
16301
                var that = this,
16302
                        target = $( event ? event.target : this.element )
16303
                                // we need closest here due to mouseover bubbling,
16304
                                // but always pointing at the same event target
16305
                                .closest( this.options.items );
16306

    
16307
                // No element to show a tooltip for or the tooltip is already open
16308
                if ( !target.length || target.data( "ui-tooltip-id" ) ) {
16309
                        return;
16310
                }
16311

    
16312
                if ( target.attr( "title" ) ) {
16313
                        target.data( "ui-tooltip-title", target.attr( "title" ) );
16314
                }
16315

    
16316
                target.data( "ui-tooltip-open", true );
16317

    
16318
                // kill parent tooltips, custom or native, for hover
16319
                if ( event && event.type === "mouseover" ) {
16320
                        target.parents().each(function() {
16321
                                var parent = $( this ),
16322
                                        blurEvent;
16323
                                if ( parent.data( "ui-tooltip-open" ) ) {
16324
                                        blurEvent = $.Event( "blur" );
16325
                                        blurEvent.target = blurEvent.currentTarget = this;
16326
                                        that.close( blurEvent, true );
16327
                                }
16328
                                if ( parent.attr( "title" ) ) {
16329
                                        parent.uniqueId();
16330
                                        that.parents[ this.id ] = {
16331
                                                element: this,
16332
                                                title: parent.attr( "title" )
16333
                                        };
16334
                                        parent.attr( "title", "" );
16335
                                }
16336
                        });
16337
                }
16338

    
16339
                this._registerCloseHandlers( event, target );
16340
                this._updateContent( target, event );
16341
        },
16342

    
16343
        _updateContent: function( target, event ) {
16344
                var content,
16345
                        contentOption = this.options.content,
16346
                        that = this,
16347
                        eventType = event ? event.type : null;
16348

    
16349
                if ( typeof contentOption === "string" ) {
16350
                        return this._open( event, target, contentOption );
16351
                }
16352

    
16353
                content = contentOption.call( target[0], function( response ) {
16354

    
16355
                        // IE may instantly serve a cached response for ajax requests
16356
                        // delay this call to _open so the other call to _open runs first
16357
                        that._delay(function() {
16358

    
16359
                                // Ignore async response if tooltip was closed already
16360
                                if ( !target.data( "ui-tooltip-open" ) ) {
16361
                                        return;
16362
                                }
16363

    
16364
                                // jQuery creates a special event for focusin when it doesn't
16365
                                // exist natively. To improve performance, the native event
16366
                                // object is reused and the type is changed. Therefore, we can't
16367
                                // rely on the type being correct after the event finished
16368
                                // bubbling, so we set it back to the previous value. (#8740)
16369
                                if ( event ) {
16370
                                        event.type = eventType;
16371
                                }
16372
                                this._open( event, target, response );
16373
                        });
16374
                });
16375
                if ( content ) {
16376
                        this._open( event, target, content );
16377
                }
16378
        },
16379

    
16380
        _open: function( event, target, content ) {
16381
                var tooltipData, tooltip, delayedShow, a11yContent,
16382
                        positionOption = $.extend( {}, this.options.position );
16383

    
16384
                if ( !content ) {
16385
                        return;
16386
                }
16387

    
16388
                // Content can be updated multiple times. If the tooltip already
16389
                // exists, then just update the content and bail.
16390
                tooltipData = this._find( target );
16391
                if ( tooltipData ) {
16392
                        tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
16393
                        return;
16394
                }
16395

    
16396
                // if we have a title, clear it to prevent the native tooltip
16397
                // we have to check first to avoid defining a title if none exists
16398
                // (we don't want to cause an element to start matching [title])
16399
                //
16400
                // We use removeAttr only for key events, to allow IE to export the correct
16401
                // accessible attributes. For mouse events, set to empty string to avoid
16402
                // native tooltip showing up (happens only when removing inside mouseover).
16403
                if ( target.is( "[title]" ) ) {
16404
                        if ( event && event.type === "mouseover" ) {
16405
                                target.attr( "title", "" );
16406
                        } else {
16407
                                target.removeAttr( "title" );
16408
                        }
16409
                }
16410

    
16411
                tooltipData = this._tooltip( target );
16412
                tooltip = tooltipData.tooltip;
16413
                this._addDescribedBy( target, tooltip.attr( "id" ) );
16414
                tooltip.find( ".ui-tooltip-content" ).html( content );
16415

    
16416
                // Support: Voiceover on OS X, JAWS on IE <= 9
16417
                // JAWS announces deletions even when aria-relevant="additions"
16418
                // Voiceover will sometimes re-read the entire log region's contents from the beginning
16419
                this.liveRegion.children().hide();
16420
                if ( content.clone ) {
16421
                        a11yContent = content.clone();
16422
                        a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
16423
                } else {
16424
                        a11yContent = content;
16425
                }
16426
                $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
16427

    
16428
                function position( event ) {
16429
                        positionOption.of = event;
16430
                        if ( tooltip.is( ":hidden" ) ) {
16431
                                return;
16432
                        }
16433
                        tooltip.position( positionOption );
16434
                }
16435
                if ( this.options.track && event && /^mouse/.test( event.type ) ) {
16436
                        this._on( this.document, {
16437
                                mousemove: position
16438
                        });
16439
                        // trigger once to override element-relative positioning
16440
                        position( event );
16441
                } else {
16442
                        tooltip.position( $.extend({
16443
                                of: target
16444
                        }, this.options.position ) );
16445
                }
16446

    
16447
                tooltip.hide();
16448

    
16449
                this._show( tooltip, this.options.show );
16450
                // Handle tracking tooltips that are shown with a delay (#8644). As soon
16451
                // as the tooltip is visible, position the tooltip using the most recent
16452
                // event.
16453
                if ( this.options.show && this.options.show.delay ) {
16454
                        delayedShow = this.delayedShow = setInterval(function() {
16455
                                if ( tooltip.is( ":visible" ) ) {
16456
                                        position( positionOption.of );
16457
                                        clearInterval( delayedShow );
16458
                                }
16459
                        }, $.fx.interval );
16460
                }
16461

    
16462
                this._trigger( "open", event, { tooltip: tooltip } );
16463
        },
16464

    
16465
        _registerCloseHandlers: function( event, target ) {
16466
                var events = {
16467
                        keyup: function( event ) {
16468
                                if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
16469
                                        var fakeEvent = $.Event(event);
16470
                                        fakeEvent.currentTarget = target[0];
16471
                                        this.close( fakeEvent, true );
16472
                                }
16473
                        }
16474
                };
16475

    
16476
                // Only bind remove handler for delegated targets. Non-delegated
16477
                // tooltips will handle this in destroy.
16478
                if ( target[ 0 ] !== this.element[ 0 ] ) {
16479
                        events.remove = function() {
16480
                                this._removeTooltip( this._find( target ).tooltip );
16481
                        };
16482
                }
16483

    
16484
                if ( !event || event.type === "mouseover" ) {
16485
                        events.mouseleave = "close";
16486
                }
16487
                if ( !event || event.type === "focusin" ) {
16488
                        events.focusout = "close";
16489
                }
16490
                this._on( true, target, events );
16491
        },
16492

    
16493
        close: function( event ) {
16494
                var tooltip,
16495
                        that = this,
16496
                        target = $( event ? event.currentTarget : this.element ),
16497
                        tooltipData = this._find( target );
16498

    
16499
                // The tooltip may already be closed
16500
                if ( !tooltipData ) {
16501

    
16502
                        // We set ui-tooltip-open immediately upon open (in open()), but only set the
16503
                        // additional data once there's actually content to show (in _open()). So even if the
16504
                        // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
16505
                        // the period between open() and _open().
16506
                        target.removeData( "ui-tooltip-open" );
16507
                        return;
16508
                }
16509

    
16510
                tooltip = tooltipData.tooltip;
16511

    
16512
                // disabling closes the tooltip, so we need to track when we're closing
16513
                // to avoid an infinite loop in case the tooltip becomes disabled on close
16514
                if ( tooltipData.closing ) {
16515
                        return;
16516
                }
16517

    
16518
                // Clear the interval for delayed tracking tooltips
16519
                clearInterval( this.delayedShow );
16520

    
16521
                // only set title if we had one before (see comment in _open())
16522
                // If the title attribute has changed since open(), don't restore
16523
                if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
16524
                        target.attr( "title", target.data( "ui-tooltip-title" ) );
16525
                }
16526

    
16527
                this._removeDescribedBy( target );
16528

    
16529
                tooltipData.hiding = true;
16530
                tooltip.stop( true );
16531
                this._hide( tooltip, this.options.hide, function() {
16532
                        that._removeTooltip( $( this ) );
16533
                });
16534

    
16535
                target.removeData( "ui-tooltip-open" );
16536
                this._off( target, "mouseleave focusout keyup" );
16537

    
16538
                // Remove 'remove' binding only on delegated targets
16539
                if ( target[ 0 ] !== this.element[ 0 ] ) {
16540
                        this._off( target, "remove" );
16541
                }
16542
                this._off( this.document, "mousemove" );
16543

    
16544
                if ( event && event.type === "mouseleave" ) {
16545
                        $.each( this.parents, function( id, parent ) {
16546
                                $( parent.element ).attr( "title", parent.title );
16547
                                delete that.parents[ id ];
16548
                        });
16549
                }
16550

    
16551
                tooltipData.closing = true;
16552
                this._trigger( "close", event, { tooltip: tooltip } );
16553
                if ( !tooltipData.hiding ) {
16554
                        tooltipData.closing = false;
16555
                }
16556
        },
16557

    
16558
        _tooltip: function( element ) {
16559
                var tooltip = $( "<div>" )
16560
                                .attr( "role", "tooltip" )
16561
                                .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
16562
                                        ( this.options.tooltipClass || "" ) ),
16563
                        id = tooltip.uniqueId().attr( "id" );
16564

    
16565
                $( "<div>" )
16566
                        .addClass( "ui-tooltip-content" )
16567
                        .appendTo( tooltip );
16568

    
16569
                tooltip.appendTo( this.document[0].body );
16570

    
16571
                return this.tooltips[ id ] = {
16572
                        element: element,
16573
                        tooltip: tooltip
16574
                };
16575
        },
16576

    
16577
        _find: function( target ) {
16578
                var id = target.data( "ui-tooltip-id" );
16579
                return id ? this.tooltips[ id ] : null;
16580
        },
16581

    
16582
        _removeTooltip: function( tooltip ) {
16583
                tooltip.remove();
16584
                delete this.tooltips[ tooltip.attr( "id" ) ];
16585
        },
16586

    
16587
        _destroy: function() {
16588
                var that = this;
16589

    
16590
                // close open tooltips
16591
                $.each( this.tooltips, function( id, tooltipData ) {
16592
                        // Delegate to close method to handle common cleanup
16593
                        var event = $.Event( "blur" ),
16594
                                element = tooltipData.element;
16595
                        event.target = event.currentTarget = element[ 0 ];
16596
                        that.close( event, true );
16597

    
16598
                        // Remove immediately; destroying an open tooltip doesn't use the
16599
                        // hide animation
16600
                        $( "#" + id ).remove();
16601

    
16602
                        // Restore the title
16603
                        if ( element.data( "ui-tooltip-title" ) ) {
16604
                                // If the title attribute has changed since open(), don't restore
16605
                                if ( !element.attr( "title" ) ) {
16606
                                        element.attr( "title", element.data( "ui-tooltip-title" ) );
16607
                                }
16608
                                element.removeData( "ui-tooltip-title" );
16609
                        }
16610
                });
16611
                this.liveRegion.remove();
16612
        }
16613
});
16614

    
16615

    
16616

    
16617
}));