Projet

Général

Profil

Paste
Télécharger (426 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / jquery_update / replace / ui / ui / jquery-ui.js @ 503b3f7b

1
/*! jQuery UI - v1.10.2 - 2013-03-14
2
* http://jqueryui.com
3
* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
4
* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
5
(function( $, undefined ) {
6

    
7
var uuid = 0,
8
        runiqueId = /^ui-id-\d+$/;
9

    
10
// $.ui might exist from components with no dependencies, e.g., $.ui.position
11
$.ui = $.ui || {};
12

    
13
$.extend( $.ui, {
14
        version: "1.10.2",
15

    
16
        keyCode: {
17
                BACKSPACE: 8,
18
                COMMA: 188,
19
                DELETE: 46,
20
                DOWN: 40,
21
                END: 35,
22
                ENTER: 13,
23
                ESCAPE: 27,
24
                HOME: 36,
25
                LEFT: 37,
26
                NUMPAD_ADD: 107,
27
                NUMPAD_DECIMAL: 110,
28
                NUMPAD_DIVIDE: 111,
29
                NUMPAD_ENTER: 108,
30
                NUMPAD_MULTIPLY: 106,
31
                NUMPAD_SUBTRACT: 109,
32
                PAGE_DOWN: 34,
33
                PAGE_UP: 33,
34
                PERIOD: 190,
35
                RIGHT: 39,
36
                SPACE: 32,
37
                TAB: 9,
38
                UP: 38
39
        }
40
});
41

    
42
// plugins
43
$.fn.extend({
44
        focus: (function( orig ) {
45
                return function( delay, fn ) {
46
                        return typeof delay === "number" ?
47
                                this.each(function() {
48
                                        var elem = this;
49
                                        setTimeout(function() {
50
                                                $( elem ).focus();
51
                                                if ( fn ) {
52
                                                        fn.call( elem );
53
                                                }
54
                                        }, delay );
55
                                }) :
56
                                orig.apply( this, arguments );
57
                };
58
        })( $.fn.focus ),
59

    
60
        scrollParent: function() {
61
                var scrollParent;
62
                if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
63
                        scrollParent = this.parents().filter(function() {
64
                                return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
65
                        }).eq(0);
66
                } else {
67
                        scrollParent = this.parents().filter(function() {
68
                                return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
69
                        }).eq(0);
70
                }
71

    
72
                return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
73
        },
74

    
75
        zIndex: function( zIndex ) {
76
                if ( zIndex !== undefined ) {
77
                        return this.css( "zIndex", zIndex );
78
                }
79

    
80
                if ( this.length ) {
81
                        var elem = $( this[ 0 ] ), position, value;
82
                        while ( elem.length && elem[ 0 ] !== document ) {
83
                                // Ignore z-index if position is set to a value where z-index is ignored by the browser
84
                                // This makes behavior of this function consistent across browsers
85
                                // WebKit always returns auto if the element is positioned
86
                                position = elem.css( "position" );
87
                                if ( position === "absolute" || position === "relative" || position === "fixed" ) {
88
                                        // IE returns 0 when zIndex is not specified
89
                                        // other browsers return a string
90
                                        // we ignore the case of nested elements with an explicit value of 0
91
                                        // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
92
                                        value = parseInt( elem.css( "zIndex" ), 10 );
93
                                        if ( !isNaN( value ) && value !== 0 ) {
94
                                                return value;
95
                                        }
96
                                }
97
                                elem = elem.parent();
98
                        }
99
                }
100

    
101
                return 0;
102
        },
103

    
104
        uniqueId: function() {
105
                return this.each(function() {
106
                        if ( !this.id ) {
107
                                this.id = "ui-id-" + (++uuid);
108
                        }
109
                });
110
        },
111

    
112
        removeUniqueId: function() {
113
                return this.each(function() {
114
                        if ( runiqueId.test( this.id ) ) {
115
                                $( this ).removeAttr( "id" );
116
                        }
117
                });
118
        }
119
});
120

    
121
// selectors
122
function focusable( element, isTabIndexNotNaN ) {
123
        var map, mapName, img,
124
                nodeName = element.nodeName.toLowerCase();
125
        if ( "area" === nodeName ) {
126
                map = element.parentNode;
127
                mapName = map.name;
128
                if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
129
                        return false;
130
                }
131
                img = $( "img[usemap=#" + mapName + "]" )[0];
132
                return !!img && visible( img );
133
        }
134
        return ( /input|select|textarea|button|object/.test( nodeName ) ?
135
                !element.disabled :
136
                "a" === nodeName ?
137
                        element.href || isTabIndexNotNaN :
138
                        isTabIndexNotNaN) &&
139
                // the element and all of its ancestors must be visible
140
                visible( element );
141
}
142

    
143
function visible( element ) {
144
        return $.expr.filters.visible( element ) &&
145
                !$( element ).parents().addBack().filter(function() {
146
                        return $.css( this, "visibility" ) === "hidden";
147
                }).length;
148
}
149

    
150
$.extend( $.expr[ ":" ], {
151
        data: $.expr.createPseudo ?
152
                $.expr.createPseudo(function( dataName ) {
153
                        return function( elem ) {
154
                                return !!$.data( elem, dataName );
155
                        };
156
                }) :
157
                // support: jQuery <1.8
158
                function( elem, i, match ) {
159
                        return !!$.data( elem, match[ 3 ] );
160
                },
161

    
162
        focusable: function( element ) {
163
                return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
164
        },
165

    
166
        tabbable: function( element ) {
167
                var tabIndex = $.attr( element, "tabindex" ),
168
                        isTabIndexNaN = isNaN( tabIndex );
169
                return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
170
        }
171
});
172

    
173
// support: jQuery <1.8
174
if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
175
        $.each( [ "Width", "Height" ], function( i, name ) {
176
                var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
177
                        type = name.toLowerCase(),
178
                        orig = {
179
                                innerWidth: $.fn.innerWidth,
180
                                innerHeight: $.fn.innerHeight,
181
                                outerWidth: $.fn.outerWidth,
182
                                outerHeight: $.fn.outerHeight
183
                        };
184

    
185
                function reduce( elem, size, border, margin ) {
186
                        $.each( side, function() {
187
                                size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
188
                                if ( border ) {
189
                                        size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
190
                                }
191
                                if ( margin ) {
192
                                        size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
193
                                }
194
                        });
195
                        return size;
196
                }
197

    
198
                $.fn[ "inner" + name ] = function( size ) {
199
                        if ( size === undefined ) {
200
                                return orig[ "inner" + name ].call( this );
201
                        }
202

    
203
                        return this.each(function() {
204
                                $( this ).css( type, reduce( this, size ) + "px" );
205
                        });
206
                };
207

    
208
                $.fn[ "outer" + name] = function( size, margin ) {
209
                        if ( typeof size !== "number" ) {
210
                                return orig[ "outer" + name ].call( this, size );
211
                        }
212

    
213
                        return this.each(function() {
214
                                $( this).css( type, reduce( this, size, true, margin ) + "px" );
215
                        });
216
                };
217
        });
218
}
219

    
220
// support: jQuery <1.8
221
if ( !$.fn.addBack ) {
222
        $.fn.addBack = function( selector ) {
223
                return this.add( selector == null ?
224
                        this.prevObject : this.prevObject.filter( selector )
225
                );
226
        };
227
}
228

    
229
// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
230
if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
231
        $.fn.removeData = (function( removeData ) {
232
                return function( key ) {
233
                        if ( arguments.length ) {
234
                                return removeData.call( this, $.camelCase( key ) );
235
                        } else {
236
                                return removeData.call( this );
237
                        }
238
                };
239
        })( $.fn.removeData );
240
}
241

    
242

    
243

    
244

    
245

    
246
// deprecated
247
$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
248

    
249
$.support.selectstart = "onselectstart" in document.createElement( "div" );
250
$.fn.extend({
251
        disableSelection: function() {
252
                return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
253
                        ".ui-disableSelection", function( event ) {
254
                                event.preventDefault();
255
                        });
256
        },
257

    
258
        enableSelection: function() {
259
                return this.unbind( ".ui-disableSelection" );
260
        }
261
});
262

    
263
$.extend( $.ui, {
264
        // $.ui.plugin is deprecated.  Use the proxy pattern instead.
265
        plugin: {
266
                add: function( module, option, set ) {
267
                        var i,
268
                                proto = $.ui[ module ].prototype;
269
                        for ( i in set ) {
270
                                proto.plugins[ i ] = proto.plugins[ i ] || [];
271
                                proto.plugins[ i ].push( [ option, set[ i ] ] );
272
                        }
273
                },
274
                call: function( instance, name, args ) {
275
                        var i,
276
                                set = instance.plugins[ name ];
277
                        if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
278
                                return;
279
                        }
280

    
281
                        for ( i = 0; i < set.length; i++ ) {
282
                                if ( instance.options[ set[ i ][ 0 ] ] ) {
283
                                        set[ i ][ 1 ].apply( instance.element, args );
284
                                }
285
                        }
286
                }
287
        },
288

    
289
        // only used by resizable
290
        hasScroll: function( el, a ) {
291

    
292
                //If overflow is hidden, the element might have extra content, but the user wants to hide it
293
                if ( $( el ).css( "overflow" ) === "hidden") {
294
                        return false;
295
                }
296

    
297
                var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
298
                        has = false;
299

    
300
                if ( el[ scroll ] > 0 ) {
301
                        return true;
302
                }
303

    
304
                // TODO: determine which cases actually cause this to happen
305
                // if the element doesn't have the scroll set, see if it's possible to
306
                // set the scroll
307
                el[ scroll ] = 1;
308
                has = ( el[ scroll ] > 0 );
309
                el[ scroll ] = 0;
310
                return has;
311
        }
312
});
313

    
314
})( jQuery );
315

    
316
(function( $, undefined ) {
317

    
318
var uuid = 0,
319
        slice = Array.prototype.slice,
320
        _cleanData = $.cleanData;
321
$.cleanData = function( elems ) {
322
        for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
323
                try {
324
                        $( elem ).triggerHandler( "remove" );
325
                // http://bugs.jquery.com/ticket/8235
326
                } catch( e ) {}
327
        }
328
        _cleanData( elems );
329
};
330

    
331
$.widget = function( name, base, prototype ) {
332
        var fullName, existingConstructor, constructor, basePrototype,
333
                // proxiedPrototype allows the provided prototype to remain unmodified
334
                // so that it can be used as a mixin for multiple widgets (#8876)
335
                proxiedPrototype = {},
336
                namespace = name.split( "." )[ 0 ];
337

    
338
        name = name.split( "." )[ 1 ];
339
        fullName = namespace + "-" + name;
340

    
341
        if ( !prototype ) {
342
                prototype = base;
343
                base = $.Widget;
344
        }
345

    
346
        // create selector for plugin
347
        $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
348
                return !!$.data( elem, fullName );
349
        };
350

    
351
        $[ namespace ] = $[ namespace ] || {};
352
        existingConstructor = $[ namespace ][ name ];
353
        constructor = $[ namespace ][ name ] = function( options, element ) {
354
                // allow instantiation without "new" keyword
355
                if ( !this._createWidget ) {
356
                        return new constructor( options, element );
357
                }
358

    
359
                // allow instantiation without initializing for simple inheritance
360
                // must use "new" keyword (the code above always passes args)
361
                if ( arguments.length ) {
362
                        this._createWidget( options, element );
363
                }
364
        };
365
        // extend with the existing constructor to carry over any static properties
366
        $.extend( constructor, existingConstructor, {
367
                version: prototype.version,
368
                // copy the object used to create the prototype in case we need to
369
                // redefine the widget later
370
                _proto: $.extend( {}, prototype ),
371
                // track widgets that inherit from this widget in case this widget is
372
                // redefined after a widget inherits from it
373
                _childConstructors: []
374
        });
375

    
376
        basePrototype = new base();
377
        // we need to make the options hash a property directly on the new instance
378
        // otherwise we'll modify the options hash on the prototype that we're
379
        // inheriting from
380
        basePrototype.options = $.widget.extend( {}, basePrototype.options );
381
        $.each( prototype, function( prop, value ) {
382
                if ( !$.isFunction( value ) ) {
383
                        proxiedPrototype[ prop ] = value;
384
                        return;
385
                }
386
                proxiedPrototype[ prop ] = (function() {
387
                        var _super = function() {
388
                                        return base.prototype[ prop ].apply( this, arguments );
389
                                },
390
                                _superApply = function( args ) {
391
                                        return base.prototype[ prop ].apply( this, args );
392
                                };
393
                        return function() {
394
                                var __super = this._super,
395
                                        __superApply = this._superApply,
396
                                        returnValue;
397

    
398
                                this._super = _super;
399
                                this._superApply = _superApply;
400

    
401
                                returnValue = value.apply( this, arguments );
402

    
403
                                this._super = __super;
404
                                this._superApply = __superApply;
405

    
406
                                return returnValue;
407
                        };
408
                })();
409
        });
410
        constructor.prototype = $.widget.extend( basePrototype, {
411
                // TODO: remove support for widgetEventPrefix
412
                // always use the name + a colon as the prefix, e.g., draggable:start
413
                // don't prefix for widgets that aren't DOM-based
414
                widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
415
        }, proxiedPrototype, {
416
                constructor: constructor,
417
                namespace: namespace,
418
                widgetName: name,
419
                widgetFullName: fullName
420
        });
421

    
422
        // If this widget is being redefined then we need to find all widgets that
423
        // are inheriting from it and redefine all of them so that they inherit from
424
        // the new version of this widget. We're essentially trying to replace one
425
        // level in the prototype chain.
426
        if ( existingConstructor ) {
427
                $.each( existingConstructor._childConstructors, function( i, child ) {
428
                        var childPrototype = child.prototype;
429

    
430
                        // redefine the child widget using the same prototype that was
431
                        // originally used, but inherit from the new version of the base
432
                        $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
433
                });
434
                // remove the list of existing child constructors from the old constructor
435
                // so the old child constructors can be garbage collected
436
                delete existingConstructor._childConstructors;
437
        } else {
438
                base._childConstructors.push( constructor );
439
        }
440

    
441
        $.widget.bridge( name, constructor );
442
};
443

    
444
$.widget.extend = function( target ) {
445
        var input = slice.call( arguments, 1 ),
446
                inputIndex = 0,
447
                inputLength = input.length,
448
                key,
449
                value;
450
        for ( ; inputIndex < inputLength; inputIndex++ ) {
451
                for ( key in input[ inputIndex ] ) {
452
                        value = input[ inputIndex ][ key ];
453
                        if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
454
                                // Clone objects
455
                                if ( $.isPlainObject( value ) ) {
456
                                        target[ key ] = $.isPlainObject( target[ key ] ) ?
457
                                                $.widget.extend( {}, target[ key ], value ) :
458
                                                // Don't extend strings, arrays, etc. with objects
459
                                                $.widget.extend( {}, value );
460
                                // Copy everything else by reference
461
                                } else {
462
                                        target[ key ] = value;
463
                                }
464
                        }
465
                }
466
        }
467
        return target;
468
};
469

    
470
$.widget.bridge = function( name, object ) {
471
        var fullName = object.prototype.widgetFullName || name;
472
        $.fn[ name ] = function( options ) {
473
                var isMethodCall = typeof options === "string",
474
                        args = slice.call( arguments, 1 ),
475
                        returnValue = this;
476

    
477
                // allow multiple hashes to be passed on init
478
                options = !isMethodCall && args.length ?
479
                        $.widget.extend.apply( null, [ options ].concat(args) ) :
480
                        options;
481

    
482
                if ( isMethodCall ) {
483
                        this.each(function() {
484
                                var methodValue,
485
                                        instance = $.data( this, fullName );
486
                                if ( !instance ) {
487
                                        return $.error( "cannot call methods on " + name + " prior to initialization; " +
488
                                                "attempted to call method '" + options + "'" );
489
                                }
490
                                if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
491
                                        return $.error( "no such method '" + options + "' for " + name + " widget instance" );
492
                                }
493
                                methodValue = instance[ options ].apply( instance, args );
494
                                if ( methodValue !== instance && methodValue !== undefined ) {
495
                                        returnValue = methodValue && methodValue.jquery ?
496
                                                returnValue.pushStack( methodValue.get() ) :
497
                                                methodValue;
498
                                        return false;
499
                                }
500
                        });
501
                } else {
502
                        this.each(function() {
503
                                var instance = $.data( this, fullName );
504
                                if ( instance ) {
505
                                        instance.option( options || {} )._init();
506
                                } else {
507
                                        $.data( this, fullName, new object( options, this ) );
508
                                }
509
                        });
510
                }
511

    
512
                return returnValue;
513
        };
514
};
515

    
516
$.Widget = function( /* options, element */ ) {};
517
$.Widget._childConstructors = [];
518

    
519
$.Widget.prototype = {
520
        widgetName: "widget",
521
        widgetEventPrefix: "",
522
        defaultElement: "<div>",
523
        options: {
524
                disabled: false,
525

    
526
                // callbacks
527
                create: null
528
        },
529
        _createWidget: function( options, element ) {
530
                element = $( element || this.defaultElement || this )[ 0 ];
531
                this.element = $( element );
532
                this.uuid = uuid++;
533
                this.eventNamespace = "." + this.widgetName + this.uuid;
534
                this.options = $.widget.extend( {},
535
                        this.options,
536
                        this._getCreateOptions(),
537
                        options );
538

    
539
                this.bindings = $();
540
                this.hoverable = $();
541
                this.focusable = $();
542

    
543
                if ( element !== this ) {
544
                        $.data( element, this.widgetFullName, this );
545
                        this._on( true, this.element, {
546
                                remove: function( event ) {
547
                                        if ( event.target === element ) {
548
                                                this.destroy();
549
                                        }
550
                                }
551
                        });
552
                        this.document = $( element.style ?
553
                                // element within the document
554
                                element.ownerDocument :
555
                                // element is window or document
556
                                element.document || element );
557
                        this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
558
                }
559

    
560
                this._create();
561
                this._trigger( "create", null, this._getCreateEventData() );
562
                this._init();
563
        },
564
        _getCreateOptions: $.noop,
565
        _getCreateEventData: $.noop,
566
        _create: $.noop,
567
        _init: $.noop,
568

    
569
        destroy: function() {
570
                this._destroy();
571
                // we can probably remove the unbind calls in 2.0
572
                // all event bindings should go through this._on()
573
                this.element
574
                        .unbind( this.eventNamespace )
575
                        // 1.9 BC for #7810
576
                        // TODO remove dual storage
577
                        .removeData( this.widgetName )
578
                        .removeData( this.widgetFullName )
579
                        // support: jquery <1.6.3
580
                        // http://bugs.jquery.com/ticket/9413
581
                        .removeData( $.camelCase( this.widgetFullName ) );
582
                this.widget()
583
                        .unbind( this.eventNamespace )
584
                        .removeAttr( "aria-disabled" )
585
                        .removeClass(
586
                                this.widgetFullName + "-disabled " +
587
                                "ui-state-disabled" );
588

    
589
                // clean up events and states
590
                this.bindings.unbind( this.eventNamespace );
591
                this.hoverable.removeClass( "ui-state-hover" );
592
                this.focusable.removeClass( "ui-state-focus" );
593
        },
594
        _destroy: $.noop,
595

    
596
        widget: function() {
597
                return this.element;
598
        },
599

    
600
        option: function( key, value ) {
601
                var options = key,
602
                        parts,
603
                        curOption,
604
                        i;
605

    
606
                if ( arguments.length === 0 ) {
607
                        // don't return a reference to the internal hash
608
                        return $.widget.extend( {}, this.options );
609
                }
610

    
611
                if ( typeof key === "string" ) {
612
                        // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
613
                        options = {};
614
                        parts = key.split( "." );
615
                        key = parts.shift();
616
                        if ( parts.length ) {
617
                                curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
618
                                for ( i = 0; i < parts.length - 1; i++ ) {
619
                                        curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
620
                                        curOption = curOption[ parts[ i ] ];
621
                                }
622
                                key = parts.pop();
623
                                if ( value === undefined ) {
624
                                        return curOption[ key ] === undefined ? null : curOption[ key ];
625
                                }
626
                                curOption[ key ] = value;
627
                        } else {
628
                                if ( value === undefined ) {
629
                                        return this.options[ key ] === undefined ? null : this.options[ key ];
630
                                }
631
                                options[ key ] = value;
632
                        }
633
                }
634

    
635
                this._setOptions( options );
636

    
637
                return this;
638
        },
639
        _setOptions: function( options ) {
640
                var key;
641

    
642
                for ( key in options ) {
643
                        this._setOption( key, options[ key ] );
644
                }
645

    
646
                return this;
647
        },
648
        _setOption: function( key, value ) {
649
                this.options[ key ] = value;
650

    
651
                if ( key === "disabled" ) {
652
                        this.widget()
653
                                .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
654
                                .attr( "aria-disabled", value );
655
                        this.hoverable.removeClass( "ui-state-hover" );
656
                        this.focusable.removeClass( "ui-state-focus" );
657
                }
658

    
659
                return this;
660
        },
661

    
662
        enable: function() {
663
                return this._setOption( "disabled", false );
664
        },
665
        disable: function() {
666
                return this._setOption( "disabled", true );
667
        },
668

    
669
        _on: function( suppressDisabledCheck, element, handlers ) {
670
                var delegateElement,
671
                        instance = this;
672

    
673
                // no suppressDisabledCheck flag, shuffle arguments
674
                if ( typeof suppressDisabledCheck !== "boolean" ) {
675
                        handlers = element;
676
                        element = suppressDisabledCheck;
677
                        suppressDisabledCheck = false;
678
                }
679

    
680
                // no element argument, shuffle and use this.element
681
                if ( !handlers ) {
682
                        handlers = element;
683
                        element = this.element;
684
                        delegateElement = this.widget();
685
                } else {
686
                        // accept selectors, DOM elements
687
                        element = delegateElement = $( element );
688
                        this.bindings = this.bindings.add( element );
689
                }
690

    
691
                $.each( handlers, function( event, handler ) {
692
                        function handlerProxy() {
693
                                // allow widgets to customize the disabled handling
694
                                // - disabled as an array instead of boolean
695
                                // - disabled class as method for disabling individual parts
696
                                if ( !suppressDisabledCheck &&
697
                                                ( instance.options.disabled === true ||
698
                                                        $( this ).hasClass( "ui-state-disabled" ) ) ) {
699
                                        return;
700
                                }
701
                                return ( typeof handler === "string" ? instance[ handler ] : handler )
702
                                        .apply( instance, arguments );
703
                        }
704

    
705
                        // copy the guid so direct unbinding works
706
                        if ( typeof handler !== "string" ) {
707
                                handlerProxy.guid = handler.guid =
708
                                        handler.guid || handlerProxy.guid || $.guid++;
709
                        }
710

    
711
                        var match = event.match( /^(\w+)\s*(.*)$/ ),
712
                                eventName = match[1] + instance.eventNamespace,
713
                                selector = match[2];
714
                        if ( selector ) {
715
                                delegateElement.delegate( selector, eventName, handlerProxy );
716
                        } else {
717
                                element.bind( eventName, handlerProxy );
718
                        }
719
                });
720
        },
721

    
722
        _off: function( element, eventName ) {
723
                eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
724
                element.unbind( eventName ).undelegate( eventName );
725
        },
726

    
727
        _delay: function( handler, delay ) {
728
                function handlerProxy() {
729
                        return ( typeof handler === "string" ? instance[ handler ] : handler )
730
                                .apply( instance, arguments );
731
                }
732
                var instance = this;
733
                return setTimeout( handlerProxy, delay || 0 );
734
        },
735

    
736
        _hoverable: function( element ) {
737
                this.hoverable = this.hoverable.add( element );
738
                this._on( element, {
739
                        mouseenter: function( event ) {
740
                                $( event.currentTarget ).addClass( "ui-state-hover" );
741
                        },
742
                        mouseleave: function( event ) {
743
                                $( event.currentTarget ).removeClass( "ui-state-hover" );
744
                        }
745
                });
746
        },
747

    
748
        _focusable: function( element ) {
749
                this.focusable = this.focusable.add( element );
750
                this._on( element, {
751
                        focusin: function( event ) {
752
                                $( event.currentTarget ).addClass( "ui-state-focus" );
753
                        },
754
                        focusout: function( event ) {
755
                                $( event.currentTarget ).removeClass( "ui-state-focus" );
756
                        }
757
                });
758
        },
759

    
760
        _trigger: function( type, event, data ) {
761
                var prop, orig,
762
                        callback = this.options[ type ];
763

    
764
                data = data || {};
765
                event = $.Event( event );
766
                event.type = ( type === this.widgetEventPrefix ?
767
                        type :
768
                        this.widgetEventPrefix + type ).toLowerCase();
769
                // the original event may come from any element
770
                // so we need to reset the target on the new event
771
                event.target = this.element[ 0 ];
772

    
773
                // copy original event properties over to the new event
774
                orig = event.originalEvent;
775
                if ( orig ) {
776
                        for ( prop in orig ) {
777
                                if ( !( prop in event ) ) {
778
                                        event[ prop ] = orig[ prop ];
779
                                }
780
                        }
781
                }
782

    
783
                this.element.trigger( event, data );
784
                return !( $.isFunction( callback ) &&
785
                        callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
786
                        event.isDefaultPrevented() );
787
        }
788
};
789

    
790
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
791
        $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
792
                if ( typeof options === "string" ) {
793
                        options = { effect: options };
794
                }
795
                var hasOptions,
796
                        effectName = !options ?
797
                                method :
798
                                options === true || typeof options === "number" ?
799
                                        defaultEffect :
800
                                        options.effect || defaultEffect;
801
                options = options || {};
802
                if ( typeof options === "number" ) {
803
                        options = { duration: options };
804
                }
805
                hasOptions = !$.isEmptyObject( options );
806
                options.complete = callback;
807
                if ( options.delay ) {
808
                        element.delay( options.delay );
809
                }
810
                if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
811
                        element[ method ]( options );
812
                } else if ( effectName !== method && element[ effectName ] ) {
813
                        element[ effectName ]( options.duration, options.easing, callback );
814
                } else {
815
                        element.queue(function( next ) {
816
                                $( this )[ method ]();
817
                                if ( callback ) {
818
                                        callback.call( element[ 0 ] );
819
                                }
820
                                next();
821
                        });
822
                }
823
        };
824
});
825

    
826
})( jQuery );
827

    
828
(function( $, undefined ) {
829

    
830
var mouseHandled = false;
831
$( document ).mouseup( function() {
832
        mouseHandled = false;
833
});
834

    
835
$.widget("ui.mouse", {
836
        version: "1.10.2",
837
        options: {
838
                cancel: "input,textarea,button,select,option",
839
                distance: 1,
840
                delay: 0
841
        },
842
        _mouseInit: function() {
843
                var that = this;
844

    
845
                this.element
846
                        .bind("mousedown."+this.widgetName, function(event) {
847
                                return that._mouseDown(event);
848
                        })
849
                        .bind("click."+this.widgetName, function(event) {
850
                                if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
851
                                        $.removeData(event.target, that.widgetName + ".preventClickEvent");
852
                                        event.stopImmediatePropagation();
853
                                        return false;
854
                                }
855
                        });
856

    
857
                this.started = false;
858
        },
859

    
860
        // TODO: make sure destroying one instance of mouse doesn't mess with
861
        // other instances of mouse
862
        _mouseDestroy: function() {
863
                this.element.unbind("."+this.widgetName);
864
                if ( this._mouseMoveDelegate ) {
865
                        $(document)
866
                                .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
867
                                .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
868
                }
869
        },
870

    
871
        _mouseDown: function(event) {
872
                // don't let more than one widget handle mouseStart
873
                if( mouseHandled ) { return; }
874

    
875
                // we may have missed mouseup (out of window)
876
                (this._mouseStarted && this._mouseUp(event));
877

    
878
                this._mouseDownEvent = event;
879

    
880
                var that = this,
881
                        btnIsLeft = (event.which === 1),
882
                        // event.target.nodeName works around a bug in IE 8 with
883
                        // disabled inputs (#7620)
884
                        elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
885
                if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
886
                        return true;
887
                }
888

    
889
                this.mouseDelayMet = !this.options.delay;
890
                if (!this.mouseDelayMet) {
891
                        this._mouseDelayTimer = setTimeout(function() {
892
                                that.mouseDelayMet = true;
893
                        }, this.options.delay);
894
                }
895

    
896
                if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
897
                        this._mouseStarted = (this._mouseStart(event) !== false);
898
                        if (!this._mouseStarted) {
899
                                event.preventDefault();
900
                                return true;
901
                        }
902
                }
903

    
904
                // Click event may never have fired (Gecko & Opera)
905
                if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
906
                        $.removeData(event.target, this.widgetName + ".preventClickEvent");
907
                }
908

    
909
                // these delegates are required to keep context
910
                this._mouseMoveDelegate = function(event) {
911
                        return that._mouseMove(event);
912
                };
913
                this._mouseUpDelegate = function(event) {
914
                        return that._mouseUp(event);
915
                };
916
                $(document)
917
                        .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
918
                        .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
919

    
920
                event.preventDefault();
921

    
922
                mouseHandled = true;
923
                return true;
924
        },
925

    
926
        _mouseMove: function(event) {
927
                // IE mouseup check - mouseup happened when mouse was out of window
928
                if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
929
                        return this._mouseUp(event);
930
                }
931

    
932
                if (this._mouseStarted) {
933
                        this._mouseDrag(event);
934
                        return event.preventDefault();
935
                }
936

    
937
                if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
938
                        this._mouseStarted =
939
                                (this._mouseStart(this._mouseDownEvent, event) !== false);
940
                        (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
941
                }
942

    
943
                return !this._mouseStarted;
944
        },
945

    
946
        _mouseUp: function(event) {
947
                $(document)
948
                        .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
949
                        .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
950

    
951
                if (this._mouseStarted) {
952
                        this._mouseStarted = false;
953

    
954
                        if (event.target === this._mouseDownEvent.target) {
955
                                $.data(event.target, this.widgetName + ".preventClickEvent", true);
956
                        }
957

    
958
                        this._mouseStop(event);
959
                }
960

    
961
                return false;
962
        },
963

    
964
        _mouseDistanceMet: function(event) {
965
                return (Math.max(
966
                                Math.abs(this._mouseDownEvent.pageX - event.pageX),
967
                                Math.abs(this._mouseDownEvent.pageY - event.pageY)
968
                        ) >= this.options.distance
969
                );
970
        },
971

    
972
        _mouseDelayMet: function(/* event */) {
973
                return this.mouseDelayMet;
974
        },
975

    
976
        // These are placeholder methods, to be overriden by extending plugin
977
        _mouseStart: function(/* event */) {},
978
        _mouseDrag: function(/* event */) {},
979
        _mouseStop: function(/* event */) {},
980
        _mouseCapture: function(/* event */) { return true; }
981
});
982

    
983
})(jQuery);
984

    
985
(function( $, undefined ) {
986

    
987
$.widget("ui.draggable", $.ui.mouse, {
988
        version: "1.10.2",
989
        widgetEventPrefix: "drag",
990
        options: {
991
                addClasses: true,
992
                appendTo: "parent",
993
                axis: false,
994
                connectToSortable: false,
995
                containment: false,
996
                cursor: "auto",
997
                cursorAt: false,
998
                grid: false,
999
                handle: false,
1000
                helper: "original",
1001
                iframeFix: false,
1002
                opacity: false,
1003
                refreshPositions: false,
1004
                revert: false,
1005
                revertDuration: 500,
1006
                scope: "default",
1007
                scroll: true,
1008
                scrollSensitivity: 20,
1009
                scrollSpeed: 20,
1010
                snap: false,
1011
                snapMode: "both",
1012
                snapTolerance: 20,
1013
                stack: false,
1014
                zIndex: false,
1015

    
1016
                // callbacks
1017
                drag: null,
1018
                start: null,
1019
                stop: null
1020
        },
1021
        _create: function() {
1022

    
1023
                if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1024
                        this.element[0].style.position = "relative";
1025
                }
1026
                if (this.options.addClasses){
1027
                        this.element.addClass("ui-draggable");
1028
                }
1029
                if (this.options.disabled){
1030
                        this.element.addClass("ui-draggable-disabled");
1031
                }
1032

    
1033
                this._mouseInit();
1034

    
1035
        },
1036

    
1037
        _destroy: function() {
1038
                this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1039
                this._mouseDestroy();
1040
        },
1041

    
1042
        _mouseCapture: function(event) {
1043

    
1044
                var o = this.options;
1045

    
1046
                // among others, prevent a drag on a resizable-handle
1047
                if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1048
                        return false;
1049
                }
1050

    
1051
                //Quit if we're not on a valid handle
1052
                this.handle = this._getHandle(event);
1053
                if (!this.handle) {
1054
                        return false;
1055
                }
1056

    
1057
                $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1058
                        $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1059
                        .css({
1060
                                width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1061
                                position: "absolute", opacity: "0.001", zIndex: 1000
1062
                        })
1063
                        .css($(this).offset())
1064
                        .appendTo("body");
1065
                });
1066

    
1067
                return true;
1068

    
1069
        },
1070

    
1071
        _mouseStart: function(event) {
1072

    
1073
                var o = this.options;
1074

    
1075
                //Create and append the visible helper
1076
                this.helper = this._createHelper(event);
1077

    
1078
                this.helper.addClass("ui-draggable-dragging");
1079

    
1080
                //Cache the helper size
1081
                this._cacheHelperProportions();
1082

    
1083
                //If ddmanager is used for droppables, set the global draggable
1084
                if($.ui.ddmanager) {
1085
                        $.ui.ddmanager.current = this;
1086
                }
1087

    
1088
                /*
1089
                 * - Position generation -
1090
                 * This block generates everything position related - it's the core of draggables.
1091
                 */
1092

    
1093
                //Cache the margins of the original element
1094
                this._cacheMargins();
1095

    
1096
                //Store the helper's css position
1097
                this.cssPosition = this.helper.css("position");
1098
                this.scrollParent = this.helper.scrollParent();
1099

    
1100
                //The element's absolute position on the page minus margins
1101
                this.offset = this.positionAbs = this.element.offset();
1102
                this.offset = {
1103
                        top: this.offset.top - this.margins.top,
1104
                        left: this.offset.left - this.margins.left
1105
                };
1106

    
1107
                $.extend(this.offset, {
1108
                        click: { //Where the click happened, relative to the element
1109
                                left: event.pageX - this.offset.left,
1110
                                top: event.pageY - this.offset.top
1111
                        },
1112
                        parent: this._getParentOffset(),
1113
                        relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1114
                });
1115

    
1116
                //Generate the original position
1117
                this.originalPosition = this.position = this._generatePosition(event);
1118
                this.originalPageX = event.pageX;
1119
                this.originalPageY = event.pageY;
1120

    
1121
                //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1122
                (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1123

    
1124
                //Set a containment if given in the options
1125
                if(o.containment) {
1126
                        this._setContainment();
1127
                }
1128

    
1129
                //Trigger event + callbacks
1130
                if(this._trigger("start", event) === false) {
1131
                        this._clear();
1132
                        return false;
1133
                }
1134

    
1135
                //Recache the helper size
1136
                this._cacheHelperProportions();
1137

    
1138
                //Prepare the droppable offsets
1139
                if ($.ui.ddmanager && !o.dropBehaviour) {
1140
                        $.ui.ddmanager.prepareOffsets(this, event);
1141
                }
1142

    
1143

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

    
1146
                //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1147
                if ( $.ui.ddmanager ) {
1148
                        $.ui.ddmanager.dragStart(this, event);
1149
                }
1150

    
1151
                return true;
1152
        },
1153

    
1154
        _mouseDrag: function(event, noPropagation) {
1155

    
1156
                //Compute the helpers position
1157
                this.position = this._generatePosition(event);
1158
                this.positionAbs = this._convertPositionTo("absolute");
1159

    
1160
                //Call plugins and callbacks and use the resulting position if something is returned
1161
                if (!noPropagation) {
1162
                        var ui = this._uiHash();
1163
                        if(this._trigger("drag", event, ui) === false) {
1164
                                this._mouseUp({});
1165
                                return false;
1166
                        }
1167
                        this.position = ui.position;
1168
                }
1169

    
1170
                if(!this.options.axis || this.options.axis !== "y") {
1171
                        this.helper[0].style.left = this.position.left+"px";
1172
                }
1173
                if(!this.options.axis || this.options.axis !== "x") {
1174
                        this.helper[0].style.top = this.position.top+"px";
1175
                }
1176
                if($.ui.ddmanager) {
1177
                        $.ui.ddmanager.drag(this, event);
1178
                }
1179

    
1180
                return false;
1181
        },
1182

    
1183
        _mouseStop: function(event) {
1184

    
1185
                //If we are using droppables, inform the manager about the drop
1186
                var element,
1187
                        that = this,
1188
                        elementInDom = false,
1189
                        dropped = false;
1190
                if ($.ui.ddmanager && !this.options.dropBehaviour) {
1191
                        dropped = $.ui.ddmanager.drop(this, event);
1192
                }
1193

    
1194
                //if a drop comes from outside (a sortable)
1195
                if(this.dropped) {
1196
                        dropped = this.dropped;
1197
                        this.dropped = false;
1198
                }
1199

    
1200
                //if the original element is no longer in the DOM don't bother to continue (see #8269)
1201
                element = this.element[0];
1202
                while ( element && (element = element.parentNode) ) {
1203
                        if (element === document ) {
1204
                                elementInDom = true;
1205
                        }
1206
                }
1207
                if ( !elementInDom && this.options.helper === "original" ) {
1208
                        return false;
1209
                }
1210

    
1211
                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))) {
1212
                        $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1213
                                if(that._trigger("stop", event) !== false) {
1214
                                        that._clear();
1215
                                }
1216
                        });
1217
                } else {
1218
                        if(this._trigger("stop", event) !== false) {
1219
                                this._clear();
1220
                        }
1221
                }
1222

    
1223
                return false;
1224
        },
1225

    
1226
        _mouseUp: function(event) {
1227
                //Remove frame helpers
1228
                $("div.ui-draggable-iframeFix").each(function() {
1229
                        this.parentNode.removeChild(this);
1230
                });
1231

    
1232
                //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1233
                if( $.ui.ddmanager ) {
1234
                        $.ui.ddmanager.dragStop(this, event);
1235
                }
1236

    
1237
                return $.ui.mouse.prototype._mouseUp.call(this, event);
1238
        },
1239

    
1240
        cancel: function() {
1241

    
1242
                if(this.helper.is(".ui-draggable-dragging")) {
1243
                        this._mouseUp({});
1244
                } else {
1245
                        this._clear();
1246
                }
1247

    
1248
                return this;
1249

    
1250
        },
1251

    
1252
        _getHandle: function(event) {
1253
                return this.options.handle ?
1254
                        !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1255
                        true;
1256
        },
1257

    
1258
        _createHelper: function(event) {
1259

    
1260
                var o = this.options,
1261
                        helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1262

    
1263
                if(!helper.parents("body").length) {
1264
                        helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1265
                }
1266

    
1267
                if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1268
                        helper.css("position", "absolute");
1269
                }
1270

    
1271
                return helper;
1272

    
1273
        },
1274

    
1275
        _adjustOffsetFromHelper: function(obj) {
1276
                if (typeof obj === "string") {
1277
                        obj = obj.split(" ");
1278
                }
1279
                if ($.isArray(obj)) {
1280
                        obj = {left: +obj[0], top: +obj[1] || 0};
1281
                }
1282
                if ("left" in obj) {
1283
                        this.offset.click.left = obj.left + this.margins.left;
1284
                }
1285
                if ("right" in obj) {
1286
                        this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1287
                }
1288
                if ("top" in obj) {
1289
                        this.offset.click.top = obj.top + this.margins.top;
1290
                }
1291
                if ("bottom" in obj) {
1292
                        this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1293
                }
1294
        },
1295

    
1296
        _getParentOffset: function() {
1297

    
1298
                //Get the offsetParent and cache its position
1299
                this.offsetParent = this.helper.offsetParent();
1300
                var po = this.offsetParent.offset();
1301

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

    
1311
                //This needs to be actually done for all browsers, since pageX/pageY includes this information
1312
                //Ugly IE fix
1313
                if((this.offsetParent[0] === document.body) ||
1314
                        (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1315
                        po = { top: 0, left: 0 };
1316
                }
1317

    
1318
                return {
1319
                        top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1320
                        left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1321
                };
1322

    
1323
        },
1324

    
1325
        _getRelativeOffset: function() {
1326

    
1327
                if(this.cssPosition === "relative") {
1328
                        var p = this.element.position();
1329
                        return {
1330
                                top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1331
                                left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1332
                        };
1333
                } else {
1334
                        return { top: 0, left: 0 };
1335
                }
1336

    
1337
        },
1338

    
1339
        _cacheMargins: function() {
1340
                this.margins = {
1341
                        left: (parseInt(this.element.css("marginLeft"),10) || 0),
1342
                        top: (parseInt(this.element.css("marginTop"),10) || 0),
1343
                        right: (parseInt(this.element.css("marginRight"),10) || 0),
1344
                        bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1345
                };
1346
        },
1347

    
1348
        _cacheHelperProportions: function() {
1349
                this.helperProportions = {
1350
                        width: this.helper.outerWidth(),
1351
                        height: this.helper.outerHeight()
1352
                };
1353
        },
1354

    
1355
        _setContainment: function() {
1356

    
1357
                var over, c, ce,
1358
                        o = this.options;
1359

    
1360
                if(o.containment === "parent") {
1361
                        o.containment = this.helper[0].parentNode;
1362
                }
1363
                if(o.containment === "document" || o.containment === "window") {
1364
                        this.containment = [
1365
                                o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1366
                                o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1367
                                (o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
1368
                                (o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1369
                        ];
1370
                }
1371

    
1372
                if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) {
1373
                        c = $(o.containment);
1374
                        ce = c[0];
1375

    
1376
                        if(!ce) {
1377
                                return;
1378
                        }
1379

    
1380
                        over = ($(ce).css("overflow") !== "hidden");
1381

    
1382
                        this.containment = [
1383
                                (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1384
                                (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1385
                                (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderRightWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
1386
                                (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderBottomWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
1387
                        ];
1388
                        this.relative_container = c;
1389

    
1390
                } else if(o.containment.constructor === Array) {
1391
                        this.containment = o.containment;
1392
                }
1393

    
1394
        },
1395

    
1396
        _convertPositionTo: function(d, pos) {
1397

    
1398
                if(!pos) {
1399
                        pos = this.position;
1400
                }
1401

    
1402
                var mod = d === "absolute" ? 1 : -1,
1403
                        scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1404

    
1405
                return {
1406
                        top: (
1407
                                pos.top        +                                                                                                                                // The absolute mouse position
1408
                                this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1409
                                this.offset.parent.top * mod -                                                                                // The offsetParent's offset without borders (offset + border)
1410
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1411
                        ),
1412
                        left: (
1413
                                pos.left +                                                                                                                                // The absolute mouse position
1414
                                this.offset.relative.left * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1415
                                this.offset.parent.left * mod        -                                                                                // The offsetParent's offset without borders (offset + border)
1416
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1417
                        )
1418
                };
1419

    
1420
        },
1421

    
1422
        _generatePosition: function(event) {
1423

    
1424
                var containment, co, top, left,
1425
                        o = this.options,
1426
                        scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
1427
                        scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName),
1428
                        pageX = event.pageX,
1429
                        pageY = event.pageY;
1430

    
1431
                /*
1432
                 * - Position constraining -
1433
                 * Constrain the position to a mix of grid, containment.
1434
                 */
1435

    
1436
                if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1437
                        if(this.containment) {
1438
                        if (this.relative_container){
1439
                                co = this.relative_container.offset();
1440
                                containment = [ this.containment[0] + co.left,
1441
                                        this.containment[1] + co.top,
1442
                                        this.containment[2] + co.left,
1443
                                        this.containment[3] + co.top ];
1444
                        }
1445
                        else {
1446
                                containment = this.containment;
1447
                        }
1448

    
1449
                                if(event.pageX - this.offset.click.left < containment[0]) {
1450
                                        pageX = containment[0] + this.offset.click.left;
1451
                                }
1452
                                if(event.pageY - this.offset.click.top < containment[1]) {
1453
                                        pageY = containment[1] + this.offset.click.top;
1454
                                }
1455
                                if(event.pageX - this.offset.click.left > containment[2]) {
1456
                                        pageX = containment[2] + this.offset.click.left;
1457
                                }
1458
                                if(event.pageY - this.offset.click.top > containment[3]) {
1459
                                        pageY = containment[3] + this.offset.click.top;
1460
                                }
1461
                        }
1462

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

    
1468
                                left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1469
                                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;
1470
                        }
1471

    
1472
                }
1473

    
1474
                return {
1475
                        top: (
1476
                                pageY -                                                                                                                                        // The absolute mouse position
1477
                                this.offset.click.top        -                                                                                                // Click offset (relative to the element)
1478
                                this.offset.relative.top -                                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1479
                                this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
1480
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1481
                        ),
1482
                        left: (
1483
                                pageX -                                                                                                                                        // The absolute mouse position
1484
                                this.offset.click.left -                                                                                                // Click offset (relative to the element)
1485
                                this.offset.relative.left -                                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1486
                                this.offset.parent.left +                                                                                                // The offsetParent's offset without borders (offset + border)
1487
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1488
                        )
1489
                };
1490

    
1491
        },
1492

    
1493
        _clear: function() {
1494
                this.helper.removeClass("ui-draggable-dragging");
1495
                if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
1496
                        this.helper.remove();
1497
                }
1498
                this.helper = null;
1499
                this.cancelHelperRemoval = false;
1500
        },
1501

    
1502
        // From now on bulk stuff - mainly helpers
1503

    
1504
        _trigger: function(type, event, ui) {
1505
                ui = ui || this._uiHash();
1506
                $.ui.plugin.call(this, type, [event, ui]);
1507
                //The absolute position has to be recalculated after plugins
1508
                if(type === "drag") {
1509
                        this.positionAbs = this._convertPositionTo("absolute");
1510
                }
1511
                return $.Widget.prototype._trigger.call(this, type, event, ui);
1512
        },
1513

    
1514
        plugins: {},
1515

    
1516
        _uiHash: function() {
1517
                return {
1518
                        helper: this.helper,
1519
                        position: this.position,
1520
                        originalPosition: this.originalPosition,
1521
                        offset: this.positionAbs
1522
                };
1523
        }
1524

    
1525
});
1526

    
1527
$.ui.plugin.add("draggable", "connectToSortable", {
1528
        start: function(event, ui) {
1529

    
1530
                var inst = $(this).data("ui-draggable"), o = inst.options,
1531
                        uiSortable = $.extend({}, ui, { item: inst.element });
1532
                inst.sortables = [];
1533
                $(o.connectToSortable).each(function() {
1534
                        var sortable = $.data(this, "ui-sortable");
1535
                        if (sortable && !sortable.options.disabled) {
1536
                                inst.sortables.push({
1537
                                        instance: sortable,
1538
                                        shouldRevert: sortable.options.revert
1539
                                });
1540
                                sortable.refreshPositions();        // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
1541
                                sortable._trigger("activate", event, uiSortable);
1542
                        }
1543
                });
1544

    
1545
        },
1546
        stop: function(event, ui) {
1547

    
1548
                //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1549
                var inst = $(this).data("ui-draggable"),
1550
                        uiSortable = $.extend({}, ui, { item: inst.element });
1551

    
1552
                $.each(inst.sortables, function() {
1553
                        if(this.instance.isOver) {
1554

    
1555
                                this.instance.isOver = 0;
1556

    
1557
                                inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1558
                                this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1559

    
1560
                                //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
1561
                                if(this.shouldRevert) {
1562
                                        this.instance.options.revert = this.shouldRevert;
1563
                                }
1564

    
1565
                                //Trigger the stop of the sortable
1566
                                this.instance._mouseStop(event);
1567

    
1568
                                this.instance.options.helper = this.instance.options._helper;
1569

    
1570
                                //If the helper has been the original item, restore properties in the sortable
1571
                                if(inst.options.helper === "original") {
1572
                                        this.instance.currentItem.css({ top: "auto", left: "auto" });
1573
                                }
1574

    
1575
                        } else {
1576
                                this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1577
                                this.instance._trigger("deactivate", event, uiSortable);
1578
                        }
1579

    
1580
                });
1581

    
1582
        },
1583
        drag: function(event, ui) {
1584

    
1585
                var inst = $(this).data("ui-draggable"), that = this;
1586

    
1587
                $.each(inst.sortables, function() {
1588

    
1589
                        var innermostIntersecting = false,
1590
                                thisSortable = this;
1591

    
1592
                        //Copy over some variables to allow calling the sortable's native _intersectsWith
1593
                        this.instance.positionAbs = inst.positionAbs;
1594
                        this.instance.helperProportions = inst.helperProportions;
1595
                        this.instance.offset.click = inst.offset.click;
1596

    
1597
                        if(this.instance._intersectsWith(this.instance.containerCache)) {
1598
                                innermostIntersecting = true;
1599
                                $.each(inst.sortables, function () {
1600
                                        this.instance.positionAbs = inst.positionAbs;
1601
                                        this.instance.helperProportions = inst.helperProportions;
1602
                                        this.instance.offset.click = inst.offset.click;
1603
                                        if (this !== thisSortable &&
1604
                                                this.instance._intersectsWith(this.instance.containerCache) &&
1605
                                                $.contains(thisSortable.instance.element[0], this.instance.element[0])
1606
                                        ) {
1607
                                                innermostIntersecting = false;
1608
                                        }
1609
                                        return innermostIntersecting;
1610
                                });
1611
                        }
1612

    
1613

    
1614
                        if(innermostIntersecting) {
1615
                                //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1616
                                if(!this.instance.isOver) {
1617

    
1618
                                        this.instance.isOver = 1;
1619
                                        //Now we fake the start of dragging for the sortable instance,
1620
                                        //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1621
                                        //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
1622
                                        this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
1623
                                        this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1624
                                        this.instance.options.helper = function() { return ui.helper[0]; };
1625

    
1626
                                        event.target = this.instance.currentItem[0];
1627
                                        this.instance._mouseCapture(event, true);
1628
                                        this.instance._mouseStart(event, true, true);
1629

    
1630
                                        //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1631
                                        this.instance.offset.click.top = inst.offset.click.top;
1632
                                        this.instance.offset.click.left = inst.offset.click.left;
1633
                                        this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1634
                                        this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1635

    
1636
                                        inst._trigger("toSortable", event);
1637
                                        inst.dropped = this.instance.element; //draggable revert needs that
1638
                                        //hack so receive/update callbacks work (mostly)
1639
                                        inst.currentItem = inst.element;
1640
                                        this.instance.fromOutside = inst;
1641

    
1642
                                }
1643

    
1644
                                //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
1645
                                if(this.instance.currentItem) {
1646
                                        this.instance._mouseDrag(event);
1647
                                }
1648

    
1649
                        } else {
1650

    
1651
                                //If it doesn't intersect with the sortable, and it intersected before,
1652
                                //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1653
                                if(this.instance.isOver) {
1654

    
1655
                                        this.instance.isOver = 0;
1656
                                        this.instance.cancelHelperRemoval = true;
1657

    
1658
                                        //Prevent reverting on this forced stop
1659
                                        this.instance.options.revert = false;
1660

    
1661
                                        // The out event needs to be triggered independently
1662
                                        this.instance._trigger("out", event, this.instance._uiHash(this.instance));
1663

    
1664
                                        this.instance._mouseStop(event, true);
1665
                                        this.instance.options.helper = this.instance.options._helper;
1666

    
1667
                                        //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1668
                                        this.instance.currentItem.remove();
1669
                                        if(this.instance.placeholder) {
1670
                                                this.instance.placeholder.remove();
1671
                                        }
1672

    
1673
                                        inst._trigger("fromSortable", event);
1674
                                        inst.dropped = false; //draggable revert needs that
1675
                                }
1676

    
1677
                        }
1678

    
1679
                });
1680

    
1681
        }
1682
});
1683

    
1684
$.ui.plugin.add("draggable", "cursor", {
1685
        start: function() {
1686
                var t = $("body"), o = $(this).data("ui-draggable").options;
1687
                if (t.css("cursor")) {
1688
                        o._cursor = t.css("cursor");
1689
                }
1690
                t.css("cursor", o.cursor);
1691
        },
1692
        stop: function() {
1693
                var o = $(this).data("ui-draggable").options;
1694
                if (o._cursor) {
1695
                        $("body").css("cursor", o._cursor);
1696
                }
1697
        }
1698
});
1699

    
1700
$.ui.plugin.add("draggable", "opacity", {
1701
        start: function(event, ui) {
1702
                var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1703
                if(t.css("opacity")) {
1704
                        o._opacity = t.css("opacity");
1705
                }
1706
                t.css("opacity", o.opacity);
1707
        },
1708
        stop: function(event, ui) {
1709
                var o = $(this).data("ui-draggable").options;
1710
                if(o._opacity) {
1711
                        $(ui.helper).css("opacity", o._opacity);
1712
                }
1713
        }
1714
});
1715

    
1716
$.ui.plugin.add("draggable", "scroll", {
1717
        start: function() {
1718
                var i = $(this).data("ui-draggable");
1719
                if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1720
                        i.overflowOffset = i.scrollParent.offset();
1721
                }
1722
        },
1723
        drag: function( event ) {
1724

    
1725
                var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
1726

    
1727
                if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1728

    
1729
                        if(!o.axis || o.axis !== "x") {
1730
                                if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
1731
                                        i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1732
                                } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
1733
                                        i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1734
                                }
1735
                        }
1736

    
1737
                        if(!o.axis || o.axis !== "y") {
1738
                                if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
1739
                                        i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1740
                                } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
1741
                                        i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1742
                                }
1743
                        }
1744

    
1745
                } else {
1746

    
1747
                        if(!o.axis || o.axis !== "x") {
1748
                                if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
1749
                                        scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1750
                                } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
1751
                                        scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1752
                                }
1753
                        }
1754

    
1755
                        if(!o.axis || o.axis !== "y") {
1756
                                if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
1757
                                        scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1758
                                } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
1759
                                        scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1760
                                }
1761
                        }
1762

    
1763
                }
1764

    
1765
                if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1766
                        $.ui.ddmanager.prepareOffsets(i, event);
1767
                }
1768

    
1769
        }
1770
});
1771

    
1772
$.ui.plugin.add("draggable", "snap", {
1773
        start: function() {
1774

    
1775
                var i = $(this).data("ui-draggable"),
1776
                        o = i.options;
1777

    
1778
                i.snapElements = [];
1779

    
1780
                $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
1781
                        var $t = $(this),
1782
                                $o = $t.offset();
1783
                        if(this !== i.element[0]) {
1784
                                i.snapElements.push({
1785
                                        item: this,
1786
                                        width: $t.outerWidth(), height: $t.outerHeight(),
1787
                                        top: $o.top, left: $o.left
1788
                                });
1789
                        }
1790
                });
1791

    
1792
        },
1793
        drag: function(event, ui) {
1794

    
1795
                var ts, bs, ls, rs, l, r, t, b, i, first,
1796
                        inst = $(this).data("ui-draggable"),
1797
                        o = inst.options,
1798
                        d = o.snapTolerance,
1799
                        x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1800
                        y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1801

    
1802
                for (i = inst.snapElements.length - 1; i >= 0; i--){
1803

    
1804
                        l = inst.snapElements[i].left;
1805
                        r = l + inst.snapElements[i].width;
1806
                        t = inst.snapElements[i].top;
1807
                        b = t + inst.snapElements[i].height;
1808

    
1809
                        //Yes, I know, this is insane ;)
1810
                        if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
1811
                                if(inst.snapElements[i].snapping) {
1812
                                        (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1813
                                }
1814
                                inst.snapElements[i].snapping = false;
1815
                                continue;
1816
                        }
1817

    
1818
                        if(o.snapMode !== "inner") {
1819
                                ts = Math.abs(t - y2) <= d;
1820
                                bs = Math.abs(b - y1) <= d;
1821
                                ls = Math.abs(l - x2) <= d;
1822
                                rs = Math.abs(r - x1) <= d;
1823
                                if(ts) {
1824
                                        ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1825
                                }
1826
                                if(bs) {
1827
                                        ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1828
                                }
1829
                                if(ls) {
1830
                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1831
                                }
1832
                                if(rs) {
1833
                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1834
                                }
1835
                        }
1836

    
1837
                        first = (ts || bs || ls || rs);
1838

    
1839
                        if(o.snapMode !== "outer") {
1840
                                ts = Math.abs(t - y1) <= d;
1841
                                bs = Math.abs(b - y2) <= d;
1842
                                ls = Math.abs(l - x1) <= d;
1843
                                rs = Math.abs(r - x2) <= d;
1844
                                if(ts) {
1845
                                        ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1846
                                }
1847
                                if(bs) {
1848
                                        ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1849
                                }
1850
                                if(ls) {
1851
                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1852
                                }
1853
                                if(rs) {
1854
                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1855
                                }
1856
                        }
1857

    
1858
                        if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
1859
                                (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1860
                        }
1861
                        inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1862

    
1863
                }
1864

    
1865
        }
1866
});
1867

    
1868
$.ui.plugin.add("draggable", "stack", {
1869
        start: function() {
1870
                var min,
1871
                        o = this.data("ui-draggable").options,
1872
                        group = $.makeArray($(o.stack)).sort(function(a,b) {
1873
                                return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1874
                        });
1875

    
1876
                if (!group.length) { return; }
1877

    
1878
                min = parseInt($(group[0]).css("zIndex"), 10) || 0;
1879
                $(group).each(function(i) {
1880
                        $(this).css("zIndex", min + i);
1881
                });
1882
                this.css("zIndex", (min + group.length));
1883
        }
1884
});
1885

    
1886
$.ui.plugin.add("draggable", "zIndex", {
1887
        start: function(event, ui) {
1888
                var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1889
                if(t.css("zIndex")) {
1890
                        o._zIndex = t.css("zIndex");
1891
                }
1892
                t.css("zIndex", o.zIndex);
1893
        },
1894
        stop: function(event, ui) {
1895
                var o = $(this).data("ui-draggable").options;
1896
                if(o._zIndex) {
1897
                        $(ui.helper).css("zIndex", o._zIndex);
1898
                }
1899
        }
1900
});
1901

    
1902
})(jQuery);
1903

    
1904
(function( $, undefined ) {
1905

    
1906
function isOverAxis( x, reference, size ) {
1907
        return ( x > reference ) && ( x < ( reference + size ) );
1908
}
1909

    
1910
$.widget("ui.droppable", {
1911
        version: "1.10.2",
1912
        widgetEventPrefix: "drop",
1913
        options: {
1914
                accept: "*",
1915
                activeClass: false,
1916
                addClasses: true,
1917
                greedy: false,
1918
                hoverClass: false,
1919
                scope: "default",
1920
                tolerance: "intersect",
1921

    
1922
                // callbacks
1923
                activate: null,
1924
                deactivate: null,
1925
                drop: null,
1926
                out: null,
1927
                over: null
1928
        },
1929
        _create: function() {
1930

    
1931
                var o = this.options,
1932
                        accept = o.accept;
1933

    
1934
                this.isover = false;
1935
                this.isout = true;
1936

    
1937
                this.accept = $.isFunction(accept) ? accept : function(d) {
1938
                        return d.is(accept);
1939
                };
1940

    
1941
                //Store the droppable's proportions
1942
                this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1943

    
1944
                // Add the reference and positions to the manager
1945
                $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1946
                $.ui.ddmanager.droppables[o.scope].push(this);
1947

    
1948
                (o.addClasses && this.element.addClass("ui-droppable"));
1949

    
1950
        },
1951

    
1952
        _destroy: function() {
1953
                var i = 0,
1954
                        drop = $.ui.ddmanager.droppables[this.options.scope];
1955

    
1956
                for ( ; i < drop.length; i++ ) {
1957
                        if ( drop[i] === this ) {
1958
                                drop.splice(i, 1);
1959
                        }
1960
                }
1961

    
1962
                this.element.removeClass("ui-droppable ui-droppable-disabled");
1963
        },
1964

    
1965
        _setOption: function(key, value) {
1966

    
1967
                if(key === "accept") {
1968
                        this.accept = $.isFunction(value) ? value : function(d) {
1969
                                return d.is(value);
1970
                        };
1971
                }
1972
                $.Widget.prototype._setOption.apply(this, arguments);
1973
        },
1974

    
1975
        _activate: function(event) {
1976
                var draggable = $.ui.ddmanager.current;
1977
                if(this.options.activeClass) {
1978
                        this.element.addClass(this.options.activeClass);
1979
                }
1980
                if(draggable){
1981
                        this._trigger("activate", event, this.ui(draggable));
1982
                }
1983
        },
1984

    
1985
        _deactivate: function(event) {
1986
                var draggable = $.ui.ddmanager.current;
1987
                if(this.options.activeClass) {
1988
                        this.element.removeClass(this.options.activeClass);
1989
                }
1990
                if(draggable){
1991
                        this._trigger("deactivate", event, this.ui(draggable));
1992
                }
1993
        },
1994

    
1995
        _over: function(event) {
1996

    
1997
                var draggable = $.ui.ddmanager.current;
1998

    
1999
                // Bail if draggable and droppable are same element
2000
                if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2001
                        return;
2002
                }
2003

    
2004
                if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2005
                        if(this.options.hoverClass) {
2006
                                this.element.addClass(this.options.hoverClass);
2007
                        }
2008
                        this._trigger("over", event, this.ui(draggable));
2009
                }
2010

    
2011
        },
2012

    
2013
        _out: function(event) {
2014

    
2015
                var draggable = $.ui.ddmanager.current;
2016

    
2017
                // Bail if draggable and droppable are same element
2018
                if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2019
                        return;
2020
                }
2021

    
2022
                if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2023
                        if(this.options.hoverClass) {
2024
                                this.element.removeClass(this.options.hoverClass);
2025
                        }
2026
                        this._trigger("out", event, this.ui(draggable));
2027
                }
2028

    
2029
        },
2030

    
2031
        _drop: function(event,custom) {
2032

    
2033
                var draggable = custom || $.ui.ddmanager.current,
2034
                        childrenIntersection = false;
2035

    
2036
                // Bail if draggable and droppable are same element
2037
                if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2038
                        return false;
2039
                }
2040

    
2041
                this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2042
                        var inst = $.data(this, "ui-droppable");
2043
                        if(
2044
                                inst.options.greedy &&
2045
                                !inst.options.disabled &&
2046
                                inst.options.scope === draggable.options.scope &&
2047
                                inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
2048
                                $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2049
                        ) { childrenIntersection = true; return false; }
2050
                });
2051
                if(childrenIntersection) {
2052
                        return false;
2053
                }
2054

    
2055
                if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2056
                        if(this.options.activeClass) {
2057
                                this.element.removeClass(this.options.activeClass);
2058
                        }
2059
                        if(this.options.hoverClass) {
2060
                                this.element.removeClass(this.options.hoverClass);
2061
                        }
2062
                        this._trigger("drop", event, this.ui(draggable));
2063
                        return this.element;
2064
                }
2065

    
2066
                return false;
2067

    
2068
        },
2069

    
2070
        ui: function(c) {
2071
                return {
2072
                        draggable: (c.currentItem || c.element),
2073
                        helper: c.helper,
2074
                        position: c.position,
2075
                        offset: c.positionAbs
2076
                };
2077
        }
2078

    
2079
});
2080

    
2081
$.ui.intersect = function(draggable, droppable, toleranceMode) {
2082

    
2083
        if (!droppable.offset) {
2084
                return false;
2085
        }
2086

    
2087
        var draggableLeft, draggableTop,
2088
                x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2089
                y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
2090
                l = droppable.offset.left, r = l + droppable.proportions.width,
2091
                t = droppable.offset.top, b = t + droppable.proportions.height;
2092

    
2093
        switch (toleranceMode) {
2094
                case "fit":
2095
                        return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2096
                case "intersect":
2097
                        return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
2098
                                x2 - (draggable.helperProportions.width / 2) < r && // Left Half
2099
                                t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
2100
                                y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2101
                case "pointer":
2102
                        draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
2103
                        draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
2104
                        return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
2105
                case "touch":
2106
                        return (
2107
                                (y1 >= t && y1 <= b) ||        // Top edge touching
2108
                                (y2 >= t && y2 <= b) ||        // Bottom edge touching
2109
                                (y1 < t && y2 > b)                // Surrounded vertically
2110
                        ) && (
2111
                                (x1 >= l && x1 <= r) ||        // Left edge touching
2112
                                (x2 >= l && x2 <= r) ||        // Right edge touching
2113
                                (x1 < l && x2 > r)                // Surrounded horizontally
2114
                        );
2115
                default:
2116
                        return false;
2117
                }
2118

    
2119
};
2120

    
2121
/*
2122
        This manager tracks offsets of draggables and droppables
2123
*/
2124
$.ui.ddmanager = {
2125
        current: null,
2126
        droppables: { "default": [] },
2127
        prepareOffsets: function(t, event) {
2128

    
2129
                var i, j,
2130
                        m = $.ui.ddmanager.droppables[t.options.scope] || [],
2131
                        type = event ? event.type : null, // workaround for #2317
2132
                        list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
2133

    
2134
                droppablesLoop: for (i = 0; i < m.length; i++) {
2135

    
2136
                        //No disabled and non-accepted
2137
                        if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
2138
                                continue;
2139
                        }
2140

    
2141
                        // Filter out elements in the current dragged item
2142
                        for (j=0; j < list.length; j++) {
2143
                                if(list[j] === m[i].element[0]) {
2144
                                        m[i].proportions.height = 0;
2145
                                        continue droppablesLoop;
2146
                                }
2147
                        }
2148

    
2149
                        m[i].visible = m[i].element.css("display") !== "none";
2150
                        if(!m[i].visible) {
2151
                                continue;
2152
                        }
2153

    
2154
                        //Activate the droppable if used directly from draggables
2155
                        if(type === "mousedown") {
2156
                                m[i]._activate.call(m[i], event);
2157
                        }
2158

    
2159
                        m[i].offset = m[i].element.offset();
2160
                        m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2161

    
2162
                }
2163

    
2164
        },
2165
        drop: function(draggable, event) {
2166

    
2167
                var dropped = false;
2168
                // Create a copy of the droppables in case the list changes during the drop (#9116)
2169
                $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
2170

    
2171
                        if(!this.options) {
2172
                                return;
2173
                        }
2174
                        if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2175
                                dropped = this._drop.call(this, event) || dropped;
2176
                        }
2177

    
2178
                        if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2179
                                this.isout = true;
2180
                                this.isover = false;
2181
                                this._deactivate.call(this, event);
2182
                        }
2183

    
2184
                });
2185
                return dropped;
2186

    
2187
        },
2188
        dragStart: function( draggable, event ) {
2189
                //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2190
                draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2191
                        if( !draggable.options.refreshPositions ) {
2192
                                $.ui.ddmanager.prepareOffsets( draggable, event );
2193
                        }
2194
                });
2195
        },
2196
        drag: function(draggable, event) {
2197

    
2198
                //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2199
                if(draggable.options.refreshPositions) {
2200
                        $.ui.ddmanager.prepareOffsets(draggable, event);
2201
                }
2202

    
2203
                //Run through all droppables and check their positions based on specific tolerance options
2204
                $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2205

    
2206
                        if(this.options.disabled || this.greedyChild || !this.visible) {
2207
                                return;
2208
                        }
2209

    
2210
                        var parentInstance, scope, parent,
2211
                                intersects = $.ui.intersect(draggable, this, this.options.tolerance),
2212
                                c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
2213
                        if(!c) {
2214
                                return;
2215
                        }
2216

    
2217
                        if (this.options.greedy) {
2218
                                // find droppable parents with same scope
2219
                                scope = this.options.scope;
2220
                                parent = this.element.parents(":data(ui-droppable)").filter(function () {
2221
                                        return $.data(this, "ui-droppable").options.scope === scope;
2222
                                });
2223

    
2224
                                if (parent.length) {
2225
                                        parentInstance = $.data(parent[0], "ui-droppable");
2226
                                        parentInstance.greedyChild = (c === "isover");
2227
                                }
2228
                        }
2229

    
2230
                        // we just moved into a greedy child
2231
                        if (parentInstance && c === "isover") {
2232
                                parentInstance.isover = false;
2233
                                parentInstance.isout = true;
2234
                                parentInstance._out.call(parentInstance, event);
2235
                        }
2236

    
2237
                        this[c] = true;
2238
                        this[c === "isout" ? "isover" : "isout"] = false;
2239
                        this[c === "isover" ? "_over" : "_out"].call(this, event);
2240

    
2241
                        // we just moved out of a greedy child
2242
                        if (parentInstance && c === "isout") {
2243
                                parentInstance.isout = false;
2244
                                parentInstance.isover = true;
2245
                                parentInstance._over.call(parentInstance, event);
2246
                        }
2247
                });
2248

    
2249
        },
2250
        dragStop: function( draggable, event ) {
2251
                draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2252
                //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2253
                if( !draggable.options.refreshPositions ) {
2254
                        $.ui.ddmanager.prepareOffsets( draggable, event );
2255
                }
2256
        }
2257
};
2258

    
2259
})(jQuery);
2260

    
2261
(function( $, undefined ) {
2262

    
2263
function num(v) {
2264
        return parseInt(v, 10) || 0;
2265
}
2266

    
2267
function isNumber(value) {
2268
        return !isNaN(parseInt(value, 10));
2269
}
2270

    
2271
$.widget("ui.resizable", $.ui.mouse, {
2272
        version: "1.10.2",
2273
        widgetEventPrefix: "resize",
2274
        options: {
2275
                alsoResize: false,
2276
                animate: false,
2277
                animateDuration: "slow",
2278
                animateEasing: "swing",
2279
                aspectRatio: false,
2280
                autoHide: false,
2281
                containment: false,
2282
                ghost: false,
2283
                grid: false,
2284
                handles: "e,s,se",
2285
                helper: false,
2286
                maxHeight: null,
2287
                maxWidth: null,
2288
                minHeight: 10,
2289
                minWidth: 10,
2290
                // See #7960
2291
                zIndex: 90,
2292

    
2293
                // callbacks
2294
                resize: null,
2295
                start: null,
2296
                stop: null
2297
        },
2298
        _create: function() {
2299

    
2300
                var n, i, handle, axis, hname,
2301
                        that = this,
2302
                        o = this.options;
2303
                this.element.addClass("ui-resizable");
2304

    
2305
                $.extend(this, {
2306
                        _aspectRatio: !!(o.aspectRatio),
2307
                        aspectRatio: o.aspectRatio,
2308
                        originalElement: this.element,
2309
                        _proportionallyResizeElements: [],
2310
                        _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2311
                });
2312

    
2313
                //Wrap the element if it cannot hold child nodes
2314
                if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2315

    
2316
                        //Create a wrapper element and set the wrapper to the new current internal element
2317
                        this.element.wrap(
2318
                                $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
2319
                                        position: this.element.css("position"),
2320
                                        width: this.element.outerWidth(),
2321
                                        height: this.element.outerHeight(),
2322
                                        top: this.element.css("top"),
2323
                                        left: this.element.css("left")
2324
                                })
2325
                        );
2326

    
2327
                        //Overwrite the original this.element
2328
                        this.element = this.element.parent().data(
2329
                                "ui-resizable", this.element.data("ui-resizable")
2330
                        );
2331

    
2332
                        this.elementIsWrapper = true;
2333

    
2334
                        //Move margins to the wrapper
2335
                        this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2336
                        this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2337

    
2338
                        //Prevent Safari textarea resize
2339
                        this.originalResizeStyle = this.originalElement.css("resize");
2340
                        this.originalElement.css("resize", "none");
2341

    
2342
                        //Push the actual element to our proportionallyResize internal array
2343
                        this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
2344

    
2345
                        // avoid IE jump (hard set the margin)
2346
                        this.originalElement.css({ margin: this.originalElement.css("margin") });
2347

    
2348
                        // fix handlers offset
2349
                        this._proportionallyResize();
2350

    
2351
                }
2352

    
2353
                this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" });
2354
                if(this.handles.constructor === String) {
2355

    
2356
                        if ( this.handles === "all") {
2357
                                this.handles = "n,e,s,w,se,sw,ne,nw";
2358
                        }
2359

    
2360
                        n = this.handles.split(",");
2361
                        this.handles = {};
2362

    
2363
                        for(i = 0; i < n.length; i++) {
2364

    
2365
                                handle = $.trim(n[i]);
2366
                                hname = "ui-resizable-"+handle;
2367
                                axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
2368

    
2369
                                // Apply zIndex to all handles - see #7960
2370
                                axis.css({ zIndex: o.zIndex });
2371

    
2372
                                //TODO : What's going on here?
2373
                                if ("se" === handle) {
2374
                                        axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
2375
                                }
2376

    
2377
                                //Insert into internal handles object and append to element
2378
                                this.handles[handle] = ".ui-resizable-"+handle;
2379
                                this.element.append(axis);
2380
                        }
2381

    
2382
                }
2383

    
2384
                this._renderAxis = function(target) {
2385

    
2386
                        var i, axis, padPos, padWrapper;
2387

    
2388
                        target = target || this.element;
2389

    
2390
                        for(i in this.handles) {
2391

    
2392
                                if(this.handles[i].constructor === String) {
2393
                                        this.handles[i] = $(this.handles[i], this.element).show();
2394
                                }
2395

    
2396
                                //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2397
                                if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2398

    
2399
                                        axis = $(this.handles[i], this.element);
2400

    
2401
                                        //Checking the correct pad and border
2402
                                        padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2403

    
2404
                                        //The padding type i have to apply...
2405
                                        padPos = [ "padding",
2406
                                                /ne|nw|n/.test(i) ? "Top" :
2407
                                                /se|sw|s/.test(i) ? "Bottom" :
2408
                                                /^e$/.test(i) ? "Right" : "Left" ].join("");
2409

    
2410
                                        target.css(padPos, padWrapper);
2411

    
2412
                                        this._proportionallyResize();
2413

    
2414
                                }
2415

    
2416
                                //TODO: What's that good for? There's not anything to be executed left
2417
                                if(!$(this.handles[i]).length) {
2418
                                        continue;
2419
                                }
2420
                        }
2421
                };
2422

    
2423
                //TODO: make renderAxis a prototype function
2424
                this._renderAxis(this.element);
2425

    
2426
                this._handles = $(".ui-resizable-handle", this.element)
2427
                        .disableSelection();
2428

    
2429
                //Matching axis name
2430
                this._handles.mouseover(function() {
2431
                        if (!that.resizing) {
2432
                                if (this.className) {
2433
                                        axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2434
                                }
2435
                                //Axis, default = se
2436
                                that.axis = axis && axis[1] ? axis[1] : "se";
2437
                        }
2438
                });
2439

    
2440
                //If we want to auto hide the elements
2441
                if (o.autoHide) {
2442
                        this._handles.hide();
2443
                        $(this.element)
2444
                                .addClass("ui-resizable-autohide")
2445
                                .mouseenter(function() {
2446
                                        if (o.disabled) {
2447
                                                return;
2448
                                        }
2449
                                        $(this).removeClass("ui-resizable-autohide");
2450
                                        that._handles.show();
2451
                                })
2452
                                .mouseleave(function(){
2453
                                        if (o.disabled) {
2454
                                                return;
2455
                                        }
2456
                                        if (!that.resizing) {
2457
                                                $(this).addClass("ui-resizable-autohide");
2458
                                                that._handles.hide();
2459
                                        }
2460
                                });
2461
                }
2462

    
2463
                //Initialize the mouse interaction
2464
                this._mouseInit();
2465

    
2466
        },
2467

    
2468
        _destroy: function() {
2469

    
2470
                this._mouseDestroy();
2471

    
2472
                var wrapper,
2473
                        _destroy = function(exp) {
2474
                                $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2475
                                        .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
2476
                        };
2477

    
2478
                //TODO: Unwrap at same DOM position
2479
                if (this.elementIsWrapper) {
2480
                        _destroy(this.element);
2481
                        wrapper = this.element;
2482
                        this.originalElement.css({
2483
                                position: wrapper.css("position"),
2484
                                width: wrapper.outerWidth(),
2485
                                height: wrapper.outerHeight(),
2486
                                top: wrapper.css("top"),
2487
                                left: wrapper.css("left")
2488
                        }).insertAfter( wrapper );
2489
                        wrapper.remove();
2490
                }
2491

    
2492
                this.originalElement.css("resize", this.originalResizeStyle);
2493
                _destroy(this.originalElement);
2494

    
2495
                return this;
2496
        },
2497

    
2498
        _mouseCapture: function(event) {
2499
                var i, handle,
2500
                        capture = false;
2501

    
2502
                for (i in this.handles) {
2503
                        handle = $(this.handles[i])[0];
2504
                        if (handle === event.target || $.contains(handle, event.target)) {
2505
                                capture = true;
2506
                        }
2507
                }
2508

    
2509
                return !this.options.disabled && capture;
2510
        },
2511

    
2512
        _mouseStart: function(event) {
2513

    
2514
                var curleft, curtop, cursor,
2515
                        o = this.options,
2516
                        iniPos = this.element.position(),
2517
                        el = this.element;
2518

    
2519
                this.resizing = true;
2520

    
2521
                // bugfix for http://dev.jquery.com/ticket/1749
2522
                if ( (/absolute/).test( el.css("position") ) ) {
2523
                        el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
2524
                } else if (el.is(".ui-draggable")) {
2525
                        el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
2526
                }
2527

    
2528
                this._renderProxy();
2529

    
2530
                curleft = num(this.helper.css("left"));
2531
                curtop = num(this.helper.css("top"));
2532

    
2533
                if (o.containment) {
2534
                        curleft += $(o.containment).scrollLeft() || 0;
2535
                        curtop += $(o.containment).scrollTop() || 0;
2536
                }
2537

    
2538
                //Store needed variables
2539
                this.offset = this.helper.offset();
2540
                this.position = { left: curleft, top: curtop };
2541
                this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2542
                this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2543
                this.originalPosition = { left: curleft, top: curtop };
2544
                this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2545
                this.originalMousePosition = { left: event.pageX, top: event.pageY };
2546

    
2547
                //Aspect Ratio
2548
                this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2549

    
2550
                cursor = $(".ui-resizable-" + this.axis).css("cursor");
2551
                $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
2552

    
2553
                el.addClass("ui-resizable-resizing");
2554
                this._propagate("start", event);
2555
                return true;
2556
        },
2557

    
2558
        _mouseDrag: function(event) {
2559

    
2560
                //Increase performance, avoid regex
2561
                var data,
2562
                        el = this.helper, props = {},
2563
                        smp = this.originalMousePosition,
2564
                        a = this.axis,
2565
                        prevTop = this.position.top,
2566
                        prevLeft = this.position.left,
2567
                        prevWidth = this.size.width,
2568
                        prevHeight = this.size.height,
2569
                        dx = (event.pageX-smp.left)||0,
2570
                        dy = (event.pageY-smp.top)||0,
2571
                        trigger = this._change[a];
2572

    
2573
                if (!trigger) {
2574
                        return false;
2575
                }
2576

    
2577
                // Calculate the attrs that will be change
2578
                data = trigger.apply(this, [event, dx, dy]);
2579

    
2580
                // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2581
                this._updateVirtualBoundaries(event.shiftKey);
2582
                if (this._aspectRatio || event.shiftKey) {
2583
                        data = this._updateRatio(data, event);
2584
                }
2585

    
2586
                data = this._respectSize(data, event);
2587

    
2588
                this._updateCache(data);
2589

    
2590
                // plugins callbacks need to be called first
2591
                this._propagate("resize", event);
2592

    
2593
                if (this.position.top !== prevTop) {
2594
                        props.top = this.position.top + "px";
2595
                }
2596
                if (this.position.left !== prevLeft) {
2597
                        props.left = this.position.left + "px";
2598
                }
2599
                if (this.size.width !== prevWidth) {
2600
                        props.width = this.size.width + "px";
2601
                }
2602
                if (this.size.height !== prevHeight) {
2603
                        props.height = this.size.height + "px";
2604
                }
2605
                el.css(props);
2606

    
2607
                if (!this._helper && this._proportionallyResizeElements.length) {
2608
                        this._proportionallyResize();
2609
                }
2610

    
2611
                // Call the user callback if the element was resized
2612
                if ( ! $.isEmptyObject(props) ) {
2613
                        this._trigger("resize", event, this.ui());
2614
                }
2615

    
2616
                return false;
2617
        },
2618

    
2619
        _mouseStop: function(event) {
2620

    
2621
                this.resizing = false;
2622
                var pr, ista, soffseth, soffsetw, s, left, top,
2623
                        o = this.options, that = this;
2624

    
2625
                if(this._helper) {
2626

    
2627
                        pr = this._proportionallyResizeElements;
2628
                        ista = pr.length && (/textarea/i).test(pr[0].nodeName);
2629
                        soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
2630
                        soffsetw = ista ? 0 : that.sizeDiff.width;
2631

    
2632
                        s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
2633
                        left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
2634
                        top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2635

    
2636
                        if (!o.animate) {
2637
                                this.element.css($.extend(s, { top: top, left: left }));
2638
                        }
2639

    
2640
                        that.helper.height(that.size.height);
2641
                        that.helper.width(that.size.width);
2642

    
2643
                        if (this._helper && !o.animate) {
2644
                                this._proportionallyResize();
2645
                        }
2646
                }
2647

    
2648
                $("body").css("cursor", "auto");
2649

    
2650
                this.element.removeClass("ui-resizable-resizing");
2651

    
2652
                this._propagate("stop", event);
2653

    
2654
                if (this._helper) {
2655
                        this.helper.remove();
2656
                }
2657

    
2658
                return false;
2659

    
2660
        },
2661

    
2662
        _updateVirtualBoundaries: function(forceAspectRatio) {
2663
                var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
2664
                        o = this.options;
2665

    
2666
                b = {
2667
                        minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2668
                        maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2669
                        minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2670
                        maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2671
                };
2672

    
2673
                if(this._aspectRatio || forceAspectRatio) {
2674
                        // We want to create an enclosing box whose aspect ration is the requested one
2675
                        // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2676
                        pMinWidth = b.minHeight * this.aspectRatio;
2677
                        pMinHeight = b.minWidth / this.aspectRatio;
2678
                        pMaxWidth = b.maxHeight * this.aspectRatio;
2679
                        pMaxHeight = b.maxWidth / this.aspectRatio;
2680

    
2681
                        if(pMinWidth > b.minWidth) {
2682
                                b.minWidth = pMinWidth;
2683
                        }
2684
                        if(pMinHeight > b.minHeight) {
2685
                                b.minHeight = pMinHeight;
2686
                        }
2687
                        if(pMaxWidth < b.maxWidth) {
2688
                                b.maxWidth = pMaxWidth;
2689
                        }
2690
                        if(pMaxHeight < b.maxHeight) {
2691
                                b.maxHeight = pMaxHeight;
2692
                        }
2693
                }
2694
                this._vBoundaries = b;
2695
        },
2696

    
2697
        _updateCache: function(data) {
2698
                this.offset = this.helper.offset();
2699
                if (isNumber(data.left)) {
2700
                        this.position.left = data.left;
2701
                }
2702
                if (isNumber(data.top)) {
2703
                        this.position.top = data.top;
2704
                }
2705
                if (isNumber(data.height)) {
2706
                        this.size.height = data.height;
2707
                }
2708
                if (isNumber(data.width)) {
2709
                        this.size.width = data.width;
2710
                }
2711
        },
2712

    
2713
        _updateRatio: function( data ) {
2714

    
2715
                var cpos = this.position,
2716
                        csize = this.size,
2717
                        a = this.axis;
2718

    
2719
                if (isNumber(data.height)) {
2720
                        data.width = (data.height * this.aspectRatio);
2721
                } else if (isNumber(data.width)) {
2722
                        data.height = (data.width / this.aspectRatio);
2723
                }
2724

    
2725
                if (a === "sw") {
2726
                        data.left = cpos.left + (csize.width - data.width);
2727
                        data.top = null;
2728
                }
2729
                if (a === "nw") {
2730
                        data.top = cpos.top + (csize.height - data.height);
2731
                        data.left = cpos.left + (csize.width - data.width);
2732
                }
2733

    
2734
                return data;
2735
        },
2736

    
2737
        _respectSize: function( data ) {
2738

    
2739
                var o = this._vBoundaries,
2740
                        a = this.axis,
2741
                        ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2742
                        isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
2743
                        dw = this.originalPosition.left + this.originalSize.width,
2744
                        dh = this.position.top + this.size.height,
2745
                        cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2746
                if (isminw) {
2747
                        data.width = o.minWidth;
2748
                }
2749
                if (isminh) {
2750
                        data.height = o.minHeight;
2751
                }
2752
                if (ismaxw) {
2753
                        data.width = o.maxWidth;
2754
                }
2755
                if (ismaxh) {
2756
                        data.height = o.maxHeight;
2757
                }
2758

    
2759
                if (isminw && cw) {
2760
                        data.left = dw - o.minWidth;
2761
                }
2762
                if (ismaxw && cw) {
2763
                        data.left = dw - o.maxWidth;
2764
                }
2765
                if (isminh && ch) {
2766
                        data.top = dh - o.minHeight;
2767
                }
2768
                if (ismaxh && ch) {
2769
                        data.top = dh - o.maxHeight;
2770
                }
2771

    
2772
                // fixing jump error on top/left - bug #2330
2773
                if (!data.width && !data.height && !data.left && data.top) {
2774
                        data.top = null;
2775
                } else if (!data.width && !data.height && !data.top && data.left) {
2776
                        data.left = null;
2777
                }
2778

    
2779
                return data;
2780
        },
2781

    
2782
        _proportionallyResize: function() {
2783

    
2784
                if (!this._proportionallyResizeElements.length) {
2785
                        return;
2786
                }
2787

    
2788
                var i, j, borders, paddings, prel,
2789
                        element = this.helper || this.element;
2790

    
2791
                for ( i=0; i < this._proportionallyResizeElements.length; i++) {
2792

    
2793
                        prel = this._proportionallyResizeElements[i];
2794

    
2795
                        if (!this.borderDif) {
2796
                                this.borderDif = [];
2797
                                borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
2798
                                paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
2799

    
2800
                                for ( j = 0; j < borders.length; j++ ) {
2801
                                        this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
2802
                                }
2803
                        }
2804

    
2805
                        prel.css({
2806
                                height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2807
                                width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2808
                        });
2809

    
2810
                }
2811

    
2812
        },
2813

    
2814
        _renderProxy: function() {
2815

    
2816
                var el = this.element, o = this.options;
2817
                this.elementOffset = el.offset();
2818

    
2819
                if(this._helper) {
2820

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

    
2823
                        this.helper.addClass(this._helper).css({
2824
                                width: this.element.outerWidth() - 1,
2825
                                height: this.element.outerHeight() - 1,
2826
                                position: "absolute",
2827
                                left: this.elementOffset.left +"px",
2828
                                top: this.elementOffset.top +"px",
2829
                                zIndex: ++o.zIndex //TODO: Don't modify option
2830
                        });
2831

    
2832
                        this.helper
2833
                                .appendTo("body")
2834
                                .disableSelection();
2835

    
2836
                } else {
2837
                        this.helper = this.element;
2838
                }
2839

    
2840
        },
2841

    
2842
        _change: {
2843
                e: function(event, dx) {
2844
                        return { width: this.originalSize.width + dx };
2845
                },
2846
                w: function(event, dx) {
2847
                        var cs = this.originalSize, sp = this.originalPosition;
2848
                        return { left: sp.left + dx, width: cs.width - dx };
2849
                },
2850
                n: function(event, dx, dy) {
2851
                        var cs = this.originalSize, sp = this.originalPosition;
2852
                        return { top: sp.top + dy, height: cs.height - dy };
2853
                },
2854
                s: function(event, dx, dy) {
2855
                        return { height: this.originalSize.height + dy };
2856
                },
2857
                se: function(event, dx, dy) {
2858
                        return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2859
                },
2860
                sw: function(event, dx, dy) {
2861
                        return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2862
                },
2863
                ne: function(event, dx, dy) {
2864
                        return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2865
                },
2866
                nw: function(event, dx, dy) {
2867
                        return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2868
                }
2869
        },
2870

    
2871
        _propagate: function(n, event) {
2872
                $.ui.plugin.call(this, n, [event, this.ui()]);
2873
                (n !== "resize" && this._trigger(n, event, this.ui()));
2874
        },
2875

    
2876
        plugins: {},
2877

    
2878
        ui: function() {
2879
                return {
2880
                        originalElement: this.originalElement,
2881
                        element: this.element,
2882
                        helper: this.helper,
2883
                        position: this.position,
2884
                        size: this.size,
2885
                        originalSize: this.originalSize,
2886
                        originalPosition: this.originalPosition
2887
                };
2888
        }
2889

    
2890
});
2891

    
2892
/*
2893
 * Resizable Extensions
2894
 */
2895

    
2896
$.ui.plugin.add("resizable", "animate", {
2897

    
2898
        stop: function( event ) {
2899
                var that = $(this).data("ui-resizable"),
2900
                        o = that.options,
2901
                        pr = that._proportionallyResizeElements,
2902
                        ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2903
                        soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2904
                        soffsetw = ista ? 0 : that.sizeDiff.width,
2905
                        style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
2906
                        left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
2907
                        top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2908

    
2909
                that.element.animate(
2910
                        $.extend(style, top && left ? { top: top, left: left } : {}), {
2911
                                duration: o.animateDuration,
2912
                                easing: o.animateEasing,
2913
                                step: function() {
2914

    
2915
                                        var data = {
2916
                                                width: parseInt(that.element.css("width"), 10),
2917
                                                height: parseInt(that.element.css("height"), 10),
2918
                                                top: parseInt(that.element.css("top"), 10),
2919
                                                left: parseInt(that.element.css("left"), 10)
2920
                                        };
2921

    
2922
                                        if (pr && pr.length) {
2923
                                                $(pr[0]).css({ width: data.width, height: data.height });
2924
                                        }
2925

    
2926
                                        // propagating resize, and updating values for each animation step
2927
                                        that._updateCache(data);
2928
                                        that._propagate("resize", event);
2929

    
2930
                                }
2931
                        }
2932
                );
2933
        }
2934

    
2935
});
2936

    
2937
$.ui.plugin.add("resizable", "containment", {
2938

    
2939
        start: function() {
2940
                var element, p, co, ch, cw, width, height,
2941
                        that = $(this).data("ui-resizable"),
2942
                        o = that.options,
2943
                        el = that.element,
2944
                        oc = o.containment,
2945
                        ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2946

    
2947
                if (!ce) {
2948
                        return;
2949
                }
2950

    
2951
                that.containerElement = $(ce);
2952

    
2953
                if (/document/.test(oc) || oc === document) {
2954
                        that.containerOffset = { left: 0, top: 0 };
2955
                        that.containerPosition = { left: 0, top: 0 };
2956

    
2957
                        that.parentData = {
2958
                                element: $(document), left: 0, top: 0,
2959
                                width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2960
                        };
2961
                }
2962

    
2963
                // i'm a node, so compute top, left, right, bottom
2964
                else {
2965
                        element = $(ce);
2966
                        p = [];
2967
                        $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2968

    
2969
                        that.containerOffset = element.offset();
2970
                        that.containerPosition = element.position();
2971
                        that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2972

    
2973
                        co = that.containerOffset;
2974
                        ch = that.containerSize.height;
2975
                        cw = that.containerSize.width;
2976
                        width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
2977
                        height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2978

    
2979
                        that.parentData = {
2980
                                element: ce, left: co.left, top: co.top, width: width, height: height
2981
                        };
2982
                }
2983
        },
2984

    
2985
        resize: function( event ) {
2986
                var woset, hoset, isParent, isOffsetRelative,
2987
                        that = $(this).data("ui-resizable"),
2988
                        o = that.options,
2989
                        co = that.containerOffset, cp = that.position,
2990
                        pRatio = that._aspectRatio || event.shiftKey,
2991
                        cop = { top:0, left:0 }, ce = that.containerElement;
2992

    
2993
                if (ce[0] !== document && (/static/).test(ce.css("position"))) {
2994
                        cop = co;
2995
                }
2996

    
2997
                if (cp.left < (that._helper ? co.left : 0)) {
2998
                        that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
2999
                        if (pRatio) {
3000
                                that.size.height = that.size.width / that.aspectRatio;
3001
                        }
3002
                        that.position.left = o.helper ? co.left : 0;
3003
                }
3004

    
3005
                if (cp.top < (that._helper ? co.top : 0)) {
3006
                        that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3007
                        if (pRatio) {
3008
                                that.size.width = that.size.height * that.aspectRatio;
3009
                        }
3010
                        that.position.top = that._helper ? co.top : 0;
3011
                }
3012

    
3013
                that.offset.left = that.parentData.left+that.position.left;
3014
                that.offset.top = that.parentData.top+that.position.top;
3015

    
3016
                woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
3017
                hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3018

    
3019
                isParent = that.containerElement.get(0) === that.element.parent().get(0);
3020
                isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
3021

    
3022
                if(isParent && isOffsetRelative) {
3023
                        woset -= that.parentData.left;
3024
                }
3025

    
3026
                if (woset + that.size.width >= that.parentData.width) {
3027
                        that.size.width = that.parentData.width - woset;
3028
                        if (pRatio) {
3029
                                that.size.height = that.size.width / that.aspectRatio;
3030
                        }
3031
                }
3032

    
3033
                if (hoset + that.size.height >= that.parentData.height) {
3034
                        that.size.height = that.parentData.height - hoset;
3035
                        if (pRatio) {
3036
                                that.size.width = that.size.height * that.aspectRatio;
3037
                        }
3038
                }
3039
        },
3040

    
3041
        stop: function(){
3042
                var that = $(this).data("ui-resizable"),
3043
                        o = that.options,
3044
                        co = that.containerOffset,
3045
                        cop = that.containerPosition,
3046
                        ce = that.containerElement,
3047
                        helper = $(that.helper),
3048
                        ho = helper.offset(),
3049
                        w = helper.outerWidth() - that.sizeDiff.width,
3050
                        h = helper.outerHeight() - that.sizeDiff.height;
3051

    
3052
                if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
3053
                        $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3054
                }
3055

    
3056
                if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
3057
                        $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3058
                }
3059

    
3060
        }
3061
});
3062

    
3063
$.ui.plugin.add("resizable", "alsoResize", {
3064

    
3065
        start: function () {
3066
                var that = $(this).data("ui-resizable"),
3067
                        o = that.options,
3068
                        _store = function (exp) {
3069
                                $(exp).each(function() {
3070
                                        var el = $(this);
3071
                                        el.data("ui-resizable-alsoresize", {
3072
                                                width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3073
                                                left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3074
                                        });
3075
                                });
3076
                        };
3077

    
3078
                if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3079
                        if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3080
                        else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3081
                }else{
3082
                        _store(o.alsoResize);
3083
                }
3084
        },
3085

    
3086
        resize: function (event, ui) {
3087
                var that = $(this).data("ui-resizable"),
3088
                        o = that.options,
3089
                        os = that.originalSize,
3090
                        op = that.originalPosition,
3091
                        delta = {
3092
                                height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3093
                                top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3094
                        },
3095

    
3096
                        _alsoResize = function (exp, c) {
3097
                                $(exp).each(function() {
3098
                                        var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3099
                                                css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3100

    
3101
                                        $.each(css, function (i, prop) {
3102
                                                var sum = (start[prop]||0) + (delta[prop]||0);
3103
                                                if (sum && sum >= 0) {
3104
                                                        style[prop] = sum || null;
3105
                                                }
3106
                                        });
3107

    
3108
                                        el.css(style);
3109
                                });
3110
                        };
3111

    
3112
                if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3113
                        $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3114
                }else{
3115
                        _alsoResize(o.alsoResize);
3116
                }
3117
        },
3118

    
3119
        stop: function () {
3120
                $(this).removeData("resizable-alsoresize");
3121
        }
3122
});
3123

    
3124
$.ui.plugin.add("resizable", "ghost", {
3125

    
3126
        start: function() {
3127

    
3128
                var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
3129

    
3130
                that.ghost = that.originalElement.clone();
3131
                that.ghost
3132
                        .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3133
                        .addClass("ui-resizable-ghost")
3134
                        .addClass(typeof o.ghost === "string" ? o.ghost : "");
3135

    
3136
                that.ghost.appendTo(that.helper);
3137

    
3138
        },
3139

    
3140
        resize: function(){
3141
                var that = $(this).data("ui-resizable");
3142
                if (that.ghost) {
3143
                        that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3144
                }
3145
        },
3146

    
3147
        stop: function() {
3148
                var that = $(this).data("ui-resizable");
3149
                if (that.ghost && that.helper) {
3150
                        that.helper.get(0).removeChild(that.ghost.get(0));
3151
                }
3152
        }
3153

    
3154
});
3155

    
3156
$.ui.plugin.add("resizable", "grid", {
3157

    
3158
        resize: function() {
3159
                var that = $(this).data("ui-resizable"),
3160
                        o = that.options,
3161
                        cs = that.size,
3162
                        os = that.originalSize,
3163
                        op = that.originalPosition,
3164
                        a = that.axis,
3165
                        grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
3166
                        gridX = (grid[0]||1),
3167
                        gridY = (grid[1]||1),
3168
                        ox = Math.round((cs.width - os.width) / gridX) * gridX,
3169
                        oy = Math.round((cs.height - os.height) / gridY) * gridY,
3170
                        newWidth = os.width + ox,
3171
                        newHeight = os.height + oy,
3172
                        isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
3173
                        isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
3174
                        isMinWidth = o.minWidth && (o.minWidth > newWidth),
3175
                        isMinHeight = o.minHeight && (o.minHeight > newHeight);
3176

    
3177
                o.grid = grid;
3178

    
3179
                if (isMinWidth) {
3180
                        newWidth = newWidth + gridX;
3181
                }
3182
                if (isMinHeight) {
3183
                        newHeight = newHeight + gridY;
3184
                }
3185
                if (isMaxWidth) {
3186
                        newWidth = newWidth - gridX;
3187
                }
3188
                if (isMaxHeight) {
3189
                        newHeight = newHeight - gridY;
3190
                }
3191

    
3192
                if (/^(se|s|e)$/.test(a)) {
3193
                        that.size.width = newWidth;
3194
                        that.size.height = newHeight;
3195
                } else if (/^(ne)$/.test(a)) {
3196
                        that.size.width = newWidth;
3197
                        that.size.height = newHeight;
3198
                        that.position.top = op.top - oy;
3199
                } else if (/^(sw)$/.test(a)) {
3200
                        that.size.width = newWidth;
3201
                        that.size.height = newHeight;
3202
                        that.position.left = op.left - ox;
3203
                } else {
3204
                        that.size.width = newWidth;
3205
                        that.size.height = newHeight;
3206
                        that.position.top = op.top - oy;
3207
                        that.position.left = op.left - ox;
3208
                }
3209
        }
3210

    
3211
});
3212

    
3213
})(jQuery);
3214

    
3215
(function( $, undefined ) {
3216

    
3217
$.widget("ui.selectable", $.ui.mouse, {
3218
        version: "1.10.2",
3219
        options: {
3220
                appendTo: "body",
3221
                autoRefresh: true,
3222
                distance: 0,
3223
                filter: "*",
3224
                tolerance: "touch",
3225

    
3226
                // callbacks
3227
                selected: null,
3228
                selecting: null,
3229
                start: null,
3230
                stop: null,
3231
                unselected: null,
3232
                unselecting: null
3233
        },
3234
        _create: function() {
3235
                var selectees,
3236
                        that = this;
3237

    
3238
                this.element.addClass("ui-selectable");
3239

    
3240
                this.dragged = false;
3241

    
3242
                // cache selectee children based on filter
3243
                this.refresh = function() {
3244
                        selectees = $(that.options.filter, that.element[0]);
3245
                        selectees.addClass("ui-selectee");
3246
                        selectees.each(function() {
3247
                                var $this = $(this),
3248
                                        pos = $this.offset();
3249
                                $.data(this, "selectable-item", {
3250
                                        element: this,
3251
                                        $element: $this,
3252
                                        left: pos.left,
3253
                                        top: pos.top,
3254
                                        right: pos.left + $this.outerWidth(),
3255
                                        bottom: pos.top + $this.outerHeight(),
3256
                                        startselected: false,
3257
                                        selected: $this.hasClass("ui-selected"),
3258
                                        selecting: $this.hasClass("ui-selecting"),
3259
                                        unselecting: $this.hasClass("ui-unselecting")
3260
                                });
3261
                        });
3262
                };
3263
                this.refresh();
3264

    
3265
                this.selectees = selectees.addClass("ui-selectee");
3266

    
3267
                this._mouseInit();
3268

    
3269
                this.helper = $("<div class='ui-selectable-helper'></div>");
3270
        },
3271

    
3272
        _destroy: function() {
3273
                this.selectees
3274
                        .removeClass("ui-selectee")
3275
                        .removeData("selectable-item");
3276
                this.element
3277
                        .removeClass("ui-selectable ui-selectable-disabled");
3278
                this._mouseDestroy();
3279
        },
3280

    
3281
        _mouseStart: function(event) {
3282
                var that = this,
3283
                        options = this.options;
3284

    
3285
                this.opos = [event.pageX, event.pageY];
3286

    
3287
                if (this.options.disabled) {
3288
                        return;
3289
                }
3290

    
3291
                this.selectees = $(options.filter, this.element[0]);
3292

    
3293
                this._trigger("start", event);
3294

    
3295
                $(options.appendTo).append(this.helper);
3296
                // position helper (lasso)
3297
                this.helper.css({
3298
                        "left": event.pageX,
3299
                        "top": event.pageY,
3300
                        "width": 0,
3301
                        "height": 0
3302
                });
3303

    
3304
                if (options.autoRefresh) {
3305
                        this.refresh();
3306
                }
3307

    
3308
                this.selectees.filter(".ui-selected").each(function() {
3309
                        var selectee = $.data(this, "selectable-item");
3310
                        selectee.startselected = true;
3311
                        if (!event.metaKey && !event.ctrlKey) {
3312
                                selectee.$element.removeClass("ui-selected");
3313
                                selectee.selected = false;
3314
                                selectee.$element.addClass("ui-unselecting");
3315
                                selectee.unselecting = true;
3316
                                // selectable UNSELECTING callback
3317
                                that._trigger("unselecting", event, {
3318
                                        unselecting: selectee.element
3319
                                });
3320
                        }
3321
                });
3322

    
3323
                $(event.target).parents().addBack().each(function() {
3324
                        var doSelect,
3325
                                selectee = $.data(this, "selectable-item");
3326
                        if (selectee) {
3327
                                doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
3328
                                selectee.$element
3329
                                        .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3330
                                        .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3331
                                selectee.unselecting = !doSelect;
3332
                                selectee.selecting = doSelect;
3333
                                selectee.selected = doSelect;
3334
                                // selectable (UN)SELECTING callback
3335
                                if (doSelect) {
3336
                                        that._trigger("selecting", event, {
3337
                                                selecting: selectee.element
3338
                                        });
3339
                                } else {
3340
                                        that._trigger("unselecting", event, {
3341
                                                unselecting: selectee.element
3342
                                        });
3343
                                }
3344
                                return false;
3345
                        }
3346
                });
3347

    
3348
        },
3349

    
3350
        _mouseDrag: function(event) {
3351

    
3352
                this.dragged = true;
3353

    
3354
                if (this.options.disabled) {
3355
                        return;
3356
                }
3357

    
3358
                var tmp,
3359
                        that = this,
3360
                        options = this.options,
3361
                        x1 = this.opos[0],
3362
                        y1 = this.opos[1],
3363
                        x2 = event.pageX,
3364
                        y2 = event.pageY;
3365

    
3366
                if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
3367
                if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
3368
                this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3369

    
3370
                this.selectees.each(function() {
3371
                        var selectee = $.data(this, "selectable-item"),
3372
                                hit = false;
3373

    
3374
                        //prevent helper from being selected if appendTo: selectable
3375
                        if (!selectee || selectee.element === that.element[0]) {
3376
                                return;
3377
                        }
3378

    
3379
                        if (options.tolerance === "touch") {
3380
                                hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3381
                        } else if (options.tolerance === "fit") {
3382
                                hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3383
                        }
3384

    
3385
                        if (hit) {
3386
                                // SELECT
3387
                                if (selectee.selected) {
3388
                                        selectee.$element.removeClass("ui-selected");
3389
                                        selectee.selected = false;
3390
                                }
3391
                                if (selectee.unselecting) {
3392
                                        selectee.$element.removeClass("ui-unselecting");
3393
                                        selectee.unselecting = false;
3394
                                }
3395
                                if (!selectee.selecting) {
3396
                                        selectee.$element.addClass("ui-selecting");
3397
                                        selectee.selecting = true;
3398
                                        // selectable SELECTING callback
3399
                                        that._trigger("selecting", event, {
3400
                                                selecting: selectee.element
3401
                                        });
3402
                                }
3403
                        } else {
3404
                                // UNSELECT
3405
                                if (selectee.selecting) {
3406
                                        if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3407
                                                selectee.$element.removeClass("ui-selecting");
3408
                                                selectee.selecting = false;
3409
                                                selectee.$element.addClass("ui-selected");
3410
                                                selectee.selected = true;
3411
                                        } else {
3412
                                                selectee.$element.removeClass("ui-selecting");
3413
                                                selectee.selecting = false;
3414
                                                if (selectee.startselected) {
3415
                                                        selectee.$element.addClass("ui-unselecting");
3416
                                                        selectee.unselecting = true;
3417
                                                }
3418
                                                // selectable UNSELECTING callback
3419
                                                that._trigger("unselecting", event, {
3420
                                                        unselecting: selectee.element
3421
                                                });
3422
                                        }
3423
                                }
3424
                                if (selectee.selected) {
3425
                                        if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3426
                                                selectee.$element.removeClass("ui-selected");
3427
                                                selectee.selected = false;
3428

    
3429
                                                selectee.$element.addClass("ui-unselecting");
3430
                                                selectee.unselecting = true;
3431
                                                // selectable UNSELECTING callback
3432
                                                that._trigger("unselecting", event, {
3433
                                                        unselecting: selectee.element
3434
                                                });
3435
                                        }
3436
                                }
3437
                        }
3438
                });
3439

    
3440
                return false;
3441
        },
3442

    
3443
        _mouseStop: function(event) {
3444
                var that = this;
3445

    
3446
                this.dragged = false;
3447

    
3448
                $(".ui-unselecting", this.element[0]).each(function() {
3449
                        var selectee = $.data(this, "selectable-item");
3450
                        selectee.$element.removeClass("ui-unselecting");
3451
                        selectee.unselecting = false;
3452
                        selectee.startselected = false;
3453
                        that._trigger("unselected", event, {
3454
                                unselected: selectee.element
3455
                        });
3456
                });
3457
                $(".ui-selecting", this.element[0]).each(function() {
3458
                        var selectee = $.data(this, "selectable-item");
3459
                        selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
3460
                        selectee.selecting = false;
3461
                        selectee.selected = true;
3462
                        selectee.startselected = true;
3463
                        that._trigger("selected", event, {
3464
                                selected: selectee.element
3465
                        });
3466
                });
3467
                this._trigger("stop", event);
3468

    
3469
                this.helper.remove();
3470

    
3471
                return false;
3472
        }
3473

    
3474
});
3475

    
3476
})(jQuery);
3477

    
3478
(function( $, undefined ) {
3479

    
3480
/*jshint loopfunc: true */
3481

    
3482
function isOverAxis( x, reference, size ) {
3483
        return ( x > reference ) && ( x < ( reference + size ) );
3484
}
3485

    
3486
function isFloating(item) {
3487
        return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
3488
}
3489

    
3490
$.widget("ui.sortable", $.ui.mouse, {
3491
        version: "1.10.2",
3492
        widgetEventPrefix: "sort",
3493
        ready: false,
3494
        options: {
3495
                appendTo: "parent",
3496
                axis: false,
3497
                connectWith: false,
3498
                containment: false,
3499
                cursor: "auto",
3500
                cursorAt: false,
3501
                dropOnEmpty: true,
3502
                forcePlaceholderSize: false,
3503
                forceHelperSize: false,
3504
                grid: false,
3505
                handle: false,
3506
                helper: "original",
3507
                items: "> *",
3508
                opacity: false,
3509
                placeholder: false,
3510
                revert: false,
3511
                scroll: true,
3512
                scrollSensitivity: 20,
3513
                scrollSpeed: 20,
3514
                scope: "default",
3515
                tolerance: "intersect",
3516
                zIndex: 1000,
3517

    
3518
                // callbacks
3519
                activate: null,
3520
                beforeStop: null,
3521
                change: null,
3522
                deactivate: null,
3523
                out: null,
3524
                over: null,
3525
                receive: null,
3526
                remove: null,
3527
                sort: null,
3528
                start: null,
3529
                stop: null,
3530
                update: null
3531
        },
3532
        _create: function() {
3533

    
3534
                var o = this.options;
3535
                this.containerCache = {};
3536
                this.element.addClass("ui-sortable");
3537

    
3538
                //Get the items
3539
                this.refresh();
3540

    
3541
                //Let's determine if the items are being displayed horizontally
3542
                this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
3543

    
3544
                //Let's determine the parent's offset
3545
                this.offset = this.element.offset();
3546

    
3547
                //Initialize mouse events for interaction
3548
                this._mouseInit();
3549

    
3550
                //We're ready to go
3551
                this.ready = true;
3552

    
3553
        },
3554

    
3555
        _destroy: function() {
3556
                this.element
3557
                        .removeClass("ui-sortable ui-sortable-disabled");
3558
                this._mouseDestroy();
3559

    
3560
                for ( var i = this.items.length - 1; i >= 0; i-- ) {
3561
                        this.items[i].item.removeData(this.widgetName + "-item");
3562
                }
3563

    
3564
                return this;
3565
        },
3566

    
3567
        _setOption: function(key, value){
3568
                if ( key === "disabled" ) {
3569
                        this.options[ key ] = value;
3570

    
3571
                        this.widget().toggleClass( "ui-sortable-disabled", !!value );
3572
                } else {
3573
                        // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3574
                        $.Widget.prototype._setOption.apply(this, arguments);
3575
                }
3576
        },
3577

    
3578
        _mouseCapture: function(event, overrideHandle) {
3579
                var currentItem = null,
3580
                        validHandle = false,
3581
                        that = this;
3582

    
3583
                if (this.reverting) {
3584
                        return false;
3585
                }
3586

    
3587
                if(this.options.disabled || this.options.type === "static") {
3588
                        return false;
3589
                }
3590

    
3591
                //We have to refresh the items data once first
3592
                this._refreshItems(event);
3593

    
3594
                //Find out if the clicked node (or one of its parents) is a actual item in this.items
3595
                $(event.target).parents().each(function() {
3596
                        if($.data(this, that.widgetName + "-item") === that) {
3597
                                currentItem = $(this);
3598
                                return false;
3599
                        }
3600
                });
3601
                if($.data(event.target, that.widgetName + "-item") === that) {
3602
                        currentItem = $(event.target);
3603
                }
3604

    
3605
                if(!currentItem) {
3606
                        return false;
3607
                }
3608
                if(this.options.handle && !overrideHandle) {
3609
                        $(this.options.handle, currentItem).find("*").addBack().each(function() {
3610
                                if(this === event.target) {
3611
                                        validHandle = true;
3612
                                }
3613
                        });
3614
                        if(!validHandle) {
3615
                                return false;
3616
                        }
3617
                }
3618

    
3619
                this.currentItem = currentItem;
3620
                this._removeCurrentsFromItems();
3621
                return true;
3622

    
3623
        },
3624

    
3625
        _mouseStart: function(event, overrideHandle, noActivation) {
3626

    
3627
                var i, body,
3628
                        o = this.options;
3629

    
3630
                this.currentContainer = this;
3631

    
3632
                //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3633
                this.refreshPositions();
3634

    
3635
                //Create and append the visible helper
3636
                this.helper = this._createHelper(event);
3637

    
3638
                //Cache the helper size
3639
                this._cacheHelperProportions();
3640

    
3641
                /*
3642
                 * - Position generation -
3643
                 * This block generates everything position related - it's the core of draggables.
3644
                 */
3645

    
3646
                //Cache the margins of the original element
3647
                this._cacheMargins();
3648

    
3649
                //Get the next scrolling parent
3650
                this.scrollParent = this.helper.scrollParent();
3651

    
3652
                //The element's absolute position on the page minus margins
3653
                this.offset = this.currentItem.offset();
3654
                this.offset = {
3655
                        top: this.offset.top - this.margins.top,
3656
                        left: this.offset.left - this.margins.left
3657
                };
3658

    
3659
                $.extend(this.offset, {
3660
                        click: { //Where the click happened, relative to the element
3661
                                left: event.pageX - this.offset.left,
3662
                                top: event.pageY - this.offset.top
3663
                        },
3664
                        parent: this._getParentOffset(),
3665
                        relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3666
                });
3667

    
3668
                // Only after we got the offset, we can change the helper's position to absolute
3669
                // TODO: Still need to figure out a way to make relative sorting possible
3670
                this.helper.css("position", "absolute");
3671
                this.cssPosition = this.helper.css("position");
3672

    
3673
                //Generate the original position
3674
                this.originalPosition = this._generatePosition(event);
3675
                this.originalPageX = event.pageX;
3676
                this.originalPageY = event.pageY;
3677

    
3678
                //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
3679
                (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3680

    
3681
                //Cache the former DOM position
3682
                this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3683

    
3684
                //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
3685
                if(this.helper[0] !== this.currentItem[0]) {
3686
                        this.currentItem.hide();
3687
                }
3688

    
3689
                //Create the placeholder
3690
                this._createPlaceholder();
3691

    
3692
                //Set a containment if given in the options
3693
                if(o.containment) {
3694
                        this._setContainment();
3695
                }
3696

    
3697
                if( o.cursor && o.cursor !== "auto" ) { // cursor option
3698
                        body = this.document.find( "body" );
3699

    
3700
                        // support: IE
3701
                        this.storedCursor = body.css( "cursor" );
3702
                        body.css( "cursor", o.cursor );
3703

    
3704
                        this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
3705
                }
3706

    
3707
                if(o.opacity) { // opacity option
3708
                        if (this.helper.css("opacity")) {
3709
                                this._storedOpacity = this.helper.css("opacity");
3710
                        }
3711
                        this.helper.css("opacity", o.opacity);
3712
                }
3713

    
3714
                if(o.zIndex) { // zIndex option
3715
                        if (this.helper.css("zIndex")) {
3716
                                this._storedZIndex = this.helper.css("zIndex");
3717
                        }
3718
                        this.helper.css("zIndex", o.zIndex);
3719
                }
3720

    
3721
                //Prepare scrolling
3722
                if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3723
                        this.overflowOffset = this.scrollParent.offset();
3724
                }
3725

    
3726
                //Call callbacks
3727
                this._trigger("start", event, this._uiHash());
3728

    
3729
                //Recache the helper size
3730
                if(!this._preserveHelperProportions) {
3731
                        this._cacheHelperProportions();
3732
                }
3733

    
3734

    
3735
                //Post "activate" events to possible containers
3736
                if( !noActivation ) {
3737
                        for ( i = this.containers.length - 1; i >= 0; i-- ) {
3738
                                this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
3739
                        }
3740
                }
3741

    
3742
                //Prepare possible droppables
3743
                if($.ui.ddmanager) {
3744
                        $.ui.ddmanager.current = this;
3745
                }
3746

    
3747
                if ($.ui.ddmanager && !o.dropBehaviour) {
3748
                        $.ui.ddmanager.prepareOffsets(this, event);
3749
                }
3750

    
3751
                this.dragging = true;
3752

    
3753
                this.helper.addClass("ui-sortable-helper");
3754
                this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3755
                return true;
3756

    
3757
        },
3758

    
3759
        _mouseDrag: function(event) {
3760
                var i, item, itemElement, intersection,
3761
                        o = this.options,
3762
                        scrolled = false;
3763

    
3764
                //Compute the helpers position
3765
                this.position = this._generatePosition(event);
3766
                this.positionAbs = this._convertPositionTo("absolute");
3767

    
3768
                if (!this.lastPositionAbs) {
3769
                        this.lastPositionAbs = this.positionAbs;
3770
                }
3771

    
3772
                //Do scrolling
3773
                if(this.options.scroll) {
3774
                        if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3775

    
3776
                                if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
3777
                                        this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3778
                                } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
3779
                                        this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3780
                                }
3781

    
3782
                                if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
3783
                                        this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3784
                                } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
3785
                                        this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3786
                                }
3787

    
3788
                        } else {
3789

    
3790
                                if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
3791
                                        scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3792
                                } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
3793
                                        scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3794
                                }
3795

    
3796
                                if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
3797
                                        scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3798
                                } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
3799
                                        scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3800
                                }
3801

    
3802
                        }
3803

    
3804
                        if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
3805
                                $.ui.ddmanager.prepareOffsets(this, event);
3806
                        }
3807
                }
3808

    
3809
                //Regenerate the absolute position used for position checks
3810
                this.positionAbs = this._convertPositionTo("absolute");
3811

    
3812
                //Set the helper position
3813
                if(!this.options.axis || this.options.axis !== "y") {
3814
                        this.helper[0].style.left = this.position.left+"px";
3815
                }
3816
                if(!this.options.axis || this.options.axis !== "x") {
3817
                        this.helper[0].style.top = this.position.top+"px";
3818
                }
3819

    
3820
                //Rearrange
3821
                for (i = this.items.length - 1; i >= 0; i--) {
3822

    
3823
                        //Cache variables and intersection, continue if no intersection
3824
                        item = this.items[i];
3825
                        itemElement = item.item[0];
3826
                        intersection = this._intersectsWithPointer(item);
3827
                        if (!intersection) {
3828
                                continue;
3829
                        }
3830

    
3831
                        // Only put the placeholder inside the current Container, skip all
3832
                        // items form other containers. This works because when moving
3833
                        // an item from one container to another the
3834
                        // currentContainer is switched before the placeholder is moved.
3835
                        //
3836
                        // Without this moving items in "sub-sortables" can cause the placeholder to jitter
3837
                        // beetween the outer and inner container.
3838
                        if (item.instance !== this.currentContainer) {
3839
                                continue;
3840
                        }
3841

    
3842
                        // cannot intersect with itself
3843
                        // no useless actions that have been done before
3844
                        // no action if the item moved is the parent of the item checked
3845
                        if (itemElement !== this.currentItem[0] &&
3846
                                this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
3847
                                !$.contains(this.placeholder[0], itemElement) &&
3848
                                (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
3849
                        ) {
3850

    
3851
                                this.direction = intersection === 1 ? "down" : "up";
3852

    
3853
                                if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
3854
                                        this._rearrange(event, item);
3855
                                } else {
3856
                                        break;
3857
                                }
3858

    
3859
                                this._trigger("change", event, this._uiHash());
3860
                                break;
3861
                        }
3862
                }
3863

    
3864
                //Post events to containers
3865
                this._contactContainers(event);
3866

    
3867
                //Interconnect with droppables
3868
                if($.ui.ddmanager) {
3869
                        $.ui.ddmanager.drag(this, event);
3870
                }
3871

    
3872
                //Call callbacks
3873
                this._trigger("sort", event, this._uiHash());
3874

    
3875
                this.lastPositionAbs = this.positionAbs;
3876
                return false;
3877

    
3878
        },
3879

    
3880
        _mouseStop: function(event, noPropagation) {
3881

    
3882
                if(!event) {
3883
                        return;
3884
                }
3885

    
3886
                //If we are using droppables, inform the manager about the drop
3887
                if ($.ui.ddmanager && !this.options.dropBehaviour) {
3888
                        $.ui.ddmanager.drop(this, event);
3889
                }
3890

    
3891
                if(this.options.revert) {
3892
                        var that = this,
3893
                                cur = this.placeholder.offset(),
3894
                                axis = this.options.axis,
3895
                                animation = {};
3896

    
3897
                        if ( !axis || axis === "x" ) {
3898
                                animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
3899
                        }
3900
                        if ( !axis || axis === "y" ) {
3901
                                animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
3902
                        }
3903
                        this.reverting = true;
3904
                        $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
3905
                                that._clear(event);
3906
                        });
3907
                } else {
3908
                        this._clear(event, noPropagation);
3909
                }
3910

    
3911
                return false;
3912

    
3913
        },
3914

    
3915
        cancel: function() {
3916

    
3917
                if(this.dragging) {
3918

    
3919
                        this._mouseUp({ target: null });
3920

    
3921
                        if(this.options.helper === "original") {
3922
                                this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3923
                        } else {
3924
                                this.currentItem.show();
3925
                        }
3926

    
3927
                        //Post deactivating events to containers
3928
                        for (var i = this.containers.length - 1; i >= 0; i--){
3929
                                this.containers[i]._trigger("deactivate", null, this._uiHash(this));
3930
                                if(this.containers[i].containerCache.over) {
3931
                                        this.containers[i]._trigger("out", null, this._uiHash(this));
3932
                                        this.containers[i].containerCache.over = 0;
3933
                                }
3934
                        }
3935

    
3936
                }
3937

    
3938
                if (this.placeholder) {
3939
                        //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3940
                        if(this.placeholder[0].parentNode) {
3941
                                this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3942
                        }
3943
                        if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
3944
                                this.helper.remove();
3945
                        }
3946

    
3947
                        $.extend(this, {
3948
                                helper: null,
3949
                                dragging: false,
3950
                                reverting: false,
3951
                                _noFinalSort: null
3952
                        });
3953

    
3954
                        if(this.domPosition.prev) {
3955
                                $(this.domPosition.prev).after(this.currentItem);
3956
                        } else {
3957
                                $(this.domPosition.parent).prepend(this.currentItem);
3958
                        }
3959
                }
3960

    
3961
                return this;
3962

    
3963
        },
3964

    
3965
        serialize: function(o) {
3966

    
3967
                var items = this._getItemsAsjQuery(o && o.connected),
3968
                        str = [];
3969
                o = o || {};
3970

    
3971
                $(items).each(function() {
3972
                        var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
3973
                        if (res) {
3974
                                str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
3975
                        }
3976
                });
3977

    
3978
                if(!str.length && o.key) {
3979
                        str.push(o.key + "=");
3980
                }
3981

    
3982
                return str.join("&");
3983

    
3984
        },
3985

    
3986
        toArray: function(o) {
3987

    
3988
                var items = this._getItemsAsjQuery(o && o.connected),
3989
                        ret = [];
3990

    
3991
                o = o || {};
3992

    
3993
                items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
3994
                return ret;
3995

    
3996
        },
3997

    
3998
        /* Be careful with the following core functions */
3999
        _intersectsWith: function(item) {
4000

    
4001
                var x1 = this.positionAbs.left,
4002
                        x2 = x1 + this.helperProportions.width,
4003
                        y1 = this.positionAbs.top,
4004
                        y2 = y1 + this.helperProportions.height,
4005
                        l = item.left,
4006
                        r = l + item.width,
4007
                        t = item.top,
4008
                        b = t + item.height,
4009
                        dyClick = this.offset.click.top,
4010
                        dxClick = this.offset.click.left,
4011
                        isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
4012

    
4013
                if ( this.options.tolerance === "pointer" ||
4014
                        this.options.forcePointerForContainers ||
4015
                        (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
4016
                ) {
4017
                        return isOverElement;
4018
                } else {
4019

    
4020
                        return (l < x1 + (this.helperProportions.width / 2) && // Right Half
4021
                                x2 - (this.helperProportions.width / 2) < r && // Left Half
4022
                                t < y1 + (this.helperProportions.height / 2) && // Bottom Half
4023
                                y2 - (this.helperProportions.height / 2) < b ); // Top Half
4024

    
4025
                }
4026
        },
4027

    
4028
        _intersectsWithPointer: function(item) {
4029

    
4030
                var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4031
                        isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4032
                        isOverElement = isOverElementHeight && isOverElementWidth,
4033
                        verticalDirection = this._getDragVerticalDirection(),
4034
                        horizontalDirection = this._getDragHorizontalDirection();
4035

    
4036
                if (!isOverElement) {
4037
                        return false;
4038
                }
4039

    
4040
                return this.floating ?
4041
                        ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
4042
                        : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
4043

    
4044
        },
4045

    
4046
        _intersectsWithSides: function(item) {
4047

    
4048
                var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4049
                        isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4050
                        verticalDirection = this._getDragVerticalDirection(),
4051
                        horizontalDirection = this._getDragHorizontalDirection();
4052

    
4053
                if (this.floating && horizontalDirection) {
4054
                        return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
4055
                } else {
4056
                        return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
4057
                }
4058

    
4059
        },
4060

    
4061
        _getDragVerticalDirection: function() {
4062
                var delta = this.positionAbs.top - this.lastPositionAbs.top;
4063
                return delta !== 0 && (delta > 0 ? "down" : "up");
4064
        },
4065

    
4066
        _getDragHorizontalDirection: function() {
4067
                var delta = this.positionAbs.left - this.lastPositionAbs.left;
4068
                return delta !== 0 && (delta > 0 ? "right" : "left");
4069
        },
4070

    
4071
        refresh: function(event) {
4072
                this._refreshItems(event);
4073
                this.refreshPositions();
4074
                return this;
4075
        },
4076

    
4077
        _connectWith: function() {
4078
                var options = this.options;
4079
                return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
4080
        },
4081

    
4082
        _getItemsAsjQuery: function(connected) {
4083

    
4084
                var i, j, cur, inst,
4085
                        items = [],
4086
                        queries = [],
4087
                        connectWith = this._connectWith();
4088

    
4089
                if(connectWith && connected) {
4090
                        for (i = connectWith.length - 1; i >= 0; i--){
4091
                                cur = $(connectWith[i]);
4092
                                for ( j = cur.length - 1; j >= 0; j--){
4093
                                        inst = $.data(cur[j], this.widgetFullName);
4094
                                        if(inst && inst !== this && !inst.options.disabled) {
4095
                                                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]);
4096
                                        }
4097
                                }
4098
                        }
4099
                }
4100

    
4101
                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]);
4102

    
4103
                for (i = queries.length - 1; i >= 0; i--){
4104
                        queries[i][0].each(function() {
4105
                                items.push(this);
4106
                        });
4107
                }
4108

    
4109
                return $(items);
4110

    
4111
        },
4112

    
4113
        _removeCurrentsFromItems: function() {
4114

    
4115
                var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4116

    
4117
                this.items = $.grep(this.items, function (item) {
4118
                        for (var j=0; j < list.length; j++) {
4119
                                if(list[j] === item.item[0]) {
4120
                                        return false;
4121
                                }
4122
                        }
4123
                        return true;
4124
                });
4125

    
4126
        },
4127

    
4128
        _refreshItems: function(event) {
4129

    
4130
                this.items = [];
4131
                this.containers = [this];
4132

    
4133
                var i, j, cur, inst, targetData, _queries, item, queriesLength,
4134
                        items = this.items,
4135
                        queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
4136
                        connectWith = this._connectWith();
4137

    
4138
                if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4139
                        for (i = connectWith.length - 1; i >= 0; i--){
4140
                                cur = $(connectWith[i]);
4141
                                for (j = cur.length - 1; j >= 0; j--){
4142
                                        inst = $.data(cur[j], this.widgetFullName);
4143
                                        if(inst && inst !== this && !inst.options.disabled) {
4144
                                                queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4145
                                                this.containers.push(inst);
4146
                                        }
4147
                                }
4148
                        }
4149
                }
4150

    
4151
                for (i = queries.length - 1; i >= 0; i--) {
4152
                        targetData = queries[i][1];
4153
                        _queries = queries[i][0];
4154

    
4155
                        for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4156
                                item = $(_queries[j]);
4157

    
4158
                                item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
4159

    
4160
                                items.push({
4161
                                        item: item,
4162
                                        instance: targetData,
4163
                                        width: 0, height: 0,
4164
                                        left: 0, top: 0
4165
                                });
4166
                        }
4167
                }
4168

    
4169
        },
4170

    
4171
        refreshPositions: function(fast) {
4172

    
4173
                //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4174
                if(this.offsetParent && this.helper) {
4175
                        this.offset.parent = this._getParentOffset();
4176
                }
4177

    
4178
                var i, item, t, p;
4179

    
4180
                for (i = this.items.length - 1; i >= 0; i--){
4181
                        item = this.items[i];
4182

    
4183
                        //We ignore calculating positions of all connected containers when we're not over them
4184
                        if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
4185
                                continue;
4186
                        }
4187

    
4188
                        t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4189

    
4190
                        if (!fast) {
4191
                                item.width = t.outerWidth();
4192
                                item.height = t.outerHeight();
4193
                        }
4194

    
4195
                        p = t.offset();
4196
                        item.left = p.left;
4197
                        item.top = p.top;
4198
                }
4199

    
4200
                if(this.options.custom && this.options.custom.refreshContainers) {
4201
                        this.options.custom.refreshContainers.call(this);
4202
                } else {
4203
                        for (i = this.containers.length - 1; i >= 0; i--){
4204
                                p = this.containers[i].element.offset();
4205
                                this.containers[i].containerCache.left = p.left;
4206
                                this.containers[i].containerCache.top = p.top;
4207
                                this.containers[i].containerCache.width        = this.containers[i].element.outerWidth();
4208
                                this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4209
                        }
4210
                }
4211

    
4212
                return this;
4213
        },
4214

    
4215
        _createPlaceholder: function(that) {
4216
                that = that || this;
4217
                var className,
4218
                        o = that.options;
4219

    
4220
                if(!o.placeholder || o.placeholder.constructor === String) {
4221
                        className = o.placeholder;
4222
                        o.placeholder = {
4223
                                element: function() {
4224

    
4225
                                        var nodeName = that.currentItem[0].nodeName.toLowerCase(),
4226
                                                element = $( that.document[0].createElement( nodeName ) )
4227
                                                        .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4228
                                                        .removeClass("ui-sortable-helper");
4229

    
4230
                                        if ( nodeName === "tr" ) {
4231
                                                // Use a high colspan to force the td to expand the full
4232
                                                // width of the table (browsers are smart enough to
4233
                                                // handle this properly)
4234
                                                element.append( "<td colspan='99'>&#160;</td>" );
4235
                                        } else if ( nodeName === "img" ) {
4236
                                                element.attr( "src", that.currentItem.attr( "src" ) );
4237
                                        }
4238

    
4239
                                        if ( !className ) {
4240
                                                element.css( "visibility", "hidden" );
4241
                                        }
4242

    
4243
                                        return element;
4244
                                },
4245
                                update: function(container, p) {
4246

    
4247
                                        // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4248
                                        // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4249
                                        if(className && !o.forcePlaceholderSize) {
4250
                                                return;
4251
                                        }
4252

    
4253
                                        //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
4254
                                        if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
4255
                                        if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
4256
                                }
4257
                        };
4258
                }
4259

    
4260
                //Create the placeholder
4261
                that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4262

    
4263
                //Append it after the actual current item
4264
                that.currentItem.after(that.placeholder);
4265

    
4266
                //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4267
                o.placeholder.update(that, that.placeholder);
4268

    
4269
        },
4270

    
4271
        _contactContainers: function(event) {
4272
                var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
4273
                        innermostContainer = null,
4274
                        innermostIndex = null;
4275

    
4276
                // get innermost container that intersects with item
4277
                for (i = this.containers.length - 1; i >= 0; i--) {
4278

    
4279
                        // never consider a container that's located within the item itself
4280
                        if($.contains(this.currentItem[0], this.containers[i].element[0])) {
4281
                                continue;
4282
                        }
4283

    
4284
                        if(this._intersectsWith(this.containers[i].containerCache)) {
4285

    
4286
                                // if we've already found a container and it's more "inner" than this, then continue
4287
                                if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
4288
                                        continue;
4289
                                }
4290

    
4291
                                innermostContainer = this.containers[i];
4292
                                innermostIndex = i;
4293

    
4294
                        } else {
4295
                                // container doesn't intersect. trigger "out" event if necessary
4296
                                if(this.containers[i].containerCache.over) {
4297
                                        this.containers[i]._trigger("out", event, this._uiHash(this));
4298
                                        this.containers[i].containerCache.over = 0;
4299
                                }
4300
                        }
4301

    
4302
                }
4303

    
4304
                // if no intersecting containers found, return
4305
                if(!innermostContainer) {
4306
                        return;
4307
                }
4308

    
4309
                // move the item into the container if it's not there already
4310
                if(this.containers.length === 1) {
4311
                        if (!this.containers[innermostIndex].containerCache.over) {
4312
                                this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4313
                                this.containers[innermostIndex].containerCache.over = 1;
4314
                        }
4315
                } else {
4316

    
4317
                        //When entering a new container, we will find the item with the least distance and append our item near it
4318
                        dist = 10000;
4319
                        itemWithLeastDistance = null;
4320
                        floating = innermostContainer.floating || isFloating(this.currentItem);
4321
                        posProperty = floating ? "left" : "top";
4322
                        sizeProperty = floating ? "width" : "height";
4323
                        base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4324
                        for (j = this.items.length - 1; j >= 0; j--) {
4325
                                if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
4326
                                        continue;
4327
                                }
4328
                                if(this.items[j].item[0] === this.currentItem[0]) {
4329
                                        continue;
4330
                                }
4331
                                if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
4332
                                        continue;
4333
                                }
4334
                                cur = this.items[j].item.offset()[posProperty];
4335
                                nearBottom = false;
4336
                                if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4337
                                        nearBottom = true;
4338
                                        cur += this.items[j][sizeProperty];
4339
                                }
4340

    
4341
                                if(Math.abs(cur - base) < dist) {
4342
                                        dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4343
                                        this.direction = nearBottom ? "up": "down";
4344
                                }
4345
                        }
4346

    
4347
                        //Check if dropOnEmpty is enabled
4348
                        if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
4349
                                return;
4350
                        }
4351

    
4352
                        if(this.currentContainer === this.containers[innermostIndex]) {
4353
                                return;
4354
                        }
4355

    
4356
                        itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4357
                        this._trigger("change", event, this._uiHash());
4358
                        this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4359
                        this.currentContainer = this.containers[innermostIndex];
4360

    
4361
                        //Update the placeholder
4362
                        this.options.placeholder.update(this.currentContainer, this.placeholder);
4363

    
4364
                        this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4365
                        this.containers[innermostIndex].containerCache.over = 1;
4366
                }
4367

    
4368

    
4369
        },
4370

    
4371
        _createHelper: function(event) {
4372

    
4373
                var o = this.options,
4374
                        helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
4375

    
4376
                //Add the helper to the DOM if that didn't happen already
4377
                if(!helper.parents("body").length) {
4378
                        $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4379
                }
4380

    
4381
                if(helper[0] === this.currentItem[0]) {
4382
                        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") };
4383
                }
4384

    
4385
                if(!helper[0].style.width || o.forceHelperSize) {
4386
                        helper.width(this.currentItem.width());
4387
                }
4388
                if(!helper[0].style.height || o.forceHelperSize) {
4389
                        helper.height(this.currentItem.height());
4390
                }
4391

    
4392
                return helper;
4393

    
4394
        },
4395

    
4396
        _adjustOffsetFromHelper: function(obj) {
4397
                if (typeof obj === "string") {
4398
                        obj = obj.split(" ");
4399
                }
4400
                if ($.isArray(obj)) {
4401
                        obj = {left: +obj[0], top: +obj[1] || 0};
4402
                }
4403
                if ("left" in obj) {
4404
                        this.offset.click.left = obj.left + this.margins.left;
4405
                }
4406
                if ("right" in obj) {
4407
                        this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4408
                }
4409
                if ("top" in obj) {
4410
                        this.offset.click.top = obj.top + this.margins.top;
4411
                }
4412
                if ("bottom" in obj) {
4413
                        this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4414
                }
4415
        },
4416

    
4417
        _getParentOffset: function() {
4418

    
4419

    
4420
                //Get the offsetParent and cache its position
4421
                this.offsetParent = this.helper.offsetParent();
4422
                var po = this.offsetParent.offset();
4423

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

    
4433
                // This needs to be actually done for all browsers, since pageX/pageY includes this information
4434
                // with an ugly IE fix
4435
                if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
4436
                        po = { top: 0, left: 0 };
4437
                }
4438

    
4439
                return {
4440
                        top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4441
                        left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4442
                };
4443

    
4444
        },
4445

    
4446
        _getRelativeOffset: function() {
4447

    
4448
                if(this.cssPosition === "relative") {
4449
                        var p = this.currentItem.position();
4450
                        return {
4451
                                top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4452
                                left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4453
                        };
4454
                } else {
4455
                        return { top: 0, left: 0 };
4456
                }
4457

    
4458
        },
4459

    
4460
        _cacheMargins: function() {
4461
                this.margins = {
4462
                        left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4463
                        top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4464
                };
4465
        },
4466

    
4467
        _cacheHelperProportions: function() {
4468
                this.helperProportions = {
4469
                        width: this.helper.outerWidth(),
4470
                        height: this.helper.outerHeight()
4471
                };
4472
        },
4473

    
4474
        _setContainment: function() {
4475

    
4476
                var ce, co, over,
4477
                        o = this.options;
4478
                if(o.containment === "parent") {
4479
                        o.containment = this.helper[0].parentNode;
4480
                }
4481
                if(o.containment === "document" || o.containment === "window") {
4482
                        this.containment = [
4483
                                0 - this.offset.relative.left - this.offset.parent.left,
4484
                                0 - this.offset.relative.top - this.offset.parent.top,
4485
                                $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
4486
                                ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4487
                        ];
4488
                }
4489

    
4490
                if(!(/^(document|window|parent)$/).test(o.containment)) {
4491
                        ce = $(o.containment)[0];
4492
                        co = $(o.containment).offset();
4493
                        over = ($(ce).css("overflow") !== "hidden");
4494

    
4495
                        this.containment = [
4496
                                co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4497
                                co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4498
                                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,
4499
                                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
4500
                        ];
4501
                }
4502

    
4503
        },
4504

    
4505
        _convertPositionTo: function(d, pos) {
4506

    
4507
                if(!pos) {
4508
                        pos = this.position;
4509
                }
4510
                var mod = d === "absolute" ? 1 : -1,
4511
                        scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
4512
                        scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4513

    
4514
                return {
4515
                        top: (
4516
                                pos.top        +                                                                                                                                // The absolute mouse position
4517
                                this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
4518
                                this.offset.parent.top * mod -                                                                                        // The offsetParent's offset without borders (offset + border)
4519
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4520
                        ),
4521
                        left: (
4522
                                pos.left +                                                                                                                                // The absolute mouse position
4523
                                this.offset.relative.left * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
4524
                                this.offset.parent.left * mod        -                                                                                // The offsetParent's offset without borders (offset + border)
4525
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4526
                        )
4527
                };
4528

    
4529
        },
4530

    
4531
        _generatePosition: function(event) {
4532

    
4533
                var top, left,
4534
                        o = this.options,
4535
                        pageX = event.pageX,
4536
                        pageY = event.pageY,
4537
                        scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4538

    
4539
                // This is another very weird special case that only happens for relative elements:
4540
                // 1. If the css position is relative
4541
                // 2. and the scroll parent is the document or similar to the offset parent
4542
                // we have to refresh the relative offset during the scroll so there are no jumps
4543
                if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
4544
                        this.offset.relative = this._getRelativeOffset();
4545
                }
4546

    
4547
                /*
4548
                 * - Position constraining -
4549
                 * Constrain the position to a mix of grid, containment.
4550
                 */
4551

    
4552
                if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4553

    
4554
                        if(this.containment) {
4555
                                if(event.pageX - this.offset.click.left < this.containment[0]) {
4556
                                        pageX = this.containment[0] + this.offset.click.left;
4557
                                }
4558
                                if(event.pageY - this.offset.click.top < this.containment[1]) {
4559
                                        pageY = this.containment[1] + this.offset.click.top;
4560
                                }
4561
                                if(event.pageX - this.offset.click.left > this.containment[2]) {
4562
                                        pageX = this.containment[2] + this.offset.click.left;
4563
                                }
4564
                                if(event.pageY - this.offset.click.top > this.containment[3]) {
4565
                                        pageY = this.containment[3] + this.offset.click.top;
4566
                                }
4567
                        }
4568

    
4569
                        if(o.grid) {
4570
                                top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4571
                                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;
4572

    
4573
                                left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4574
                                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;
4575
                        }
4576

    
4577
                }
4578

    
4579
                return {
4580
                        top: (
4581
                                pageY -                                                                                                                                // The absolute mouse position
4582
                                this.offset.click.top -                                                                                                        // Click offset (relative to the element)
4583
                                this.offset.relative.top        -                                                                                        // Only for relative positioned nodes: Relative offset from element to offset parent
4584
                                this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
4585
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4586
                        ),
4587
                        left: (
4588
                                pageX -                                                                                                                                // The absolute mouse position
4589
                                this.offset.click.left -                                                                                                // Click offset (relative to the element)
4590
                                this.offset.relative.left        -                                                                                        // Only for relative positioned nodes: Relative offset from element to offset parent
4591
                                this.offset.parent.left +                                                                                                // The offsetParent's offset without borders (offset + border)
4592
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4593
                        )
4594
                };
4595

    
4596
        },
4597

    
4598
        _rearrange: function(event, i, a, hardRefresh) {
4599

    
4600
                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));
4601

    
4602
                //Various things done here to improve the performance:
4603
                // 1. we create a setTimeout, that calls refreshPositions
4604
                // 2. on the instance, we have a counter variable, that get's higher after every append
4605
                // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4606
                // 4. this lets only the last addition to the timeout stack through
4607
                this.counter = this.counter ? ++this.counter : 1;
4608
                var counter = this.counter;
4609

    
4610
                this._delay(function() {
4611
                        if(counter === this.counter) {
4612
                                this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4613
                        }
4614
                });
4615

    
4616
        },
4617

    
4618
        _clear: function(event, noPropagation) {
4619

    
4620
                this.reverting = false;
4621
                // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4622
                // everything else normalized again
4623
                var i,
4624
                        delayedTriggers = [];
4625

    
4626
                // We first have to update the dom position of the actual currentItem
4627
                // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4628
                if(!this._noFinalSort && this.currentItem.parent().length) {
4629
                        this.placeholder.before(this.currentItem);
4630
                }
4631
                this._noFinalSort = null;
4632

    
4633
                if(this.helper[0] === this.currentItem[0]) {
4634
                        for(i in this._storedCSS) {
4635
                                if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
4636
                                        this._storedCSS[i] = "";
4637
                                }
4638
                        }
4639
                        this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4640
                } else {
4641
                        this.currentItem.show();
4642
                }
4643

    
4644
                if(this.fromOutside && !noPropagation) {
4645
                        delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4646
                }
4647
                if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
4648
                        delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4649
                }
4650

    
4651
                // Check if the items Container has Changed and trigger appropriate
4652
                // events.
4653
                if (this !== this.currentContainer) {
4654
                        if(!noPropagation) {
4655
                                delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4656
                                delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4657
                                delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4658
                        }
4659
                }
4660

    
4661

    
4662
                //Post events to containers
4663
                for (i = this.containers.length - 1; i >= 0; i--){
4664
                        if(!noPropagation) {
4665
                                delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4666
                        }
4667
                        if(this.containers[i].containerCache.over) {
4668
                                delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4669
                                this.containers[i].containerCache.over = 0;
4670
                        }
4671
                }
4672

    
4673
                //Do what was originally in plugins
4674
                if ( this.storedCursor ) {
4675
                        this.document.find( "body" ).css( "cursor", this.storedCursor );
4676
                        this.storedStylesheet.remove();
4677
                }
4678
                if(this._storedOpacity) {
4679
                        this.helper.css("opacity", this._storedOpacity);
4680
                }
4681
                if(this._storedZIndex) {
4682
                        this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
4683
                }
4684

    
4685
                this.dragging = false;
4686
                if(this.cancelHelperRemoval) {
4687
                        if(!noPropagation) {
4688
                                this._trigger("beforeStop", event, this._uiHash());
4689
                                for (i=0; i < delayedTriggers.length; i++) {
4690
                                        delayedTriggers[i].call(this, event);
4691
                                } //Trigger all delayed events
4692
                                this._trigger("stop", event, this._uiHash());
4693
                        }
4694

    
4695
                        this.fromOutside = false;
4696
                        return false;
4697
                }
4698

    
4699
                if(!noPropagation) {
4700
                        this._trigger("beforeStop", event, this._uiHash());
4701
                }
4702

    
4703
                //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4704
                this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4705

    
4706
                if(this.helper[0] !== this.currentItem[0]) {
4707
                        this.helper.remove();
4708
                }
4709
                this.helper = null;
4710

    
4711
                if(!noPropagation) {
4712
                        for (i=0; i < delayedTriggers.length; i++) {
4713
                                delayedTriggers[i].call(this, event);
4714
                        } //Trigger all delayed events
4715
                        this._trigger("stop", event, this._uiHash());
4716
                }
4717

    
4718
                this.fromOutside = false;
4719
                return true;
4720

    
4721
        },
4722

    
4723
        _trigger: function() {
4724
                if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4725
                        this.cancel();
4726
                }
4727
        },
4728

    
4729
        _uiHash: function(_inst) {
4730
                var inst = _inst || this;
4731
                return {
4732
                        helper: inst.helper,
4733
                        placeholder: inst.placeholder || $([]),
4734
                        position: inst.position,
4735
                        originalPosition: inst.originalPosition,
4736
                        offset: inst.positionAbs,
4737
                        item: inst.currentItem,
4738
                        sender: _inst ? _inst.element : null
4739
                };
4740
        }
4741

    
4742
});
4743

    
4744
})(jQuery);
4745

    
4746
(function($, undefined) {
4747

    
4748
var dataSpace = "ui-effects-";
4749

    
4750
$.effects = {
4751
        effect: {}
4752
};
4753

    
4754
/*!
4755
 * jQuery Color Animations v2.1.2
4756
 * https://github.com/jquery/jquery-color
4757
 *
4758
 * Copyright 2013 jQuery Foundation and other contributors
4759
 * Released under the MIT license.
4760
 * http://jquery.org/license
4761
 *
4762
 * Date: Wed Jan 16 08:47:09 2013 -0600
4763
 */
4764
(function( jQuery, undefined ) {
4765

    
4766
        var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
4767

    
4768
        // plusequals test for += 100 -= 100
4769
        rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
4770
        // a set of RE's that can match strings and generate color tuples.
4771
        stringParsers = [{
4772
                        re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4773
                        parse: function( execResult ) {
4774
                                return [
4775
                                        execResult[ 1 ],
4776
                                        execResult[ 2 ],
4777
                                        execResult[ 3 ],
4778
                                        execResult[ 4 ]
4779
                                ];
4780
                        }
4781
                }, {
4782
                        re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4783
                        parse: function( execResult ) {
4784
                                return [
4785
                                        execResult[ 1 ] * 2.55,
4786
                                        execResult[ 2 ] * 2.55,
4787
                                        execResult[ 3 ] * 2.55,
4788
                                        execResult[ 4 ]
4789
                                ];
4790
                        }
4791
                }, {
4792
                        // this regex ignores A-F because it's compared against an already lowercased string
4793
                        re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
4794
                        parse: function( execResult ) {
4795
                                return [
4796
                                        parseInt( execResult[ 1 ], 16 ),
4797
                                        parseInt( execResult[ 2 ], 16 ),
4798
                                        parseInt( execResult[ 3 ], 16 )
4799
                                ];
4800
                        }
4801
                }, {
4802
                        // this regex ignores A-F because it's compared against an already lowercased string
4803
                        re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
4804
                        parse: function( execResult ) {
4805
                                return [
4806
                                        parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
4807
                                        parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
4808
                                        parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
4809
                                ];
4810
                        }
4811
                }, {
4812
                        re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4813
                        space: "hsla",
4814
                        parse: function( execResult ) {
4815
                                return [
4816
                                        execResult[ 1 ],
4817
                                        execResult[ 2 ] / 100,
4818
                                        execResult[ 3 ] / 100,
4819
                                        execResult[ 4 ]
4820
                                ];
4821
                        }
4822
                }],
4823

    
4824
        // jQuery.Color( )
4825
        color = jQuery.Color = function( color, green, blue, alpha ) {
4826
                return new jQuery.Color.fn.parse( color, green, blue, alpha );
4827
        },
4828
        spaces = {
4829
                rgba: {
4830
                        props: {
4831
                                red: {
4832
                                        idx: 0,
4833
                                        type: "byte"
4834
                                },
4835
                                green: {
4836
                                        idx: 1,
4837
                                        type: "byte"
4838
                                },
4839
                                blue: {
4840
                                        idx: 2,
4841
                                        type: "byte"
4842
                                }
4843
                        }
4844
                },
4845

    
4846
                hsla: {
4847
                        props: {
4848
                                hue: {
4849
                                        idx: 0,
4850
                                        type: "degrees"
4851
                                },
4852
                                saturation: {
4853
                                        idx: 1,
4854
                                        type: "percent"
4855
                                },
4856
                                lightness: {
4857
                                        idx: 2,
4858
                                        type: "percent"
4859
                                }
4860
                        }
4861
                }
4862
        },
4863
        propTypes = {
4864
                "byte": {
4865
                        floor: true,
4866
                        max: 255
4867
                },
4868
                "percent": {
4869
                        max: 1
4870
                },
4871
                "degrees": {
4872
                        mod: 360,
4873
                        floor: true
4874
                }
4875
        },
4876
        support = color.support = {},
4877

    
4878
        // element for support tests
4879
        supportElem = jQuery( "<p>" )[ 0 ],
4880

    
4881
        // colors = jQuery.Color.names
4882
        colors,
4883

    
4884
        // local aliases of functions called often
4885
        each = jQuery.each;
4886

    
4887
// determine rgba support immediately
4888
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
4889
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
4890

    
4891
// define cache name and alpha properties
4892
// for rgba and hsla spaces
4893
each( spaces, function( spaceName, space ) {
4894
        space.cache = "_" + spaceName;
4895
        space.props.alpha = {
4896
                idx: 3,
4897
                type: "percent",
4898
                def: 1
4899
        };
4900
});
4901

    
4902
function clamp( value, prop, allowEmpty ) {
4903
        var type = propTypes[ prop.type ] || {};
4904

    
4905
        if ( value == null ) {
4906
                return (allowEmpty || !prop.def) ? null : prop.def;
4907
        }
4908

    
4909
        // ~~ is an short way of doing floor for positive numbers
4910
        value = type.floor ? ~~value : parseFloat( value );
4911

    
4912
        // IE will pass in empty strings as value for alpha,
4913
        // which will hit this case
4914
        if ( isNaN( value ) ) {
4915
                return prop.def;
4916
        }
4917

    
4918
        if ( type.mod ) {
4919
                // we add mod before modding to make sure that negatives values
4920
                // get converted properly: -10 -> 350
4921
                return (value + type.mod) % type.mod;
4922
        }
4923

    
4924
        // for now all property types without mod have min and max
4925
        return 0 > value ? 0 : type.max < value ? type.max : value;
4926
}
4927

    
4928
function stringParse( string ) {
4929
        var inst = color(),
4930
                rgba = inst._rgba = [];
4931

    
4932
        string = string.toLowerCase();
4933

    
4934
        each( stringParsers, function( i, parser ) {
4935
                var parsed,
4936
                        match = parser.re.exec( string ),
4937
                        values = match && parser.parse( match ),
4938
                        spaceName = parser.space || "rgba";
4939

    
4940
                if ( values ) {
4941
                        parsed = inst[ spaceName ]( values );
4942

    
4943
                        // if this was an rgba parse the assignment might happen twice
4944
                        // oh well....
4945
                        inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
4946
                        rgba = inst._rgba = parsed._rgba;
4947

    
4948
                        // exit each( stringParsers ) here because we matched
4949
                        return false;
4950
                }
4951
        });
4952

    
4953
        // Found a stringParser that handled it
4954
        if ( rgba.length ) {
4955

    
4956
                // if this came from a parsed string, force "transparent" when alpha is 0
4957
                // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
4958
                if ( rgba.join() === "0,0,0,0" ) {
4959
                        jQuery.extend( rgba, colors.transparent );
4960
                }
4961
                return inst;
4962
        }
4963

    
4964
        // named colors
4965
        return colors[ string ];
4966
}
4967

    
4968
color.fn = jQuery.extend( color.prototype, {
4969
        parse: function( red, green, blue, alpha ) {
4970
                if ( red === undefined ) {
4971
                        this._rgba = [ null, null, null, null ];
4972
                        return this;
4973
                }
4974
                if ( red.jquery || red.nodeType ) {
4975
                        red = jQuery( red ).css( green );
4976
                        green = undefined;
4977
                }
4978

    
4979
                var inst = this,
4980
                        type = jQuery.type( red ),
4981
                        rgba = this._rgba = [];
4982

    
4983
                // more than 1 argument specified - assume ( red, green, blue, alpha )
4984
                if ( green !== undefined ) {
4985
                        red = [ red, green, blue, alpha ];
4986
                        type = "array";
4987
                }
4988

    
4989
                if ( type === "string" ) {
4990
                        return this.parse( stringParse( red ) || colors._default );
4991
                }
4992

    
4993
                if ( type === "array" ) {
4994
                        each( spaces.rgba.props, function( key, prop ) {
4995
                                rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
4996
                        });
4997
                        return this;
4998
                }
4999

    
5000
                if ( type === "object" ) {
5001
                        if ( red instanceof color ) {
5002
                                each( spaces, function( spaceName, space ) {
5003
                                        if ( red[ space.cache ] ) {
5004
                                                inst[ space.cache ] = red[ space.cache ].slice();
5005
                                        }
5006
                                });
5007
                        } else {
5008
                                each( spaces, function( spaceName, space ) {
5009
                                        var cache = space.cache;
5010
                                        each( space.props, function( key, prop ) {
5011

    
5012
                                                // if the cache doesn't exist, and we know how to convert
5013
                                                if ( !inst[ cache ] && space.to ) {
5014

    
5015
                                                        // if the value was null, we don't need to copy it
5016
                                                        // if the key was alpha, we don't need to copy it either
5017
                                                        if ( key === "alpha" || red[ key ] == null ) {
5018
                                                                return;
5019
                                                        }
5020
                                                        inst[ cache ] = space.to( inst._rgba );
5021
                                                }
5022

    
5023
                                                // this is the only case where we allow nulls for ALL properties.
5024
                                                // call clamp with alwaysAllowEmpty
5025
                                                inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
5026
                                        });
5027

    
5028
                                        // everything defined but alpha?
5029
                                        if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
5030
                                                // use the default of 1
5031
                                                inst[ cache ][ 3 ] = 1;
5032
                                                if ( space.from ) {
5033
                                                        inst._rgba = space.from( inst[ cache ] );
5034
                                                }
5035
                                        }
5036
                                });
5037
                        }
5038
                        return this;
5039
                }
5040
        },
5041
        is: function( compare ) {
5042
                var is = color( compare ),
5043
                        same = true,
5044
                        inst = this;
5045

    
5046
                each( spaces, function( _, space ) {
5047
                        var localCache,
5048
                                isCache = is[ space.cache ];
5049
                        if (isCache) {
5050
                                localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
5051
                                each( space.props, function( _, prop ) {
5052
                                        if ( isCache[ prop.idx ] != null ) {
5053
                                                same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
5054
                                                return same;
5055
                                        }
5056
                                });
5057
                        }
5058
                        return same;
5059
                });
5060
                return same;
5061
        },
5062
        _space: function() {
5063
                var used = [],
5064
                        inst = this;
5065
                each( spaces, function( spaceName, space ) {
5066
                        if ( inst[ space.cache ] ) {
5067
                                used.push( spaceName );
5068
                        }
5069
                });
5070
                return used.pop();
5071
        },
5072
        transition: function( other, distance ) {
5073
                var end = color( other ),
5074
                        spaceName = end._space(),
5075
                        space = spaces[ spaceName ],
5076
                        startColor = this.alpha() === 0 ? color( "transparent" ) : this,
5077
                        start = startColor[ space.cache ] || space.to( startColor._rgba ),
5078
                        result = start.slice();
5079

    
5080
                end = end[ space.cache ];
5081
                each( space.props, function( key, prop ) {
5082
                        var index = prop.idx,
5083
                                startValue = start[ index ],
5084
                                endValue = end[ index ],
5085
                                type = propTypes[ prop.type ] || {};
5086

    
5087
                        // if null, don't override start value
5088
                        if ( endValue === null ) {
5089
                                return;
5090
                        }
5091
                        // if null - use end
5092
                        if ( startValue === null ) {
5093
                                result[ index ] = endValue;
5094
                        } else {
5095
                                if ( type.mod ) {
5096
                                        if ( endValue - startValue > type.mod / 2 ) {
5097
                                                startValue += type.mod;
5098
                                        } else if ( startValue - endValue > type.mod / 2 ) {
5099
                                                startValue -= type.mod;
5100
                                        }
5101
                                }
5102
                                result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
5103
                        }
5104
                });
5105
                return this[ spaceName ]( result );
5106
        },
5107
        blend: function( opaque ) {
5108
                // if we are already opaque - return ourself
5109
                if ( this._rgba[ 3 ] === 1 ) {
5110
                        return this;
5111
                }
5112

    
5113
                var rgb = this._rgba.slice(),
5114
                        a = rgb.pop(),
5115
                        blend = color( opaque )._rgba;
5116

    
5117
                return color( jQuery.map( rgb, function( v, i ) {
5118
                        return ( 1 - a ) * blend[ i ] + a * v;
5119
                }));
5120
        },
5121
        toRgbaString: function() {
5122
                var prefix = "rgba(",
5123
                        rgba = jQuery.map( this._rgba, function( v, i ) {
5124
                                return v == null ? ( i > 2 ? 1 : 0 ) : v;
5125
                        });
5126

    
5127
                if ( rgba[ 3 ] === 1 ) {
5128
                        rgba.pop();
5129
                        prefix = "rgb(";
5130
                }
5131

    
5132
                return prefix + rgba.join() + ")";
5133
        },
5134
        toHslaString: function() {
5135
                var prefix = "hsla(",
5136
                        hsla = jQuery.map( this.hsla(), function( v, i ) {
5137
                                if ( v == null ) {
5138
                                        v = i > 2 ? 1 : 0;
5139
                                }
5140

    
5141
                                // catch 1 and 2
5142
                                if ( i && i < 3 ) {
5143
                                        v = Math.round( v * 100 ) + "%";
5144
                                }
5145
                                return v;
5146
                        });
5147

    
5148
                if ( hsla[ 3 ] === 1 ) {
5149
                        hsla.pop();
5150
                        prefix = "hsl(";
5151
                }
5152
                return prefix + hsla.join() + ")";
5153
        },
5154
        toHexString: function( includeAlpha ) {
5155
                var rgba = this._rgba.slice(),
5156
                        alpha = rgba.pop();
5157

    
5158
                if ( includeAlpha ) {
5159
                        rgba.push( ~~( alpha * 255 ) );
5160
                }
5161

    
5162
                return "#" + jQuery.map( rgba, function( v ) {
5163

    
5164
                        // default to 0 when nulls exist
5165
                        v = ( v || 0 ).toString( 16 );
5166
                        return v.length === 1 ? "0" + v : v;
5167
                }).join("");
5168
        },
5169
        toString: function() {
5170
                return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
5171
        }
5172
});
5173
color.fn.parse.prototype = color.fn;
5174

    
5175
// hsla conversions adapted from:
5176
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
5177

    
5178
function hue2rgb( p, q, h ) {
5179
        h = ( h + 1 ) % 1;
5180
        if ( h * 6 < 1 ) {
5181
                return p + (q - p) * h * 6;
5182
        }
5183
        if ( h * 2 < 1) {
5184
                return q;
5185
        }
5186
        if ( h * 3 < 2 ) {
5187
                return p + (q - p) * ((2/3) - h) * 6;
5188
        }
5189
        return p;
5190
}
5191

    
5192
spaces.hsla.to = function ( rgba ) {
5193
        if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
5194
                return [ null, null, null, rgba[ 3 ] ];
5195
        }
5196
        var r = rgba[ 0 ] / 255,
5197
                g = rgba[ 1 ] / 255,
5198
                b = rgba[ 2 ] / 255,
5199
                a = rgba[ 3 ],
5200
                max = Math.max( r, g, b ),
5201
                min = Math.min( r, g, b ),
5202
                diff = max - min,
5203
                add = max + min,
5204
                l = add * 0.5,
5205
                h, s;
5206

    
5207
        if ( min === max ) {
5208
                h = 0;
5209
        } else if ( r === max ) {
5210
                h = ( 60 * ( g - b ) / diff ) + 360;
5211
        } else if ( g === max ) {
5212
                h = ( 60 * ( b - r ) / diff ) + 120;
5213
        } else {
5214
                h = ( 60 * ( r - g ) / diff ) + 240;
5215
        }
5216

    
5217
        // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
5218
        // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
5219
        if ( diff === 0 ) {
5220
                s = 0;
5221
        } else if ( l <= 0.5 ) {
5222
                s = diff / add;
5223
        } else {
5224
                s = diff / ( 2 - add );
5225
        }
5226
        return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
5227
};
5228

    
5229
spaces.hsla.from = function ( hsla ) {
5230
        if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
5231
                return [ null, null, null, hsla[ 3 ] ];
5232
        }
5233
        var h = hsla[ 0 ] / 360,
5234
                s = hsla[ 1 ],
5235
                l = hsla[ 2 ],
5236
                a = hsla[ 3 ],
5237
                q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
5238
                p = 2 * l - q;
5239

    
5240
        return [
5241
                Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
5242
                Math.round( hue2rgb( p, q, h ) * 255 ),
5243
                Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
5244
                a
5245
        ];
5246
};
5247

    
5248

    
5249
each( spaces, function( spaceName, space ) {
5250
        var props = space.props,
5251
                cache = space.cache,
5252
                to = space.to,
5253
                from = space.from;
5254

    
5255
        // makes rgba() and hsla()
5256
        color.fn[ spaceName ] = function( value ) {
5257

    
5258
                // generate a cache for this space if it doesn't exist
5259
                if ( to && !this[ cache ] ) {
5260
                        this[ cache ] = to( this._rgba );
5261
                }
5262
                if ( value === undefined ) {
5263
                        return this[ cache ].slice();
5264
                }
5265

    
5266
                var ret,
5267
                        type = jQuery.type( value ),
5268
                        arr = ( type === "array" || type === "object" ) ? value : arguments,
5269
                        local = this[ cache ].slice();
5270

    
5271
                each( props, function( key, prop ) {
5272
                        var val = arr[ type === "object" ? key : prop.idx ];
5273
                        if ( val == null ) {
5274
                                val = local[ prop.idx ];
5275
                        }
5276
                        local[ prop.idx ] = clamp( val, prop );
5277
                });
5278

    
5279
                if ( from ) {
5280
                        ret = color( from( local ) );
5281
                        ret[ cache ] = local;
5282
                        return ret;
5283
                } else {
5284
                        return color( local );
5285
                }
5286
        };
5287

    
5288
        // makes red() green() blue() alpha() hue() saturation() lightness()
5289
        each( props, function( key, prop ) {
5290
                // alpha is included in more than one space
5291
                if ( color.fn[ key ] ) {
5292
                        return;
5293
                }
5294
                color.fn[ key ] = function( value ) {
5295
                        var vtype = jQuery.type( value ),
5296
                                fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
5297
                                local = this[ fn ](),
5298
                                cur = local[ prop.idx ],
5299
                                match;
5300

    
5301
                        if ( vtype === "undefined" ) {
5302
                                return cur;
5303
                        }
5304

    
5305
                        if ( vtype === "function" ) {
5306
                                value = value.call( this, cur );
5307
                                vtype = jQuery.type( value );
5308
                        }
5309
                        if ( value == null && prop.empty ) {
5310
                                return this;
5311
                        }
5312
                        if ( vtype === "string" ) {
5313
                                match = rplusequals.exec( value );
5314
                                if ( match ) {
5315
                                        value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
5316
                                }
5317
                        }
5318
                        local[ prop.idx ] = value;
5319
                        return this[ fn ]( local );
5320
                };
5321
        });
5322
});
5323

    
5324
// add cssHook and .fx.step function for each named hook.
5325
// accept a space separated string of properties
5326
color.hook = function( hook ) {
5327
        var hooks = hook.split( " " );
5328
        each( hooks, function( i, hook ) {
5329
                jQuery.cssHooks[ hook ] = {
5330
                        set: function( elem, value ) {
5331
                                var parsed, curElem,
5332
                                        backgroundColor = "";
5333

    
5334
                                if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
5335
                                        value = color( parsed || value );
5336
                                        if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
5337
                                                curElem = hook === "backgroundColor" ? elem.parentNode : elem;
5338
                                                while (
5339
                                                        (backgroundColor === "" || backgroundColor === "transparent") &&
5340
                                                        curElem && curElem.style
5341
                                                ) {
5342
                                                        try {
5343
                                                                backgroundColor = jQuery.css( curElem, "backgroundColor" );
5344
                                                                curElem = curElem.parentNode;
5345
                                                        } catch ( e ) {
5346
                                                        }
5347
                                                }
5348

    
5349
                                                value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
5350
                                                        backgroundColor :
5351
                                                        "_default" );
5352
                                        }
5353

    
5354
                                        value = value.toRgbaString();
5355
                                }
5356
                                try {
5357
                                        elem.style[ hook ] = value;
5358
                                } catch( e ) {
5359
                                        // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
5360
                                }
5361
                        }
5362
                };
5363
                jQuery.fx.step[ hook ] = function( fx ) {
5364
                        if ( !fx.colorInit ) {
5365
                                fx.start = color( fx.elem, hook );
5366
                                fx.end = color( fx.end );
5367
                                fx.colorInit = true;
5368
                        }
5369
                        jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
5370
                };
5371
        });
5372

    
5373
};
5374

    
5375
color.hook( stepHooks );
5376

    
5377
jQuery.cssHooks.borderColor = {
5378
        expand: function( value ) {
5379
                var expanded = {};
5380

    
5381
                each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
5382
                        expanded[ "border" + part + "Color" ] = value;
5383
                });
5384
                return expanded;
5385
        }
5386
};
5387

    
5388
// Basic color names only.
5389
// Usage of any of the other color names requires adding yourself or including
5390
// jquery.color.svg-names.js.
5391
colors = jQuery.Color.names = {
5392
        // 4.1. Basic color keywords
5393
        aqua: "#00ffff",
5394
        black: "#000000",
5395
        blue: "#0000ff",
5396
        fuchsia: "#ff00ff",
5397
        gray: "#808080",
5398
        green: "#008000",
5399
        lime: "#00ff00",
5400
        maroon: "#800000",
5401
        navy: "#000080",
5402
        olive: "#808000",
5403
        purple: "#800080",
5404
        red: "#ff0000",
5405
        silver: "#c0c0c0",
5406
        teal: "#008080",
5407
        white: "#ffffff",
5408
        yellow: "#ffff00",
5409

    
5410
        // 4.2.3. "transparent" color keyword
5411
        transparent: [ null, null, null, 0 ],
5412

    
5413
        _default: "#ffffff"
5414
};
5415

    
5416
})( jQuery );
5417

    
5418

    
5419
/******************************************************************************/
5420
/****************************** CLASS ANIMATIONS ******************************/
5421
/******************************************************************************/
5422
(function() {
5423

    
5424
var classAnimationActions = [ "add", "remove", "toggle" ],
5425
        shorthandStyles = {
5426
                border: 1,
5427
                borderBottom: 1,
5428
                borderColor: 1,
5429
                borderLeft: 1,
5430
                borderRight: 1,
5431
                borderTop: 1,
5432
                borderWidth: 1,
5433
                margin: 1,
5434
                padding: 1
5435
        };
5436

    
5437
$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
5438
        $.fx.step[ prop ] = function( fx ) {
5439
                if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
5440
                        jQuery.style( fx.elem, prop, fx.end );
5441
                        fx.setAttr = true;
5442
                }
5443
        };
5444
});
5445

    
5446
function getElementStyles( elem ) {
5447
        var key, len,
5448
                style = elem.ownerDocument.defaultView ?
5449
                        elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
5450
                        elem.currentStyle,
5451
                styles = {};
5452

    
5453
        if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
5454
                len = style.length;
5455
                while ( len-- ) {
5456
                        key = style[ len ];
5457
                        if ( typeof style[ key ] === "string" ) {
5458
                                styles[ $.camelCase( key ) ] = style[ key ];
5459
                        }
5460
                }
5461
        // support: Opera, IE <9
5462
        } else {
5463
                for ( key in style ) {
5464
                        if ( typeof style[ key ] === "string" ) {
5465
                                styles[ key ] = style[ key ];
5466
                        }
5467
                }
5468
        }
5469

    
5470
        return styles;
5471
}
5472

    
5473

    
5474
function styleDifference( oldStyle, newStyle ) {
5475
        var diff = {},
5476
                name, value;
5477

    
5478
        for ( name in newStyle ) {
5479
                value = newStyle[ name ];
5480
                if ( oldStyle[ name ] !== value ) {
5481
                        if ( !shorthandStyles[ name ] ) {
5482
                                if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
5483
                                        diff[ name ] = value;
5484
                                }
5485
                        }
5486
                }
5487
        }
5488

    
5489
        return diff;
5490
}
5491

    
5492
// support: jQuery <1.8
5493
if ( !$.fn.addBack ) {
5494
        $.fn.addBack = function( selector ) {
5495
                return this.add( selector == null ?
5496
                        this.prevObject : this.prevObject.filter( selector )
5497
                );
5498
        };
5499
}
5500

    
5501
$.effects.animateClass = function( value, duration, easing, callback ) {
5502
        var o = $.speed( duration, easing, callback );
5503

    
5504
        return this.queue( function() {
5505
                var animated = $( this ),
5506
                        baseClass = animated.attr( "class" ) || "",
5507
                        applyClassChange,
5508
                        allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
5509

    
5510
                // map the animated objects to store the original styles.
5511
                allAnimations = allAnimations.map(function() {
5512
                        var el = $( this );
5513
                        return {
5514
                                el: el,
5515
                                start: getElementStyles( this )
5516
                        };
5517
                });
5518

    
5519
                // apply class change
5520
                applyClassChange = function() {
5521
                        $.each( classAnimationActions, function(i, action) {
5522
                                if ( value[ action ] ) {
5523
                                        animated[ action + "Class" ]( value[ action ] );
5524
                                }
5525
                        });
5526
                };
5527
                applyClassChange();
5528

    
5529
                // map all animated objects again - calculate new styles and diff
5530
                allAnimations = allAnimations.map(function() {
5531
                        this.end = getElementStyles( this.el[ 0 ] );
5532
                        this.diff = styleDifference( this.start, this.end );
5533
                        return this;
5534
                });
5535

    
5536
                // apply original class
5537
                animated.attr( "class", baseClass );
5538

    
5539
                // map all animated objects again - this time collecting a promise
5540
                allAnimations = allAnimations.map(function() {
5541
                        var styleInfo = this,
5542
                                dfd = $.Deferred(),
5543
                                opts = $.extend({}, o, {
5544
                                        queue: false,
5545
                                        complete: function() {
5546
                                                dfd.resolve( styleInfo );
5547
                                        }
5548
                                });
5549

    
5550
                        this.el.animate( this.diff, opts );
5551
                        return dfd.promise();
5552
                });
5553

    
5554
                // once all animations have completed:
5555
                $.when.apply( $, allAnimations.get() ).done(function() {
5556

    
5557
                        // set the final class
5558
                        applyClassChange();
5559

    
5560
                        // for each animated element,
5561
                        // clear all css properties that were animated
5562
                        $.each( arguments, function() {
5563
                                var el = this.el;
5564
                                $.each( this.diff, function(key) {
5565
                                        el.css( key, "" );
5566
                                });
5567
                        });
5568

    
5569
                        // this is guarnteed to be there if you use jQuery.speed()
5570
                        // it also handles dequeuing the next anim...
5571
                        o.complete.call( animated[ 0 ] );
5572
                });
5573
        });
5574
};
5575

    
5576
$.fn.extend({
5577
        addClass: (function( orig ) {
5578
                return function( classNames, speed, easing, callback ) {
5579
                        return speed ?
5580
                                $.effects.animateClass.call( this,
5581
                                        { add: classNames }, speed, easing, callback ) :
5582
                                orig.apply( this, arguments );
5583
                };
5584
        })( $.fn.addClass ),
5585

    
5586
        removeClass: (function( orig ) {
5587
                return function( classNames, speed, easing, callback ) {
5588
                        return arguments.length > 1 ?
5589
                                $.effects.animateClass.call( this,
5590
                                        { remove: classNames }, speed, easing, callback ) :
5591
                                orig.apply( this, arguments );
5592
                };
5593
        })( $.fn.removeClass ),
5594

    
5595
        toggleClass: (function( orig ) {
5596
                return function( classNames, force, speed, easing, callback ) {
5597
                        if ( typeof force === "boolean" || force === undefined ) {
5598
                                if ( !speed ) {
5599
                                        // without speed parameter
5600
                                        return orig.apply( this, arguments );
5601
                                } else {
5602
                                        return $.effects.animateClass.call( this,
5603
                                                (force ? { add: classNames } : { remove: classNames }),
5604
                                                speed, easing, callback );
5605
                                }
5606
                        } else {
5607
                                // without force parameter
5608
                                return $.effects.animateClass.call( this,
5609
                                        { toggle: classNames }, force, speed, easing );
5610
                        }
5611
                };
5612
        })( $.fn.toggleClass ),
5613

    
5614
        switchClass: function( remove, add, speed, easing, callback) {
5615
                return $.effects.animateClass.call( this, {
5616
                        add: add,
5617
                        remove: remove
5618
                }, speed, easing, callback );
5619
        }
5620
});
5621

    
5622
})();
5623

    
5624
/******************************************************************************/
5625
/*********************************** EFFECTS **********************************/
5626
/******************************************************************************/
5627

    
5628
(function() {
5629

    
5630
$.extend( $.effects, {
5631
        version: "1.10.2",
5632

    
5633
        // Saves a set of properties in a data storage
5634
        save: function( element, set ) {
5635
                for( var i=0; i < set.length; i++ ) {
5636
                        if ( set[ i ] !== null ) {
5637
                                element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
5638
                        }
5639
                }
5640
        },
5641

    
5642
        // Restores a set of previously saved properties from a data storage
5643
        restore: function( element, set ) {
5644
                var val, i;
5645
                for( i=0; i < set.length; i++ ) {
5646
                        if ( set[ i ] !== null ) {
5647
                                val = element.data( dataSpace + set[ i ] );
5648
                                // support: jQuery 1.6.2
5649
                                // http://bugs.jquery.com/ticket/9917
5650
                                // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
5651
                                // We can't differentiate between "" and 0 here, so we just assume
5652
                                // empty string since it's likely to be a more common value...
5653
                                if ( val === undefined ) {
5654
                                        val = "";
5655
                                }
5656
                                element.css( set[ i ], val );
5657
                        }
5658
                }
5659
        },
5660

    
5661
        setMode: function( el, mode ) {
5662
                if (mode === "toggle") {
5663
                        mode = el.is( ":hidden" ) ? "show" : "hide";
5664
                }
5665
                return mode;
5666
        },
5667

    
5668
        // Translates a [top,left] array into a baseline value
5669
        // this should be a little more flexible in the future to handle a string & hash
5670
        getBaseline: function( origin, original ) {
5671
                var y, x;
5672
                switch ( origin[ 0 ] ) {
5673
                        case "top": y = 0; break;
5674
                        case "middle": y = 0.5; break;
5675
                        case "bottom": y = 1; break;
5676
                        default: y = origin[ 0 ] / original.height;
5677
                }
5678
                switch ( origin[ 1 ] ) {
5679
                        case "left": x = 0; break;
5680
                        case "center": x = 0.5; break;
5681
                        case "right": x = 1; break;
5682
                        default: x = origin[ 1 ] / original.width;
5683
                }
5684
                return {
5685
                        x: x,
5686
                        y: y
5687
                };
5688
        },
5689

    
5690
        // Wraps the element around a wrapper that copies position properties
5691
        createWrapper: function( element ) {
5692

    
5693
                // if the element is already wrapped, return it
5694
                if ( element.parent().is( ".ui-effects-wrapper" )) {
5695
                        return element.parent();
5696
                }
5697

    
5698
                // wrap the element
5699
                var props = {
5700
                                width: element.outerWidth(true),
5701
                                height: element.outerHeight(true),
5702
                                "float": element.css( "float" )
5703
                        },
5704
                        wrapper = $( "<div></div>" )
5705
                                .addClass( "ui-effects-wrapper" )
5706
                                .css({
5707
                                        fontSize: "100%",
5708
                                        background: "transparent",
5709
                                        border: "none",
5710
                                        margin: 0,
5711
                                        padding: 0
5712
                                }),
5713
                        // Store the size in case width/height are defined in % - Fixes #5245
5714
                        size = {
5715
                                width: element.width(),
5716
                                height: element.height()
5717
                        },
5718
                        active = document.activeElement;
5719

    
5720
                // support: Firefox
5721
                // Firefox incorrectly exposes anonymous content
5722
                // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
5723
                try {
5724
                        active.id;
5725
                } catch( e ) {
5726
                        active = document.body;
5727
                }
5728

    
5729
                element.wrap( wrapper );
5730

    
5731
                // Fixes #7595 - Elements lose focus when wrapped.
5732
                if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5733
                        $( active ).focus();
5734
                }
5735

    
5736
                wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
5737

    
5738
                // transfer positioning properties to the wrapper
5739
                if ( element.css( "position" ) === "static" ) {
5740
                        wrapper.css({ position: "relative" });
5741
                        element.css({ position: "relative" });
5742
                } else {
5743
                        $.extend( props, {
5744
                                position: element.css( "position" ),
5745
                                zIndex: element.css( "z-index" )
5746
                        });
5747
                        $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
5748
                                props[ pos ] = element.css( pos );
5749
                                if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
5750
                                        props[ pos ] = "auto";
5751
                                }
5752
                        });
5753
                        element.css({
5754
                                position: "relative",
5755
                                top: 0,
5756
                                left: 0,
5757
                                right: "auto",
5758
                                bottom: "auto"
5759
                        });
5760
                }
5761
                element.css(size);
5762

    
5763
                return wrapper.css( props ).show();
5764
        },
5765

    
5766
        removeWrapper: function( element ) {
5767
                var active = document.activeElement;
5768

    
5769
                if ( element.parent().is( ".ui-effects-wrapper" ) ) {
5770
                        element.parent().replaceWith( element );
5771

    
5772
                        // Fixes #7595 - Elements lose focus when wrapped.
5773
                        if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5774
                                $( active ).focus();
5775
                        }
5776
                }
5777

    
5778

    
5779
                return element;
5780
        },
5781

    
5782
        setTransition: function( element, list, factor, value ) {
5783
                value = value || {};
5784
                $.each( list, function( i, x ) {
5785
                        var unit = element.cssUnit( x );
5786
                        if ( unit[ 0 ] > 0 ) {
5787
                                value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
5788
                        }
5789
                });
5790
                return value;
5791
        }
5792
});
5793

    
5794
// return an effect options object for the given parameters:
5795
function _normalizeArguments( effect, options, speed, callback ) {
5796

    
5797
        // allow passing all options as the first parameter
5798
        if ( $.isPlainObject( effect ) ) {
5799
                options = effect;
5800
                effect = effect.effect;
5801
        }
5802

    
5803
        // convert to an object
5804
        effect = { effect: effect };
5805

    
5806
        // catch (effect, null, ...)
5807
        if ( options == null ) {
5808
                options = {};
5809
        }
5810

    
5811
        // catch (effect, callback)
5812
        if ( $.isFunction( options ) ) {
5813
                callback = options;
5814
                speed = null;
5815
                options = {};
5816
        }
5817

    
5818
        // catch (effect, speed, ?)
5819
        if ( typeof options === "number" || $.fx.speeds[ options ] ) {
5820
                callback = speed;
5821
                speed = options;
5822
                options = {};
5823
        }
5824

    
5825
        // catch (effect, options, callback)
5826
        if ( $.isFunction( speed ) ) {
5827
                callback = speed;
5828
                speed = null;
5829
        }
5830

    
5831
        // add options to effect
5832
        if ( options ) {
5833
                $.extend( effect, options );
5834
        }
5835

    
5836
        speed = speed || options.duration;
5837
        effect.duration = $.fx.off ? 0 :
5838
                typeof speed === "number" ? speed :
5839
                speed in $.fx.speeds ? $.fx.speeds[ speed ] :
5840
                $.fx.speeds._default;
5841

    
5842
        effect.complete = callback || options.complete;
5843

    
5844
        return effect;
5845
}
5846

    
5847
function standardAnimationOption( option ) {
5848
        // Valid standard speeds (nothing, number, named speed)
5849
        if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
5850
                return true;
5851
        }
5852

    
5853
        // Invalid strings - treat as "normal" speed
5854
        if ( typeof option === "string" && !$.effects.effect[ option ] ) {
5855
                return true;
5856
        }
5857

    
5858
        // Complete callback
5859
        if ( $.isFunction( option ) ) {
5860
                return true;
5861
        }
5862

    
5863
        // Options hash (but not naming an effect)
5864
        if ( typeof option === "object" && !option.effect ) {
5865
                return true;
5866
        }
5867

    
5868
        // Didn't match any standard API
5869
        return false;
5870
}
5871

    
5872
$.fn.extend({
5873
        effect: function( /* effect, options, speed, callback */ ) {
5874
                var args = _normalizeArguments.apply( this, arguments ),
5875
                        mode = args.mode,
5876
                        queue = args.queue,
5877
                        effectMethod = $.effects.effect[ args.effect ];
5878

    
5879
                if ( $.fx.off || !effectMethod ) {
5880
                        // delegate to the original method (e.g., .show()) if possible
5881
                        if ( mode ) {
5882
                                return this[ mode ]( args.duration, args.complete );
5883
                        } else {
5884
                                return this.each( function() {
5885
                                        if ( args.complete ) {
5886
                                                args.complete.call( this );
5887
                                        }
5888
                                });
5889
                        }
5890
                }
5891

    
5892
                function run( next ) {
5893
                        var elem = $( this ),
5894
                                complete = args.complete,
5895
                                mode = args.mode;
5896

    
5897
                        function done() {
5898
                                if ( $.isFunction( complete ) ) {
5899
                                        complete.call( elem[0] );
5900
                                }
5901
                                if ( $.isFunction( next ) ) {
5902
                                        next();
5903
                                }
5904
                        }
5905

    
5906
                        // If the element already has the correct final state, delegate to
5907
                        // the core methods so the internal tracking of "olddisplay" works.
5908
                        if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
5909
                                elem[ mode ]();
5910
                                done();
5911
                        } else {
5912
                                effectMethod.call( elem[0], args, done );
5913
                        }
5914
                }
5915

    
5916
                return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
5917
        },
5918

    
5919
        show: (function( orig ) {
5920
                return function( option ) {
5921
                        if ( standardAnimationOption( option ) ) {
5922
                                return orig.apply( this, arguments );
5923
                        } else {
5924
                                var args = _normalizeArguments.apply( this, arguments );
5925
                                args.mode = "show";
5926
                                return this.effect.call( this, args );
5927
                        }
5928
                };
5929
        })( $.fn.show ),
5930

    
5931
        hide: (function( orig ) {
5932
                return function( option ) {
5933
                        if ( standardAnimationOption( option ) ) {
5934
                                return orig.apply( this, arguments );
5935
                        } else {
5936
                                var args = _normalizeArguments.apply( this, arguments );
5937
                                args.mode = "hide";
5938
                                return this.effect.call( this, args );
5939
                        }
5940
                };
5941
        })( $.fn.hide ),
5942

    
5943
        toggle: (function( orig ) {
5944
                return function( option ) {
5945
                        if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
5946
                                return orig.apply( this, arguments );
5947
                        } else {
5948
                                var args = _normalizeArguments.apply( this, arguments );
5949
                                args.mode = "toggle";
5950
                                return this.effect.call( this, args );
5951
                        }
5952
                };
5953
        })( $.fn.toggle ),
5954

    
5955
        // helper functions
5956
        cssUnit: function(key) {
5957
                var style = this.css( key ),
5958
                        val = [];
5959

    
5960
                $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
5961
                        if ( style.indexOf( unit ) > 0 ) {
5962
                                val = [ parseFloat( style ), unit ];
5963
                        }
5964
                });
5965
                return val;
5966
        }
5967
});
5968

    
5969
})();
5970

    
5971
/******************************************************************************/
5972
/*********************************** EASING ***********************************/
5973
/******************************************************************************/
5974

    
5975
(function() {
5976

    
5977
// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
5978

    
5979
var baseEasings = {};
5980

    
5981
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
5982
        baseEasings[ name ] = function( p ) {
5983
                return Math.pow( p, i + 2 );
5984
        };
5985
});
5986

    
5987
$.extend( baseEasings, {
5988
        Sine: function ( p ) {
5989
                return 1 - Math.cos( p * Math.PI / 2 );
5990
        },
5991
        Circ: function ( p ) {
5992
                return 1 - Math.sqrt( 1 - p * p );
5993
        },
5994
        Elastic: function( p ) {
5995
                return p === 0 || p === 1 ? p :
5996
                        -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
5997
        },
5998
        Back: function( p ) {
5999
                return p * p * ( 3 * p - 2 );
6000
        },
6001
        Bounce: function ( p ) {
6002
                var pow2,
6003
                        bounce = 4;
6004

    
6005
                while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
6006
                return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
6007
        }
6008
});
6009

    
6010
$.each( baseEasings, function( name, easeIn ) {
6011
        $.easing[ "easeIn" + name ] = easeIn;
6012
        $.easing[ "easeOut" + name ] = function( p ) {
6013
                return 1 - easeIn( 1 - p );
6014
        };
6015
        $.easing[ "easeInOut" + name ] = function( p ) {
6016
                return p < 0.5 ?
6017
                        easeIn( p * 2 ) / 2 :
6018
                        1 - easeIn( p * -2 + 2 ) / 2;
6019
        };
6020
});
6021

    
6022
})();
6023

    
6024
})(jQuery);
6025

    
6026
(function( $, undefined ) {
6027

    
6028
var uid = 0,
6029
        hideProps = {},
6030
        showProps = {};
6031

    
6032
hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
6033
        hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
6034
showProps.height = showProps.paddingTop = showProps.paddingBottom =
6035
        showProps.borderTopWidth = showProps.borderBottomWidth = "show";
6036

    
6037
$.widget( "ui.accordion", {
6038
        version: "1.10.2",
6039
        options: {
6040
                active: 0,
6041
                animate: {},
6042
                collapsible: false,
6043
                event: "click",
6044
                header: "> li > :first-child,> :not(li):even",
6045
                heightStyle: "auto",
6046
                icons: {
6047
                        activeHeader: "ui-icon-triangle-1-s",
6048
                        header: "ui-icon-triangle-1-e"
6049
                },
6050

    
6051
                // callbacks
6052
                activate: null,
6053
                beforeActivate: null
6054
        },
6055

    
6056
        _create: function() {
6057
                var options = this.options;
6058
                this.prevShow = this.prevHide = $();
6059
                this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
6060
                        // ARIA
6061
                        .attr( "role", "tablist" );
6062

    
6063
                // don't allow collapsible: false and active: false / null
6064
                if ( !options.collapsible && (options.active === false || options.active == null) ) {
6065
                        options.active = 0;
6066
                }
6067

    
6068
                this._processPanels();
6069
                // handle negative values
6070
                if ( options.active < 0 ) {
6071
                        options.active += this.headers.length;
6072
                }
6073
                this._refresh();
6074
        },
6075

    
6076
        _getCreateEventData: function() {
6077
                return {
6078
                        header: this.active,
6079
                        panel: !this.active.length ? $() : this.active.next(),
6080
                        content: !this.active.length ? $() : this.active.next()
6081
                };
6082
        },
6083

    
6084
        _createIcons: function() {
6085
                var icons = this.options.icons;
6086
                if ( icons ) {
6087
                        $( "<span>" )
6088
                                .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
6089
                                .prependTo( this.headers );
6090
                        this.active.children( ".ui-accordion-header-icon" )
6091
                                .removeClass( icons.header )
6092
                                .addClass( icons.activeHeader );
6093
                        this.headers.addClass( "ui-accordion-icons" );
6094
                }
6095
        },
6096

    
6097
        _destroyIcons: function() {
6098
                this.headers
6099
                        .removeClass( "ui-accordion-icons" )
6100
                        .children( ".ui-accordion-header-icon" )
6101
                                .remove();
6102
        },
6103

    
6104
        _destroy: function() {
6105
                var contents;
6106

    
6107
                // clean up main element
6108
                this.element
6109
                        .removeClass( "ui-accordion ui-widget ui-helper-reset" )
6110
                        .removeAttr( "role" );
6111

    
6112
                // clean up headers
6113
                this.headers
6114
                        .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
6115
                        .removeAttr( "role" )
6116
                        .removeAttr( "aria-selected" )
6117
                        .removeAttr( "aria-controls" )
6118
                        .removeAttr( "tabIndex" )
6119
                        .each(function() {
6120
                                if ( /^ui-accordion/.test( this.id ) ) {
6121
                                        this.removeAttribute( "id" );
6122
                                }
6123
                        });
6124
                this._destroyIcons();
6125

    
6126
                // clean up content panels
6127
                contents = this.headers.next()
6128
                        .css( "display", "" )
6129
                        .removeAttr( "role" )
6130
                        .removeAttr( "aria-expanded" )
6131
                        .removeAttr( "aria-hidden" )
6132
                        .removeAttr( "aria-labelledby" )
6133
                        .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
6134
                        .each(function() {
6135
                                if ( /^ui-accordion/.test( this.id ) ) {
6136
                                        this.removeAttribute( "id" );
6137
                                }
6138
                        });
6139
                if ( this.options.heightStyle !== "content" ) {
6140
                        contents.css( "height", "" );
6141
                }
6142
        },
6143

    
6144
        _setOption: function( key, value ) {
6145
                if ( key === "active" ) {
6146
                        // _activate() will handle invalid values and update this.options
6147
                        this._activate( value );
6148
                        return;
6149
                }
6150

    
6151
                if ( key === "event" ) {
6152
                        if ( this.options.event ) {
6153
                                this._off( this.headers, this.options.event );
6154
                        }
6155
                        this._setupEvents( value );
6156
                }
6157

    
6158
                this._super( key, value );
6159

    
6160
                // setting collapsible: false while collapsed; open first panel
6161
                if ( key === "collapsible" && !value && this.options.active === false ) {
6162
                        this._activate( 0 );
6163
                }
6164

    
6165
                if ( key === "icons" ) {
6166
                        this._destroyIcons();
6167
                        if ( value ) {
6168
                                this._createIcons();
6169
                        }
6170
                }
6171

    
6172
                // #5332 - opacity doesn't cascade to positioned elements in IE
6173
                // so we need to add the disabled class to the headers and panels
6174
                if ( key === "disabled" ) {
6175
                        this.headers.add( this.headers.next() )
6176
                                .toggleClass( "ui-state-disabled", !!value );
6177
                }
6178
        },
6179

    
6180
        _keydown: function( event ) {
6181
                /*jshint maxcomplexity:15*/
6182
                if ( event.altKey || event.ctrlKey ) {
6183
                        return;
6184
                }
6185

    
6186
                var keyCode = $.ui.keyCode,
6187
                        length = this.headers.length,
6188
                        currentIndex = this.headers.index( event.target ),
6189
                        toFocus = false;
6190

    
6191
                switch ( event.keyCode ) {
6192
                        case keyCode.RIGHT:
6193
                        case keyCode.DOWN:
6194
                                toFocus = this.headers[ ( currentIndex + 1 ) % length ];
6195
                                break;
6196
                        case keyCode.LEFT:
6197
                        case keyCode.UP:
6198
                                toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
6199
                                break;
6200
                        case keyCode.SPACE:
6201
                        case keyCode.ENTER:
6202
                                this._eventHandler( event );
6203
                                break;
6204
                        case keyCode.HOME:
6205
                                toFocus = this.headers[ 0 ];
6206
                                break;
6207
                        case keyCode.END:
6208
                                toFocus = this.headers[ length - 1 ];
6209
                                break;
6210
                }
6211

    
6212
                if ( toFocus ) {
6213
                        $( event.target ).attr( "tabIndex", -1 );
6214
                        $( toFocus ).attr( "tabIndex", 0 );
6215
                        toFocus.focus();
6216
                        event.preventDefault();
6217
                }
6218
        },
6219

    
6220
        _panelKeyDown : function( event ) {
6221
                if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
6222
                        $( event.currentTarget ).prev().focus();
6223
                }
6224
        },
6225

    
6226
        refresh: function() {
6227
                var options = this.options;
6228
                this._processPanels();
6229

    
6230
                // was collapsed or no panel
6231
                if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
6232
                        options.active = false;
6233
                        this.active = $();
6234
                // active false only when collapsible is true
6235
                } if ( options.active === false ) {
6236
                        this._activate( 0 );
6237
                // was active, but active panel is gone
6238
                } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6239
                        // all remaining panel are disabled
6240
                        if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
6241
                                options.active = false;
6242
                                this.active = $();
6243
                        // activate previous panel
6244
                        } else {
6245
                                this._activate( Math.max( 0, options.active - 1 ) );
6246
                        }
6247
                // was active, active panel still exists
6248
                } else {
6249
                        // make sure active index is correct
6250
                        options.active = this.headers.index( this.active );
6251
                }
6252

    
6253
                this._destroyIcons();
6254

    
6255
                this._refresh();
6256
        },
6257

    
6258
        _processPanels: function() {
6259
                this.headers = this.element.find( this.options.header )
6260
                        .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
6261

    
6262
                this.headers.next()
6263
                        .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
6264
                        .filter(":not(.ui-accordion-content-active)")
6265
                        .hide();
6266
        },
6267

    
6268
        _refresh: function() {
6269
                var maxHeight,
6270
                        options = this.options,
6271
                        heightStyle = options.heightStyle,
6272
                        parent = this.element.parent(),
6273
                        accordionId = this.accordionId = "ui-accordion-" +
6274
                                (this.element.attr( "id" ) || ++uid);
6275

    
6276
                this.active = this._findActive( options.active )
6277
                        .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
6278
                        .removeClass( "ui-corner-all" );
6279
                this.active.next()
6280
                        .addClass( "ui-accordion-content-active" )
6281
                        .show();
6282

    
6283
                this.headers
6284
                        .attr( "role", "tab" )
6285
                        .each(function( i ) {
6286
                                var header = $( this ),
6287
                                        headerId = header.attr( "id" ),
6288
                                        panel = header.next(),
6289
                                        panelId = panel.attr( "id" );
6290
                                if ( !headerId ) {
6291
                                        headerId = accordionId + "-header-" + i;
6292
                                        header.attr( "id", headerId );
6293
                                }
6294
                                if ( !panelId ) {
6295
                                        panelId = accordionId + "-panel-" + i;
6296
                                        panel.attr( "id", panelId );
6297
                                }
6298
                                header.attr( "aria-controls", panelId );
6299
                                panel.attr( "aria-labelledby", headerId );
6300
                        })
6301
                        .next()
6302
                                .attr( "role", "tabpanel" );
6303

    
6304
                this.headers
6305
                        .not( this.active )
6306
                        .attr({
6307
                                "aria-selected": "false",
6308
                                tabIndex: -1
6309
                        })
6310
                        .next()
6311
                                .attr({
6312
                                        "aria-expanded": "false",
6313
                                        "aria-hidden": "true"
6314
                                })
6315
                                .hide();
6316

    
6317
                // make sure at least one header is in the tab order
6318
                if ( !this.active.length ) {
6319
                        this.headers.eq( 0 ).attr( "tabIndex", 0 );
6320
                } else {
6321
                        this.active.attr({
6322
                                "aria-selected": "true",
6323
                                tabIndex: 0
6324
                        })
6325
                        .next()
6326
                                .attr({
6327
                                        "aria-expanded": "true",
6328
                                        "aria-hidden": "false"
6329
                                });
6330
                }
6331

    
6332
                this._createIcons();
6333

    
6334
                this._setupEvents( options.event );
6335

    
6336
                if ( heightStyle === "fill" ) {
6337
                        maxHeight = parent.height();
6338
                        this.element.siblings( ":visible" ).each(function() {
6339
                                var elem = $( this ),
6340
                                        position = elem.css( "position" );
6341

    
6342
                                if ( position === "absolute" || position === "fixed" ) {
6343
                                        return;
6344
                                }
6345
                                maxHeight -= elem.outerHeight( true );
6346
                        });
6347

    
6348
                        this.headers.each(function() {
6349
                                maxHeight -= $( this ).outerHeight( true );
6350
                        });
6351

    
6352
                        this.headers.next()
6353
                                .each(function() {
6354
                                        $( this ).height( Math.max( 0, maxHeight -
6355
                                                $( this ).innerHeight() + $( this ).height() ) );
6356
                                })
6357
                                .css( "overflow", "auto" );
6358
                } else if ( heightStyle === "auto" ) {
6359
                        maxHeight = 0;
6360
                        this.headers.next()
6361
                                .each(function() {
6362
                                        maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
6363
                                })
6364
                                .height( maxHeight );
6365
                }
6366
        },
6367

    
6368
        _activate: function( index ) {
6369
                var active = this._findActive( index )[ 0 ];
6370

    
6371
                // trying to activate the already active panel
6372
                if ( active === this.active[ 0 ] ) {
6373
                        return;
6374
                }
6375

    
6376
                // trying to collapse, simulate a click on the currently active header
6377
                active = active || this.active[ 0 ];
6378

    
6379
                this._eventHandler({
6380
                        target: active,
6381
                        currentTarget: active,
6382
                        preventDefault: $.noop
6383
                });
6384
        },
6385

    
6386
        _findActive: function( selector ) {
6387
                return typeof selector === "number" ? this.headers.eq( selector ) : $();
6388
        },
6389

    
6390
        _setupEvents: function( event ) {
6391
                var events = {
6392
                        keydown: "_keydown"
6393
                };
6394
                if ( event ) {
6395
                        $.each( event.split(" "), function( index, eventName ) {
6396
                                events[ eventName ] = "_eventHandler";
6397
                        });
6398
                }
6399

    
6400
                this._off( this.headers.add( this.headers.next() ) );
6401
                this._on( this.headers, events );
6402
                this._on( this.headers.next(), { keydown: "_panelKeyDown" });
6403
                this._hoverable( this.headers );
6404
                this._focusable( this.headers );
6405
        },
6406

    
6407
        _eventHandler: function( event ) {
6408
                var options = this.options,
6409
                        active = this.active,
6410
                        clicked = $( event.currentTarget ),
6411
                        clickedIsActive = clicked[ 0 ] === active[ 0 ],
6412
                        collapsing = clickedIsActive && options.collapsible,
6413
                        toShow = collapsing ? $() : clicked.next(),
6414
                        toHide = active.next(),
6415
                        eventData = {
6416
                                oldHeader: active,
6417
                                oldPanel: toHide,
6418
                                newHeader: collapsing ? $() : clicked,
6419
                                newPanel: toShow
6420
                        };
6421

    
6422
                event.preventDefault();
6423

    
6424
                if (
6425
                                // click on active header, but not collapsible
6426
                                ( clickedIsActive && !options.collapsible ) ||
6427
                                // allow canceling activation
6428
                                ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6429
                        return;
6430
                }
6431

    
6432
                options.active = collapsing ? false : this.headers.index( clicked );
6433

    
6434
                // when the call to ._toggle() comes after the class changes
6435
                // it causes a very odd bug in IE 8 (see #6720)
6436
                this.active = clickedIsActive ? $() : clicked;
6437
                this._toggle( eventData );
6438

    
6439
                // switch classes
6440
                // corner classes on the previously active header stay after the animation
6441
                active.removeClass( "ui-accordion-header-active ui-state-active" );
6442
                if ( options.icons ) {
6443
                        active.children( ".ui-accordion-header-icon" )
6444
                                .removeClass( options.icons.activeHeader )
6445
                                .addClass( options.icons.header );
6446
                }
6447

    
6448
                if ( !clickedIsActive ) {
6449
                        clicked
6450
                                .removeClass( "ui-corner-all" )
6451
                                .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
6452
                        if ( options.icons ) {
6453
                                clicked.children( ".ui-accordion-header-icon" )
6454
                                        .removeClass( options.icons.header )
6455
                                        .addClass( options.icons.activeHeader );
6456
                        }
6457

    
6458
                        clicked
6459
                                .next()
6460
                                .addClass( "ui-accordion-content-active" );
6461
                }
6462
        },
6463

    
6464
        _toggle: function( data ) {
6465
                var toShow = data.newPanel,
6466
                        toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
6467

    
6468
                // handle activating a panel during the animation for another activation
6469
                this.prevShow.add( this.prevHide ).stop( true, true );
6470
                this.prevShow = toShow;
6471
                this.prevHide = toHide;
6472

    
6473
                if ( this.options.animate ) {
6474
                        this._animate( toShow, toHide, data );
6475
                } else {
6476
                        toHide.hide();
6477
                        toShow.show();
6478
                        this._toggleComplete( data );
6479
                }
6480

    
6481
                toHide.attr({
6482
                        "aria-expanded": "false",
6483
                        "aria-hidden": "true"
6484
                });
6485
                toHide.prev().attr( "aria-selected", "false" );
6486
                // if we're switching panels, remove the old header from the tab order
6487
                // if we're opening from collapsed state, remove the previous header from the tab order
6488
                // if we're collapsing, then keep the collapsing header in the tab order
6489
                if ( toShow.length && toHide.length ) {
6490
                        toHide.prev().attr( "tabIndex", -1 );
6491
                } else if ( toShow.length ) {
6492
                        this.headers.filter(function() {
6493
                                return $( this ).attr( "tabIndex" ) === 0;
6494
                        })
6495
                        .attr( "tabIndex", -1 );
6496
                }
6497

    
6498
                toShow
6499
                        .attr({
6500
                                "aria-expanded": "true",
6501
                                "aria-hidden": "false"
6502
                        })
6503
                        .prev()
6504
                                .attr({
6505
                                        "aria-selected": "true",
6506
                                        tabIndex: 0
6507
                                });
6508
        },
6509

    
6510
        _animate: function( toShow, toHide, data ) {
6511
                var total, easing, duration,
6512
                        that = this,
6513
                        adjust = 0,
6514
                        down = toShow.length &&
6515
                                ( !toHide.length || ( toShow.index() < toHide.index() ) ),
6516
                        animate = this.options.animate || {},
6517
                        options = down && animate.down || animate,
6518
                        complete = function() {
6519
                                that._toggleComplete( data );
6520
                        };
6521

    
6522
                if ( typeof options === "number" ) {
6523
                        duration = options;
6524
                }
6525
                if ( typeof options === "string" ) {
6526
                        easing = options;
6527
                }
6528
                // fall back from options to animation in case of partial down settings
6529
                easing = easing || options.easing || animate.easing;
6530
                duration = duration || options.duration || animate.duration;
6531

    
6532
                if ( !toHide.length ) {
6533
                        return toShow.animate( showProps, duration, easing, complete );
6534
                }
6535
                if ( !toShow.length ) {
6536
                        return toHide.animate( hideProps, duration, easing, complete );
6537
                }
6538

    
6539
                total = toShow.show().outerHeight();
6540
                toHide.animate( hideProps, {
6541
                        duration: duration,
6542
                        easing: easing,
6543
                        step: function( now, fx ) {
6544
                                fx.now = Math.round( now );
6545
                        }
6546
                });
6547
                toShow
6548
                        .hide()
6549
                        .animate( showProps, {
6550
                                duration: duration,
6551
                                easing: easing,
6552
                                complete: complete,
6553
                                step: function( now, fx ) {
6554
                                        fx.now = Math.round( now );
6555
                                        if ( fx.prop !== "height" ) {
6556
                                                adjust += fx.now;
6557
                                        } else if ( that.options.heightStyle !== "content" ) {
6558
                                                fx.now = Math.round( total - toHide.outerHeight() - adjust );
6559
                                                adjust = 0;
6560
                                        }
6561
                                }
6562
                        });
6563
        },
6564

    
6565
        _toggleComplete: function( data ) {
6566
                var toHide = data.oldPanel;
6567

    
6568
                toHide
6569
                        .removeClass( "ui-accordion-content-active" )
6570
                        .prev()
6571
                                .removeClass( "ui-corner-top" )
6572
                                .addClass( "ui-corner-all" );
6573

    
6574
                // Work around for rendering bug in IE (#5421)
6575
                if ( toHide.length ) {
6576
                        toHide.parent()[0].className = toHide.parent()[0].className;
6577
                }
6578

    
6579
                this._trigger( "activate", null, data );
6580
        }
6581
});
6582

    
6583
})( jQuery );
6584

    
6585
(function( $, undefined ) {
6586

    
6587
// used to prevent race conditions with remote data sources
6588
var requestIndex = 0;
6589

    
6590
$.widget( "ui.autocomplete", {
6591
        version: "1.10.2",
6592
        defaultElement: "<input>",
6593
        options: {
6594
                appendTo: null,
6595
                autoFocus: false,
6596
                delay: 300,
6597
                minLength: 1,
6598
                position: {
6599
                        my: "left top",
6600
                        at: "left bottom",
6601
                        collision: "none"
6602
                },
6603
                source: null,
6604

    
6605
                // callbacks
6606
                change: null,
6607
                close: null,
6608
                focus: null,
6609
                open: null,
6610
                response: null,
6611
                search: null,
6612
                select: null
6613
        },
6614

    
6615
        pending: 0,
6616

    
6617
        _create: function() {
6618
                // Some browsers only repeat keydown events, not keypress events,
6619
                // so we use the suppressKeyPress flag to determine if we've already
6620
                // handled the keydown event. #7269
6621
                // Unfortunately the code for & in keypress is the same as the up arrow,
6622
                // so we use the suppressKeyPressRepeat flag to avoid handling keypress
6623
                // events when we know the keydown event was used to modify the
6624
                // search term. #7799
6625
                var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
6626
                        nodeName = this.element[0].nodeName.toLowerCase(),
6627
                        isTextarea = nodeName === "textarea",
6628
                        isInput = nodeName === "input";
6629

    
6630
                this.isMultiLine =
6631
                        // Textareas are always multi-line
6632
                        isTextarea ? true :
6633
                        // Inputs are always single-line, even if inside a contentEditable element
6634
                        // IE also treats inputs as contentEditable
6635
                        isInput ? false :
6636
                        // All other element types are determined by whether or not they're contentEditable
6637
                        this.element.prop( "isContentEditable" );
6638

    
6639
                this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
6640
                this.isNewMenu = true;
6641

    
6642
                this.element
6643
                        .addClass( "ui-autocomplete-input" )
6644
                        .attr( "autocomplete", "off" );
6645

    
6646
                this._on( this.element, {
6647
                        keydown: function( event ) {
6648
                                /*jshint maxcomplexity:15*/
6649
                                if ( this.element.prop( "readOnly" ) ) {
6650
                                        suppressKeyPress = true;
6651
                                        suppressInput = true;
6652
                                        suppressKeyPressRepeat = true;
6653
                                        return;
6654
                                }
6655

    
6656
                                suppressKeyPress = false;
6657
                                suppressInput = false;
6658
                                suppressKeyPressRepeat = false;
6659
                                var keyCode = $.ui.keyCode;
6660
                                switch( event.keyCode ) {
6661
                                case keyCode.PAGE_UP:
6662
                                        suppressKeyPress = true;
6663
                                        this._move( "previousPage", event );
6664
                                        break;
6665
                                case keyCode.PAGE_DOWN:
6666
                                        suppressKeyPress = true;
6667
                                        this._move( "nextPage", event );
6668
                                        break;
6669
                                case keyCode.UP:
6670
                                        suppressKeyPress = true;
6671
                                        this._keyEvent( "previous", event );
6672
                                        break;
6673
                                case keyCode.DOWN:
6674
                                        suppressKeyPress = true;
6675
                                        this._keyEvent( "next", event );
6676
                                        break;
6677
                                case keyCode.ENTER:
6678
                                case keyCode.NUMPAD_ENTER:
6679
                                        // when menu is open and has focus
6680
                                        if ( this.menu.active ) {
6681
                                                // #6055 - Opera still allows the keypress to occur
6682
                                                // which causes forms to submit
6683
                                                suppressKeyPress = true;
6684
                                                event.preventDefault();
6685
                                                this.menu.select( event );
6686
                                        }
6687
                                        break;
6688
                                case keyCode.TAB:
6689
                                        if ( this.menu.active ) {
6690
                                                this.menu.select( event );
6691
                                        }
6692
                                        break;
6693
                                case keyCode.ESCAPE:
6694
                                        if ( this.menu.element.is( ":visible" ) ) {
6695
                                                this._value( this.term );
6696
                                                this.close( event );
6697
                                                // Different browsers have different default behavior for escape
6698
                                                // Single press can mean undo or clear
6699
                                                // Double press in IE means clear the whole form
6700
                                                event.preventDefault();
6701
                                        }
6702
                                        break;
6703
                                default:
6704
                                        suppressKeyPressRepeat = true;
6705
                                        // search timeout should be triggered before the input value is changed
6706
                                        this._searchTimeout( event );
6707
                                        break;
6708
                                }
6709
                        },
6710
                        keypress: function( event ) {
6711
                                if ( suppressKeyPress ) {
6712
                                        suppressKeyPress = false;
6713
                                        event.preventDefault();
6714
                                        return;
6715
                                }
6716
                                if ( suppressKeyPressRepeat ) {
6717
                                        return;
6718
                                }
6719

    
6720
                                // replicate some key handlers to allow them to repeat in Firefox and Opera
6721
                                var keyCode = $.ui.keyCode;
6722
                                switch( event.keyCode ) {
6723
                                case keyCode.PAGE_UP:
6724
                                        this._move( "previousPage", event );
6725
                                        break;
6726
                                case keyCode.PAGE_DOWN:
6727
                                        this._move( "nextPage", event );
6728
                                        break;
6729
                                case keyCode.UP:
6730
                                        this._keyEvent( "previous", event );
6731
                                        break;
6732
                                case keyCode.DOWN:
6733
                                        this._keyEvent( "next", event );
6734
                                        break;
6735
                                }
6736
                        },
6737
                        input: function( event ) {
6738
                                if ( suppressInput ) {
6739
                                        suppressInput = false;
6740
                                        event.preventDefault();
6741
                                        return;
6742
                                }
6743
                                this._searchTimeout( event );
6744
                        },
6745
                        focus: function() {
6746
                                this.selectedItem = null;
6747
                                this.previous = this._value();
6748
                        },
6749
                        blur: function( event ) {
6750
                                if ( this.cancelBlur ) {
6751
                                        delete this.cancelBlur;
6752
                                        return;
6753
                                }
6754

    
6755
                                clearTimeout( this.searching );
6756
                                this.close( event );
6757
                                this._change( event );
6758
                        }
6759
                });
6760

    
6761
                this._initSource();
6762
                this.menu = $( "<ul>" )
6763
                        .addClass( "ui-autocomplete ui-front" )
6764
                        .appendTo( this._appendTo() )
6765
                        .menu({
6766
                                // custom key handling for now
6767
                                input: $(),
6768
                                // disable ARIA support, the live region takes care of that
6769
                                role: null
6770
                        })
6771
                        .hide()
6772
                        .data( "ui-menu" );
6773

    
6774
                this._on( this.menu.element, {
6775
                        mousedown: function( event ) {
6776
                                // prevent moving focus out of the text field
6777
                                event.preventDefault();
6778

    
6779
                                // IE doesn't prevent moving focus even with event.preventDefault()
6780
                                // so we set a flag to know when we should ignore the blur event
6781
                                this.cancelBlur = true;
6782
                                this._delay(function() {
6783
                                        delete this.cancelBlur;
6784
                                });
6785

    
6786
                                // clicking on the scrollbar causes focus to shift to the body
6787
                                // but we can't detect a mouseup or a click immediately afterward
6788
                                // so we have to track the next mousedown and close the menu if
6789
                                // the user clicks somewhere outside of the autocomplete
6790
                                var menuElement = this.menu.element[ 0 ];
6791
                                if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6792
                                        this._delay(function() {
6793
                                                var that = this;
6794
                                                this.document.one( "mousedown", function( event ) {
6795
                                                        if ( event.target !== that.element[ 0 ] &&
6796
                                                                        event.target !== menuElement &&
6797
                                                                        !$.contains( menuElement, event.target ) ) {
6798
                                                                that.close();
6799
                                                        }
6800
                                                });
6801
                                        });
6802
                                }
6803
                        },
6804
                        menufocus: function( event, ui ) {
6805
                                // support: Firefox
6806
                                // Prevent accidental activation of menu items in Firefox (#7024 #9118)
6807
                                if ( this.isNewMenu ) {
6808
                                        this.isNewMenu = false;
6809
                                        if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6810
                                                this.menu.blur();
6811

    
6812
                                                this.document.one( "mousemove", function() {
6813
                                                        $( event.target ).trigger( event.originalEvent );
6814
                                                });
6815

    
6816
                                                return;
6817
                                        }
6818
                                }
6819

    
6820
                                var item = ui.item.data( "ui-autocomplete-item" );
6821
                                if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6822
                                        // use value to match what will end up in the input, if it was a key event
6823
                                        if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6824
                                                this._value( item.value );
6825
                                        }
6826
                                } else {
6827
                                        // Normally the input is populated with the item's value as the
6828
                                        // menu is navigated, causing screen readers to notice a change and
6829
                                        // announce the item. Since the focus event was canceled, this doesn't
6830
                                        // happen, so we update the live region so that screen readers can
6831
                                        // still notice the change and announce it.
6832
                                        this.liveRegion.text( item.value );
6833
                                }
6834
                        },
6835
                        menuselect: function( event, ui ) {
6836
                                var item = ui.item.data( "ui-autocomplete-item" ),
6837
                                        previous = this.previous;
6838

    
6839
                                // only trigger when focus was lost (click on menu)
6840
                                if ( this.element[0] !== this.document[0].activeElement ) {
6841
                                        this.element.focus();
6842
                                        this.previous = previous;
6843
                                        // #6109 - IE triggers two focus events and the second
6844
                                        // is asynchronous, so we need to reset the previous
6845
                                        // term synchronously and asynchronously :-(
6846
                                        this._delay(function() {
6847
                                                this.previous = previous;
6848
                                                this.selectedItem = item;
6849
                                        });
6850
                                }
6851

    
6852
                                if ( false !== this._trigger( "select", event, { item: item } ) ) {
6853
                                        this._value( item.value );
6854
                                }
6855
                                // reset the term after the select event
6856
                                // this allows custom select handling to work properly
6857
                                this.term = this._value();
6858

    
6859
                                this.close( event );
6860
                                this.selectedItem = item;
6861
                        }
6862
                });
6863

    
6864
                this.liveRegion = $( "<span>", {
6865
                                role: "status",
6866
                                "aria-live": "polite"
6867
                        })
6868
                        .addClass( "ui-helper-hidden-accessible" )
6869
                        .insertAfter( this.element );
6870

    
6871
                // turning off autocomplete prevents the browser from remembering the
6872
                // value when navigating through history, so we re-enable autocomplete
6873
                // if the page is unloaded before the widget is destroyed. #7790
6874
                this._on( this.window, {
6875
                        beforeunload: function() {
6876
                                this.element.removeAttr( "autocomplete" );
6877
                        }
6878
                });
6879
        },
6880

    
6881
        _destroy: function() {
6882
                clearTimeout( this.searching );
6883
                this.element
6884
                        .removeClass( "ui-autocomplete-input" )
6885
                        .removeAttr( "autocomplete" );
6886
                this.menu.element.remove();
6887
                this.liveRegion.remove();
6888
        },
6889

    
6890
        _setOption: function( key, value ) {
6891
                this._super( key, value );
6892
                if ( key === "source" ) {
6893
                        this._initSource();
6894
                }
6895
                if ( key === "appendTo" ) {
6896
                        this.menu.element.appendTo( this._appendTo() );
6897
                }
6898
                if ( key === "disabled" && value && this.xhr ) {
6899
                        this.xhr.abort();
6900
                }
6901
        },
6902

    
6903
        _appendTo: function() {
6904
                var element = this.options.appendTo;
6905

    
6906
                if ( element ) {
6907
                        element = element.jquery || element.nodeType ?
6908
                                $( element ) :
6909
                                this.document.find( element ).eq( 0 );
6910
                }
6911

    
6912
                if ( !element ) {
6913
                        element = this.element.closest( ".ui-front" );
6914
                }
6915

    
6916
                if ( !element.length ) {
6917
                        element = this.document[0].body;
6918
                }
6919

    
6920
                return element;
6921
        },
6922

    
6923
        _initSource: function() {
6924
                var array, url,
6925
                        that = this;
6926
                if ( $.isArray(this.options.source) ) {
6927
                        array = this.options.source;
6928
                        this.source = function( request, response ) {
6929
                                response( $.ui.autocomplete.filter( array, request.term ) );
6930
                        };
6931
                } else if ( typeof this.options.source === "string" ) {
6932
                        url = this.options.source;
6933
                        this.source = function( request, response ) {
6934
                                if ( that.xhr ) {
6935
                                        that.xhr.abort();
6936
                                }
6937
                                that.xhr = $.ajax({
6938
                                        url: url,
6939
                                        data: request,
6940
                                        dataType: "json",
6941
                                        success: function( data ) {
6942
                                                response( data );
6943
                                        },
6944
                                        error: function() {
6945
                                                response( [] );
6946
                                        }
6947
                                });
6948
                        };
6949
                } else {
6950
                        this.source = this.options.source;
6951
                }
6952
        },
6953

    
6954
        _searchTimeout: function( event ) {
6955
                clearTimeout( this.searching );
6956
                this.searching = this._delay(function() {
6957
                        // only search if the value has changed
6958
                        if ( this.term !== this._value() ) {
6959
                                this.selectedItem = null;
6960
                                this.search( null, event );
6961
                        }
6962
                }, this.options.delay );
6963
        },
6964

    
6965
        search: function( value, event ) {
6966
                value = value != null ? value : this._value();
6967

    
6968
                // always save the actual value, not the one passed as an argument
6969
                this.term = this._value();
6970

    
6971
                if ( value.length < this.options.minLength ) {
6972
                        return this.close( event );
6973
                }
6974

    
6975
                if ( this._trigger( "search", event ) === false ) {
6976
                        return;
6977
                }
6978

    
6979
                return this._search( value );
6980
        },
6981

    
6982
        _search: function( value ) {
6983
                this.pending++;
6984
                this.element.addClass( "ui-autocomplete-loading" );
6985
                this.cancelSearch = false;
6986

    
6987
                this.source( { term: value }, this._response() );
6988
        },
6989

    
6990
        _response: function() {
6991
                var that = this,
6992
                        index = ++requestIndex;
6993

    
6994
                return function( content ) {
6995
                        if ( index === requestIndex ) {
6996
                                that.__response( content );
6997
                        }
6998

    
6999
                        that.pending--;
7000
                        if ( !that.pending ) {
7001
                                that.element.removeClass( "ui-autocomplete-loading" );
7002
                        }
7003
                };
7004
        },
7005

    
7006
        __response: function( content ) {
7007
                if ( content ) {
7008
                        content = this._normalize( content );
7009
                }
7010
                this._trigger( "response", null, { content: content } );
7011
                if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
7012
                        this._suggest( content );
7013
                        this._trigger( "open" );
7014
                } else {
7015
                        // use ._close() instead of .close() so we don't cancel future searches
7016
                        this._close();
7017
                }
7018
        },
7019

    
7020
        close: function( event ) {
7021
                this.cancelSearch = true;
7022
                this._close( event );
7023
        },
7024

    
7025
        _close: function( event ) {
7026
                if ( this.menu.element.is( ":visible" ) ) {
7027
                        this.menu.element.hide();
7028
                        this.menu.blur();
7029
                        this.isNewMenu = true;
7030
                        this._trigger( "close", event );
7031
                }
7032
        },
7033

    
7034
        _change: function( event ) {
7035
                if ( this.previous !== this._value() ) {
7036
                        this._trigger( "change", event, { item: this.selectedItem } );
7037
                }
7038
        },
7039

    
7040
        _normalize: function( items ) {
7041
                // assume all items have the right format when the first item is complete
7042
                if ( items.length && items[0].label && items[0].value ) {
7043
                        return items;
7044
                }
7045
                return $.map( items, function( item ) {
7046
                        if ( typeof item === "string" ) {
7047
                                return {
7048
                                        label: item,
7049
                                        value: item
7050
                                };
7051
                        }
7052
                        return $.extend({
7053
                                label: item.label || item.value,
7054
                                value: item.value || item.label
7055
                        }, item );
7056
                });
7057
        },
7058

    
7059
        _suggest: function( items ) {
7060
                var ul = this.menu.element.empty();
7061
                this._renderMenu( ul, items );
7062
                this.isNewMenu = true;
7063
                this.menu.refresh();
7064

    
7065
                // size and position menu
7066
                ul.show();
7067
                this._resizeMenu();
7068
                ul.position( $.extend({
7069
                        of: this.element
7070
                }, this.options.position ));
7071

    
7072
                if ( this.options.autoFocus ) {
7073
                        this.menu.next();
7074
                }
7075
        },
7076

    
7077
        _resizeMenu: function() {
7078
                var ul = this.menu.element;
7079
                ul.outerWidth( Math.max(
7080
                        // Firefox wraps long text (possibly a rounding bug)
7081
                        // so we add 1px to avoid the wrapping (#7513)
7082
                        ul.width( "" ).outerWidth() + 1,
7083
                        this.element.outerWidth()
7084
                ) );
7085
        },
7086

    
7087
        _renderMenu: function( ul, items ) {
7088
                var that = this;
7089
                $.each( items, function( index, item ) {
7090
                        that._renderItemData( ul, item );
7091
                });
7092
        },
7093

    
7094
        _renderItemData: function( ul, item ) {
7095
                return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7096
        },
7097

    
7098
        _renderItem: function( ul, item ) {
7099
                return $( "<li>" )
7100
                        .append( $( "<a>" ).text( item.label ) )
7101
                        .appendTo( ul );
7102
        },
7103

    
7104
        _move: function( direction, event ) {
7105
                if ( !this.menu.element.is( ":visible" ) ) {
7106
                        this.search( null, event );
7107
                        return;
7108
                }
7109
                if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7110
                                this.menu.isLastItem() && /^next/.test( direction ) ) {
7111
                        this._value( this.term );
7112
                        this.menu.blur();
7113
                        return;
7114
                }
7115
                this.menu[ direction ]( event );
7116
        },
7117

    
7118
        widget: function() {
7119
                return this.menu.element;
7120
        },
7121

    
7122
        _value: function() {
7123
                return this.valueMethod.apply( this.element, arguments );
7124
        },
7125

    
7126
        _keyEvent: function( keyEvent, event ) {
7127
                if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7128
                        this._move( keyEvent, event );
7129

    
7130
                        // prevents moving cursor to beginning/end of the text field in some browsers
7131
                        event.preventDefault();
7132
                }
7133
        }
7134
});
7135

    
7136
$.extend( $.ui.autocomplete, {
7137
        escapeRegex: function( value ) {
7138
                return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
7139
        },
7140
        filter: function(array, term) {
7141
                var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
7142
                return $.grep( array, function(value) {
7143
                        return matcher.test( value.label || value.value || value );
7144
                });
7145
        }
7146
});
7147

    
7148

    
7149
// live region extension, adding a `messages` option
7150
// NOTE: This is an experimental API. We are still investigating
7151
// a full solution for string manipulation and internationalization.
7152
$.widget( "ui.autocomplete", $.ui.autocomplete, {
7153
        options: {
7154
                messages: {
7155
                        noResults: "No search results.",
7156
                        results: function( amount ) {
7157
                                return amount + ( amount > 1 ? " results are" : " result is" ) +
7158
                                        " available, use up and down arrow keys to navigate.";
7159
                        }
7160
                }
7161
        },
7162

    
7163
        __response: function( content ) {
7164
                var message;
7165
                this._superApply( arguments );
7166
                if ( this.options.disabled || this.cancelSearch ) {
7167
                        return;
7168
                }
7169
                if ( content && content.length ) {
7170
                        message = this.options.messages.results( content.length );
7171
                } else {
7172
                        message = this.options.messages.noResults;
7173
                }
7174
                this.liveRegion.text( message );
7175
        }
7176
});
7177

    
7178
}( jQuery ));
7179

    
7180
(function( $, undefined ) {
7181

    
7182
var lastActive, startXPos, startYPos, clickDragged,
7183
        baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7184
        stateClasses = "ui-state-hover ui-state-active ",
7185
        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",
7186
        formResetHandler = function() {
7187
                var buttons = $( this ).find( ":ui-button" );
7188
                setTimeout(function() {
7189
                        buttons.button( "refresh" );
7190
                }, 1 );
7191
        },
7192
        radioGroup = function( radio ) {
7193
                var name = radio.name,
7194
                        form = radio.form,
7195
                        radios = $( [] );
7196
                if ( name ) {
7197
                        name = name.replace( /'/g, "\\'" );
7198
                        if ( form ) {
7199
                                radios = $( form ).find( "[name='" + name + "']" );
7200
                        } else {
7201
                                radios = $( "[name='" + name + "']", radio.ownerDocument )
7202
                                        .filter(function() {
7203
                                                return !this.form;
7204
                                        });
7205
                        }
7206
                }
7207
                return radios;
7208
        };
7209

    
7210
$.widget( "ui.button", {
7211
        version: "1.10.2",
7212
        defaultElement: "<button>",
7213
        options: {
7214
                disabled: null,
7215
                text: true,
7216
                label: null,
7217
                icons: {
7218
                        primary: null,
7219
                        secondary: null
7220
                }
7221
        },
7222
        _create: function() {
7223
                this.element.closest( "form" )
7224
                        .unbind( "reset" + this.eventNamespace )
7225
                        .bind( "reset" + this.eventNamespace, formResetHandler );
7226

    
7227
                if ( typeof this.options.disabled !== "boolean" ) {
7228
                        this.options.disabled = !!this.element.prop( "disabled" );
7229
                } else {
7230
                        this.element.prop( "disabled", this.options.disabled );
7231
                }
7232

    
7233
                this._determineButtonType();
7234
                this.hasTitle = !!this.buttonElement.attr( "title" );
7235

    
7236
                var that = this,
7237
                        options = this.options,
7238
                        toggleButton = this.type === "checkbox" || this.type === "radio",
7239
                        activeClass = !toggleButton ? "ui-state-active" : "",
7240
                        focusClass = "ui-state-focus";
7241

    
7242
                if ( options.label === null ) {
7243
                        options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7244
                }
7245

    
7246
                this._hoverable( this.buttonElement );
7247

    
7248
                this.buttonElement
7249
                        .addClass( baseClasses )
7250
                        .attr( "role", "button" )
7251
                        .bind( "mouseenter" + this.eventNamespace, function() {
7252
                                if ( options.disabled ) {
7253
                                        return;
7254
                                }
7255
                                if ( this === lastActive ) {
7256
                                        $( this ).addClass( "ui-state-active" );
7257
                                }
7258
                        })
7259
                        .bind( "mouseleave" + this.eventNamespace, function() {
7260
                                if ( options.disabled ) {
7261
                                        return;
7262
                                }
7263
                                $( this ).removeClass( activeClass );
7264
                        })
7265
                        .bind( "click" + this.eventNamespace, function( event ) {
7266
                                if ( options.disabled ) {
7267
                                        event.preventDefault();
7268
                                        event.stopImmediatePropagation();
7269
                                }
7270
                        });
7271

    
7272
                this.element
7273
                        .bind( "focus" + this.eventNamespace, function() {
7274
                                // no need to check disabled, focus won't be triggered anyway
7275
                                that.buttonElement.addClass( focusClass );
7276
                        })
7277
                        .bind( "blur" + this.eventNamespace, function() {
7278
                                that.buttonElement.removeClass( focusClass );
7279
                        });
7280

    
7281
                if ( toggleButton ) {
7282
                        this.element.bind( "change" + this.eventNamespace, function() {
7283
                                if ( clickDragged ) {
7284
                                        return;
7285
                                }
7286
                                that.refresh();
7287
                        });
7288
                        // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
7289
                        // prevents issue where button state changes but checkbox/radio checked state
7290
                        // does not in Firefox (see ticket #6970)
7291
                        this.buttonElement
7292
                                .bind( "mousedown" + this.eventNamespace, function( event ) {
7293
                                        if ( options.disabled ) {
7294
                                                return;
7295
                                        }
7296
                                        clickDragged = false;
7297
                                        startXPos = event.pageX;
7298
                                        startYPos = event.pageY;
7299
                                })
7300
                                .bind( "mouseup" + this.eventNamespace, function( event ) {
7301
                                        if ( options.disabled ) {
7302
                                                return;
7303
                                        }
7304
                                        if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
7305
                                                clickDragged = true;
7306
                                        }
7307
                        });
7308
                }
7309

    
7310
                if ( this.type === "checkbox" ) {
7311
                        this.buttonElement.bind( "click" + this.eventNamespace, function() {
7312
                                if ( options.disabled || clickDragged ) {
7313
                                        return false;
7314
                                }
7315
                        });
7316
                } else if ( this.type === "radio" ) {
7317
                        this.buttonElement.bind( "click" + this.eventNamespace, function() {
7318
                                if ( options.disabled || clickDragged ) {
7319
                                        return false;
7320
                                }
7321
                                $( this ).addClass( "ui-state-active" );
7322
                                that.buttonElement.attr( "aria-pressed", "true" );
7323

    
7324
                                var radio = that.element[ 0 ];
7325
                                radioGroup( radio )
7326
                                        .not( radio )
7327
                                        .map(function() {
7328
                                                return $( this ).button( "widget" )[ 0 ];
7329
                                        })
7330
                                        .removeClass( "ui-state-active" )
7331
                                        .attr( "aria-pressed", "false" );
7332
                        });
7333
                } else {
7334
                        this.buttonElement
7335
                                .bind( "mousedown" + this.eventNamespace, function() {
7336
                                        if ( options.disabled ) {
7337
                                                return false;
7338
                                        }
7339
                                        $( this ).addClass( "ui-state-active" );
7340
                                        lastActive = this;
7341
                                        that.document.one( "mouseup", function() {
7342
                                                lastActive = null;
7343
                                        });
7344
                                })
7345
                                .bind( "mouseup" + this.eventNamespace, function() {
7346
                                        if ( options.disabled ) {
7347
                                                return false;
7348
                                        }
7349
                                        $( this ).removeClass( "ui-state-active" );
7350
                                })
7351
                                .bind( "keydown" + this.eventNamespace, function(event) {
7352
                                        if ( options.disabled ) {
7353
                                                return false;
7354
                                        }
7355
                                        if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7356
                                                $( this ).addClass( "ui-state-active" );
7357
                                        }
7358
                                })
7359
                                // see #8559, we bind to blur here in case the button element loses
7360
                                // focus between keydown and keyup, it would be left in an "active" state
7361
                                .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7362
                                        $( this ).removeClass( "ui-state-active" );
7363
                                });
7364

    
7365
                        if ( this.buttonElement.is("a") ) {
7366
                                this.buttonElement.keyup(function(event) {
7367
                                        if ( event.keyCode === $.ui.keyCode.SPACE ) {
7368
                                                // TODO pass through original event correctly (just as 2nd argument doesn't work)
7369
                                                $( this ).click();
7370
                                        }
7371
                                });
7372
                        }
7373
                }
7374

    
7375
                // TODO: pull out $.Widget's handling for the disabled option into
7376
                // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
7377
                // be overridden by individual plugins
7378
                this._setOption( "disabled", options.disabled );
7379
                this._resetButton();
7380
        },
7381

    
7382
        _determineButtonType: function() {
7383
                var ancestor, labelSelector, checked;
7384

    
7385
                if ( this.element.is("[type=checkbox]") ) {
7386
                        this.type = "checkbox";
7387
                } else if ( this.element.is("[type=radio]") ) {
7388
                        this.type = "radio";
7389
                } else if ( this.element.is("input") ) {
7390
                        this.type = "input";
7391
                } else {
7392
                        this.type = "button";
7393
                }
7394

    
7395
                if ( this.type === "checkbox" || this.type === "radio" ) {
7396
                        // we don't search against the document in case the element
7397
                        // is disconnected from the DOM
7398
                        ancestor = this.element.parents().last();
7399
                        labelSelector = "label[for='" + this.element.attr("id") + "']";
7400
                        this.buttonElement = ancestor.find( labelSelector );
7401
                        if ( !this.buttonElement.length ) {
7402
                                ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7403
                                this.buttonElement = ancestor.filter( labelSelector );
7404
                                if ( !this.buttonElement.length ) {
7405
                                        this.buttonElement = ancestor.find( labelSelector );
7406
                                }
7407
                        }
7408
                        this.element.addClass( "ui-helper-hidden-accessible" );
7409

    
7410
                        checked = this.element.is( ":checked" );
7411
                        if ( checked ) {
7412
                                this.buttonElement.addClass( "ui-state-active" );
7413
                        }
7414
                        this.buttonElement.prop( "aria-pressed", checked );
7415
                } else {
7416
                        this.buttonElement = this.element;
7417
                }
7418
        },
7419

    
7420
        widget: function() {
7421
                return this.buttonElement;
7422
        },
7423

    
7424
        _destroy: function() {
7425
                this.element
7426
                        .removeClass( "ui-helper-hidden-accessible" );
7427
                this.buttonElement
7428
                        .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
7429
                        .removeAttr( "role" )
7430
                        .removeAttr( "aria-pressed" )
7431
                        .html( this.buttonElement.find(".ui-button-text").html() );
7432

    
7433
                if ( !this.hasTitle ) {
7434
                        this.buttonElement.removeAttr( "title" );
7435
                }
7436
        },
7437

    
7438
        _setOption: function( key, value ) {
7439
                this._super( key, value );
7440
                if ( key === "disabled" ) {
7441
                        if ( value ) {
7442
                                this.element.prop( "disabled", true );
7443
                        } else {
7444
                                this.element.prop( "disabled", false );
7445
                        }
7446
                        return;
7447
                }
7448
                this._resetButton();
7449
        },
7450

    
7451
        refresh: function() {
7452
                //See #8237 & #8828
7453
                var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7454

    
7455
                if ( isDisabled !== this.options.disabled ) {
7456
                        this._setOption( "disabled", isDisabled );
7457
                }
7458
                if ( this.type === "radio" ) {
7459
                        radioGroup( this.element[0] ).each(function() {
7460
                                if ( $( this ).is( ":checked" ) ) {
7461
                                        $( this ).button( "widget" )
7462
                                                .addClass( "ui-state-active" )
7463
                                                .attr( "aria-pressed", "true" );
7464
                                } else {
7465
                                        $( this ).button( "widget" )
7466
                                                .removeClass( "ui-state-active" )
7467
                                                .attr( "aria-pressed", "false" );
7468
                                }
7469
                        });
7470
                } else if ( this.type === "checkbox" ) {
7471
                        if ( this.element.is( ":checked" ) ) {
7472
                                this.buttonElement
7473
                                        .addClass( "ui-state-active" )
7474
                                        .attr( "aria-pressed", "true" );
7475
                        } else {
7476
                                this.buttonElement
7477
                                        .removeClass( "ui-state-active" )
7478
                                        .attr( "aria-pressed", "false" );
7479
                        }
7480
                }
7481
        },
7482

    
7483
        _resetButton: function() {
7484
                if ( this.type === "input" ) {
7485
                        if ( this.options.label ) {
7486
                                this.element.val( this.options.label );
7487
                        }
7488
                        return;
7489
                }
7490
                var buttonElement = this.buttonElement.removeClass( typeClasses ),
7491
                        buttonText = $( "<span></span>", this.document[0] )
7492
                                .addClass( "ui-button-text" )
7493
                                .html( this.options.label )
7494
                                .appendTo( buttonElement.empty() )
7495
                                .text(),
7496
                        icons = this.options.icons,
7497
                        multipleIcons = icons.primary && icons.secondary,
7498
                        buttonClasses = [];
7499

    
7500
                if ( icons.primary || icons.secondary ) {
7501
                        if ( this.options.text ) {
7502
                                buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7503
                        }
7504

    
7505
                        if ( icons.primary ) {
7506
                                buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7507
                        }
7508

    
7509
                        if ( icons.secondary ) {
7510
                                buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7511
                        }
7512

    
7513
                        if ( !this.options.text ) {
7514
                                buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7515

    
7516
                                if ( !this.hasTitle ) {
7517
                                        buttonElement.attr( "title", $.trim( buttonText ) );
7518
                                }
7519
                        }
7520
                } else {
7521
                        buttonClasses.push( "ui-button-text-only" );
7522
                }
7523
                buttonElement.addClass( buttonClasses.join( " " ) );
7524
        }
7525
});
7526

    
7527
$.widget( "ui.buttonset", {
7528
        version: "1.10.2",
7529
        options: {
7530
                items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7531
        },
7532

    
7533
        _create: function() {
7534
                this.element.addClass( "ui-buttonset" );
7535
        },
7536

    
7537
        _init: function() {
7538
                this.refresh();
7539
        },
7540

    
7541
        _setOption: function( key, value ) {
7542
                if ( key === "disabled" ) {
7543
                        this.buttons.button( "option", key, value );
7544
                }
7545

    
7546
                this._super( key, value );
7547
        },
7548

    
7549
        refresh: function() {
7550
                var rtl = this.element.css( "direction" ) === "rtl";
7551

    
7552
                this.buttons = this.element.find( this.options.items )
7553
                        .filter( ":ui-button" )
7554
                                .button( "refresh" )
7555
                        .end()
7556
                        .not( ":ui-button" )
7557
                                .button()
7558
                        .end()
7559
                        .map(function() {
7560
                                return $( this ).button( "widget" )[ 0 ];
7561
                        })
7562
                                .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7563
                                .filter( ":first" )
7564
                                        .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7565
                                .end()
7566
                                .filter( ":last" )
7567
                                        .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7568
                                .end()
7569
                        .end();
7570
        },
7571

    
7572
        _destroy: function() {
7573
                this.element.removeClass( "ui-buttonset" );
7574
                this.buttons
7575
                        .map(function() {
7576
                                return $( this ).button( "widget" )[ 0 ];
7577
                        })
7578
                                .removeClass( "ui-corner-left ui-corner-right" )
7579
                        .end()
7580
                        .button( "destroy" );
7581
        }
7582
});
7583

    
7584
}( jQuery ) );
7585

    
7586
(function( $, undefined ) {
7587

    
7588
$.extend($.ui, { datepicker: { version: "1.10.2" } });
7589

    
7590
var PROP_NAME = "datepicker",
7591
        dpuuid = new Date().getTime(),
7592
        instActive;
7593

    
7594
/* Date picker manager.
7595
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7596
   Settings for (groups of) date pickers are maintained in an instance object,
7597
   allowing multiple different settings on the same page. */
7598

    
7599
function Datepicker() {
7600
        this._curInst = null; // The current instance in use
7601
        this._keyEvent = false; // If the last event was a key event
7602
        this._disabledInputs = []; // List of date picker inputs that have been disabled
7603
        this._datepickerShowing = false; // True if the popup picker is showing , false if not
7604
        this._inDialog = false; // True if showing within a "dialog", false if not
7605
        this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7606
        this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7607
        this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7608
        this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7609
        this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7610
        this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7611
        this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7612
        this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7613
        this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7614
        this.regional = []; // Available regional settings, indexed by language code
7615
        this.regional[""] = { // Default regional settings
7616
                closeText: "Done", // Display text for close link
7617
                prevText: "Prev", // Display text for previous month link
7618
                nextText: "Next", // Display text for next month link
7619
                currentText: "Today", // Display text for current month link
7620
                monthNames: ["January","February","March","April","May","June",
7621
                        "July","August","September","October","November","December"], // Names of months for drop-down and formatting
7622
                monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
7623
                dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
7624
                dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
7625
                dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
7626
                weekHeader: "Wk", // Column header for week of the year
7627
                dateFormat: "mm/dd/yy", // See format options on parseDate
7628
                firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7629
                isRTL: false, // True if right-to-left language, false if left-to-right
7630
                showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7631
                yearSuffix: "" // Additional text to append to the year in the month headers
7632
        };
7633
        this._defaults = { // Global defaults for all the date picker instances
7634
                showOn: "focus", // "focus" for popup on focus,
7635
                        // "button" for trigger button, or "both" for either
7636
                showAnim: "fadeIn", // Name of jQuery animation for popup
7637
                showOptions: {}, // Options for enhanced animations
7638
                defaultDate: null, // Used when field is blank: actual date,
7639
                        // +/-number for offset from today, null for today
7640
                appendText: "", // Display text following the input box, e.g. showing the format
7641
                buttonText: "...", // Text for trigger button
7642
                buttonImage: "", // URL for trigger button image
7643
                buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7644
                hideIfNoPrevNext: false, // True to hide next/previous month links
7645
                        // if not applicable, false to just disable them
7646
                navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7647
                gotoCurrent: false, // True if today link goes back to current selection instead
7648
                changeMonth: false, // True if month can be selected directly, false if only prev/next
7649
                changeYear: false, // True if year can be selected directly, false if only prev/next
7650
                yearRange: "c-10:c+10", // Range of years to display in drop-down,
7651
                        // either relative to today's year (-nn:+nn), relative to currently displayed year
7652
                        // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7653
                showOtherMonths: false, // True to show dates in other months, false to leave blank
7654
                selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7655
                showWeek: false, // True to show week of the year, false to not show it
7656
                calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7657
                        // takes a Date and returns the number of the week for it
7658
                shortYearCutoff: "+10", // Short year values < this are in the current century,
7659
                        // > this are in the previous century,
7660
                        // string value starting with "+" for current year + value
7661
                minDate: null, // The earliest selectable date, or null for no limit
7662
                maxDate: null, // The latest selectable date, or null for no limit
7663
                duration: "fast", // Duration of display/closure
7664
                beforeShowDay: null, // Function that takes a date and returns an array with
7665
                        // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7666
                        // [2] = cell title (optional), e.g. $.datepicker.noWeekends
7667
                beforeShow: null, // Function that takes an input field and
7668
                        // returns a set of custom settings for the date picker
7669
                onSelect: null, // Define a callback function when a date is selected
7670
                onChangeMonthYear: null, // Define a callback function when the month or year is changed
7671
                onClose: null, // Define a callback function when the datepicker is closed
7672
                numberOfMonths: 1, // Number of months to show at a time
7673
                showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7674
                stepMonths: 1, // Number of months to step back/forward
7675
                stepBigMonths: 12, // Number of months to step back/forward for the big links
7676
                altField: "", // Selector for an alternate field to store selected dates into
7677
                altFormat: "", // The date format to use for the alternate field
7678
                constrainInput: true, // The input is constrained by the current date format
7679
                showButtonPanel: false, // True to show button panel, false to not show it
7680
                autoSize: false, // True to size the input for the date format, false to leave as is
7681
                disabled: false // The initial disabled state
7682
        };
7683
        $.extend(this._defaults, this.regional[""]);
7684
        this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
7685
}
7686

    
7687
$.extend(Datepicker.prototype, {
7688
        /* Class name added to elements to indicate already configured with a date picker. */
7689
        markerClassName: "hasDatepicker",
7690

    
7691
        //Keep track of the maximum number of rows displayed (see #7043)
7692
        maxRows: 4,
7693

    
7694
        // TODO rename to "widget" when switching to widget factory
7695
        _widgetDatepicker: function() {
7696
                return this.dpDiv;
7697
        },
7698

    
7699
        /* Override the default settings for all instances of the date picker.
7700
         * @param  settings  object - the new settings to use as defaults (anonymous object)
7701
         * @return the manager object
7702
         */
7703
        setDefaults: function(settings) {
7704
                extendRemove(this._defaults, settings || {});
7705
                return this;
7706
        },
7707

    
7708
        /* Attach the date picker to a jQuery selection.
7709
         * @param  target        element - the target input field or division or span
7710
         * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7711
         */
7712
        _attachDatepicker: function(target, settings) {
7713
                var nodeName, inline, inst;
7714
                nodeName = target.nodeName.toLowerCase();
7715
                inline = (nodeName === "div" || nodeName === "span");
7716
                if (!target.id) {
7717
                        this.uuid += 1;
7718
                        target.id = "dp" + this.uuid;
7719
                }
7720
                inst = this._newInst($(target), inline);
7721
                inst.settings = $.extend({}, settings || {});
7722
                if (nodeName === "input") {
7723
                        this._connectDatepicker(target, inst);
7724
                } else if (inline) {
7725
                        this._inlineDatepicker(target, inst);
7726
                }
7727
        },
7728

    
7729
        /* Create a new instance object. */
7730
        _newInst: function(target, inline) {
7731
                var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
7732
                return {id: id, input: target, // associated target
7733
                        selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7734
                        drawMonth: 0, drawYear: 0, // month being drawn
7735
                        inline: inline, // is datepicker inline or not
7736
                        dpDiv: (!inline ? this.dpDiv : // presentation div
7737
                        bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
7738
        },
7739

    
7740
        /* Attach the date picker to an input field. */
7741
        _connectDatepicker: function(target, inst) {
7742
                var input = $(target);
7743
                inst.append = $([]);
7744
                inst.trigger = $([]);
7745
                if (input.hasClass(this.markerClassName)) {
7746
                        return;
7747
                }
7748
                this._attachments(input, inst);
7749
                input.addClass(this.markerClassName).keydown(this._doKeyDown).
7750
                        keypress(this._doKeyPress).keyup(this._doKeyUp);
7751
                this._autoSize(inst);
7752
                $.data(target, PROP_NAME, inst);
7753
                //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7754
                if( inst.settings.disabled ) {
7755
                        this._disableDatepicker( target );
7756
                }
7757
        },
7758

    
7759
        /* Make attachments based on settings. */
7760
        _attachments: function(input, inst) {
7761
                var showOn, buttonText, buttonImage,
7762
                        appendText = this._get(inst, "appendText"),
7763
                        isRTL = this._get(inst, "isRTL");
7764

    
7765
                if (inst.append) {
7766
                        inst.append.remove();
7767
                }
7768
                if (appendText) {
7769
                        inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
7770
                        input[isRTL ? "before" : "after"](inst.append);
7771
                }
7772

    
7773
                input.unbind("focus", this._showDatepicker);
7774

    
7775
                if (inst.trigger) {
7776
                        inst.trigger.remove();
7777
                }
7778

    
7779
                showOn = this._get(inst, "showOn");
7780
                if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
7781
                        input.focus(this._showDatepicker);
7782
                }
7783
                if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
7784
                        buttonText = this._get(inst, "buttonText");
7785
                        buttonImage = this._get(inst, "buttonImage");
7786
                        inst.trigger = $(this._get(inst, "buttonImageOnly") ?
7787
                                $("<img/>").addClass(this._triggerClass).
7788
                                        attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7789
                                $("<button type='button'></button>").addClass(this._triggerClass).
7790
                                        html(!buttonImage ? buttonText : $("<img/>").attr(
7791
                                        { src:buttonImage, alt:buttonText, title:buttonText })));
7792
                        input[isRTL ? "before" : "after"](inst.trigger);
7793
                        inst.trigger.click(function() {
7794
                                if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
7795
                                        $.datepicker._hideDatepicker();
7796
                                } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
7797
                                        $.datepicker._hideDatepicker();
7798
                                        $.datepicker._showDatepicker(input[0]);
7799
                                } else {
7800
                                        $.datepicker._showDatepicker(input[0]);
7801
                                }
7802
                                return false;
7803
                        });
7804
                }
7805
        },
7806

    
7807
        /* Apply the maximum length for the date format. */
7808
        _autoSize: function(inst) {
7809
                if (this._get(inst, "autoSize") && !inst.inline) {
7810
                        var findMax, max, maxI, i,
7811
                                date = new Date(2009, 12 - 1, 20), // Ensure double digits
7812
                                dateFormat = this._get(inst, "dateFormat");
7813

    
7814
                        if (dateFormat.match(/[DM]/)) {
7815
                                findMax = function(names) {
7816
                                        max = 0;
7817
                                        maxI = 0;
7818
                                        for (i = 0; i < names.length; i++) {
7819
                                                if (names[i].length > max) {
7820
                                                        max = names[i].length;
7821
                                                        maxI = i;
7822
                                                }
7823
                                        }
7824
                                        return maxI;
7825
                                };
7826
                                date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7827
                                        "monthNames" : "monthNamesShort"))));
7828
                                date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7829
                                        "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
7830
                        }
7831
                        inst.input.attr("size", this._formatDate(inst, date).length);
7832
                }
7833
        },
7834

    
7835
        /* Attach an inline date picker to a div. */
7836
        _inlineDatepicker: function(target, inst) {
7837
                var divSpan = $(target);
7838
                if (divSpan.hasClass(this.markerClassName)) {
7839
                        return;
7840
                }
7841
                divSpan.addClass(this.markerClassName).append(inst.dpDiv);
7842
                $.data(target, PROP_NAME, inst);
7843
                this._setDate(inst, this._getDefaultDate(inst), true);
7844
                this._updateDatepicker(inst);
7845
                this._updateAlternate(inst);
7846
                //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7847
                if( inst.settings.disabled ) {
7848
                        this._disableDatepicker( target );
7849
                }
7850
                // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7851
                // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7852
                inst.dpDiv.css( "display", "block" );
7853
        },
7854

    
7855
        /* Pop-up the date picker in a "dialog" box.
7856
         * @param  input element - ignored
7857
         * @param  date        string or Date - the initial date to display
7858
         * @param  onSelect  function - the function to call when a date is selected
7859
         * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7860
         * @param  pos int[2] - coordinates for the dialog's position within the screen or
7861
         *                                        event - with x/y coordinates or
7862
         *                                        leave empty for default (screen centre)
7863
         * @return the manager object
7864
         */
7865
        _dialogDatepicker: function(input, date, onSelect, settings, pos) {
7866
                var id, browserWidth, browserHeight, scrollX, scrollY,
7867
                        inst = this._dialogInst; // internal instance
7868

    
7869
                if (!inst) {
7870
                        this.uuid += 1;
7871
                        id = "dp" + this.uuid;
7872
                        this._dialogInput = $("<input type='text' id='" + id +
7873
                                "' style='position: absolute; top: -100px; width: 0px;'/>");
7874
                        this._dialogInput.keydown(this._doKeyDown);
7875
                        $("body").append(this._dialogInput);
7876
                        inst = this._dialogInst = this._newInst(this._dialogInput, false);
7877
                        inst.settings = {};
7878
                        $.data(this._dialogInput[0], PROP_NAME, inst);
7879
                }
7880
                extendRemove(inst.settings, settings || {});
7881
                date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
7882
                this._dialogInput.val(date);
7883

    
7884
                this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7885
                if (!this._pos) {
7886
                        browserWidth = document.documentElement.clientWidth;
7887
                        browserHeight = document.documentElement.clientHeight;
7888
                        scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7889
                        scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7890
                        this._pos = // should use actual width/height below
7891
                                [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7892
                }
7893

    
7894
                // move input on screen for focus, but hidden behind dialog
7895
                this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
7896
                inst.settings.onSelect = onSelect;
7897
                this._inDialog = true;
7898
                this.dpDiv.addClass(this._dialogClass);
7899
                this._showDatepicker(this._dialogInput[0]);
7900
                if ($.blockUI) {
7901
                        $.blockUI(this.dpDiv);
7902
                }
7903
                $.data(this._dialogInput[0], PROP_NAME, inst);
7904
                return this;
7905
        },
7906

    
7907
        /* Detach a datepicker from its control.
7908
         * @param  target        element - the target input field or division or span
7909
         */
7910
        _destroyDatepicker: function(target) {
7911
                var nodeName,
7912
                        $target = $(target),
7913
                        inst = $.data(target, PROP_NAME);
7914

    
7915
                if (!$target.hasClass(this.markerClassName)) {
7916
                        return;
7917
                }
7918

    
7919
                nodeName = target.nodeName.toLowerCase();
7920
                $.removeData(target, PROP_NAME);
7921
                if (nodeName === "input") {
7922
                        inst.append.remove();
7923
                        inst.trigger.remove();
7924
                        $target.removeClass(this.markerClassName).
7925
                                unbind("focus", this._showDatepicker).
7926
                                unbind("keydown", this._doKeyDown).
7927
                                unbind("keypress", this._doKeyPress).
7928
                                unbind("keyup", this._doKeyUp);
7929
                } else if (nodeName === "div" || nodeName === "span") {
7930
                        $target.removeClass(this.markerClassName).empty();
7931
                }
7932
        },
7933

    
7934
        /* Enable the date picker to a jQuery selection.
7935
         * @param  target        element - the target input field or division or span
7936
         */
7937
        _enableDatepicker: function(target) {
7938
                var nodeName, inline,
7939
                        $target = $(target),
7940
                        inst = $.data(target, PROP_NAME);
7941

    
7942
                if (!$target.hasClass(this.markerClassName)) {
7943
                        return;
7944
                }
7945

    
7946
                nodeName = target.nodeName.toLowerCase();
7947
                if (nodeName === "input") {
7948
                        target.disabled = false;
7949
                        inst.trigger.filter("button").
7950
                                each(function() { this.disabled = false; }).end().
7951
                                filter("img").css({opacity: "1.0", cursor: ""});
7952
                } else if (nodeName === "div" || nodeName === "span") {
7953
                        inline = $target.children("." + this._inlineClass);
7954
                        inline.children().removeClass("ui-state-disabled");
7955
                        inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7956
                                prop("disabled", false);
7957
                }
7958
                this._disabledInputs = $.map(this._disabledInputs,
7959
                        function(value) { return (value === target ? null : value); }); // delete entry
7960
        },
7961

    
7962
        /* Disable the date picker to a jQuery selection.
7963
         * @param  target        element - the target input field or division or span
7964
         */
7965
        _disableDatepicker: function(target) {
7966
                var nodeName, inline,
7967
                        $target = $(target),
7968
                        inst = $.data(target, PROP_NAME);
7969

    
7970
                if (!$target.hasClass(this.markerClassName)) {
7971
                        return;
7972
                }
7973

    
7974
                nodeName = target.nodeName.toLowerCase();
7975
                if (nodeName === "input") {
7976
                        target.disabled = true;
7977
                        inst.trigger.filter("button").
7978
                                each(function() { this.disabled = true; }).end().
7979
                                filter("img").css({opacity: "0.5", cursor: "default"});
7980
                } else if (nodeName === "div" || nodeName === "span") {
7981
                        inline = $target.children("." + this._inlineClass);
7982
                        inline.children().addClass("ui-state-disabled");
7983
                        inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7984
                                prop("disabled", true);
7985
                }
7986
                this._disabledInputs = $.map(this._disabledInputs,
7987
                        function(value) { return (value === target ? null : value); }); // delete entry
7988
                this._disabledInputs[this._disabledInputs.length] = target;
7989
        },
7990

    
7991
        /* Is the first field in a jQuery collection disabled as a datepicker?
7992
         * @param  target        element - the target input field or division or span
7993
         * @return boolean - true if disabled, false if enabled
7994
         */
7995
        _isDisabledDatepicker: function(target) {
7996
                if (!target) {
7997
                        return false;
7998
                }
7999
                for (var i = 0; i < this._disabledInputs.length; i++) {
8000
                        if (this._disabledInputs[i] === target) {
8001
                                return true;
8002
                        }
8003
                }
8004
                return false;
8005
        },
8006

    
8007
        /* Retrieve the instance data for the target control.
8008
         * @param  target  element - the target input field or division or span
8009
         * @return  object - the associated instance data
8010
         * @throws  error if a jQuery problem getting data
8011
         */
8012
        _getInst: function(target) {
8013
                try {
8014
                        return $.data(target, PROP_NAME);
8015
                }
8016
                catch (err) {
8017
                        throw "Missing instance data for this datepicker";
8018
                }
8019
        },
8020

    
8021
        /* Update or retrieve the settings for a date picker attached to an input field or division.
8022
         * @param  target  element - the target input field or division or span
8023
         * @param  name        object - the new settings to update or
8024
         *                                string - the name of the setting to change or retrieve,
8025
         *                                when retrieving also "all" for all instance settings or
8026
         *                                "defaults" for all global defaults
8027
         * @param  value   any - the new value for the setting
8028
         *                                (omit if above is an object or to retrieve a value)
8029
         */
8030
        _optionDatepicker: function(target, name, value) {
8031
                var settings, date, minDate, maxDate,
8032
                        inst = this._getInst(target);
8033

    
8034
                if (arguments.length === 2 && typeof name === "string") {
8035
                        return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
8036
                                (inst ? (name === "all" ? $.extend({}, inst.settings) :
8037
                                this._get(inst, name)) : null));
8038
                }
8039

    
8040
                settings = name || {};
8041
                if (typeof name === "string") {
8042
                        settings = {};
8043
                        settings[name] = value;
8044
                }
8045

    
8046
                if (inst) {
8047
                        if (this._curInst === inst) {
8048
                                this._hideDatepicker();
8049
                        }
8050

    
8051
                        date = this._getDateDatepicker(target, true);
8052
                        minDate = this._getMinMaxDate(inst, "min");
8053
                        maxDate = this._getMinMaxDate(inst, "max");
8054
                        extendRemove(inst.settings, settings);
8055
                        // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8056
                        if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
8057
                                inst.settings.minDate = this._formatDate(inst, minDate);
8058
                        }
8059
                        if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
8060
                                inst.settings.maxDate = this._formatDate(inst, maxDate);
8061
                        }
8062
                        if ( "disabled" in settings ) {
8063
                                if ( settings.disabled ) {
8064
                                        this._disableDatepicker(target);
8065
                                } else {
8066
                                        this._enableDatepicker(target);
8067
                                }
8068
                        }
8069
                        this._attachments($(target), inst);
8070
                        this._autoSize(inst);
8071
                        this._setDate(inst, date);
8072
                        this._updateAlternate(inst);
8073
                        this._updateDatepicker(inst);
8074
                }
8075
        },
8076

    
8077
        // change method deprecated
8078
        _changeDatepicker: function(target, name, value) {
8079
                this._optionDatepicker(target, name, value);
8080
        },
8081

    
8082
        /* Redraw the date picker attached to an input field or division.
8083
         * @param  target  element - the target input field or division or span
8084
         */
8085
        _refreshDatepicker: function(target) {
8086
                var inst = this._getInst(target);
8087
                if (inst) {
8088
                        this._updateDatepicker(inst);
8089
                }
8090
        },
8091

    
8092
        /* Set the dates for a jQuery selection.
8093
         * @param  target element - the target input field or division or span
8094
         * @param  date        Date - the new date
8095
         */
8096
        _setDateDatepicker: function(target, date) {
8097
                var inst = this._getInst(target);
8098
                if (inst) {
8099
                        this._setDate(inst, date);
8100
                        this._updateDatepicker(inst);
8101
                        this._updateAlternate(inst);
8102
                }
8103
        },
8104

    
8105
        /* Get the date(s) for the first entry in a jQuery selection.
8106
         * @param  target element - the target input field or division or span
8107
         * @param  noDefault boolean - true if no default date is to be used
8108
         * @return Date - the current date
8109
         */
8110
        _getDateDatepicker: function(target, noDefault) {
8111
                var inst = this._getInst(target);
8112
                if (inst && !inst.inline) {
8113
                        this._setDateFromField(inst, noDefault);
8114
                }
8115
                return (inst ? this._getDate(inst) : null);
8116
        },
8117

    
8118
        /* Handle keystrokes. */
8119
        _doKeyDown: function(event) {
8120
                var onSelect, dateStr, sel,
8121
                        inst = $.datepicker._getInst(event.target),
8122
                        handled = true,
8123
                        isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
8124

    
8125
                inst._keyEvent = true;
8126
                if ($.datepicker._datepickerShowing) {
8127
                        switch (event.keyCode) {
8128
                                case 9: $.datepicker._hideDatepicker();
8129
                                                handled = false;
8130
                                                break; // hide on tab out
8131
                                case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
8132
                                                                        $.datepicker._currentClass + ")", inst.dpDiv);
8133
                                                if (sel[0]) {
8134
                                                        $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8135
                                                }
8136

    
8137
                                                onSelect = $.datepicker._get(inst, "onSelect");
8138
                                                if (onSelect) {
8139
                                                        dateStr = $.datepicker._formatDate(inst);
8140

    
8141
                                                        // trigger custom callback
8142
                                                        onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8143
                                                } else {
8144
                                                        $.datepicker._hideDatepicker();
8145
                                                }
8146

    
8147
                                                return false; // don't submit the form
8148
                                case 27: $.datepicker._hideDatepicker();
8149
                                                break; // hide on escape
8150
                                case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8151
                                                        -$.datepicker._get(inst, "stepBigMonths") :
8152
                                                        -$.datepicker._get(inst, "stepMonths")), "M");
8153
                                                break; // previous month/year on page up/+ ctrl
8154
                                case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8155
                                                        +$.datepicker._get(inst, "stepBigMonths") :
8156
                                                        +$.datepicker._get(inst, "stepMonths")), "M");
8157
                                                break; // next month/year on page down/+ ctrl
8158
                                case 35: if (event.ctrlKey || event.metaKey) {
8159
                                                        $.datepicker._clearDate(event.target);
8160
                                                }
8161
                                                handled = event.ctrlKey || event.metaKey;
8162
                                                break; // clear on ctrl or command +end
8163
                                case 36: if (event.ctrlKey || event.metaKey) {
8164
                                                        $.datepicker._gotoToday(event.target);
8165
                                                }
8166
                                                handled = event.ctrlKey || event.metaKey;
8167
                                                break; // current on ctrl or command +home
8168
                                case 37: if (event.ctrlKey || event.metaKey) {
8169
                                                        $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
8170
                                                }
8171
                                                handled = event.ctrlKey || event.metaKey;
8172
                                                // -1 day on ctrl or command +left
8173
                                                if (event.originalEvent.altKey) {
8174
                                                        $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8175
                                                                -$.datepicker._get(inst, "stepBigMonths") :
8176
                                                                -$.datepicker._get(inst, "stepMonths")), "M");
8177
                                                }
8178
                                                // next month/year on alt +left on Mac
8179
                                                break;
8180
                                case 38: if (event.ctrlKey || event.metaKey) {
8181
                                                        $.datepicker._adjustDate(event.target, -7, "D");
8182
                                                }
8183
                                                handled = event.ctrlKey || event.metaKey;
8184
                                                break; // -1 week on ctrl or command +up
8185
                                case 39: if (event.ctrlKey || event.metaKey) {
8186
                                                        $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
8187
                                                }
8188
                                                handled = event.ctrlKey || event.metaKey;
8189
                                                // +1 day on ctrl or command +right
8190
                                                if (event.originalEvent.altKey) {
8191
                                                        $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8192
                                                                +$.datepicker._get(inst, "stepBigMonths") :
8193
                                                                +$.datepicker._get(inst, "stepMonths")), "M");
8194
                                                }
8195
                                                // next month/year on alt +right
8196
                                                break;
8197
                                case 40: if (event.ctrlKey || event.metaKey) {
8198
                                                        $.datepicker._adjustDate(event.target, +7, "D");
8199
                                                }
8200
                                                handled = event.ctrlKey || event.metaKey;
8201
                                                break; // +1 week on ctrl or command +down
8202
                                default: handled = false;
8203
                        }
8204
                } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
8205
                        $.datepicker._showDatepicker(this);
8206
                } else {
8207
                        handled = false;
8208
                }
8209

    
8210
                if (handled) {
8211
                        event.preventDefault();
8212
                        event.stopPropagation();
8213
                }
8214
        },
8215

    
8216
        /* Filter entered characters - based on date format. */
8217
        _doKeyPress: function(event) {
8218
                var chars, chr,
8219
                        inst = $.datepicker._getInst(event.target);
8220

    
8221
                if ($.datepicker._get(inst, "constrainInput")) {
8222
                        chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
8223
                        chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
8224
                        return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
8225
                }
8226
        },
8227

    
8228
        /* Synchronise manual entry and field/alternate field. */
8229
        _doKeyUp: function(event) {
8230
                var date,
8231
                        inst = $.datepicker._getInst(event.target);
8232

    
8233
                if (inst.input.val() !== inst.lastVal) {
8234
                        try {
8235
                                date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8236
                                        (inst.input ? inst.input.val() : null),
8237
                                        $.datepicker._getFormatConfig(inst));
8238

    
8239
                                if (date) { // only if valid
8240
                                        $.datepicker._setDateFromField(inst);
8241
                                        $.datepicker._updateAlternate(inst);
8242
                                        $.datepicker._updateDatepicker(inst);
8243
                                }
8244
                        }
8245
                        catch (err) {
8246
                        }
8247
                }
8248
                return true;
8249
        },
8250

    
8251
        /* Pop-up the date picker for a given input field.
8252
         * If false returned from beforeShow event handler do not show.
8253
         * @param  input  element - the input field attached to the date picker or
8254
         *                                        event - if triggered by focus
8255
         */
8256
        _showDatepicker: function(input) {
8257
                input = input.target || input;
8258
                if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
8259
                        input = $("input", input.parentNode)[0];
8260
                }
8261

    
8262
                if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
8263
                        return;
8264
                }
8265

    
8266
                var inst, beforeShow, beforeShowSettings, isFixed,
8267
                        offset, showAnim, duration;
8268

    
8269
                inst = $.datepicker._getInst(input);
8270
                if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
8271
                        $.datepicker._curInst.dpDiv.stop(true, true);
8272
                        if ( inst && $.datepicker._datepickerShowing ) {
8273
                                $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8274
                        }
8275
                }
8276

    
8277
                beforeShow = $.datepicker._get(inst, "beforeShow");
8278
                beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8279
                if(beforeShowSettings === false){
8280
                        return;
8281
                }
8282
                extendRemove(inst.settings, beforeShowSettings);
8283

    
8284
                inst.lastVal = null;
8285
                $.datepicker._lastInput = input;
8286
                $.datepicker._setDateFromField(inst);
8287

    
8288
                if ($.datepicker._inDialog) { // hide cursor
8289
                        input.value = "";
8290
                }
8291
                if (!$.datepicker._pos) { // position below input
8292
                        $.datepicker._pos = $.datepicker._findPos(input);
8293
                        $.datepicker._pos[1] += input.offsetHeight; // add the height
8294
                }
8295

    
8296
                isFixed = false;
8297
                $(input).parents().each(function() {
8298
                        isFixed |= $(this).css("position") === "fixed";
8299
                        return !isFixed;
8300
                });
8301

    
8302
                offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8303
                $.datepicker._pos = null;
8304
                //to avoid flashes on Firefox
8305
                inst.dpDiv.empty();
8306
                // determine sizing offscreen
8307
                inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
8308
                $.datepicker._updateDatepicker(inst);
8309
                // fix width for dynamic number of date pickers
8310
                // and adjust position before showing
8311
                offset = $.datepicker._checkOffset(inst, offset, isFixed);
8312
                inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8313
                        "static" : (isFixed ? "fixed" : "absolute")), display: "none",
8314
                        left: offset.left + "px", top: offset.top + "px"});
8315

    
8316
                if (!inst.inline) {
8317
                        showAnim = $.datepicker._get(inst, "showAnim");
8318
                        duration = $.datepicker._get(inst, "duration");
8319
                        inst.dpDiv.zIndex($(input).zIndex()+1);
8320
                        $.datepicker._datepickerShowing = true;
8321

    
8322
                        if ( $.effects && $.effects.effect[ showAnim ] ) {
8323
                                inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
8324
                        } else {
8325
                                inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
8326
                        }
8327

    
8328
                        if (inst.input.is(":visible") && !inst.input.is(":disabled")) {
8329
                                inst.input.focus();
8330
                        }
8331
                        $.datepicker._curInst = inst;
8332
                }
8333
        },
8334

    
8335
        /* Generate the date picker content. */
8336
        _updateDatepicker: function(inst) {
8337
                this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8338
                instActive = inst; // for delegate hover events
8339
                inst.dpDiv.empty().append(this._generateHTML(inst));
8340
                this._attachHandlers(inst);
8341
                inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
8342

    
8343
                var origyearshtml,
8344
                        numMonths = this._getNumberOfMonths(inst),
8345
                        cols = numMonths[1],
8346
                        width = 17;
8347

    
8348
                inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
8349
                if (cols > 1) {
8350
                        inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
8351
                }
8352
                inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
8353
                        "Class"]("ui-datepicker-multi");
8354
                inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
8355
                        "Class"]("ui-datepicker-rtl");
8356

    
8357
                // #6694 - don't focus the input if it's already focused
8358
                // this breaks the change event in IE
8359
                if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
8360
                        inst.input.is(":visible") && !inst.input.is(":disabled") && inst.input[0] !== document.activeElement) {
8361
                        inst.input.focus();
8362
                }
8363

    
8364
                // deffered render of the years select (to avoid flashes on Firefox)
8365
                if( inst.yearshtml ){
8366
                        origyearshtml = inst.yearshtml;
8367
                        setTimeout(function(){
8368
                                //assure that inst.yearshtml didn't change.
8369
                                if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8370
                                        inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
8371
                                }
8372
                                origyearshtml = inst.yearshtml = null;
8373
                        }, 0);
8374
                }
8375
        },
8376

    
8377
        /* Retrieve the size of left and top borders for an element.
8378
         * @param  elem  (jQuery object) the element of interest
8379
         * @return  (number[2]) the left and top borders
8380
         */
8381
        _getBorders: function(elem) {
8382
                var convert = function(value) {
8383
                        return {thin: 1, medium: 2, thick: 3}[value] || value;
8384
                };
8385
                return [parseFloat(convert(elem.css("border-left-width"))),
8386
                        parseFloat(convert(elem.css("border-top-width")))];
8387
        },
8388

    
8389
        /* Check positioning to remain on screen. */
8390
        _checkOffset: function(inst, offset, isFixed) {
8391
                var dpWidth = inst.dpDiv.outerWidth(),
8392
                        dpHeight = inst.dpDiv.outerHeight(),
8393
                        inputWidth = inst.input ? inst.input.outerWidth() : 0,
8394
                        inputHeight = inst.input ? inst.input.outerHeight() : 0,
8395
                        viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8396
                        viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8397

    
8398
                offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8399
                offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8400
                offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8401

    
8402
                // now check if datepicker is showing outside window viewport - move to a better place if so.
8403
                offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8404
                        Math.abs(offset.left + dpWidth - viewWidth) : 0);
8405
                offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8406
                        Math.abs(dpHeight + inputHeight) : 0);
8407

    
8408
                return offset;
8409
        },
8410

    
8411
        /* Find an object's position on the screen. */
8412
        _findPos: function(obj) {
8413
                var position,
8414
                        inst = this._getInst(obj),
8415
                        isRTL = this._get(inst, "isRTL");
8416

    
8417
                while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
8418
                        obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8419
                }
8420

    
8421
                position = $(obj).offset();
8422
                return [position.left, position.top];
8423
        },
8424

    
8425
        /* Hide the date picker from view.
8426
         * @param  input  element - the input field attached to the date picker
8427
         */
8428
        _hideDatepicker: function(input) {
8429
                var showAnim, duration, postProcess, onClose,
8430
                        inst = this._curInst;
8431

    
8432
                if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
8433
                        return;
8434
                }
8435

    
8436
                if (this._datepickerShowing) {
8437
                        showAnim = this._get(inst, "showAnim");
8438
                        duration = this._get(inst, "duration");
8439
                        postProcess = function() {
8440
                                $.datepicker._tidyDialog(inst);
8441
                        };
8442

    
8443
                        // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8444
                        if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8445
                                inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8446
                        } else {
8447
                                inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8448
                                        (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8449
                        }
8450

    
8451
                        if (!showAnim) {
8452
                                postProcess();
8453
                        }
8454
                        this._datepickerShowing = false;
8455

    
8456
                        onClose = this._get(inst, "onClose");
8457
                        if (onClose) {
8458
                                onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8459
                        }
8460

    
8461
                        this._lastInput = null;
8462
                        if (this._inDialog) {
8463
                                this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8464
                                if ($.blockUI) {
8465
                                        $.unblockUI();
8466
                                        $("body").append(this.dpDiv);
8467
                                }
8468
                        }
8469
                        this._inDialog = false;
8470
                }
8471
        },
8472

    
8473
        /* Tidy up after a dialog display. */
8474
        _tidyDialog: function(inst) {
8475
                inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
8476
        },
8477

    
8478
        /* Close date picker if clicked elsewhere. */
8479
        _checkExternalClick: function(event) {
8480
                if (!$.datepicker._curInst) {
8481
                        return;
8482
                }
8483

    
8484
                var $target = $(event.target),
8485
                        inst = $.datepicker._getInst($target[0]);
8486

    
8487
                if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
8488
                                $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8489
                                !$target.hasClass($.datepicker.markerClassName) &&
8490
                                !$target.closest("." + $.datepicker._triggerClass).length &&
8491
                                $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8492
                        ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
8493
                                $.datepicker._hideDatepicker();
8494
                }
8495
        },
8496

    
8497
        /* Adjust one of the date sub-fields. */
8498
        _adjustDate: function(id, offset, period) {
8499
                var target = $(id),
8500
                        inst = this._getInst(target[0]);
8501

    
8502
                if (this._isDisabledDatepicker(target[0])) {
8503
                        return;
8504
                }
8505
                this._adjustInstDate(inst, offset +
8506
                        (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
8507
                        period);
8508
                this._updateDatepicker(inst);
8509
        },
8510

    
8511
        /* Action for current link. */
8512
        _gotoToday: function(id) {
8513
                var date,
8514
                        target = $(id),
8515
                        inst = this._getInst(target[0]);
8516

    
8517
                if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8518
                        inst.selectedDay = inst.currentDay;
8519
                        inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8520
                        inst.drawYear = inst.selectedYear = inst.currentYear;
8521
                } else {
8522
                        date = new Date();
8523
                        inst.selectedDay = date.getDate();
8524
                        inst.drawMonth = inst.selectedMonth = date.getMonth();
8525
                        inst.drawYear = inst.selectedYear = date.getFullYear();
8526
                }
8527
                this._notifyChange(inst);
8528
                this._adjustDate(target);
8529
        },
8530

    
8531
        /* Action for selecting a new month/year. */
8532
        _selectMonthYear: function(id, select, period) {
8533
                var target = $(id),
8534
                        inst = this._getInst(target[0]);
8535

    
8536
                inst["selected" + (period === "M" ? "Month" : "Year")] =
8537
                inst["draw" + (period === "M" ? "Month" : "Year")] =
8538
                        parseInt(select.options[select.selectedIndex].value,10);
8539

    
8540
                this._notifyChange(inst);
8541
                this._adjustDate(target);
8542
        },
8543

    
8544
        /* Action for selecting a day. */
8545
        _selectDay: function(id, month, year, td) {
8546
                var inst,
8547
                        target = $(id);
8548

    
8549
                if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8550
                        return;
8551
                }
8552

    
8553
                inst = this._getInst(target[0]);
8554
                inst.selectedDay = inst.currentDay = $("a", td).html();
8555
                inst.selectedMonth = inst.currentMonth = month;
8556
                inst.selectedYear = inst.currentYear = year;
8557
                this._selectDate(id, this._formatDate(inst,
8558
                        inst.currentDay, inst.currentMonth, inst.currentYear));
8559
        },
8560

    
8561
        /* Erase the input field and hide the date picker. */
8562
        _clearDate: function(id) {
8563
                var target = $(id);
8564
                this._selectDate(target, "");
8565
        },
8566

    
8567
        /* Update the input field with the selected date. */
8568
        _selectDate: function(id, dateStr) {
8569
                var onSelect,
8570
                        target = $(id),
8571
                        inst = this._getInst(target[0]);
8572

    
8573
                dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8574
                if (inst.input) {
8575
                        inst.input.val(dateStr);
8576
                }
8577
                this._updateAlternate(inst);
8578

    
8579
                onSelect = this._get(inst, "onSelect");
8580
                if (onSelect) {
8581
                        onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
8582
                } else if (inst.input) {
8583
                        inst.input.trigger("change"); // fire the change event
8584
                }
8585

    
8586
                if (inst.inline){
8587
                        this._updateDatepicker(inst);
8588
                } else {
8589
                        this._hideDatepicker();
8590
                        this._lastInput = inst.input[0];
8591
                        if (typeof(inst.input[0]) !== "object") {
8592
                                inst.input.focus(); // restore focus
8593
                        }
8594
                        this._lastInput = null;
8595
                }
8596
        },
8597

    
8598
        /* Update any alternate field to synchronise with the main field. */
8599
        _updateAlternate: function(inst) {
8600
                var altFormat, date, dateStr,
8601
                        altField = this._get(inst, "altField");
8602

    
8603
                if (altField) { // update alternate field too
8604
                        altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
8605
                        date = this._getDate(inst);
8606
                        dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8607
                        $(altField).each(function() { $(this).val(dateStr); });
8608
                }
8609
        },
8610

    
8611
        /* Set as beforeShowDay function to prevent selection of weekends.
8612
         * @param  date  Date - the date to customise
8613
         * @return [boolean, string] - is this date selectable?, what is its CSS class?
8614
         */
8615
        noWeekends: function(date) {
8616
                var day = date.getDay();
8617
                return [(day > 0 && day < 6), ""];
8618
        },
8619

    
8620
        /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8621
         * @param  date  Date - the date to get the week for
8622
         * @return  number - the number of the week within the year that contains this date
8623
         */
8624
        iso8601Week: function(date) {
8625
                var time,
8626
                        checkDate = new Date(date.getTime());
8627

    
8628
                // Find Thursday of this week starting on Monday
8629
                checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8630

    
8631
                time = checkDate.getTime();
8632
                checkDate.setMonth(0); // Compare with Jan 1
8633
                checkDate.setDate(1);
8634
                return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8635
        },
8636

    
8637
        /* Parse a string value into a date object.
8638
         * See formatDate below for the possible formats.
8639
         *
8640
         * @param  format string - the expected format of the date
8641
         * @param  value string - the date in the above format
8642
         * @param  settings Object - attributes include:
8643
         *                                        shortYearCutoff  number - the cutoff year for determining the century (optional)
8644
         *                                        dayNamesShort        string[7] - abbreviated names of the days from Sunday (optional)
8645
         *                                        dayNames                string[7] - names of the days from Sunday (optional)
8646
         *                                        monthNamesShort string[12] - abbreviated names of the months (optional)
8647
         *                                        monthNames                string[12] - names of the months (optional)
8648
         * @return  Date - the extracted date value or null if value is blank
8649
         */
8650
        parseDate: function (format, value, settings) {
8651
                if (format == null || value == null) {
8652
                        throw "Invalid arguments";
8653
                }
8654

    
8655
                value = (typeof value === "object" ? value.toString() : value + "");
8656
                if (value === "") {
8657
                        return null;
8658
                }
8659

    
8660
                var iFormat, dim, extra,
8661
                        iValue = 0,
8662
                        shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
8663
                        shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8664
                                new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
8665
                        dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8666
                        dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8667
                        monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8668
                        monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8669
                        year = -1,
8670
                        month = -1,
8671
                        day = -1,
8672
                        doy = -1,
8673
                        literal = false,
8674
                        date,
8675
                        // Check whether a format character is doubled
8676
                        lookAhead = function(match) {
8677
                                var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8678
                                if (matches) {
8679
                                        iFormat++;
8680
                                }
8681
                                return matches;
8682
                        },
8683
                        // Extract a number from the string value
8684
                        getNumber = function(match) {
8685
                                var isDoubled = lookAhead(match),
8686
                                        size = (match === "@" ? 14 : (match === "!" ? 20 :
8687
                                        (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
8688
                                        digits = new RegExp("^\\d{1," + size + "}"),
8689
                                        num = value.substring(iValue).match(digits);
8690
                                if (!num) {
8691
                                        throw "Missing number at position " + iValue;
8692
                                }
8693
                                iValue += num[0].length;
8694
                                return parseInt(num[0], 10);
8695
                        },
8696
                        // Extract a name from the string value and convert to an index
8697
                        getName = function(match, shortNames, longNames) {
8698
                                var index = -1,
8699
                                        names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8700
                                                return [ [k, v] ];
8701
                                        }).sort(function (a, b) {
8702
                                                return -(a[1].length - b[1].length);
8703
                                        });
8704

    
8705
                                $.each(names, function (i, pair) {
8706
                                        var name = pair[1];
8707
                                        if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
8708
                                                index = pair[0];
8709
                                                iValue += name.length;
8710
                                                return false;
8711
                                        }
8712
                                });
8713
                                if (index !== -1) {
8714
                                        return index + 1;
8715
                                } else {
8716
                                        throw "Unknown name at position " + iValue;
8717
                                }
8718
                        },
8719
                        // Confirm that a literal character matches the string value
8720
                        checkLiteral = function() {
8721
                                if (value.charAt(iValue) !== format.charAt(iFormat)) {
8722
                                        throw "Unexpected literal at position " + iValue;
8723
                                }
8724
                                iValue++;
8725
                        };
8726

    
8727
                for (iFormat = 0; iFormat < format.length; iFormat++) {
8728
                        if (literal) {
8729
                                if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8730
                                        literal = false;
8731
                                } else {
8732
                                        checkLiteral();
8733
                                }
8734
                        } else {
8735
                                switch (format.charAt(iFormat)) {
8736
                                        case "d":
8737
                                                day = getNumber("d");
8738
                                                break;
8739
                                        case "D":
8740
                                                getName("D", dayNamesShort, dayNames);
8741
                                                break;
8742
                                        case "o":
8743
                                                doy = getNumber("o");
8744
                                                break;
8745
                                        case "m":
8746
                                                month = getNumber("m");
8747
                                                break;
8748
                                        case "M":
8749
                                                month = getName("M", monthNamesShort, monthNames);
8750
                                                break;
8751
                                        case "y":
8752
                                                year = getNumber("y");
8753
                                                break;
8754
                                        case "@":
8755
                                                date = new Date(getNumber("@"));
8756
                                                year = date.getFullYear();
8757
                                                month = date.getMonth() + 1;
8758
                                                day = date.getDate();
8759
                                                break;
8760
                                        case "!":
8761
                                                date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
8762
                                                year = date.getFullYear();
8763
                                                month = date.getMonth() + 1;
8764
                                                day = date.getDate();
8765
                                                break;
8766
                                        case "'":
8767
                                                if (lookAhead("'")){
8768
                                                        checkLiteral();
8769
                                                } else {
8770
                                                        literal = true;
8771
                                                }
8772
                                                break;
8773
                                        default:
8774
                                                checkLiteral();
8775
                                }
8776
                        }
8777
                }
8778

    
8779
                if (iValue < value.length){
8780
                        extra = value.substr(iValue);
8781
                        if (!/^\s+/.test(extra)) {
8782
                                throw "Extra/unparsed characters found in date: " + extra;
8783
                        }
8784
                }
8785

    
8786
                if (year === -1) {
8787
                        year = new Date().getFullYear();
8788
                } else if (year < 100) {
8789
                        year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8790
                                (year <= shortYearCutoff ? 0 : -100);
8791
                }
8792

    
8793
                if (doy > -1) {
8794
                        month = 1;
8795
                        day = doy;
8796
                        do {
8797
                                dim = this._getDaysInMonth(year, month - 1);
8798
                                if (day <= dim) {
8799
                                        break;
8800
                                }
8801
                                month++;
8802
                                day -= dim;
8803
                        } while (true);
8804
                }
8805

    
8806
                date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8807
                if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
8808
                        throw "Invalid date"; // E.g. 31/02/00
8809
                }
8810
                return date;
8811
        },
8812

    
8813
        /* Standard date formats. */
8814
        ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8815
        COOKIE: "D, dd M yy",
8816
        ISO_8601: "yy-mm-dd",
8817
        RFC_822: "D, d M y",
8818
        RFC_850: "DD, dd-M-y",
8819
        RFC_1036: "D, d M y",
8820
        RFC_1123: "D, d M yy",
8821
        RFC_2822: "D, d M yy",
8822
        RSS: "D, d M y", // RFC 822
8823
        TICKS: "!",
8824
        TIMESTAMP: "@",
8825
        W3C: "yy-mm-dd", // ISO 8601
8826

    
8827
        _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8828
                Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8829

    
8830
        /* Format a date object into a string value.
8831
         * The format can be combinations of the following:
8832
         * d  - day of month (no leading zero)
8833
         * dd - day of month (two digit)
8834
         * o  - day of year (no leading zeros)
8835
         * oo - day of year (three digit)
8836
         * D  - day name short
8837
         * DD - day name long
8838
         * m  - month of year (no leading zero)
8839
         * mm - month of year (two digit)
8840
         * M  - month name short
8841
         * MM - month name long
8842
         * y  - year (two digit)
8843
         * yy - year (four digit)
8844
         * @ - Unix timestamp (ms since 01/01/1970)
8845
         * ! - Windows ticks (100ns since 01/01/0001)
8846
         * "..." - literal text
8847
         * '' - single quote
8848
         *
8849
         * @param  format string - the desired format of the date
8850
         * @param  date Date - the date value to format
8851
         * @param  settings Object - attributes include:
8852
         *                                        dayNamesShort        string[7] - abbreviated names of the days from Sunday (optional)
8853
         *                                        dayNames                string[7] - names of the days from Sunday (optional)
8854
         *                                        monthNamesShort string[12] - abbreviated names of the months (optional)
8855
         *                                        monthNames                string[12] - names of the months (optional)
8856
         * @return  string - the date in the above format
8857
         */
8858
        formatDate: function (format, date, settings) {
8859
                if (!date) {
8860
                        return "";
8861
                }
8862

    
8863
                var iFormat,
8864
                        dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8865
                        dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8866
                        monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8867
                        monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8868
                        // Check whether a format character is doubled
8869
                        lookAhead = function(match) {
8870
                                var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8871
                                if (matches) {
8872
                                        iFormat++;
8873
                                }
8874
                                return matches;
8875
                        },
8876
                        // Format a number, with leading zero if necessary
8877
                        formatNumber = function(match, value, len) {
8878
                                var num = "" + value;
8879
                                if (lookAhead(match)) {
8880
                                        while (num.length < len) {
8881
                                                num = "0" + num;
8882
                                        }
8883
                                }
8884
                                return num;
8885
                        },
8886
                        // Format a name, short or long as requested
8887
                        formatName = function(match, value, shortNames, longNames) {
8888
                                return (lookAhead(match) ? longNames[value] : shortNames[value]);
8889
                        },
8890
                        output = "",
8891
                        literal = false;
8892

    
8893
                if (date) {
8894
                        for (iFormat = 0; iFormat < format.length; iFormat++) {
8895
                                if (literal) {
8896
                                        if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8897
                                                literal = false;
8898
                                        } else {
8899
                                                output += format.charAt(iFormat);
8900
                                        }
8901
                                } else {
8902
                                        switch (format.charAt(iFormat)) {
8903
                                                case "d":
8904
                                                        output += formatNumber("d", date.getDate(), 2);
8905
                                                        break;
8906
                                                case "D":
8907
                                                        output += formatName("D", date.getDay(), dayNamesShort, dayNames);
8908
                                                        break;
8909
                                                case "o":
8910
                                                        output += formatNumber("o",
8911
                                                                Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8912
                                                        break;
8913
                                                case "m":
8914
                                                        output += formatNumber("m", date.getMonth() + 1, 2);
8915
                                                        break;
8916
                                                case "M":
8917
                                                        output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
8918
                                                        break;
8919
                                                case "y":
8920
                                                        output += (lookAhead("y") ? date.getFullYear() :
8921
                                                                (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
8922
                                                        break;
8923
                                                case "@":
8924
                                                        output += date.getTime();
8925
                                                        break;
8926
                                                case "!":
8927
                                                        output += date.getTime() * 10000 + this._ticksTo1970;
8928
                                                        break;
8929
                                                case "'":
8930
                                                        if (lookAhead("'")) {
8931
                                                                output += "'";
8932
                                                        } else {
8933
                                                                literal = true;
8934
                                                        }
8935
                                                        break;
8936
                                                default:
8937
                                                        output += format.charAt(iFormat);
8938
                                        }
8939
                                }
8940
                        }
8941
                }
8942
                return output;
8943
        },
8944

    
8945
        /* Extract all possible characters from the date format. */
8946
        _possibleChars: function (format) {
8947
                var iFormat,
8948
                        chars = "",
8949
                        literal = false,
8950
                        // Check whether a format character is doubled
8951
                        lookAhead = function(match) {
8952
                                var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8953
                                if (matches) {
8954
                                        iFormat++;
8955
                                }
8956
                                return matches;
8957
                        };
8958

    
8959
                for (iFormat = 0; iFormat < format.length; iFormat++) {
8960
                        if (literal) {
8961
                                if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8962
                                        literal = false;
8963
                                } else {
8964
                                        chars += format.charAt(iFormat);
8965
                                }
8966
                        } else {
8967
                                switch (format.charAt(iFormat)) {
8968
                                        case "d": case "m": case "y": case "@":
8969
                                                chars += "0123456789";
8970
                                                break;
8971
                                        case "D": case "M":
8972
                                                return null; // Accept anything
8973
                                        case "'":
8974
                                                if (lookAhead("'")) {
8975
                                                        chars += "'";
8976
                                                } else {
8977
                                                        literal = true;
8978
                                                }
8979
                                                break;
8980
                                        default:
8981
                                                chars += format.charAt(iFormat);
8982
                                }
8983
                        }
8984
                }
8985
                return chars;
8986
        },
8987

    
8988
        /* Get a setting value, defaulting if necessary. */
8989
        _get: function(inst, name) {
8990
                return inst.settings[name] !== undefined ?
8991
                        inst.settings[name] : this._defaults[name];
8992
        },
8993

    
8994
        /* Parse existing date and initialise date picker. */
8995
        _setDateFromField: function(inst, noDefault) {
8996
                if (inst.input.val() === inst.lastVal) {
8997
                        return;
8998
                }
8999

    
9000
                var dateFormat = this._get(inst, "dateFormat"),
9001
                        dates = inst.lastVal = inst.input ? inst.input.val() : null,
9002
                        defaultDate = this._getDefaultDate(inst),
9003
                        date = defaultDate,
9004
                        settings = this._getFormatConfig(inst);
9005

    
9006
                try {
9007
                        date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9008
                } catch (event) {
9009
                        dates = (noDefault ? "" : dates);
9010
                }
9011
                inst.selectedDay = date.getDate();
9012
                inst.drawMonth = inst.selectedMonth = date.getMonth();
9013
                inst.drawYear = inst.selectedYear = date.getFullYear();
9014
                inst.currentDay = (dates ? date.getDate() : 0);
9015
                inst.currentMonth = (dates ? date.getMonth() : 0);
9016
                inst.currentYear = (dates ? date.getFullYear() : 0);
9017
                this._adjustInstDate(inst);
9018
        },
9019

    
9020
        /* Retrieve the default date shown on opening. */
9021
        _getDefaultDate: function(inst) {
9022
                return this._restrictMinMax(inst,
9023
                        this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
9024
        },
9025

    
9026
        /* A date may be specified as an exact value or a relative one. */
9027
        _determineDate: function(inst, date, defaultDate) {
9028
                var offsetNumeric = function(offset) {
9029
                                var date = new Date();
9030
                                date.setDate(date.getDate() + offset);
9031
                                return date;
9032
                        },
9033
                        offsetString = function(offset) {
9034
                                try {
9035
                                        return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
9036
                                                offset, $.datepicker._getFormatConfig(inst));
9037
                                }
9038
                                catch (e) {
9039
                                        // Ignore
9040
                                }
9041

    
9042
                                var date = (offset.toLowerCase().match(/^c/) ?
9043
                                        $.datepicker._getDate(inst) : null) || new Date(),
9044
                                        year = date.getFullYear(),
9045
                                        month = date.getMonth(),
9046
                                        day = date.getDate(),
9047
                                        pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
9048
                                        matches = pattern.exec(offset);
9049

    
9050
                                while (matches) {
9051
                                        switch (matches[2] || "d") {
9052
                                                case "d" : case "D" :
9053
                                                        day += parseInt(matches[1],10); break;
9054
                                                case "w" : case "W" :
9055
                                                        day += parseInt(matches[1],10) * 7; break;
9056
                                                case "m" : case "M" :
9057
                                                        month += parseInt(matches[1],10);
9058
                                                        day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9059
                                                        break;
9060
                                                case "y": case "Y" :
9061
                                                        year += parseInt(matches[1],10);
9062
                                                        day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9063
                                                        break;
9064
                                        }
9065
                                        matches = pattern.exec(offset);
9066
                                }
9067
                                return new Date(year, month, day);
9068
                        },
9069
                        newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
9070
                                (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9071

    
9072
                newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
9073
                if (newDate) {
9074
                        newDate.setHours(0);
9075
                        newDate.setMinutes(0);
9076
                        newDate.setSeconds(0);
9077
                        newDate.setMilliseconds(0);
9078
                }
9079
                return this._daylightSavingAdjust(newDate);
9080
        },
9081

    
9082
        /* Handle switch to/from daylight saving.
9083
         * Hours may be non-zero on daylight saving cut-over:
9084
         * > 12 when midnight changeover, but then cannot generate
9085
         * midnight datetime, so jump to 1AM, otherwise reset.
9086
         * @param  date  (Date) the date to check
9087
         * @return  (Date) the corrected date
9088
         */
9089
        _daylightSavingAdjust: function(date) {
9090
                if (!date) {
9091
                        return null;
9092
                }
9093
                date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9094
                return date;
9095
        },
9096

    
9097
        /* Set the date(s) directly. */
9098
        _setDate: function(inst, date, noChange) {
9099
                var clear = !date,
9100
                        origMonth = inst.selectedMonth,
9101
                        origYear = inst.selectedYear,
9102
                        newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9103

    
9104
                inst.selectedDay = inst.currentDay = newDate.getDate();
9105
                inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9106
                inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9107
                if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
9108
                        this._notifyChange(inst);
9109
                }
9110
                this._adjustInstDate(inst);
9111
                if (inst.input) {
9112
                        inst.input.val(clear ? "" : this._formatDate(inst));
9113
                }
9114
        },
9115

    
9116
        /* Retrieve the date(s) directly. */
9117
        _getDate: function(inst) {
9118
                var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
9119
                        this._daylightSavingAdjust(new Date(
9120
                        inst.currentYear, inst.currentMonth, inst.currentDay)));
9121
                        return startDate;
9122
        },
9123

    
9124
        /* Attach the onxxx handlers.  These are declared statically so
9125
         * they work with static code transformers like Caja.
9126
         */
9127
        _attachHandlers: function(inst) {
9128
                var stepMonths = this._get(inst, "stepMonths"),
9129
                        id = "#" + inst.id.replace( /\\\\/g, "\\" );
9130
                inst.dpDiv.find("[data-handler]").map(function () {
9131
                        var handler = {
9132
                                prev: function () {
9133
                                        window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, -stepMonths, "M");
9134
                                },
9135
                                next: function () {
9136
                                        window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, +stepMonths, "M");
9137
                                },
9138
                                hide: function () {
9139
                                        window["DP_jQuery_" + dpuuid].datepicker._hideDatepicker();
9140
                                },
9141
                                today: function () {
9142
                                        window["DP_jQuery_" + dpuuid].datepicker._gotoToday(id);
9143
                                },
9144
                                selectDay: function () {
9145
                                        window["DP_jQuery_" + dpuuid].datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
9146
                                        return false;
9147
                                },
9148
                                selectMonth: function () {
9149
                                        window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "M");
9150
                                        return false;
9151
                                },
9152
                                selectYear: function () {
9153
                                        window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "Y");
9154
                                        return false;
9155
                                }
9156
                        };
9157
                        $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
9158
                });
9159
        },
9160

    
9161
        /* Generate the HTML for the current state of the date picker. */
9162
        _generateHTML: function(inst) {
9163
                var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
9164
                        controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
9165
                        monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
9166
                        selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
9167
                        cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
9168
                        printDate, dRow, tbody, daySettings, otherMonth, unselectable,
9169
                        tempDate = new Date(),
9170
                        today = this._daylightSavingAdjust(
9171
                                new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
9172
                        isRTL = this._get(inst, "isRTL"),
9173
                        showButtonPanel = this._get(inst, "showButtonPanel"),
9174
                        hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
9175
                        navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
9176
                        numMonths = this._getNumberOfMonths(inst),
9177
                        showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
9178
                        stepMonths = this._get(inst, "stepMonths"),
9179
                        isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
9180
                        currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9181
                                new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
9182
                        minDate = this._getMinMaxDate(inst, "min"),
9183
                        maxDate = this._getMinMaxDate(inst, "max"),
9184
                        drawMonth = inst.drawMonth - showCurrentAtPos,
9185
                        drawYear = inst.drawYear;
9186

    
9187
                if (drawMonth < 0) {
9188
                        drawMonth += 12;
9189
                        drawYear--;
9190
                }
9191
                if (maxDate) {
9192
                        maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9193
                                maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9194
                        maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9195
                        while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9196
                                drawMonth--;
9197
                                if (drawMonth < 0) {
9198
                                        drawMonth = 11;
9199
                                        drawYear--;
9200
                                }
9201
                        }
9202
                }
9203
                inst.drawMonth = drawMonth;
9204
                inst.drawYear = drawYear;
9205

    
9206
                prevText = this._get(inst, "prevText");
9207
                prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9208
                        this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9209
                        this._getFormatConfig(inst)));
9210

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

    
9216
                nextText = this._get(inst, "nextText");
9217
                nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9218
                        this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9219
                        this._getFormatConfig(inst)));
9220

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

    
9226
                currentText = this._get(inst, "currentText");
9227
                gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
9228
                currentText = (!navigationAsDateFormat ? currentText :
9229
                        this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9230

    
9231
                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'>" +
9232
                        this._get(inst, "closeText") + "</button>" : "");
9233

    
9234
                buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
9235
                        (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'" +
9236
                        ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
9237

    
9238
                firstDay = parseInt(this._get(inst, "firstDay"),10);
9239
                firstDay = (isNaN(firstDay) ? 0 : firstDay);
9240

    
9241
                showWeek = this._get(inst, "showWeek");
9242
                dayNames = this._get(inst, "dayNames");
9243
                dayNamesMin = this._get(inst, "dayNamesMin");
9244
                monthNames = this._get(inst, "monthNames");
9245
                monthNamesShort = this._get(inst, "monthNamesShort");
9246
                beforeShowDay = this._get(inst, "beforeShowDay");
9247
                showOtherMonths = this._get(inst, "showOtherMonths");
9248
                selectOtherMonths = this._get(inst, "selectOtherMonths");
9249
                defaultDate = this._getDefaultDate(inst);
9250
                html = "";
9251
                dow;
9252
                for (row = 0; row < numMonths[0]; row++) {
9253
                        group = "";
9254
                        this.maxRows = 4;
9255
                        for (col = 0; col < numMonths[1]; col++) {
9256
                                selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9257
                                cornerClass = " ui-corner-all";
9258
                                calender = "";
9259
                                if (isMultiMonth) {
9260
                                        calender += "<div class='ui-datepicker-group";
9261
                                        if (numMonths[1] > 1) {
9262
                                                switch (col) {
9263
                                                        case 0: calender += " ui-datepicker-group-first";
9264
                                                                cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
9265
                                                        case numMonths[1]-1: calender += " ui-datepicker-group-last";
9266
                                                                cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
9267
                                                        default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9268
                                                }
9269
                                        }
9270
                                        calender += "'>";
9271
                                }
9272
                                calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9273
                                        (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
9274
                                        (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
9275
                                        this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9276
                                        row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9277
                                        "</div><table class='ui-datepicker-calendar'><thead>" +
9278
                                        "<tr>";
9279
                                thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
9280
                                for (dow = 0; dow < 7; dow++) { // days of the week
9281
                                        day = (dow + firstDay) % 7;
9282
                                        thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
9283
                                                "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
9284
                                }
9285
                                calender += thead + "</tr></thead><tbody>";
9286
                                daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9287
                                if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9288
                                        inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9289
                                }
9290
                                leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9291
                                curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9292
                                numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9293
                                this.maxRows = numRows;
9294
                                printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9295
                                for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9296
                                        calender += "<tr>";
9297
                                        tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9298
                                                this._get(inst, "calculateWeek")(printDate) + "</td>");
9299
                                        for (dow = 0; dow < 7; dow++) { // create date picker days
9300
                                                daySettings = (beforeShowDay ?
9301
                                                        beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9302
                                                otherMonth = (printDate.getMonth() !== drawMonth);
9303
                                                unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9304
                                                        (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9305
                                                tbody += "<td class='" +
9306
                                                        ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9307
                                                        (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9308
                                                        ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9309
                                                        (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9310
                                                        // or defaultDate is current printedDate and defaultDate is selectedDate
9311
                                                        " " + this._dayOverClass : "") + // highlight selected day
9312
                                                        (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
9313
                                                        (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9314
                                                        (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9315
                                                        (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9316
                                                        ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9317
                                                        (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9318
                                                        (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9319
                                                        (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9320
                                                        (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9321
                                                        (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9322
                                                        (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9323
                                                        "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9324
                                                printDate.setDate(printDate.getDate() + 1);
9325
                                                printDate = this._daylightSavingAdjust(printDate);
9326
                                        }
9327
                                        calender += tbody + "</tr>";
9328
                                }
9329
                                drawMonth++;
9330
                                if (drawMonth > 11) {
9331
                                        drawMonth = 0;
9332
                                        drawYear++;
9333
                                }
9334
                                calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9335
                                                        ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9336
                                group += calender;
9337
                        }
9338
                        html += group;
9339
                }
9340
                html += buttonPanel;
9341
                inst._keyEvent = false;
9342
                return html;
9343
        },
9344

    
9345
        /* Generate the month and year header. */
9346
        _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9347
                        secondary, monthNames, monthNamesShort) {
9348

    
9349
                var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9350
                        changeMonth = this._get(inst, "changeMonth"),
9351
                        changeYear = this._get(inst, "changeYear"),
9352
                        showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9353
                        html = "<div class='ui-datepicker-title'>",
9354
                        monthHtml = "";
9355

    
9356
                // month selection
9357
                if (secondary || !changeMonth) {
9358
                        monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9359
                } else {
9360
                        inMinYear = (minDate && minDate.getFullYear() === drawYear);
9361
                        inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9362
                        monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9363
                        for ( month = 0; month < 12; month++) {
9364
                                if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9365
                                        monthHtml += "<option value='" + month + "'" +
9366
                                                (month === drawMonth ? " selected='selected'" : "") +
9367
                                                ">" + monthNamesShort[month] + "</option>";
9368
                                }
9369
                        }
9370
                        monthHtml += "</select>";
9371
                }
9372

    
9373
                if (!showMonthAfterYear) {
9374
                        html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9375
                }
9376

    
9377
                // year selection
9378
                if ( !inst.yearshtml ) {
9379
                        inst.yearshtml = "";
9380
                        if (secondary || !changeYear) {
9381
                                html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9382
                        } else {
9383
                                // determine range of years to display
9384
                                years = this._get(inst, "yearRange").split(":");
9385
                                thisYear = new Date().getFullYear();
9386
                                determineYear = function(value) {
9387
                                        var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9388
                                                (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9389
                                                parseInt(value, 10)));
9390
                                        return (isNaN(year) ? thisYear : year);
9391
                                };
9392
                                year = determineYear(years[0]);
9393
                                endYear = Math.max(year, determineYear(years[1] || ""));
9394
                                year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9395
                                endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9396
                                inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9397
                                for (; year <= endYear; year++) {
9398
                                        inst.yearshtml += "<option value='" + year + "'" +
9399
                                                (year === drawYear ? " selected='selected'" : "") +
9400
                                                ">" + year + "</option>";
9401
                                }
9402
                                inst.yearshtml += "</select>";
9403

    
9404
                                html += inst.yearshtml;
9405
                                inst.yearshtml = null;
9406
                        }
9407
                }
9408

    
9409
                html += this._get(inst, "yearSuffix");
9410
                if (showMonthAfterYear) {
9411
                        html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9412
                }
9413
                html += "</div>"; // Close datepicker_header
9414
                return html;
9415
        },
9416

    
9417
        /* Adjust one of the date sub-fields. */
9418
        _adjustInstDate: function(inst, offset, period) {
9419
                var year = inst.drawYear + (period === "Y" ? offset : 0),
9420
                        month = inst.drawMonth + (period === "M" ? offset : 0),
9421
                        day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9422
                        date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9423

    
9424
                inst.selectedDay = date.getDate();
9425
                inst.drawMonth = inst.selectedMonth = date.getMonth();
9426
                inst.drawYear = inst.selectedYear = date.getFullYear();
9427
                if (period === "M" || period === "Y") {
9428
                        this._notifyChange(inst);
9429
                }
9430
        },
9431

    
9432
        /* Ensure a date is within any min/max bounds. */
9433
        _restrictMinMax: function(inst, date) {
9434
                var minDate = this._getMinMaxDate(inst, "min"),
9435
                        maxDate = this._getMinMaxDate(inst, "max"),
9436
                        newDate = (minDate && date < minDate ? minDate : date);
9437
                return (maxDate && newDate > maxDate ? maxDate : newDate);
9438
        },
9439

    
9440
        /* Notify change of month/year. */
9441
        _notifyChange: function(inst) {
9442
                var onChange = this._get(inst, "onChangeMonthYear");
9443
                if (onChange) {
9444
                        onChange.apply((inst.input ? inst.input[0] : null),
9445
                                [inst.selectedYear, inst.selectedMonth + 1, inst]);
9446
                }
9447
        },
9448

    
9449
        /* Determine the number of months to show. */
9450
        _getNumberOfMonths: function(inst) {
9451
                var numMonths = this._get(inst, "numberOfMonths");
9452
                return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9453
        },
9454

    
9455
        /* Determine the current maximum date - ensure no time components are set. */
9456
        _getMinMaxDate: function(inst, minMax) {
9457
                return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9458
        },
9459

    
9460
        /* Find the number of days in a given month. */
9461
        _getDaysInMonth: function(year, month) {
9462
                return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9463
        },
9464

    
9465
        /* Find the day of the week of the first of a month. */
9466
        _getFirstDayOfMonth: function(year, month) {
9467
                return new Date(year, month, 1).getDay();
9468
        },
9469

    
9470
        /* Determines if we should allow a "next/prev" month display change. */
9471
        _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9472
                var numMonths = this._getNumberOfMonths(inst),
9473
                        date = this._daylightSavingAdjust(new Date(curYear,
9474
                        curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9475

    
9476
                if (offset < 0) {
9477
                        date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9478
                }
9479
                return this._isInRange(inst, date);
9480
        },
9481

    
9482
        /* Is the given date in the accepted range? */
9483
        _isInRange: function(inst, date) {
9484
                var yearSplit, currentYear,
9485
                        minDate = this._getMinMaxDate(inst, "min"),
9486
                        maxDate = this._getMinMaxDate(inst, "max"),
9487
                        minYear = null,
9488
                        maxYear = null,
9489
                        years = this._get(inst, "yearRange");
9490
                        if (years){
9491
                                yearSplit = years.split(":");
9492
                                currentYear = new Date().getFullYear();
9493
                                minYear = parseInt(yearSplit[0], 10);
9494
                                maxYear = parseInt(yearSplit[1], 10);
9495
                                if ( yearSplit[0].match(/[+\-].*/) ) {
9496
                                        minYear += currentYear;
9497
                                }
9498
                                if ( yearSplit[1].match(/[+\-].*/) ) {
9499
                                        maxYear += currentYear;
9500
                                }
9501
                        }
9502

    
9503
                return ((!minDate || date.getTime() >= minDate.getTime()) &&
9504
                        (!maxDate || date.getTime() <= maxDate.getTime()) &&
9505
                        (!minYear || date.getFullYear() >= minYear) &&
9506
                        (!maxYear || date.getFullYear() <= maxYear));
9507
        },
9508

    
9509
        /* Provide the configuration settings for formatting/parsing. */
9510
        _getFormatConfig: function(inst) {
9511
                var shortYearCutoff = this._get(inst, "shortYearCutoff");
9512
                shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9513
                        new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9514
                return {shortYearCutoff: shortYearCutoff,
9515
                        dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9516
                        monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
9517
        },
9518

    
9519
        /* Format the given date for display. */
9520
        _formatDate: function(inst, day, month, year) {
9521
                if (!day) {
9522
                        inst.currentDay = inst.selectedDay;
9523
                        inst.currentMonth = inst.selectedMonth;
9524
                        inst.currentYear = inst.selectedYear;
9525
                }
9526
                var date = (day ? (typeof day === "object" ? day :
9527
                        this._daylightSavingAdjust(new Date(year, month, day))) :
9528
                        this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9529
                return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9530
        }
9531
});
9532

    
9533
/*
9534
 * Bind hover events for datepicker elements.
9535
 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9536
 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9537
 */
9538
function bindHover(dpDiv) {
9539
        var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9540
        return dpDiv.delegate(selector, "mouseout", function() {
9541
                        $(this).removeClass("ui-state-hover");
9542
                        if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9543
                                $(this).removeClass("ui-datepicker-prev-hover");
9544
                        }
9545
                        if (this.className.indexOf("ui-datepicker-next") !== -1) {
9546
                                $(this).removeClass("ui-datepicker-next-hover");
9547
                        }
9548
                })
9549
                .delegate(selector, "mouseover", function(){
9550
                        if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
9551
                                $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
9552
                                $(this).addClass("ui-state-hover");
9553
                                if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9554
                                        $(this).addClass("ui-datepicker-prev-hover");
9555
                                }
9556
                                if (this.className.indexOf("ui-datepicker-next") !== -1) {
9557
                                        $(this).addClass("ui-datepicker-next-hover");
9558
                                }
9559
                        }
9560
                });
9561
}
9562

    
9563
/* jQuery extend now ignores nulls! */
9564
function extendRemove(target, props) {
9565
        $.extend(target, props);
9566
        for (var name in props) {
9567
                if (props[name] == null) {
9568
                        target[name] = props[name];
9569
                }
9570
        }
9571
        return target;
9572
}
9573

    
9574
/* Invoke the datepicker functionality.
9575
   @param  options  string - a command, optionally followed by additional parameters or
9576
                                        Object - settings for attaching new datepicker functionality
9577
   @return  jQuery object */
9578
$.fn.datepicker = function(options){
9579

    
9580
        /* Verify an empty collection wasn't passed - Fixes #6976 */
9581
        if ( !this.length ) {
9582
                return this;
9583
        }
9584

    
9585
        /* Initialise the date picker. */
9586
        if (!$.datepicker.initialized) {
9587
                $(document).mousedown($.datepicker._checkExternalClick);
9588
                $.datepicker.initialized = true;
9589
        }
9590

    
9591
        /* Append datepicker main container to body if not exist. */
9592
        if ($("#"+$.datepicker._mainDivId).length === 0) {
9593
                $("body").append($.datepicker.dpDiv);
9594
        }
9595

    
9596
        var otherArgs = Array.prototype.slice.call(arguments, 1);
9597
        if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
9598
                return $.datepicker["_" + options + "Datepicker"].
9599
                        apply($.datepicker, [this[0]].concat(otherArgs));
9600
        }
9601
        if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
9602
                return $.datepicker["_" + options + "Datepicker"].
9603
                        apply($.datepicker, [this[0]].concat(otherArgs));
9604
        }
9605
        return this.each(function() {
9606
                typeof options === "string" ?
9607
                        $.datepicker["_" + options + "Datepicker"].
9608
                                apply($.datepicker, [this].concat(otherArgs)) :
9609
                        $.datepicker._attachDatepicker(this, options);
9610
        });
9611
};
9612

    
9613
$.datepicker = new Datepicker(); // singleton instance
9614
$.datepicker.initialized = false;
9615
$.datepicker.uuid = new Date().getTime();
9616
$.datepicker.version = "1.10.2";
9617

    
9618
// Workaround for #4055
9619
// Add another global to avoid noConflict issues with inline event handlers
9620
window["DP_jQuery_" + dpuuid] = $;
9621

    
9622
})(jQuery);
9623

    
9624
(function( $, undefined ) {
9625

    
9626
var sizeRelatedOptions = {
9627
                buttons: true,
9628
                height: true,
9629
                maxHeight: true,
9630
                maxWidth: true,
9631
                minHeight: true,
9632
                minWidth: true,
9633
                width: true
9634
        },
9635
        resizableRelatedOptions = {
9636
                maxHeight: true,
9637
                maxWidth: true,
9638
                minHeight: true,
9639
                minWidth: true
9640
        };
9641

    
9642
$.widget( "ui.dialog", {
9643
        version: "1.10.2",
9644
        options: {
9645
                appendTo: "body",
9646
                autoOpen: true,
9647
                buttons: [],
9648
                closeOnEscape: true,
9649
                closeText: "close",
9650
                dialogClass: "",
9651
                draggable: true,
9652
                hide: null,
9653
                height: "auto",
9654
                maxHeight: null,
9655
                maxWidth: null,
9656
                minHeight: 150,
9657
                minWidth: 150,
9658
                modal: false,
9659
                position: {
9660
                        my: "center",
9661
                        at: "center",
9662
                        of: window,
9663
                        collision: "fit",
9664
                        // Ensure the titlebar is always visible
9665
                        using: function( pos ) {
9666
                                var topOffset = $( this ).css( pos ).offset().top;
9667
                                if ( topOffset < 0 ) {
9668
                                        $( this ).css( "top", pos.top - topOffset );
9669
                                }
9670
                        }
9671
                },
9672
                resizable: true,
9673
                show: null,
9674
                title: null,
9675
                width: 300,
9676

    
9677
                // callbacks
9678
                beforeClose: null,
9679
                close: null,
9680
                drag: null,
9681
                dragStart: null,
9682
                dragStop: null,
9683
                focus: null,
9684
                open: null,
9685
                resize: null,
9686
                resizeStart: null,
9687
                resizeStop: null
9688
        },
9689

    
9690
        _create: function() {
9691
                this.originalCss = {
9692
                        display: this.element[0].style.display,
9693
                        width: this.element[0].style.width,
9694
                        minHeight: this.element[0].style.minHeight,
9695
                        maxHeight: this.element[0].style.maxHeight,
9696
                        height: this.element[0].style.height
9697
                };
9698
                this.originalPosition = {
9699
                        parent: this.element.parent(),
9700
                        index: this.element.parent().children().index( this.element )
9701
                };
9702
                this.originalTitle = this.element.attr("title");
9703
                this.options.title = this.options.title || this.originalTitle;
9704

    
9705
                this._createWrapper();
9706

    
9707
                this.element
9708
                        .show()
9709
                        .removeAttr("title")
9710
                        .addClass("ui-dialog-content ui-widget-content")
9711
                        .appendTo( this.uiDialog );
9712

    
9713
                this._createTitlebar();
9714
                this._createButtonPane();
9715

    
9716
                if ( this.options.draggable && $.fn.draggable ) {
9717
                        this._makeDraggable();
9718
                }
9719
                if ( this.options.resizable && $.fn.resizable ) {
9720
                        this._makeResizable();
9721
                }
9722

    
9723
                this._isOpen = false;
9724
        },
9725

    
9726
        _init: function() {
9727
                if ( this.options.autoOpen ) {
9728
                        this.open();
9729
                }
9730
        },
9731

    
9732
        _appendTo: function() {
9733
                var element = this.options.appendTo;
9734
                if ( element && (element.jquery || element.nodeType) ) {
9735
                        return $( element );
9736
                }
9737
                return this.document.find( element || "body" ).eq( 0 );
9738
        },
9739

    
9740
        _destroy: function() {
9741
                var next,
9742
                        originalPosition = this.originalPosition;
9743

    
9744
                this._destroyOverlay();
9745

    
9746
                this.element
9747
                        .removeUniqueId()
9748
                        .removeClass("ui-dialog-content ui-widget-content")
9749
                        .css( this.originalCss )
9750
                        // Without detaching first, the following becomes really slow
9751
                        .detach();
9752

    
9753
                this.uiDialog.stop( true, true ).remove();
9754

    
9755
                if ( this.originalTitle ) {
9756
                        this.element.attr( "title", this.originalTitle );
9757
                }
9758

    
9759
                next = originalPosition.parent.children().eq( originalPosition.index );
9760
                // Don't try to place the dialog next to itself (#8613)
9761
                if ( next.length && next[0] !== this.element[0] ) {
9762
                        next.before( this.element );
9763
                } else {
9764
                        originalPosition.parent.append( this.element );
9765
                }
9766
        },
9767

    
9768
        widget: function() {
9769
                return this.uiDialog;
9770
        },
9771

    
9772
        disable: $.noop,
9773
        enable: $.noop,
9774

    
9775
        close: function( event ) {
9776
                var that = this;
9777

    
9778
                if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
9779
                        return;
9780
                }
9781

    
9782
                this._isOpen = false;
9783
                this._destroyOverlay();
9784

    
9785
                if ( !this.opener.filter(":focusable").focus().length ) {
9786
                        // Hiding a focused element doesn't trigger blur in WebKit
9787
                        // so in case we have nothing to focus on, explicitly blur the active element
9788
                        // https://bugs.webkit.org/show_bug.cgi?id=47182
9789
                        $( this.document[0].activeElement ).blur();
9790
                }
9791

    
9792
                this._hide( this.uiDialog, this.options.hide, function() {
9793
                        that._trigger( "close", event );
9794
                });
9795
        },
9796

    
9797
        isOpen: function() {
9798
                return this._isOpen;
9799
        },
9800

    
9801
        moveToTop: function() {
9802
                this._moveToTop();
9803
        },
9804

    
9805
        _moveToTop: function( event, silent ) {
9806
                var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
9807
                if ( moved && !silent ) {
9808
                        this._trigger( "focus", event );
9809
                }
9810
                return moved;
9811
        },
9812

    
9813
        open: function() {
9814
                var that = this;
9815
                if ( this._isOpen ) {
9816
                        if ( this._moveToTop() ) {
9817
                                this._focusTabbable();
9818
                        }
9819
                        return;
9820
                }
9821

    
9822
                this._isOpen = true;
9823
                this.opener = $( this.document[0].activeElement );
9824

    
9825
                this._size();
9826
                this._position();
9827
                this._createOverlay();
9828
                this._moveToTop( null, true );
9829
                this._show( this.uiDialog, this.options.show, function() {
9830
                        that._focusTabbable();
9831
                        that._trigger("focus");
9832
                });
9833

    
9834
                this._trigger("open");
9835
        },
9836

    
9837
        _focusTabbable: function() {
9838
                // Set focus to the first match:
9839
                // 1. First element inside the dialog matching [autofocus]
9840
                // 2. Tabbable element inside the content element
9841
                // 3. Tabbable element inside the buttonpane
9842
                // 4. The close button
9843
                // 5. The dialog itself
9844
                var hasFocus = this.element.find("[autofocus]");
9845
                if ( !hasFocus.length ) {
9846
                        hasFocus = this.element.find(":tabbable");
9847
                }
9848
                if ( !hasFocus.length ) {
9849
                        hasFocus = this.uiDialogButtonPane.find(":tabbable");
9850
                }
9851
                if ( !hasFocus.length ) {
9852
                        hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
9853
                }
9854
                if ( !hasFocus.length ) {
9855
                        hasFocus = this.uiDialog;
9856
                }
9857
                hasFocus.eq( 0 ).focus();
9858
        },
9859

    
9860
        _keepFocus: function( event ) {
9861
                function checkFocus() {
9862
                        var activeElement = this.document[0].activeElement,
9863
                                isActive = this.uiDialog[0] === activeElement ||
9864
                                        $.contains( this.uiDialog[0], activeElement );
9865
                        if ( !isActive ) {
9866
                                this._focusTabbable();
9867
                        }
9868
                }
9869
                event.preventDefault();
9870
                checkFocus.call( this );
9871
                // support: IE
9872
                // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
9873
                // so we check again later
9874
                this._delay( checkFocus );
9875
        },
9876

    
9877
        _createWrapper: function() {
9878
                this.uiDialog = $("<div>")
9879
                        .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
9880
                                this.options.dialogClass )
9881
                        .hide()
9882
                        .attr({
9883
                                // Setting tabIndex makes the div focusable
9884
                                tabIndex: -1,
9885
                                role: "dialog"
9886
                        })
9887
                        .appendTo( this._appendTo() );
9888

    
9889
                this._on( this.uiDialog, {
9890
                        keydown: function( event ) {
9891
                                if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9892
                                                event.keyCode === $.ui.keyCode.ESCAPE ) {
9893
                                        event.preventDefault();
9894
                                        this.close( event );
9895
                                        return;
9896
                                }
9897

    
9898
                                // prevent tabbing out of dialogs
9899
                                if ( event.keyCode !== $.ui.keyCode.TAB ) {
9900
                                        return;
9901
                                }
9902
                                var tabbables = this.uiDialog.find(":tabbable"),
9903
                                        first = tabbables.filter(":first"),
9904
                                        last  = tabbables.filter(":last");
9905

    
9906
                                if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
9907
                                        first.focus( 1 );
9908
                                        event.preventDefault();
9909
                                } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
9910
                                        last.focus( 1 );
9911
                                        event.preventDefault();
9912
                                }
9913
                        },
9914
                        mousedown: function( event ) {
9915
                                if ( this._moveToTop( event ) ) {
9916
                                        this._focusTabbable();
9917
                                }
9918
                        }
9919
                });
9920

    
9921
                // We assume that any existing aria-describedby attribute means
9922
                // that the dialog content is marked up properly
9923
                // otherwise we brute force the content as the description
9924
                if ( !this.element.find("[aria-describedby]").length ) {
9925
                        this.uiDialog.attr({
9926
                                "aria-describedby": this.element.uniqueId().attr("id")
9927
                        });
9928
                }
9929
        },
9930

    
9931
        _createTitlebar: function() {
9932
                var uiDialogTitle;
9933

    
9934
                this.uiDialogTitlebar = $("<div>")
9935
                        .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
9936
                        .prependTo( this.uiDialog );
9937
                this._on( this.uiDialogTitlebar, {
9938
                        mousedown: function( event ) {
9939
                                // Don't prevent click on close button (#8838)
9940
                                // Focusing a dialog that is partially scrolled out of view
9941
                                // causes the browser to scroll it into view, preventing the click event
9942
                                if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) {
9943
                                        // Dialog isn't getting focus when dragging (#8063)
9944
                                        this.uiDialog.focus();
9945
                                }
9946
                        }
9947
                });
9948

    
9949
                this.uiDialogTitlebarClose = $("<button></button>")
9950
                        .button({
9951
                                label: this.options.closeText,
9952
                                icons: {
9953
                                        primary: "ui-icon-closethick"
9954
                                },
9955
                                text: false
9956
                        })
9957
                        .addClass("ui-dialog-titlebar-close")
9958
                        .appendTo( this.uiDialogTitlebar );
9959
                this._on( this.uiDialogTitlebarClose, {
9960
                        click: function( event ) {
9961
                                event.preventDefault();
9962
                                this.close( event );
9963
                        }
9964
                });
9965

    
9966
                uiDialogTitle = $("<span>")
9967
                        .uniqueId()
9968
                        .addClass("ui-dialog-title")
9969
                        .prependTo( this.uiDialogTitlebar );
9970
                this._title( uiDialogTitle );
9971

    
9972
                this.uiDialog.attr({
9973
                        "aria-labelledby": uiDialogTitle.attr("id")
9974
                });
9975
        },
9976

    
9977
        _title: function( title ) {
9978
                if ( !this.options.title ) {
9979
                        title.html("&#160;");
9980
                }
9981
                title.text( this.options.title );
9982
        },
9983

    
9984
        _createButtonPane: function() {
9985
                this.uiDialogButtonPane = $("<div>")
9986
                        .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
9987

    
9988
                this.uiButtonSet = $("<div>")
9989
                        .addClass("ui-dialog-buttonset")
9990
                        .appendTo( this.uiDialogButtonPane );
9991

    
9992
                this._createButtons();
9993
        },
9994

    
9995
        _createButtons: function() {
9996
                var that = this,
9997
                        buttons = this.options.buttons;
9998

    
9999
                // if we already have a button pane, remove it
10000
                this.uiDialogButtonPane.remove();
10001
                this.uiButtonSet.empty();
10002

    
10003
                if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
10004
                        this.uiDialog.removeClass("ui-dialog-buttons");
10005
                        return;
10006
                }
10007

    
10008
                $.each( buttons, function( name, props ) {
10009
                        var click, buttonOptions;
10010
                        props = $.isFunction( props ) ?
10011
                                { click: props, text: name } :
10012
                                props;
10013
                        // Default to a non-submitting button
10014
                        props = $.extend( { type: "button" }, props );
10015
                        // Change the context for the click callback to be the main element
10016
                        click = props.click;
10017
                        props.click = function() {
10018
                                click.apply( that.element[0], arguments );
10019
                        };
10020
                        buttonOptions = {
10021
                                icons: props.icons,
10022
                                text: props.showText
10023
                        };
10024
                        delete props.icons;
10025
                        delete props.showText;
10026
                        $( "<button></button>", props )
10027
                                .button( buttonOptions )
10028
                                .appendTo( that.uiButtonSet );
10029
                });
10030
                this.uiDialog.addClass("ui-dialog-buttons");
10031
                this.uiDialogButtonPane.appendTo( this.uiDialog );
10032
        },
10033

    
10034
        _makeDraggable: function() {
10035
                var that = this,
10036
                        options = this.options;
10037

    
10038
                function filteredUi( ui ) {
10039
                        return {
10040
                                position: ui.position,
10041
                                offset: ui.offset
10042
                        };
10043
                }
10044

    
10045
                this.uiDialog.draggable({
10046
                        cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
10047
                        handle: ".ui-dialog-titlebar",
10048
                        containment: "document",
10049
                        start: function( event, ui ) {
10050
                                $( this ).addClass("ui-dialog-dragging");
10051
                                that._blockFrames();
10052
                                that._trigger( "dragStart", event, filteredUi( ui ) );
10053
                        },
10054
                        drag: function( event, ui ) {
10055
                                that._trigger( "drag", event, filteredUi( ui ) );
10056
                        },
10057
                        stop: function( event, ui ) {
10058
                                options.position = [
10059
                                        ui.position.left - that.document.scrollLeft(),
10060
                                        ui.position.top - that.document.scrollTop()
10061
                                ];
10062
                                $( this ).removeClass("ui-dialog-dragging");
10063
                                that._unblockFrames();
10064
                                that._trigger( "dragStop", event, filteredUi( ui ) );
10065
                        }
10066
                });
10067
        },
10068

    
10069
        _makeResizable: function() {
10070
                var that = this,
10071
                        options = this.options,
10072
                        handles = options.resizable,
10073
                        // .ui-resizable has position: relative defined in the stylesheet
10074
                        // but dialogs have to use absolute or fixed positioning
10075
                        position = this.uiDialog.css("position"),
10076
                        resizeHandles = typeof handles === "string" ?
10077
                                handles        :
10078
                                "n,e,s,w,se,sw,ne,nw";
10079

    
10080
                function filteredUi( ui ) {
10081
                        return {
10082
                                originalPosition: ui.originalPosition,
10083
                                originalSize: ui.originalSize,
10084
                                position: ui.position,
10085
                                size: ui.size
10086
                        };
10087
                }
10088

    
10089
                this.uiDialog.resizable({
10090
                        cancel: ".ui-dialog-content",
10091
                        containment: "document",
10092
                        alsoResize: this.element,
10093
                        maxWidth: options.maxWidth,
10094
                        maxHeight: options.maxHeight,
10095
                        minWidth: options.minWidth,
10096
                        minHeight: this._minHeight(),
10097
                        handles: resizeHandles,
10098
                        start: function( event, ui ) {
10099
                                $( this ).addClass("ui-dialog-resizing");
10100
                                that._blockFrames();
10101
                                that._trigger( "resizeStart", event, filteredUi( ui ) );
10102
                        },
10103
                        resize: function( event, ui ) {
10104
                                that._trigger( "resize", event, filteredUi( ui ) );
10105
                        },
10106
                        stop: function( event, ui ) {
10107
                                options.height = $( this ).height();
10108
                                options.width = $( this ).width();
10109
                                $( this ).removeClass("ui-dialog-resizing");
10110
                                that._unblockFrames();
10111
                                that._trigger( "resizeStop", event, filteredUi( ui ) );
10112
                        }
10113
                })
10114
                .css( "position", position );
10115
        },
10116

    
10117
        _minHeight: function() {
10118
                var options = this.options;
10119

    
10120
                return options.height === "auto" ?
10121
                        options.minHeight :
10122
                        Math.min( options.minHeight, options.height );
10123
        },
10124

    
10125
        _position: function() {
10126
                // Need to show the dialog to get the actual offset in the position plugin
10127
                var isVisible = this.uiDialog.is(":visible");
10128
                if ( !isVisible ) {
10129
                        this.uiDialog.show();
10130
                }
10131
                this.uiDialog.position( this.options.position );
10132
                if ( !isVisible ) {
10133
                        this.uiDialog.hide();
10134
                }
10135
        },
10136

    
10137
        _setOptions: function( options ) {
10138
                var that = this,
10139
                        resize = false,
10140
                        resizableOptions = {};
10141

    
10142
                $.each( options, function( key, value ) {
10143
                        that._setOption( key, value );
10144

    
10145
                        if ( key in sizeRelatedOptions ) {
10146
                                resize = true;
10147
                        }
10148
                        if ( key in resizableRelatedOptions ) {
10149
                                resizableOptions[ key ] = value;
10150
                        }
10151
                });
10152

    
10153
                if ( resize ) {
10154
                        this._size();
10155
                        this._position();
10156
                }
10157
                if ( this.uiDialog.is(":data(ui-resizable)") ) {
10158
                        this.uiDialog.resizable( "option", resizableOptions );
10159
                }
10160
        },
10161

    
10162
        _setOption: function( key, value ) {
10163
                /*jshint maxcomplexity:15*/
10164
                var isDraggable, isResizable,
10165
                        uiDialog = this.uiDialog;
10166

    
10167
                if ( key === "dialogClass" ) {
10168
                        uiDialog
10169
                                .removeClass( this.options.dialogClass )
10170
                                .addClass( value );
10171
                }
10172

    
10173
                if ( key === "disabled" ) {
10174
                        return;
10175
                }
10176

    
10177
                this._super( key, value );
10178

    
10179
                if ( key === "appendTo" ) {
10180
                        this.uiDialog.appendTo( this._appendTo() );
10181
                }
10182

    
10183
                if ( key === "buttons" ) {
10184
                        this._createButtons();
10185
                }
10186

    
10187
                if ( key === "closeText" ) {
10188
                        this.uiDialogTitlebarClose.button({
10189
                                // Ensure that we always pass a string
10190
                                label: "" + value
10191
                        });
10192
                }
10193

    
10194
                if ( key === "draggable" ) {
10195
                        isDraggable = uiDialog.is(":data(ui-draggable)");
10196
                        if ( isDraggable && !value ) {
10197
                                uiDialog.draggable("destroy");
10198
                        }
10199

    
10200
                        if ( !isDraggable && value ) {
10201
                                this._makeDraggable();
10202
                        }
10203
                }
10204

    
10205
                if ( key === "position" ) {
10206
                        this._position();
10207
                }
10208

    
10209
                if ( key === "resizable" ) {
10210
                        // currently resizable, becoming non-resizable
10211
                        isResizable = uiDialog.is(":data(ui-resizable)");
10212
                        if ( isResizable && !value ) {
10213
                                uiDialog.resizable("destroy");
10214
                        }
10215

    
10216
                        // currently resizable, changing handles
10217
                        if ( isResizable && typeof value === "string" ) {
10218
                                uiDialog.resizable( "option", "handles", value );
10219
                        }
10220

    
10221
                        // currently non-resizable, becoming resizable
10222
                        if ( !isResizable && value !== false ) {
10223
                                this._makeResizable();
10224
                        }
10225
                }
10226

    
10227
                if ( key === "title" ) {
10228
                        this._title( this.uiDialogTitlebar.find(".ui-dialog-title") );
10229
                }
10230
        },
10231

    
10232
        _size: function() {
10233
                // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
10234
                // divs will both have width and height set, so we need to reset them
10235
                var nonContentHeight, minContentHeight, maxContentHeight,
10236
                        options = this.options;
10237

    
10238
                // Reset content sizing
10239
                this.element.show().css({
10240
                        width: "auto",
10241
                        minHeight: 0,
10242
                        maxHeight: "none",
10243
                        height: 0
10244
                });
10245

    
10246
                if ( options.minWidth > options.width ) {
10247
                        options.width = options.minWidth;
10248
                }
10249

    
10250
                // reset wrapper sizing
10251
                // determine the height of all the non-content elements
10252
                nonContentHeight = this.uiDialog.css({
10253
                                height: "auto",
10254
                                width: options.width
10255
                        })
10256
                        .outerHeight();
10257
                minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
10258
                maxContentHeight = typeof options.maxHeight === "number" ?
10259
                        Math.max( 0, options.maxHeight - nonContentHeight ) :
10260
                        "none";
10261

    
10262
                if ( options.height === "auto" ) {
10263
                        this.element.css({
10264
                                minHeight: minContentHeight,
10265
                                maxHeight: maxContentHeight,
10266
                                height: "auto"
10267
                        });
10268
                } else {
10269
                        this.element.height( Math.max( 0, options.height - nonContentHeight ) );
10270
                }
10271

    
10272
                if (this.uiDialog.is(":data(ui-resizable)") ) {
10273
                        this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
10274
                }
10275
        },
10276

    
10277
        _blockFrames: function() {
10278
                this.iframeBlocks = this.document.find( "iframe" ).map(function() {
10279
                        var iframe = $( this );
10280

    
10281
                        return $( "<div>" )
10282
                                .css({
10283
                                        position: "absolute",
10284
                                        width: iframe.outerWidth(),
10285
                                        height: iframe.outerHeight()
10286
                                })
10287
                                .appendTo( iframe.parent() )
10288
                                .offset( iframe.offset() )[0];
10289
                });
10290
        },
10291

    
10292
        _unblockFrames: function() {
10293
                if ( this.iframeBlocks ) {
10294
                        this.iframeBlocks.remove();
10295
                        delete this.iframeBlocks;
10296
                }
10297
        },
10298

    
10299
        _allowInteraction: function( event ) {
10300
                if ( $( event.target ).closest(".ui-dialog").length ) {
10301
                        return true;
10302
                }
10303

    
10304
                // TODO: Remove hack when datepicker implements
10305
                // the .ui-front logic (#8989)
10306
                return !!$( event.target ).closest(".ui-datepicker").length;
10307
        },
10308

    
10309
        _createOverlay: function() {
10310
                if ( !this.options.modal ) {
10311
                        return;
10312
                }
10313

    
10314
                var that = this,
10315
                        widgetFullName = this.widgetFullName;
10316
                if ( !$.ui.dialog.overlayInstances ) {
10317
                        // Prevent use of anchors and inputs.
10318
                        // We use a delay in case the overlay is created from an
10319
                        // event that we're going to be cancelling. (#2804)
10320
                        this._delay(function() {
10321
                                // Handle .dialog().dialog("close") (#4065)
10322
                                if ( $.ui.dialog.overlayInstances ) {
10323
                                        this.document.bind( "focusin.dialog", function( event ) {
10324
                                                if ( !that._allowInteraction( event ) ) {
10325
                                                        event.preventDefault();
10326
                                                        $(".ui-dialog:visible:last .ui-dialog-content")
10327
                                                                .data( widgetFullName )._focusTabbable();
10328
                                                }
10329
                                        });
10330
                                }
10331
                        });
10332
                }
10333

    
10334
                this.overlay = $("<div>")
10335
                        .addClass("ui-widget-overlay ui-front")
10336
                        .appendTo( this._appendTo() );
10337
                this._on( this.overlay, {
10338
                        mousedown: "_keepFocus"
10339
                });
10340
                $.ui.dialog.overlayInstances++;
10341
        },
10342

    
10343
        _destroyOverlay: function() {
10344
                if ( !this.options.modal ) {
10345
                        return;
10346
                }
10347

    
10348
                if ( this.overlay ) {
10349
                        $.ui.dialog.overlayInstances--;
10350

    
10351
                        if ( !$.ui.dialog.overlayInstances ) {
10352
                                this.document.unbind( "focusin.dialog" );
10353
                        }
10354
                        this.overlay.remove();
10355
                        this.overlay = null;
10356
                }
10357
        }
10358
});
10359

    
10360
$.ui.dialog.overlayInstances = 0;
10361

    
10362
// DEPRECATED
10363
if ( $.uiBackCompat !== false ) {
10364
        // position option with array notation
10365
        // just override with old implementation
10366
        $.widget( "ui.dialog", $.ui.dialog, {
10367
                _position: function() {
10368
                        var position = this.options.position,
10369
                                myAt = [],
10370
                                offset = [ 0, 0 ],
10371
                                isVisible;
10372

    
10373
                        if ( position ) {
10374
                                if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
10375
                                        myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
10376
                                        if ( myAt.length === 1 ) {
10377
                                                myAt[1] = myAt[0];
10378
                                        }
10379

    
10380
                                        $.each( [ "left", "top" ], function( i, offsetPosition ) {
10381
                                                if ( +myAt[ i ] === myAt[ i ] ) {
10382
                                                        offset[ i ] = myAt[ i ];
10383
                                                        myAt[ i ] = offsetPosition;
10384
                                                }
10385
                                        });
10386

    
10387
                                        position = {
10388
                                                my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
10389
                                                        myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
10390
                                                at: myAt.join(" ")
10391
                                        };
10392
                                }
10393

    
10394
                                position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
10395
                        } else {
10396
                                position = $.ui.dialog.prototype.options.position;
10397
                        }
10398

    
10399
                        // need to show the dialog to get the actual offset in the position plugin
10400
                        isVisible = this.uiDialog.is(":visible");
10401
                        if ( !isVisible ) {
10402
                                this.uiDialog.show();
10403
                        }
10404
                        this.uiDialog.position( position );
10405
                        if ( !isVisible ) {
10406
                                this.uiDialog.hide();
10407
                        }
10408
                }
10409
        });
10410
}
10411

    
10412
}( jQuery ) );
10413

    
10414
(function( $, undefined ) {
10415

    
10416
var rvertical = /up|down|vertical/,
10417
        rpositivemotion = /up|left|vertical|horizontal/;
10418

    
10419
$.effects.effect.blind = function( o, done ) {
10420
        // Create element
10421
        var el = $( this ),
10422
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10423
                mode = $.effects.setMode( el, o.mode || "hide" ),
10424
                direction = o.direction || "up",
10425
                vertical = rvertical.test( direction ),
10426
                ref = vertical ? "height" : "width",
10427
                ref2 = vertical ? "top" : "left",
10428
                motion = rpositivemotion.test( direction ),
10429
                animation = {},
10430
                show = mode === "show",
10431
                wrapper, distance, margin;
10432

    
10433
        // if already wrapped, the wrapper's properties are my property. #6245
10434
        if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10435
                $.effects.save( el.parent(), props );
10436
        } else {
10437
                $.effects.save( el, props );
10438
        }
10439
        el.show();
10440
        wrapper = $.effects.createWrapper( el ).css({
10441
                overflow: "hidden"
10442
        });
10443

    
10444
        distance = wrapper[ ref ]();
10445
        margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10446

    
10447
        animation[ ref ] = show ? distance : 0;
10448
        if ( !motion ) {
10449
                el
10450
                        .css( vertical ? "bottom" : "right", 0 )
10451
                        .css( vertical ? "top" : "left", "auto" )
10452
                        .css({ position: "absolute" });
10453

    
10454
                animation[ ref2 ] = show ? margin : distance + margin;
10455
        }
10456

    
10457
        // start at 0 if we are showing
10458
        if ( show ) {
10459
                wrapper.css( ref, 0 );
10460
                if ( ! motion ) {
10461
                        wrapper.css( ref2, margin + distance );
10462
                }
10463
        }
10464

    
10465
        // Animate
10466
        wrapper.animate( animation, {
10467
                duration: o.duration,
10468
                easing: o.easing,
10469
                queue: false,
10470
                complete: function() {
10471
                        if ( mode === "hide" ) {
10472
                                el.hide();
10473
                        }
10474
                        $.effects.restore( el, props );
10475
                        $.effects.removeWrapper( el );
10476
                        done();
10477
                }
10478
        });
10479

    
10480
};
10481

    
10482
})(jQuery);
10483

    
10484
(function( $, undefined ) {
10485

    
10486
$.effects.effect.bounce = function( o, done ) {
10487
        var el = $( this ),
10488
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10489

    
10490
                // defaults:
10491
                mode = $.effects.setMode( el, o.mode || "effect" ),
10492
                hide = mode === "hide",
10493
                show = mode === "show",
10494
                direction = o.direction || "up",
10495
                distance = o.distance,
10496
                times = o.times || 5,
10497

    
10498
                // number of internal animations
10499
                anims = times * 2 + ( show || hide ? 1 : 0 ),
10500
                speed = o.duration / anims,
10501
                easing = o.easing,
10502

    
10503
                // utility:
10504
                ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10505
                motion = ( direction === "up" || direction === "left" ),
10506
                i,
10507
                upAnim,
10508
                downAnim,
10509

    
10510
                // we will need to re-assemble the queue to stack our animations in place
10511
                queue = el.queue(),
10512
                queuelen = queue.length;
10513

    
10514
        // Avoid touching opacity to prevent clearType and PNG issues in IE
10515
        if ( show || hide ) {
10516
                props.push( "opacity" );
10517
        }
10518

    
10519
        $.effects.save( el, props );
10520
        el.show();
10521
        $.effects.createWrapper( el ); // Create Wrapper
10522

    
10523
        // default distance for the BIGGEST bounce is the outer Distance / 3
10524
        if ( !distance ) {
10525
                distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10526
        }
10527

    
10528
        if ( show ) {
10529
                downAnim = { opacity: 1 };
10530
                downAnim[ ref ] = 0;
10531

    
10532
                // if we are showing, force opacity 0 and set the initial position
10533
                // then do the "first" animation
10534
                el.css( "opacity", 0 )
10535
                        .css( ref, motion ? -distance * 2 : distance * 2 )
10536
                        .animate( downAnim, speed, easing );
10537
        }
10538

    
10539
        // start at the smallest distance if we are hiding
10540
        if ( hide ) {
10541
                distance = distance / Math.pow( 2, times - 1 );
10542
        }
10543

    
10544
        downAnim = {};
10545
        downAnim[ ref ] = 0;
10546
        // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10547
        for ( i = 0; i < times; i++ ) {
10548
                upAnim = {};
10549
                upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10550

    
10551
                el.animate( upAnim, speed, easing )
10552
                        .animate( downAnim, speed, easing );
10553

    
10554
                distance = hide ? distance * 2 : distance / 2;
10555
        }
10556

    
10557
        // Last Bounce when Hiding
10558
        if ( hide ) {
10559
                upAnim = { opacity: 0 };
10560
                upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10561

    
10562
                el.animate( upAnim, speed, easing );
10563
        }
10564

    
10565
        el.queue(function() {
10566
                if ( hide ) {
10567
                        el.hide();
10568
                }
10569
                $.effects.restore( el, props );
10570
                $.effects.removeWrapper( el );
10571
                done();
10572
        });
10573

    
10574
        // inject all the animations we just queued to be first in line (after "inprogress")
10575
        if ( queuelen > 1) {
10576
                queue.splice.apply( queue,
10577
                        [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10578
        }
10579
        el.dequeue();
10580

    
10581
};
10582

    
10583
})(jQuery);
10584

    
10585
(function( $, undefined ) {
10586

    
10587
$.effects.effect.clip = function( o, done ) {
10588
        // Create element
10589
        var el = $( this ),
10590
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10591
                mode = $.effects.setMode( el, o.mode || "hide" ),
10592
                show = mode === "show",
10593
                direction = o.direction || "vertical",
10594
                vert = direction === "vertical",
10595
                size = vert ? "height" : "width",
10596
                position = vert ? "top" : "left",
10597
                animation = {},
10598
                wrapper, animate, distance;
10599

    
10600
        // Save & Show
10601
        $.effects.save( el, props );
10602
        el.show();
10603

    
10604
        // Create Wrapper
10605
        wrapper = $.effects.createWrapper( el ).css({
10606
                overflow: "hidden"
10607
        });
10608
        animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10609
        distance = animate[ size ]();
10610

    
10611
        // Shift
10612
        if ( show ) {
10613
                animate.css( size, 0 );
10614
                animate.css( position, distance / 2 );
10615
        }
10616

    
10617
        // Create Animation Object:
10618
        animation[ size ] = show ? distance : 0;
10619
        animation[ position ] = show ? 0 : distance / 2;
10620

    
10621
        // Animate
10622
        animate.animate( animation, {
10623
                queue: false,
10624
                duration: o.duration,
10625
                easing: o.easing,
10626
                complete: function() {
10627
                        if ( !show ) {
10628
                                el.hide();
10629
                        }
10630
                        $.effects.restore( el, props );
10631
                        $.effects.removeWrapper( el );
10632
                        done();
10633
                }
10634
        });
10635

    
10636
};
10637

    
10638
})(jQuery);
10639

    
10640
(function( $, undefined ) {
10641

    
10642
$.effects.effect.drop = function( o, done ) {
10643

    
10644
        var el = $( this ),
10645
                props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10646
                mode = $.effects.setMode( el, o.mode || "hide" ),
10647
                show = mode === "show",
10648
                direction = o.direction || "left",
10649
                ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10650
                motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10651
                animation = {
10652
                        opacity: show ? 1 : 0
10653
                },
10654
                distance;
10655

    
10656
        // Adjust
10657
        $.effects.save( el, props );
10658
        el.show();
10659
        $.effects.createWrapper( el );
10660

    
10661
        distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
10662

    
10663
        if ( show ) {
10664
                el
10665
                        .css( "opacity", 0 )
10666
                        .css( ref, motion === "pos" ? -distance : distance );
10667
        }
10668

    
10669
        // Animation
10670
        animation[ ref ] = ( show ?
10671
                ( motion === "pos" ? "+=" : "-=" ) :
10672
                ( motion === "pos" ? "-=" : "+=" ) ) +
10673
                distance;
10674

    
10675
        // Animate
10676
        el.animate( animation, {
10677
                queue: false,
10678
                duration: o.duration,
10679
                easing: o.easing,
10680
                complete: function() {
10681
                        if ( mode === "hide" ) {
10682
                                el.hide();
10683
                        }
10684
                        $.effects.restore( el, props );
10685
                        $.effects.removeWrapper( el );
10686
                        done();
10687
                }
10688
        });
10689
};
10690

    
10691
})(jQuery);
10692

    
10693
(function( $, undefined ) {
10694

    
10695
$.effects.effect.explode = function( o, done ) {
10696

    
10697
        var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10698
                cells = rows,
10699
                el = $( this ),
10700
                mode = $.effects.setMode( el, o.mode || "hide" ),
10701
                show = mode === "show",
10702

    
10703
                // show and then visibility:hidden the element before calculating offset
10704
                offset = el.show().css( "visibility", "hidden" ).offset(),
10705

    
10706
                // width and height of a piece
10707
                width = Math.ceil( el.outerWidth() / cells ),
10708
                height = Math.ceil( el.outerHeight() / rows ),
10709
                pieces = [],
10710

    
10711
                // loop
10712
                i, j, left, top, mx, my;
10713

    
10714
        // children animate complete:
10715
        function childComplete() {
10716
                pieces.push( this );
10717
                if ( pieces.length === rows * cells ) {
10718
                        animComplete();
10719
                }
10720
        }
10721

    
10722
        // clone the element for each row and cell.
10723
        for( i = 0; i < rows ; i++ ) { // ===>
10724
                top = offset.top + i * height;
10725
                my = i - ( rows - 1 ) / 2 ;
10726

    
10727
                for( j = 0; j < cells ; j++ ) { // |||
10728
                        left = offset.left + j * width;
10729
                        mx = j - ( cells - 1 ) / 2 ;
10730

    
10731
                        // Create a clone of the now hidden main element that will be absolute positioned
10732
                        // within a wrapper div off the -left and -top equal to size of our pieces
10733
                        el
10734
                                .clone()
10735
                                .appendTo( "body" )
10736
                                .wrap( "<div></div>" )
10737
                                .css({
10738
                                        position: "absolute",
10739
                                        visibility: "visible",
10740
                                        left: -j * width,
10741
                                        top: -i * height
10742
                                })
10743

    
10744
                        // select the wrapper - make it overflow: hidden and absolute positioned based on
10745
                        // where the original was located +left and +top equal to the size of pieces
10746
                                .parent()
10747
                                .addClass( "ui-effects-explode" )
10748
                                .css({
10749
                                        position: "absolute",
10750
                                        overflow: "hidden",
10751
                                        width: width,
10752
                                        height: height,
10753
                                        left: left + ( show ? mx * width : 0 ),
10754
                                        top: top + ( show ? my * height : 0 ),
10755
                                        opacity: show ? 0 : 1
10756
                                }).animate({
10757
                                        left: left + ( show ? 0 : mx * width ),
10758
                                        top: top + ( show ? 0 : my * height ),
10759
                                        opacity: show ? 1 : 0
10760
                                }, o.duration || 500, o.easing, childComplete );
10761
                }
10762
        }
10763

    
10764
        function animComplete() {
10765
                el.css({
10766
                        visibility: "visible"
10767
                });
10768
                $( pieces ).remove();
10769
                if ( !show ) {
10770
                        el.hide();
10771
                }
10772
                done();
10773
        }
10774
};
10775

    
10776
})(jQuery);
10777

    
10778
(function( $, undefined ) {
10779

    
10780
$.effects.effect.fade = function( o, done ) {
10781
        var el = $( this ),
10782
                mode = $.effects.setMode( el, o.mode || "toggle" );
10783

    
10784
        el.animate({
10785
                opacity: mode
10786
        }, {
10787
                queue: false,
10788
                duration: o.duration,
10789
                easing: o.easing,
10790
                complete: done
10791
        });
10792
};
10793

    
10794
})( jQuery );
10795

    
10796
(function( $, undefined ) {
10797

    
10798
$.effects.effect.fold = function( o, done ) {
10799

    
10800
        // Create element
10801
        var el = $( this ),
10802
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10803
                mode = $.effects.setMode( el, o.mode || "hide" ),
10804
                show = mode === "show",
10805
                hide = mode === "hide",
10806
                size = o.size || 15,
10807
                percent = /([0-9]+)%/.exec( size ),
10808
                horizFirst = !!o.horizFirst,
10809
                widthFirst = show !== horizFirst,
10810
                ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
10811
                duration = o.duration / 2,
10812
                wrapper, distance,
10813
                animation1 = {},
10814
                animation2 = {};
10815

    
10816
        $.effects.save( el, props );
10817
        el.show();
10818

    
10819
        // Create Wrapper
10820
        wrapper = $.effects.createWrapper( el ).css({
10821
                overflow: "hidden"
10822
        });
10823
        distance = widthFirst ?
10824
                [ wrapper.width(), wrapper.height() ] :
10825
                [ wrapper.height(), wrapper.width() ];
10826

    
10827
        if ( percent ) {
10828
                size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
10829
        }
10830
        if ( show ) {
10831
                wrapper.css( horizFirst ? {
10832
                        height: 0,
10833
                        width: size
10834
                } : {
10835
                        height: size,
10836
                        width: 0
10837
                });
10838
        }
10839

    
10840
        // Animation
10841
        animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
10842
        animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
10843

    
10844
        // Animate
10845
        wrapper
10846
                .animate( animation1, duration, o.easing )
10847
                .animate( animation2, duration, o.easing, function() {
10848
                        if ( hide ) {
10849
                                el.hide();
10850
                        }
10851
                        $.effects.restore( el, props );
10852
                        $.effects.removeWrapper( el );
10853
                        done();
10854
                });
10855

    
10856
};
10857

    
10858
})(jQuery);
10859

    
10860
(function( $, undefined ) {
10861

    
10862
$.effects.effect.highlight = function( o, done ) {
10863
        var elem = $( this ),
10864
                props = [ "backgroundImage", "backgroundColor", "opacity" ],
10865
                mode = $.effects.setMode( elem, o.mode || "show" ),
10866
                animation = {
10867
                        backgroundColor: elem.css( "backgroundColor" )
10868
                };
10869

    
10870
        if (mode === "hide") {
10871
                animation.opacity = 0;
10872
        }
10873

    
10874
        $.effects.save( elem, props );
10875

    
10876
        elem
10877
                .show()
10878
                .css({
10879
                        backgroundImage: "none",
10880
                        backgroundColor: o.color || "#ffff99"
10881
                })
10882
                .animate( animation, {
10883
                        queue: false,
10884
                        duration: o.duration,
10885
                        easing: o.easing,
10886
                        complete: function() {
10887
                                if ( mode === "hide" ) {
10888
                                        elem.hide();
10889
                                }
10890
                                $.effects.restore( elem, props );
10891
                                done();
10892
                        }
10893
                });
10894
};
10895

    
10896
})(jQuery);
10897

    
10898
(function( $, undefined ) {
10899

    
10900
$.effects.effect.pulsate = function( o, done ) {
10901
        var elem = $( this ),
10902
                mode = $.effects.setMode( elem, o.mode || "show" ),
10903
                show = mode === "show",
10904
                hide = mode === "hide",
10905
                showhide = ( show || mode === "hide" ),
10906

    
10907
                // showing or hiding leaves of the "last" animation
10908
                anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
10909
                duration = o.duration / anims,
10910
                animateTo = 0,
10911
                queue = elem.queue(),
10912
                queuelen = queue.length,
10913
                i;
10914

    
10915
        if ( show || !elem.is(":visible")) {
10916
                elem.css( "opacity", 0 ).show();
10917
                animateTo = 1;
10918
        }
10919

    
10920
        // anims - 1 opacity "toggles"
10921
        for ( i = 1; i < anims; i++ ) {
10922
                elem.animate({
10923
                        opacity: animateTo
10924
                }, duration, o.easing );
10925
                animateTo = 1 - animateTo;
10926
        }
10927

    
10928
        elem.animate({
10929
                opacity: animateTo
10930
        }, duration, o.easing);
10931

    
10932
        elem.queue(function() {
10933
                if ( hide ) {
10934
                        elem.hide();
10935
                }
10936
                done();
10937
        });
10938

    
10939
        // We just queued up "anims" animations, we need to put them next in the queue
10940
        if ( queuelen > 1 ) {
10941
                queue.splice.apply( queue,
10942
                        [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10943
        }
10944
        elem.dequeue();
10945
};
10946

    
10947
})(jQuery);
10948

    
10949
(function( $, undefined ) {
10950

    
10951
$.effects.effect.puff = function( o, done ) {
10952
        var elem = $( this ),
10953
                mode = $.effects.setMode( elem, o.mode || "hide" ),
10954
                hide = mode === "hide",
10955
                percent = parseInt( o.percent, 10 ) || 150,
10956
                factor = percent / 100,
10957
                original = {
10958
                        height: elem.height(),
10959
                        width: elem.width(),
10960
                        outerHeight: elem.outerHeight(),
10961
                        outerWidth: elem.outerWidth()
10962
                };
10963

    
10964
        $.extend( o, {
10965
                effect: "scale",
10966
                queue: false,
10967
                fade: true,
10968
                mode: mode,
10969
                complete: done,
10970
                percent: hide ? percent : 100,
10971
                from: hide ?
10972
                        original :
10973
                        {
10974
                                height: original.height * factor,
10975
                                width: original.width * factor,
10976
                                outerHeight: original.outerHeight * factor,
10977
                                outerWidth: original.outerWidth * factor
10978
                        }
10979
        });
10980

    
10981
        elem.effect( o );
10982
};
10983

    
10984
$.effects.effect.scale = function( o, done ) {
10985

    
10986
        // Create element
10987
        var el = $( this ),
10988
                options = $.extend( true, {}, o ),
10989
                mode = $.effects.setMode( el, o.mode || "effect" ),
10990
                percent = parseInt( o.percent, 10 ) ||
10991
                        ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
10992
                direction = o.direction || "both",
10993
                origin = o.origin,
10994
                original = {
10995
                        height: el.height(),
10996
                        width: el.width(),
10997
                        outerHeight: el.outerHeight(),
10998
                        outerWidth: el.outerWidth()
10999
                },
11000
                factor = {
11001
                        y: direction !== "horizontal" ? (percent / 100) : 1,
11002
                        x: direction !== "vertical" ? (percent / 100) : 1
11003
                };
11004

    
11005
        // We are going to pass this effect to the size effect:
11006
        options.effect = "size";
11007
        options.queue = false;
11008
        options.complete = done;
11009

    
11010
        // Set default origin and restore for show/hide
11011
        if ( mode !== "effect" ) {
11012
                options.origin = origin || ["middle","center"];
11013
                options.restore = true;
11014
        }
11015

    
11016
        options.from = o.from || ( mode === "show" ? {
11017
                height: 0,
11018
                width: 0,
11019
                outerHeight: 0,
11020
                outerWidth: 0
11021
        } : original );
11022
        options.to = {
11023
                height: original.height * factor.y,
11024
                width: original.width * factor.x,
11025
                outerHeight: original.outerHeight * factor.y,
11026
                outerWidth: original.outerWidth * factor.x
11027
        };
11028

    
11029
        // Fade option to support puff
11030
        if ( options.fade ) {
11031
                if ( mode === "show" ) {
11032
                        options.from.opacity = 0;
11033
                        options.to.opacity = 1;
11034
                }
11035
                if ( mode === "hide" ) {
11036
                        options.from.opacity = 1;
11037
                        options.to.opacity = 0;
11038
                }
11039
        }
11040

    
11041
        // Animate
11042
        el.effect( options );
11043

    
11044
};
11045

    
11046
$.effects.effect.size = function( o, done ) {
11047

    
11048
        // Create element
11049
        var original, baseline, factor,
11050
                el = $( this ),
11051
                props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11052

    
11053
                // Always restore
11054
                props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11055

    
11056
                // Copy for children
11057
                props2 = [ "width", "height", "overflow" ],
11058
                cProps = [ "fontSize" ],
11059
                vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11060
                hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11061

    
11062
                // Set options
11063
                mode = $.effects.setMode( el, o.mode || "effect" ),
11064
                restore = o.restore || mode !== "effect",
11065
                scale = o.scale || "both",
11066
                origin = o.origin || [ "middle", "center" ],
11067
                position = el.css( "position" ),
11068
                props = restore ? props0 : props1,
11069
                zero = {
11070
                        height: 0,
11071
                        width: 0,
11072
                        outerHeight: 0,
11073
                        outerWidth: 0
11074
                };
11075

    
11076
        if ( mode === "show" ) {
11077
                el.show();
11078
        }
11079
        original = {
11080
                height: el.height(),
11081
                width: el.width(),
11082
                outerHeight: el.outerHeight(),
11083
                outerWidth: el.outerWidth()
11084
        };
11085

    
11086
        if ( o.mode === "toggle" && mode === "show" ) {
11087
                el.from = o.to || zero;
11088
                el.to = o.from || original;
11089
        } else {
11090
                el.from = o.from || ( mode === "show" ? zero : original );
11091
                el.to = o.to || ( mode === "hide" ? zero : original );
11092
        }
11093

    
11094
        // Set scaling factor
11095
        factor = {
11096
                from: {
11097
                        y: el.from.height / original.height,
11098
                        x: el.from.width / original.width
11099
                },
11100
                to: {
11101
                        y: el.to.height / original.height,
11102
                        x: el.to.width / original.width
11103
                }
11104
        };
11105

    
11106
        // Scale the css box
11107
        if ( scale === "box" || scale === "both" ) {
11108

    
11109
                // Vertical props scaling
11110
                if ( factor.from.y !== factor.to.y ) {
11111
                        props = props.concat( vProps );
11112
                        el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11113
                        el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11114
                }
11115

    
11116
                // Horizontal props scaling
11117
                if ( factor.from.x !== factor.to.x ) {
11118
                        props = props.concat( hProps );
11119
                        el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11120
                        el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11121
                }
11122
        }
11123

    
11124
        // Scale the content
11125
        if ( scale === "content" || scale === "both" ) {
11126

    
11127
                // Vertical props scaling
11128
                if ( factor.from.y !== factor.to.y ) {
11129
                        props = props.concat( cProps ).concat( props2 );
11130
                        el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11131
                        el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11132
                }
11133
        }
11134

    
11135
        $.effects.save( el, props );
11136
        el.show();
11137
        $.effects.createWrapper( el );
11138
        el.css( "overflow", "hidden" ).css( el.from );
11139

    
11140
        // Adjust
11141
        if (origin) { // Calculate baseline shifts
11142
                baseline = $.effects.getBaseline( origin, original );
11143
                el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11144
                el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11145
                el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11146
                el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11147
        }
11148
        el.css( el.from ); // set top & left
11149

    
11150
        // Animate
11151
        if ( scale === "content" || scale === "both" ) { // Scale the children
11152

    
11153
                // Add margins/font-size
11154
                vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11155
                hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11156
                props2 = props0.concat(vProps).concat(hProps);
11157

    
11158
                el.find( "*[width]" ).each( function(){
11159
                        var child = $( this ),
11160
                                c_original = {
11161
                                        height: child.height(),
11162
                                        width: child.width(),
11163
                                        outerHeight: child.outerHeight(),
11164
                                        outerWidth: child.outerWidth()
11165
                                };
11166
                        if (restore) {
11167
                                $.effects.save(child, props2);
11168
                        }
11169

    
11170
                        child.from = {
11171
                                height: c_original.height * factor.from.y,
11172
                                width: c_original.width * factor.from.x,
11173
                                outerHeight: c_original.outerHeight * factor.from.y,
11174
                                outerWidth: c_original.outerWidth * factor.from.x
11175
                        };
11176
                        child.to = {
11177
                                height: c_original.height * factor.to.y,
11178
                                width: c_original.width * factor.to.x,
11179
                                outerHeight: c_original.height * factor.to.y,
11180
                                outerWidth: c_original.width * factor.to.x
11181
                        };
11182

    
11183
                        // Vertical props scaling
11184
                        if ( factor.from.y !== factor.to.y ) {
11185
                                child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11186
                                child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11187
                        }
11188

    
11189
                        // Horizontal props scaling
11190
                        if ( factor.from.x !== factor.to.x ) {
11191
                                child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11192
                                child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11193
                        }
11194

    
11195
                        // Animate children
11196
                        child.css( child.from );
11197
                        child.animate( child.to, o.duration, o.easing, function() {
11198

    
11199
                                // Restore children
11200
                                if ( restore ) {
11201
                                        $.effects.restore( child, props2 );
11202
                                }
11203
                        });
11204
                });
11205
        }
11206

    
11207
        // Animate
11208
        el.animate( el.to, {
11209
                queue: false,
11210
                duration: o.duration,
11211
                easing: o.easing,
11212
                complete: function() {
11213
                        if ( el.to.opacity === 0 ) {
11214
                                el.css( "opacity", el.from.opacity );
11215
                        }
11216
                        if( mode === "hide" ) {
11217
                                el.hide();
11218
                        }
11219
                        $.effects.restore( el, props );
11220
                        if ( !restore ) {
11221

    
11222
                                // we need to calculate our new positioning based on the scaling
11223
                                if ( position === "static" ) {
11224
                                        el.css({
11225
                                                position: "relative",
11226
                                                top: el.to.top,
11227
                                                left: el.to.left
11228
                                        });
11229
                                } else {
11230
                                        $.each([ "top", "left" ], function( idx, pos ) {
11231
                                                el.css( pos, function( _, str ) {
11232
                                                        var val = parseInt( str, 10 ),
11233
                                                                toRef = idx ? el.to.left : el.to.top;
11234

    
11235
                                                        // if original was "auto", recalculate the new value from wrapper
11236
                                                        if ( str === "auto" ) {
11237
                                                                return toRef + "px";
11238
                                                        }
11239

    
11240
                                                        return val + toRef + "px";
11241
                                                });
11242
                                        });
11243
                                }
11244
                        }
11245

    
11246
                        $.effects.removeWrapper( el );
11247
                        done();
11248
                }
11249
        });
11250

    
11251
};
11252

    
11253
})(jQuery);
11254

    
11255
(function( $, undefined ) {
11256

    
11257
$.effects.effect.shake = function( o, done ) {
11258

    
11259
        var el = $( this ),
11260
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11261
                mode = $.effects.setMode( el, o.mode || "effect" ),
11262
                direction = o.direction || "left",
11263
                distance = o.distance || 20,
11264
                times = o.times || 3,
11265
                anims = times * 2 + 1,
11266
                speed = Math.round(o.duration/anims),
11267
                ref = (direction === "up" || direction === "down") ? "top" : "left",
11268
                positiveMotion = (direction === "up" || direction === "left"),
11269
                animation = {},
11270
                animation1 = {},
11271
                animation2 = {},
11272
                i,
11273

    
11274
                // we will need to re-assemble the queue to stack our animations in place
11275
                queue = el.queue(),
11276
                queuelen = queue.length;
11277

    
11278
        $.effects.save( el, props );
11279
        el.show();
11280
        $.effects.createWrapper( el );
11281

    
11282
        // Animation
11283
        animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11284
        animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11285
        animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11286

    
11287
        // Animate
11288
        el.animate( animation, speed, o.easing );
11289

    
11290
        // Shakes
11291
        for ( i = 1; i < times; i++ ) {
11292
                el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11293
        }
11294
        el
11295
                .animate( animation1, speed, o.easing )
11296
                .animate( animation, speed / 2, o.easing )
11297
                .queue(function() {
11298
                        if ( mode === "hide" ) {
11299
                                el.hide();
11300
                        }
11301
                        $.effects.restore( el, props );
11302
                        $.effects.removeWrapper( el );
11303
                        done();
11304
                });
11305

    
11306
        // inject all the animations we just queued to be first in line (after "inprogress")
11307
        if ( queuelen > 1) {
11308
                queue.splice.apply( queue,
11309
                        [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11310
        }
11311
        el.dequeue();
11312

    
11313
};
11314

    
11315
})(jQuery);
11316

    
11317
(function( $, undefined ) {
11318

    
11319
$.effects.effect.slide = function( o, done ) {
11320

    
11321
        // Create element
11322
        var el = $( this ),
11323
                props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11324
                mode = $.effects.setMode( el, o.mode || "show" ),
11325
                show = mode === "show",
11326
                direction = o.direction || "left",
11327
                ref = (direction === "up" || direction === "down") ? "top" : "left",
11328
                positiveMotion = (direction === "up" || direction === "left"),
11329
                distance,
11330
                animation = {};
11331

    
11332
        // Adjust
11333
        $.effects.save( el, props );
11334
        el.show();
11335
        distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11336

    
11337
        $.effects.createWrapper( el ).css({
11338
                overflow: "hidden"
11339
        });
11340

    
11341
        if ( show ) {
11342
                el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11343
        }
11344

    
11345
        // Animation
11346
        animation[ ref ] = ( show ?
11347
                ( positiveMotion ? "+=" : "-=") :
11348
                ( positiveMotion ? "-=" : "+=")) +
11349
                distance;
11350

    
11351
        // Animate
11352
        el.animate( animation, {
11353
                queue: false,
11354
                duration: o.duration,
11355
                easing: o.easing,
11356
                complete: function() {
11357
                        if ( mode === "hide" ) {
11358
                                el.hide();
11359
                        }
11360
                        $.effects.restore( el, props );
11361
                        $.effects.removeWrapper( el );
11362
                        done();
11363
                }
11364
        });
11365
};
11366

    
11367
})(jQuery);
11368

    
11369
(function( $, undefined ) {
11370

    
11371
$.effects.effect.transfer = function( o, done ) {
11372
        var elem = $( this ),
11373
                target = $( o.to ),
11374
                targetFixed = target.css( "position" ) === "fixed",
11375
                body = $("body"),
11376
                fixTop = targetFixed ? body.scrollTop() : 0,
11377
                fixLeft = targetFixed ? body.scrollLeft() : 0,
11378
                endPosition = target.offset(),
11379
                animation = {
11380
                        top: endPosition.top - fixTop ,
11381
                        left: endPosition.left - fixLeft ,
11382
                        height: target.innerHeight(),
11383
                        width: target.innerWidth()
11384
                },
11385
                startPosition = elem.offset(),
11386
                transfer = $( "<div class='ui-effects-transfer'></div>" )
11387
                        .appendTo( document.body )
11388
                        .addClass( o.className )
11389
                        .css({
11390
                                top: startPosition.top - fixTop ,
11391
                                left: startPosition.left - fixLeft ,
11392
                                height: elem.innerHeight(),
11393
                                width: elem.innerWidth(),
11394
                                position: targetFixed ? "fixed" : "absolute"
11395
                        })
11396
                        .animate( animation, o.duration, o.easing, function() {
11397
                                transfer.remove();
11398
                                done();
11399
                        });
11400
};
11401

    
11402
})(jQuery);
11403

    
11404
(function( $, undefined ) {
11405

    
11406
$.widget( "ui.menu", {
11407
        version: "1.10.2",
11408
        defaultElement: "<ul>",
11409
        delay: 300,
11410
        options: {
11411
                icons: {
11412
                        submenu: "ui-icon-carat-1-e"
11413
                },
11414
                menus: "ul",
11415
                position: {
11416
                        my: "left top",
11417
                        at: "right top"
11418
                },
11419
                role: "menu",
11420

    
11421
                // callbacks
11422
                blur: null,
11423
                focus: null,
11424
                select: null
11425
        },
11426

    
11427
        _create: function() {
11428
                this.activeMenu = this.element;
11429
                // flag used to prevent firing of the click handler
11430
                // as the event bubbles up through nested menus
11431
                this.mouseHandled = false;
11432
                this.element
11433
                        .uniqueId()
11434
                        .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11435
                        .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
11436
                        .attr({
11437
                                role: this.options.role,
11438
                                tabIndex: 0
11439
                        })
11440
                        // need to catch all clicks on disabled menu
11441
                        // not possible through _on
11442
                        .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
11443
                                if ( this.options.disabled ) {
11444
                                        event.preventDefault();
11445
                                }
11446
                        }, this ));
11447

    
11448
                if ( this.options.disabled ) {
11449
                        this.element
11450
                                .addClass( "ui-state-disabled" )
11451
                                .attr( "aria-disabled", "true" );
11452
                }
11453

    
11454
                this._on({
11455
                        // Prevent focus from sticking to links inside menu after clicking
11456
                        // them (focus should always stay on UL during navigation).
11457
                        "mousedown .ui-menu-item > a": function( event ) {
11458
                                event.preventDefault();
11459
                        },
11460
                        "click .ui-state-disabled > a": function( event ) {
11461
                                event.preventDefault();
11462
                        },
11463
                        "click .ui-menu-item:has(a)": function( event ) {
11464
                                var target = $( event.target ).closest( ".ui-menu-item" );
11465
                                if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
11466
                                        this.mouseHandled = true;
11467

    
11468
                                        this.select( event );
11469
                                        // Open submenu on click
11470
                                        if ( target.has( ".ui-menu" ).length ) {
11471
                                                this.expand( event );
11472
                                        } else if ( !this.element.is( ":focus" ) ) {
11473
                                                // Redirect focus to the menu
11474
                                                this.element.trigger( "focus", [ true ] );
11475

    
11476
                                                // If the active item is on the top level, let it stay active.
11477
                                                // Otherwise, blur the active item since it is no longer visible.
11478
                                                if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
11479
                                                        clearTimeout( this.timer );
11480
                                                }
11481
                                        }
11482
                                }
11483
                        },
11484
                        "mouseenter .ui-menu-item": function( event ) {
11485
                                var target = $( event.currentTarget );
11486
                                // Remove ui-state-active class from siblings of the newly focused menu item
11487
                                // to avoid a jump caused by adjacent elements both having a class with a border
11488
                                target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
11489
                                this.focus( event, target );
11490
                        },
11491
                        mouseleave: "collapseAll",
11492
                        "mouseleave .ui-menu": "collapseAll",
11493
                        focus: function( event, keepActiveItem ) {
11494
                                // If there's already an active item, keep it active
11495
                                // If not, activate the first item
11496
                                var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
11497

    
11498
                                if ( !keepActiveItem ) {
11499
                                        this.focus( event, item );
11500
                                }
11501
                        },
11502
                        blur: function( event ) {
11503
                                this._delay(function() {
11504
                                        if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
11505
                                                this.collapseAll( event );
11506
                                        }
11507
                                });
11508
                        },
11509
                        keydown: "_keydown"
11510
                });
11511

    
11512
                this.refresh();
11513

    
11514
                // Clicks outside of a menu collapse any open menus
11515
                this._on( this.document, {
11516
                        click: function( event ) {
11517
                                if ( !$( event.target ).closest( ".ui-menu" ).length ) {
11518
                                        this.collapseAll( event );
11519
                                }
11520

    
11521
                                // Reset the mouseHandled flag
11522
                                this.mouseHandled = false;
11523
                        }
11524
                });
11525
        },
11526

    
11527
        _destroy: function() {
11528
                // Destroy (sub)menus
11529
                this.element
11530
                        .removeAttr( "aria-activedescendant" )
11531
                        .find( ".ui-menu" ).addBack()
11532
                                .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
11533
                                .removeAttr( "role" )
11534
                                .removeAttr( "tabIndex" )
11535
                                .removeAttr( "aria-labelledby" )
11536
                                .removeAttr( "aria-expanded" )
11537
                                .removeAttr( "aria-hidden" )
11538
                                .removeAttr( "aria-disabled" )
11539
                                .removeUniqueId()
11540
                                .show();
11541

    
11542
                // Destroy menu items
11543
                this.element.find( ".ui-menu-item" )
11544
                        .removeClass( "ui-menu-item" )
11545
                        .removeAttr( "role" )
11546
                        .removeAttr( "aria-disabled" )
11547
                        .children( "a" )
11548
                                .removeUniqueId()
11549
                                .removeClass( "ui-corner-all ui-state-hover" )
11550
                                .removeAttr( "tabIndex" )
11551
                                .removeAttr( "role" )
11552
                                .removeAttr( "aria-haspopup" )
11553
                                .children().each( function() {
11554
                                        var elem = $( this );
11555
                                        if ( elem.data( "ui-menu-submenu-carat" ) ) {
11556
                                                elem.remove();
11557
                                        }
11558
                                });
11559

    
11560
                // Destroy menu dividers
11561
                this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
11562
        },
11563

    
11564
        _keydown: function( event ) {
11565
                /*jshint maxcomplexity:20*/
11566
                var match, prev, character, skip, regex,
11567
                        preventDefault = true;
11568

    
11569
                function escape( value ) {
11570
                        return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
11571
                }
11572

    
11573
                switch ( event.keyCode ) {
11574
                case $.ui.keyCode.PAGE_UP:
11575
                        this.previousPage( event );
11576
                        break;
11577
                case $.ui.keyCode.PAGE_DOWN:
11578
                        this.nextPage( event );
11579
                        break;
11580
                case $.ui.keyCode.HOME:
11581
                        this._move( "first", "first", event );
11582
                        break;
11583
                case $.ui.keyCode.END:
11584
                        this._move( "last", "last", event );
11585
                        break;
11586
                case $.ui.keyCode.UP:
11587
                        this.previous( event );
11588
                        break;
11589
                case $.ui.keyCode.DOWN:
11590
                        this.next( event );
11591
                        break;
11592
                case $.ui.keyCode.LEFT:
11593
                        this.collapse( event );
11594
                        break;
11595
                case $.ui.keyCode.RIGHT:
11596
                        if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
11597
                                this.expand( event );
11598
                        }
11599
                        break;
11600
                case $.ui.keyCode.ENTER:
11601
                case $.ui.keyCode.SPACE:
11602
                        this._activate( event );
11603
                        break;
11604
                case $.ui.keyCode.ESCAPE:
11605
                        this.collapse( event );
11606
                        break;
11607
                default:
11608
                        preventDefault = false;
11609
                        prev = this.previousFilter || "";
11610
                        character = String.fromCharCode( event.keyCode );
11611
                        skip = false;
11612

    
11613
                        clearTimeout( this.filterTimer );
11614

    
11615
                        if ( character === prev ) {
11616
                                skip = true;
11617
                        } else {
11618
                                character = prev + character;
11619
                        }
11620

    
11621
                        regex = new RegExp( "^" + escape( character ), "i" );
11622
                        match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11623
                                return regex.test( $( this ).children( "a" ).text() );
11624
                        });
11625
                        match = skip && match.index( this.active.next() ) !== -1 ?
11626
                                this.active.nextAll( ".ui-menu-item" ) :
11627
                                match;
11628

    
11629
                        // If no matches on the current filter, reset to the last character pressed
11630
                        // to move down the menu to the first item that starts with that character
11631
                        if ( !match.length ) {
11632
                                character = String.fromCharCode( event.keyCode );
11633
                                regex = new RegExp( "^" + escape( character ), "i" );
11634
                                match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11635
                                        return regex.test( $( this ).children( "a" ).text() );
11636
                                });
11637
                        }
11638

    
11639
                        if ( match.length ) {
11640
                                this.focus( event, match );
11641
                                if ( match.length > 1 ) {
11642
                                        this.previousFilter = character;
11643
                                        this.filterTimer = this._delay(function() {
11644
                                                delete this.previousFilter;
11645
                                        }, 1000 );
11646
                                } else {
11647
                                        delete this.previousFilter;
11648
                                }
11649
                        } else {
11650
                                delete this.previousFilter;
11651
                        }
11652
                }
11653

    
11654
                if ( preventDefault ) {
11655
                        event.preventDefault();
11656
                }
11657
        },
11658

    
11659
        _activate: function( event ) {
11660
                if ( !this.active.is( ".ui-state-disabled" ) ) {
11661
                        if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
11662
                                this.expand( event );
11663
                        } else {
11664
                                this.select( event );
11665
                        }
11666
                }
11667
        },
11668

    
11669
        refresh: function() {
11670
                var menus,
11671
                        icon = this.options.icons.submenu,
11672
                        submenus = this.element.find( this.options.menus );
11673

    
11674
                // Initialize nested menus
11675
                submenus.filter( ":not(.ui-menu)" )
11676
                        .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11677
                        .hide()
11678
                        .attr({
11679
                                role: this.options.role,
11680
                                "aria-hidden": "true",
11681
                                "aria-expanded": "false"
11682
                        })
11683
                        .each(function() {
11684
                                var menu = $( this ),
11685
                                        item = menu.prev( "a" ),
11686
                                        submenuCarat = $( "<span>" )
11687
                                                .addClass( "ui-menu-icon ui-icon " + icon )
11688
                                                .data( "ui-menu-submenu-carat", true );
11689

    
11690
                                item
11691
                                        .attr( "aria-haspopup", "true" )
11692
                                        .prepend( submenuCarat );
11693
                                menu.attr( "aria-labelledby", item.attr( "id" ) );
11694
                        });
11695

    
11696
                menus = submenus.add( this.element );
11697

    
11698
                // Don't refresh list items that are already adapted
11699
                menus.children( ":not(.ui-menu-item):has(a)" )
11700
                        .addClass( "ui-menu-item" )
11701
                        .attr( "role", "presentation" )
11702
                        .children( "a" )
11703
                                .uniqueId()
11704
                                .addClass( "ui-corner-all" )
11705
                                .attr({
11706
                                        tabIndex: -1,
11707
                                        role: this._itemRole()
11708
                                });
11709

    
11710
                // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
11711
                menus.children( ":not(.ui-menu-item)" ).each(function() {
11712
                        var item = $( this );
11713
                        // hyphen, em dash, en dash
11714
                        if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
11715
                                item.addClass( "ui-widget-content ui-menu-divider" );
11716
                        }
11717
                });
11718

    
11719
                // Add aria-disabled attribute to any disabled menu item
11720
                menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
11721

    
11722
                // If the active item has been removed, blur the menu
11723
                if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
11724
                        this.blur();
11725
                }
11726
        },
11727

    
11728
        _itemRole: function() {
11729
                return {
11730
                        menu: "menuitem",
11731
                        listbox: "option"
11732
                }[ this.options.role ];
11733
        },
11734

    
11735
        _setOption: function( key, value ) {
11736
                if ( key === "icons" ) {
11737
                        this.element.find( ".ui-menu-icon" )
11738
                                .removeClass( this.options.icons.submenu )
11739
                                .addClass( value.submenu );
11740
                }
11741
                this._super( key, value );
11742
        },
11743

    
11744
        focus: function( event, item ) {
11745
                var nested, focused;
11746
                this.blur( event, event && event.type === "focus" );
11747

    
11748
                this._scrollIntoView( item );
11749

    
11750
                this.active = item.first();
11751
                focused = this.active.children( "a" ).addClass( "ui-state-focus" );
11752
                // Only update aria-activedescendant if there's a role
11753
                // otherwise we assume focus is managed elsewhere
11754
                if ( this.options.role ) {
11755
                        this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
11756
                }
11757

    
11758
                // Highlight active parent menu item, if any
11759
                this.active
11760
                        .parent()
11761
                        .closest( ".ui-menu-item" )
11762
                        .children( "a:first" )
11763
                        .addClass( "ui-state-active" );
11764

    
11765
                if ( event && event.type === "keydown" ) {
11766
                        this._close();
11767
                } else {
11768
                        this.timer = this._delay(function() {
11769
                                this._close();
11770
                        }, this.delay );
11771
                }
11772

    
11773
                nested = item.children( ".ui-menu" );
11774
                if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
11775
                        this._startOpening(nested);
11776
                }
11777
                this.activeMenu = item.parent();
11778

    
11779
                this._trigger( "focus", event, { item: item } );
11780
        },
11781

    
11782
        _scrollIntoView: function( item ) {
11783
                var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
11784
                if ( this._hasScroll() ) {
11785
                        borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
11786
                        paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
11787
                        offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
11788
                        scroll = this.activeMenu.scrollTop();
11789
                        elementHeight = this.activeMenu.height();
11790
                        itemHeight = item.height();
11791

    
11792
                        if ( offset < 0 ) {
11793
                                this.activeMenu.scrollTop( scroll + offset );
11794
                        } else if ( offset + itemHeight > elementHeight ) {
11795
                                this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
11796
                        }
11797
                }
11798
        },
11799

    
11800
        blur: function( event, fromFocus ) {
11801
                if ( !fromFocus ) {
11802
                        clearTimeout( this.timer );
11803
                }
11804

    
11805
                if ( !this.active ) {
11806
                        return;
11807
                }
11808

    
11809
                this.active.children( "a" ).removeClass( "ui-state-focus" );
11810
                this.active = null;
11811

    
11812
                this._trigger( "blur", event, { item: this.active } );
11813
        },
11814

    
11815
        _startOpening: function( submenu ) {
11816
                clearTimeout( this.timer );
11817

    
11818
                // Don't open if already open fixes a Firefox bug that caused a .5 pixel
11819
                // shift in the submenu position when mousing over the carat icon
11820
                if ( submenu.attr( "aria-hidden" ) !== "true" ) {
11821
                        return;
11822
                }
11823

    
11824
                this.timer = this._delay(function() {
11825
                        this._close();
11826
                        this._open( submenu );
11827
                }, this.delay );
11828
        },
11829

    
11830
        _open: function( submenu ) {
11831
                var position = $.extend({
11832
                        of: this.active
11833
                }, this.options.position );
11834

    
11835
                clearTimeout( this.timer );
11836
                this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
11837
                        .hide()
11838
                        .attr( "aria-hidden", "true" );
11839

    
11840
                submenu
11841
                        .show()
11842
                        .removeAttr( "aria-hidden" )
11843
                        .attr( "aria-expanded", "true" )
11844
                        .position( position );
11845
        },
11846

    
11847
        collapseAll: function( event, all ) {
11848
                clearTimeout( this.timer );
11849
                this.timer = this._delay(function() {
11850
                        // If we were passed an event, look for the submenu that contains the event
11851
                        var currentMenu = all ? this.element :
11852
                                $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
11853

    
11854
                        // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
11855
                        if ( !currentMenu.length ) {
11856
                                currentMenu = this.element;
11857
                        }
11858

    
11859
                        this._close( currentMenu );
11860

    
11861
                        this.blur( event );
11862
                        this.activeMenu = currentMenu;
11863
                }, this.delay );
11864
        },
11865

    
11866
        // With no arguments, closes the currently active menu - if nothing is active
11867
        // it closes all menus.  If passed an argument, it will search for menus BELOW
11868
        _close: function( startMenu ) {
11869
                if ( !startMenu ) {
11870
                        startMenu = this.active ? this.active.parent() : this.element;
11871
                }
11872

    
11873
                startMenu
11874
                        .find( ".ui-menu" )
11875
                                .hide()
11876
                                .attr( "aria-hidden", "true" )
11877
                                .attr( "aria-expanded", "false" )
11878
                        .end()
11879
                        .find( "a.ui-state-active" )
11880
                                .removeClass( "ui-state-active" );
11881
        },
11882

    
11883
        collapse: function( event ) {
11884
                var newItem = this.active &&
11885
                        this.active.parent().closest( ".ui-menu-item", this.element );
11886
                if ( newItem && newItem.length ) {
11887
                        this._close();
11888
                        this.focus( event, newItem );
11889
                }
11890
        },
11891

    
11892
        expand: function( event ) {
11893
                var newItem = this.active &&
11894
                        this.active
11895
                                .children( ".ui-menu " )
11896
                                .children( ".ui-menu-item" )
11897
                                .first();
11898

    
11899
                if ( newItem && newItem.length ) {
11900
                        this._open( newItem.parent() );
11901

    
11902
                        // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
11903
                        this._delay(function() {
11904
                                this.focus( event, newItem );
11905
                        });
11906
                }
11907
        },
11908

    
11909
        next: function( event ) {
11910
                this._move( "next", "first", event );
11911
        },
11912

    
11913
        previous: function( event ) {
11914
                this._move( "prev", "last", event );
11915
        },
11916

    
11917
        isFirstItem: function() {
11918
                return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
11919
        },
11920

    
11921
        isLastItem: function() {
11922
                return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
11923
        },
11924

    
11925
        _move: function( direction, filter, event ) {
11926
                var next;
11927
                if ( this.active ) {
11928
                        if ( direction === "first" || direction === "last" ) {
11929
                                next = this.active
11930
                                        [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
11931
                                        .eq( -1 );
11932
                        } else {
11933
                                next = this.active
11934
                                        [ direction + "All" ]( ".ui-menu-item" )
11935
                                        .eq( 0 );
11936
                        }
11937
                }
11938
                if ( !next || !next.length || !this.active ) {
11939
                        next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
11940
                }
11941

    
11942
                this.focus( event, next );
11943
        },
11944

    
11945
        nextPage: function( event ) {
11946
                var item, base, height;
11947

    
11948
                if ( !this.active ) {
11949
                        this.next( event );
11950
                        return;
11951
                }
11952
                if ( this.isLastItem() ) {
11953
                        return;
11954
                }
11955
                if ( this._hasScroll() ) {
11956
                        base = this.active.offset().top;
11957
                        height = this.element.height();
11958
                        this.active.nextAll( ".ui-menu-item" ).each(function() {
11959
                                item = $( this );
11960
                                return item.offset().top - base - height < 0;
11961
                        });
11962

    
11963
                        this.focus( event, item );
11964
                } else {
11965
                        this.focus( event, this.activeMenu.children( ".ui-menu-item" )
11966
                                [ !this.active ? "first" : "last" ]() );
11967
                }
11968
        },
11969

    
11970
        previousPage: function( event ) {
11971
                var item, base, height;
11972
                if ( !this.active ) {
11973
                        this.next( event );
11974
                        return;
11975
                }
11976
                if ( this.isFirstItem() ) {
11977
                        return;
11978
                }
11979
                if ( this._hasScroll() ) {
11980
                        base = this.active.offset().top;
11981
                        height = this.element.height();
11982
                        this.active.prevAll( ".ui-menu-item" ).each(function() {
11983
                                item = $( this );
11984
                                return item.offset().top - base + height > 0;
11985
                        });
11986

    
11987
                        this.focus( event, item );
11988
                } else {
11989
                        this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
11990
                }
11991
        },
11992

    
11993
        _hasScroll: function() {
11994
                return this.element.outerHeight() < this.element.prop( "scrollHeight" );
11995
        },
11996

    
11997
        select: function( event ) {
11998
                // TODO: It should never be possible to not have an active item at this
11999
                // point, but the tests don't trigger mouseenter before click.
12000
                this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
12001
                var ui = { item: this.active };
12002
                if ( !this.active.has( ".ui-menu" ).length ) {
12003
                        this.collapseAll( event, true );
12004
                }
12005
                this._trigger( "select", event, ui );
12006
        }
12007
});
12008

    
12009
}( jQuery ));
12010

    
12011
(function( $, undefined ) {
12012

    
12013
$.ui = $.ui || {};
12014

    
12015
var cachedScrollbarWidth,
12016
        max = Math.max,
12017
        abs = Math.abs,
12018
        round = Math.round,
12019
        rhorizontal = /left|center|right/,
12020
        rvertical = /top|center|bottom/,
12021
        roffset = /[\+\-]\d+(\.[\d]+)?%?/,
12022
        rposition = /^\w+/,
12023
        rpercent = /%$/,
12024
        _position = $.fn.position;
12025

    
12026
function getOffsets( offsets, width, height ) {
12027
        return [
12028
                parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
12029
                parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
12030
        ];
12031
}
12032

    
12033
function parseCss( element, property ) {
12034
        return parseInt( $.css( element, property ), 10 ) || 0;
12035
}
12036

    
12037
function getDimensions( elem ) {
12038
        var raw = elem[0];
12039
        if ( raw.nodeType === 9 ) {
12040
                return {
12041
                        width: elem.width(),
12042
                        height: elem.height(),
12043
                        offset: { top: 0, left: 0 }
12044
                };
12045
        }
12046
        if ( $.isWindow( raw ) ) {
12047
                return {
12048
                        width: elem.width(),
12049
                        height: elem.height(),
12050
                        offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
12051
                };
12052
        }
12053
        if ( raw.preventDefault ) {
12054
                return {
12055
                        width: 0,
12056
                        height: 0,
12057
                        offset: { top: raw.pageY, left: raw.pageX }
12058
                };
12059
        }
12060
        return {
12061
                width: elem.outerWidth(),
12062
                height: elem.outerHeight(),
12063
                offset: elem.offset()
12064
        };
12065
}
12066

    
12067
$.position = {
12068
        scrollbarWidth: function() {
12069
                if ( cachedScrollbarWidth !== undefined ) {
12070
                        return cachedScrollbarWidth;
12071
                }
12072
                var w1, w2,
12073
                        div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
12074
                        innerDiv = div.children()[0];
12075

    
12076
                $( "body" ).append( div );
12077
                w1 = innerDiv.offsetWidth;
12078
                div.css( "overflow", "scroll" );
12079

    
12080
                w2 = innerDiv.offsetWidth;
12081

    
12082
                if ( w1 === w2 ) {
12083
                        w2 = div[0].clientWidth;
12084
                }
12085

    
12086
                div.remove();
12087

    
12088
                return (cachedScrollbarWidth = w1 - w2);
12089
        },
12090
        getScrollInfo: function( within ) {
12091
                var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
12092
                        overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
12093
                        hasOverflowX = overflowX === "scroll" ||
12094
                                ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
12095
                        hasOverflowY = overflowY === "scroll" ||
12096
                                ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
12097
                return {
12098
                        width: hasOverflowY ? $.position.scrollbarWidth() : 0,
12099
                        height: hasOverflowX ? $.position.scrollbarWidth() : 0
12100
                };
12101
        },
12102
        getWithinInfo: function( element ) {
12103
                var withinElement = $( element || window ),
12104
                        isWindow = $.isWindow( withinElement[0] );
12105
                return {
12106
                        element: withinElement,
12107
                        isWindow: isWindow,
12108
                        offset: withinElement.offset() || { left: 0, top: 0 },
12109
                        scrollLeft: withinElement.scrollLeft(),
12110
                        scrollTop: withinElement.scrollTop(),
12111
                        width: isWindow ? withinElement.width() : withinElement.outerWidth(),
12112
                        height: isWindow ? withinElement.height() : withinElement.outerHeight()
12113
                };
12114
        }
12115
};
12116

    
12117
$.fn.position = function( options ) {
12118
        if ( !options || !options.of ) {
12119
                return _position.apply( this, arguments );
12120
        }
12121

    
12122
        // make a copy, we don't want to modify arguments
12123
        options = $.extend( {}, options );
12124

    
12125
        var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
12126
                target = $( options.of ),
12127
                within = $.position.getWithinInfo( options.within ),
12128
                scrollInfo = $.position.getScrollInfo( within ),
12129
                collision = ( options.collision || "flip" ).split( " " ),
12130
                offsets = {};
12131

    
12132
        dimensions = getDimensions( target );
12133
        if ( target[0].preventDefault ) {
12134
                // force left top to allow flipping
12135
                options.at = "left top";
12136
        }
12137
        targetWidth = dimensions.width;
12138
        targetHeight = dimensions.height;
12139
        targetOffset = dimensions.offset;
12140
        // clone to reuse original targetOffset later
12141
        basePosition = $.extend( {}, targetOffset );
12142

    
12143
        // force my and at to have valid horizontal and vertical positions
12144
        // if a value is missing or invalid, it will be converted to center
12145
        $.each( [ "my", "at" ], function() {
12146
                var pos = ( options[ this ] || "" ).split( " " ),
12147
                        horizontalOffset,
12148
                        verticalOffset;
12149

    
12150
                if ( pos.length === 1) {
12151
                        pos = rhorizontal.test( pos[ 0 ] ) ?
12152
                                pos.concat( [ "center" ] ) :
12153
                                rvertical.test( pos[ 0 ] ) ?
12154
                                        [ "center" ].concat( pos ) :
12155
                                        [ "center", "center" ];
12156
                }
12157
                pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
12158
                pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
12159

    
12160
                // calculate offsets
12161
                horizontalOffset = roffset.exec( pos[ 0 ] );
12162
                verticalOffset = roffset.exec( pos[ 1 ] );
12163
                offsets[ this ] = [
12164
                        horizontalOffset ? horizontalOffset[ 0 ] : 0,
12165
                        verticalOffset ? verticalOffset[ 0 ] : 0
12166
                ];
12167

    
12168
                // reduce to just the positions without the offsets
12169
                options[ this ] = [
12170
                        rposition.exec( pos[ 0 ] )[ 0 ],
12171
                        rposition.exec( pos[ 1 ] )[ 0 ]
12172
                ];
12173
        });
12174

    
12175
        // normalize collision option
12176
        if ( collision.length === 1 ) {
12177
                collision[ 1 ] = collision[ 0 ];
12178
        }
12179

    
12180
        if ( options.at[ 0 ] === "right" ) {
12181
                basePosition.left += targetWidth;
12182
        } else if ( options.at[ 0 ] === "center" ) {
12183
                basePosition.left += targetWidth / 2;
12184
        }
12185

    
12186
        if ( options.at[ 1 ] === "bottom" ) {
12187
                basePosition.top += targetHeight;
12188
        } else if ( options.at[ 1 ] === "center" ) {
12189
                basePosition.top += targetHeight / 2;
12190
        }
12191

    
12192
        atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
12193
        basePosition.left += atOffset[ 0 ];
12194
        basePosition.top += atOffset[ 1 ];
12195

    
12196
        return this.each(function() {
12197
                var collisionPosition, using,
12198
                        elem = $( this ),
12199
                        elemWidth = elem.outerWidth(),
12200
                        elemHeight = elem.outerHeight(),
12201
                        marginLeft = parseCss( this, "marginLeft" ),
12202
                        marginTop = parseCss( this, "marginTop" ),
12203
                        collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
12204
                        collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
12205
                        position = $.extend( {}, basePosition ),
12206
                        myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
12207

    
12208
                if ( options.my[ 0 ] === "right" ) {
12209
                        position.left -= elemWidth;
12210
                } else if ( options.my[ 0 ] === "center" ) {
12211
                        position.left -= elemWidth / 2;
12212
                }
12213

    
12214
                if ( options.my[ 1 ] === "bottom" ) {
12215
                        position.top -= elemHeight;
12216
                } else if ( options.my[ 1 ] === "center" ) {
12217
                        position.top -= elemHeight / 2;
12218
                }
12219

    
12220
                position.left += myOffset[ 0 ];
12221
                position.top += myOffset[ 1 ];
12222

    
12223
                // if the browser doesn't support fractions, then round for consistent results
12224
                if ( !$.support.offsetFractions ) {
12225
                        position.left = round( position.left );
12226
                        position.top = round( position.top );
12227
                }
12228

    
12229
                collisionPosition = {
12230
                        marginLeft: marginLeft,
12231
                        marginTop: marginTop
12232
                };
12233

    
12234
                $.each( [ "left", "top" ], function( i, dir ) {
12235
                        if ( $.ui.position[ collision[ i ] ] ) {
12236
                                $.ui.position[ collision[ i ] ][ dir ]( position, {
12237
                                        targetWidth: targetWidth,
12238
                                        targetHeight: targetHeight,
12239
                                        elemWidth: elemWidth,
12240
                                        elemHeight: elemHeight,
12241
                                        collisionPosition: collisionPosition,
12242
                                        collisionWidth: collisionWidth,
12243
                                        collisionHeight: collisionHeight,
12244
                                        offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
12245
                                        my: options.my,
12246
                                        at: options.at,
12247
                                        within: within,
12248
                                        elem : elem
12249
                                });
12250
                        }
12251
                });
12252

    
12253
                if ( options.using ) {
12254
                        // adds feedback as second argument to using callback, if present
12255
                        using = function( props ) {
12256
                                var left = targetOffset.left - position.left,
12257
                                        right = left + targetWidth - elemWidth,
12258
                                        top = targetOffset.top - position.top,
12259
                                        bottom = top + targetHeight - elemHeight,
12260
                                        feedback = {
12261
                                                target: {
12262
                                                        element: target,
12263
                                                        left: targetOffset.left,
12264
                                                        top: targetOffset.top,
12265
                                                        width: targetWidth,
12266
                                                        height: targetHeight
12267
                                                },
12268
                                                element: {
12269
                                                        element: elem,
12270
                                                        left: position.left,
12271
                                                        top: position.top,
12272
                                                        width: elemWidth,
12273
                                                        height: elemHeight
12274
                                                },
12275
                                                horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
12276
                                                vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
12277
                                        };
12278
                                if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
12279
                                        feedback.horizontal = "center";
12280
                                }
12281
                                if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
12282
                                        feedback.vertical = "middle";
12283
                                }
12284
                                if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
12285
                                        feedback.important = "horizontal";
12286
                                } else {
12287
                                        feedback.important = "vertical";
12288
                                }
12289
                                options.using.call( this, props, feedback );
12290
                        };
12291
                }
12292

    
12293
                elem.offset( $.extend( position, { using: using } ) );
12294
        });
12295
};
12296

    
12297
$.ui.position = {
12298
        fit: {
12299
                left: function( position, data ) {
12300
                        var within = data.within,
12301
                                withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
12302
                                outerWidth = within.width,
12303
                                collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12304
                                overLeft = withinOffset - collisionPosLeft,
12305
                                overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
12306
                                newOverRight;
12307

    
12308
                        // element is wider than within
12309
                        if ( data.collisionWidth > outerWidth ) {
12310
                                // element is initially over the left side of within
12311
                                if ( overLeft > 0 && overRight <= 0 ) {
12312
                                        newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
12313
                                        position.left += overLeft - newOverRight;
12314
                                // element is initially over right side of within
12315
                                } else if ( overRight > 0 && overLeft <= 0 ) {
12316
                                        position.left = withinOffset;
12317
                                // element is initially over both left and right sides of within
12318
                                } else {
12319
                                        if ( overLeft > overRight ) {
12320
                                                position.left = withinOffset + outerWidth - data.collisionWidth;
12321
                                        } else {
12322
                                                position.left = withinOffset;
12323
                                        }
12324
                                }
12325
                        // too far left -> align with left edge
12326
                        } else if ( overLeft > 0 ) {
12327
                                position.left += overLeft;
12328
                        // too far right -> align with right edge
12329
                        } else if ( overRight > 0 ) {
12330
                                position.left -= overRight;
12331
                        // adjust based on position and margin
12332
                        } else {
12333
                                position.left = max( position.left - collisionPosLeft, position.left );
12334
                        }
12335
                },
12336
                top: function( position, data ) {
12337
                        var within = data.within,
12338
                                withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
12339
                                outerHeight = data.within.height,
12340
                                collisionPosTop = position.top - data.collisionPosition.marginTop,
12341
                                overTop = withinOffset - collisionPosTop,
12342
                                overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
12343
                                newOverBottom;
12344

    
12345
                        // element is taller than within
12346
                        if ( data.collisionHeight > outerHeight ) {
12347
                                // element is initially over the top of within
12348
                                if ( overTop > 0 && overBottom <= 0 ) {
12349
                                        newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
12350
                                        position.top += overTop - newOverBottom;
12351
                                // element is initially over bottom of within
12352
                                } else if ( overBottom > 0 && overTop <= 0 ) {
12353
                                        position.top = withinOffset;
12354
                                // element is initially over both top and bottom of within
12355
                                } else {
12356
                                        if ( overTop > overBottom ) {
12357
                                                position.top = withinOffset + outerHeight - data.collisionHeight;
12358
                                        } else {
12359
                                                position.top = withinOffset;
12360
                                        }
12361
                                }
12362
                        // too far up -> align with top
12363
                        } else if ( overTop > 0 ) {
12364
                                position.top += overTop;
12365
                        // too far down -> align with bottom edge
12366
                        } else if ( overBottom > 0 ) {
12367
                                position.top -= overBottom;
12368
                        // adjust based on position and margin
12369
                        } else {
12370
                                position.top = max( position.top - collisionPosTop, position.top );
12371
                        }
12372
                }
12373
        },
12374
        flip: {
12375
                left: function( position, data ) {
12376
                        var within = data.within,
12377
                                withinOffset = within.offset.left + within.scrollLeft,
12378
                                outerWidth = within.width,
12379
                                offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
12380
                                collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12381
                                overLeft = collisionPosLeft - offsetLeft,
12382
                                overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
12383
                                myOffset = data.my[ 0 ] === "left" ?
12384
                                        -data.elemWidth :
12385
                                        data.my[ 0 ] === "right" ?
12386
                                                data.elemWidth :
12387
                                                0,
12388
                                atOffset = data.at[ 0 ] === "left" ?
12389
                                        data.targetWidth :
12390
                                        data.at[ 0 ] === "right" ?
12391
                                                -data.targetWidth :
12392
                                                0,
12393
                                offset = -2 * data.offset[ 0 ],
12394
                                newOverRight,
12395
                                newOverLeft;
12396

    
12397
                        if ( overLeft < 0 ) {
12398
                                newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
12399
                                if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
12400
                                        position.left += myOffset + atOffset + offset;
12401
                                }
12402
                        }
12403
                        else if ( overRight > 0 ) {
12404
                                newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
12405
                                if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
12406
                                        position.left += myOffset + atOffset + offset;
12407
                                }
12408
                        }
12409
                },
12410
                top: function( position, data ) {
12411
                        var within = data.within,
12412
                                withinOffset = within.offset.top + within.scrollTop,
12413
                                outerHeight = within.height,
12414
                                offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
12415
                                collisionPosTop = position.top - data.collisionPosition.marginTop,
12416
                                overTop = collisionPosTop - offsetTop,
12417
                                overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
12418
                                top = data.my[ 1 ] === "top",
12419
                                myOffset = top ?
12420
                                        -data.elemHeight :
12421
                                        data.my[ 1 ] === "bottom" ?
12422
                                                data.elemHeight :
12423
                                                0,
12424
                                atOffset = data.at[ 1 ] === "top" ?
12425
                                        data.targetHeight :
12426
                                        data.at[ 1 ] === "bottom" ?
12427
                                                -data.targetHeight :
12428
                                                0,
12429
                                offset = -2 * data.offset[ 1 ],
12430
                                newOverTop,
12431
                                newOverBottom;
12432
                        if ( overTop < 0 ) {
12433
                                newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
12434
                                if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
12435
                                        position.top += myOffset + atOffset + offset;
12436
                                }
12437
                        }
12438
                        else if ( overBottom > 0 ) {
12439
                                newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
12440
                                if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
12441
                                        position.top += myOffset + atOffset + offset;
12442
                                }
12443
                        }
12444
                }
12445
        },
12446
        flipfit: {
12447
                left: function() {
12448
                        $.ui.position.flip.left.apply( this, arguments );
12449
                        $.ui.position.fit.left.apply( this, arguments );
12450
                },
12451
                top: function() {
12452
                        $.ui.position.flip.top.apply( this, arguments );
12453
                        $.ui.position.fit.top.apply( this, arguments );
12454
                }
12455
        }
12456
};
12457

    
12458
// fraction support test
12459
(function () {
12460
        var testElement, testElementParent, testElementStyle, offsetLeft, i,
12461
                body = document.getElementsByTagName( "body" )[ 0 ],
12462
                div = document.createElement( "div" );
12463

    
12464
        //Create a "fake body" for testing based on method used in jQuery.support
12465
        testElement = document.createElement( body ? "div" : "body" );
12466
        testElementStyle = {
12467
                visibility: "hidden",
12468
                width: 0,
12469
                height: 0,
12470
                border: 0,
12471
                margin: 0,
12472
                background: "none"
12473
        };
12474
        if ( body ) {
12475
                $.extend( testElementStyle, {
12476
                        position: "absolute",
12477
                        left: "-1000px",
12478
                        top: "-1000px"
12479
                });
12480
        }
12481
        for ( i in testElementStyle ) {
12482
                testElement.style[ i ] = testElementStyle[ i ];
12483
        }
12484
        testElement.appendChild( div );
12485
        testElementParent = body || document.documentElement;
12486
        testElementParent.insertBefore( testElement, testElementParent.firstChild );
12487

    
12488
        div.style.cssText = "position: absolute; left: 10.7432222px;";
12489

    
12490
        offsetLeft = $( div ).offset().left;
12491
        $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
12492

    
12493
        testElement.innerHTML = "";
12494
        testElementParent.removeChild( testElement );
12495
})();
12496

    
12497
}( jQuery ) );
12498

    
12499
(function( $, undefined ) {
12500

    
12501
$.widget( "ui.progressbar", {
12502
        version: "1.10.2",
12503
        options: {
12504
                max: 100,
12505
                value: 0,
12506

    
12507
                change: null,
12508
                complete: null
12509
        },
12510

    
12511
        min: 0,
12512

    
12513
        _create: function() {
12514
                // Constrain initial value
12515
                this.oldValue = this.options.value = this._constrainedValue();
12516

    
12517
                this.element
12518
                        .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12519
                        .attr({
12520
                                // Only set static values, aria-valuenow and aria-valuemax are
12521
                                // set inside _refreshValue()
12522
                                role: "progressbar",
12523
                                "aria-valuemin": this.min
12524
                        });
12525

    
12526
                this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
12527
                        .appendTo( this.element );
12528

    
12529
                this._refreshValue();
12530
        },
12531

    
12532
        _destroy: function() {
12533
                this.element
12534
                        .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12535
                        .removeAttr( "role" )
12536
                        .removeAttr( "aria-valuemin" )
12537
                        .removeAttr( "aria-valuemax" )
12538
                        .removeAttr( "aria-valuenow" );
12539

    
12540
                this.valueDiv.remove();
12541
        },
12542

    
12543
        value: function( newValue ) {
12544
                if ( newValue === undefined ) {
12545
                        return this.options.value;
12546
                }
12547

    
12548
                this.options.value = this._constrainedValue( newValue );
12549
                this._refreshValue();
12550
        },
12551

    
12552
        _constrainedValue: function( newValue ) {
12553
                if ( newValue === undefined ) {
12554
                        newValue = this.options.value;
12555
                }
12556

    
12557
                this.indeterminate = newValue === false;
12558

    
12559
                // sanitize value
12560
                if ( typeof newValue !== "number" ) {
12561
                        newValue = 0;
12562
                }
12563

    
12564
                return this.indeterminate ? false :
12565
                        Math.min( this.options.max, Math.max( this.min, newValue ) );
12566
        },
12567

    
12568
        _setOptions: function( options ) {
12569
                // Ensure "value" option is set after other values (like max)
12570
                var value = options.value;
12571
                delete options.value;
12572

    
12573
                this._super( options );
12574

    
12575
                this.options.value = this._constrainedValue( value );
12576
                this._refreshValue();
12577
        },
12578

    
12579
        _setOption: function( key, value ) {
12580
                if ( key === "max" ) {
12581
                        // Don't allow a max less than min
12582
                        value = Math.max( this.min, value );
12583
                }
12584

    
12585
                this._super( key, value );
12586
        },
12587

    
12588
        _percentage: function() {
12589
                return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
12590
        },
12591

    
12592
        _refreshValue: function() {
12593
                var value = this.options.value,
12594
                        percentage = this._percentage();
12595

    
12596
                this.valueDiv
12597
                        .toggle( this.indeterminate || value > this.min )
12598
                        .toggleClass( "ui-corner-right", value === this.options.max )
12599
                        .width( percentage.toFixed(0) + "%" );
12600

    
12601
                this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
12602

    
12603
                if ( this.indeterminate ) {
12604
                        this.element.removeAttr( "aria-valuenow" );
12605
                        if ( !this.overlayDiv ) {
12606
                                this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
12607
                        }
12608
                } else {
12609
                        this.element.attr({
12610
                                "aria-valuemax": this.options.max,
12611
                                "aria-valuenow": value
12612
                        });
12613
                        if ( this.overlayDiv ) {
12614
                                this.overlayDiv.remove();
12615
                                this.overlayDiv = null;
12616
                        }
12617
                }
12618

    
12619
                if ( this.oldValue !== value ) {
12620
                        this.oldValue = value;
12621
                        this._trigger( "change" );
12622
                }
12623
                if ( value === this.options.max ) {
12624
                        this._trigger( "complete" );
12625
                }
12626
        }
12627
});
12628

    
12629
})( jQuery );
12630

    
12631
(function( $, undefined ) {
12632

    
12633
// number of pages in a slider
12634
// (how many times can you page up/down to go through the whole range)
12635
var numPages = 5;
12636

    
12637
$.widget( "ui.slider", $.ui.mouse, {
12638
        version: "1.10.2",
12639
        widgetEventPrefix: "slide",
12640

    
12641
        options: {
12642
                animate: false,
12643
                distance: 0,
12644
                max: 100,
12645
                min: 0,
12646
                orientation: "horizontal",
12647
                range: false,
12648
                step: 1,
12649
                value: 0,
12650
                values: null,
12651

    
12652
                // callbacks
12653
                change: null,
12654
                slide: null,
12655
                start: null,
12656
                stop: null
12657
        },
12658

    
12659
        _create: function() {
12660
                this._keySliding = false;
12661
                this._mouseSliding = false;
12662
                this._animateOff = true;
12663
                this._handleIndex = null;
12664
                this._detectOrientation();
12665
                this._mouseInit();
12666

    
12667
                this.element
12668
                        .addClass( "ui-slider" +
12669
                                " ui-slider-" + this.orientation +
12670
                                " ui-widget" +
12671
                                " ui-widget-content" +
12672
                                " ui-corner-all");
12673

    
12674
                this._refresh();
12675
                this._setOption( "disabled", this.options.disabled );
12676

    
12677
                this._animateOff = false;
12678
        },
12679

    
12680
        _refresh: function() {
12681
                this._createRange();
12682
                this._createHandles();
12683
                this._setupEvents();
12684
                this._refreshValue();
12685
        },
12686

    
12687
        _createHandles: function() {
12688
                var i, handleCount,
12689
                        options = this.options,
12690
                        existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12691
                        handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
12692
                        handles = [];
12693

    
12694
                handleCount = ( options.values && options.values.length ) || 1;
12695

    
12696
                if ( existingHandles.length > handleCount ) {
12697
                        existingHandles.slice( handleCount ).remove();
12698
                        existingHandles = existingHandles.slice( 0, handleCount );
12699
                }
12700

    
12701
                for ( i = existingHandles.length; i < handleCount; i++ ) {
12702
                        handles.push( handle );
12703
                }
12704

    
12705
                this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12706

    
12707
                this.handle = this.handles.eq( 0 );
12708

    
12709
                this.handles.each(function( i ) {
12710
                        $( this ).data( "ui-slider-handle-index", i );
12711
                });
12712
        },
12713

    
12714
        _createRange: function() {
12715
                var options = this.options,
12716
                        classes = "";
12717

    
12718
                if ( options.range ) {
12719
                        if ( options.range === true ) {
12720
                                if ( !options.values ) {
12721
                                        options.values = [ this._valueMin(), this._valueMin() ];
12722
                                } else if ( options.values.length && options.values.length !== 2 ) {
12723
                                        options.values = [ options.values[0], options.values[0] ];
12724
                                } else if ( $.isArray( options.values ) ) {
12725
                                        options.values = options.values.slice(0);
12726
                                }
12727
                        }
12728

    
12729
                        if ( !this.range || !this.range.length ) {
12730
                                this.range = $( "<div></div>" )
12731
                                        .appendTo( this.element );
12732

    
12733
                                classes = "ui-slider-range" +
12734
                                // note: this isn't the most fittingly semantic framework class for this element,
12735
                                // but worked best visually with a variety of themes
12736
                                " ui-widget-header ui-corner-all";
12737
                        } else {
12738
                                this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12739
                                        // Handle range switching from true to min/max
12740
                                        .css({
12741
                                                "left": "",
12742
                                                "bottom": ""
12743
                                        });
12744
                        }
12745

    
12746
                        this.range.addClass( classes +
12747
                                ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12748
                } else {
12749
                        this.range = $([]);
12750
                }
12751
        },
12752

    
12753
        _setupEvents: function() {
12754
                var elements = this.handles.add( this.range ).filter( "a" );
12755
                this._off( elements );
12756
                this._on( elements, this._handleEvents );
12757
                this._hoverable( elements );
12758
                this._focusable( elements );
12759
        },
12760

    
12761
        _destroy: function() {
12762
                this.handles.remove();
12763
                this.range.remove();
12764

    
12765
                this.element
12766
                        .removeClass( "ui-slider" +
12767
                                " ui-slider-horizontal" +
12768
                                " ui-slider-vertical" +
12769
                                " ui-widget" +
12770
                                " ui-widget-content" +
12771
                                " ui-corner-all" );
12772

    
12773
                this._mouseDestroy();
12774
        },
12775

    
12776
        _mouseCapture: function( event ) {
12777
                var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12778
                        that = this,
12779
                        o = this.options;
12780

    
12781
                if ( o.disabled ) {
12782
                        return false;
12783
                }
12784

    
12785
                this.elementSize = {
12786
                        width: this.element.outerWidth(),
12787
                        height: this.element.outerHeight()
12788
                };
12789
                this.elementOffset = this.element.offset();
12790

    
12791
                position = { x: event.pageX, y: event.pageY };
12792
                normValue = this._normValueFromMouse( position );
12793
                distance = this._valueMax() - this._valueMin() + 1;
12794
                this.handles.each(function( i ) {
12795
                        var thisDistance = Math.abs( normValue - that.values(i) );
12796
                        if (( distance > thisDistance ) ||
12797
                                ( distance === thisDistance &&
12798
                                        (i === that._lastChangedValue || that.values(i) === o.min ))) {
12799
                                distance = thisDistance;
12800
                                closestHandle = $( this );
12801
                                index = i;
12802
                        }
12803
                });
12804

    
12805
                allowed = this._start( event, index );
12806
                if ( allowed === false ) {
12807
                        return false;
12808
                }
12809
                this._mouseSliding = true;
12810

    
12811
                this._handleIndex = index;
12812

    
12813
                closestHandle
12814
                        .addClass( "ui-state-active" )
12815
                        .focus();
12816

    
12817
                offset = closestHandle.offset();
12818
                mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12819
                this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12820
                        left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12821
                        top: event.pageY - offset.top -
12822
                                ( closestHandle.height() / 2 ) -
12823
                                ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12824
                                ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12825
                                ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12826
                };
12827

    
12828
                if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12829
                        this._slide( event, index, normValue );
12830
                }
12831
                this._animateOff = true;
12832
                return true;
12833
        },
12834

    
12835
        _mouseStart: function() {
12836
                return true;
12837
        },
12838

    
12839
        _mouseDrag: function( event ) {
12840
                var position = { x: event.pageX, y: event.pageY },
12841
                        normValue = this._normValueFromMouse( position );
12842

    
12843
                this._slide( event, this._handleIndex, normValue );
12844

    
12845
                return false;
12846
        },
12847

    
12848
        _mouseStop: function( event ) {
12849
                this.handles.removeClass( "ui-state-active" );
12850
                this._mouseSliding = false;
12851

    
12852
                this._stop( event, this._handleIndex );
12853
                this._change( event, this._handleIndex );
12854

    
12855
                this._handleIndex = null;
12856
                this._clickOffset = null;
12857
                this._animateOff = false;
12858

    
12859
                return false;
12860
        },
12861

    
12862
        _detectOrientation: function() {
12863
                this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
12864
        },
12865

    
12866
        _normValueFromMouse: function( position ) {
12867
                var pixelTotal,
12868
                        pixelMouse,
12869
                        percentMouse,
12870
                        valueTotal,
12871
                        valueMouse;
12872

    
12873
                if ( this.orientation === "horizontal" ) {
12874
                        pixelTotal = this.elementSize.width;
12875
                        pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
12876
                } else {
12877
                        pixelTotal = this.elementSize.height;
12878
                        pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
12879
                }
12880

    
12881
                percentMouse = ( pixelMouse / pixelTotal );
12882
                if ( percentMouse > 1 ) {
12883
                        percentMouse = 1;
12884
                }
12885
                if ( percentMouse < 0 ) {
12886
                        percentMouse = 0;
12887
                }
12888
                if ( this.orientation === "vertical" ) {
12889
                        percentMouse = 1 - percentMouse;
12890
                }
12891

    
12892
                valueTotal = this._valueMax() - this._valueMin();
12893
                valueMouse = this._valueMin() + percentMouse * valueTotal;
12894

    
12895
                return this._trimAlignValue( valueMouse );
12896
        },
12897

    
12898
        _start: function( event, index ) {
12899
                var uiHash = {
12900
                        handle: this.handles[ index ],
12901
                        value: this.value()
12902
                };
12903
                if ( this.options.values && this.options.values.length ) {
12904
                        uiHash.value = this.values( index );
12905
                        uiHash.values = this.values();
12906
                }
12907
                return this._trigger( "start", event, uiHash );
12908
        },
12909

    
12910
        _slide: function( event, index, newVal ) {
12911
                var otherVal,
12912
                        newValues,
12913
                        allowed;
12914

    
12915
                if ( this.options.values && this.options.values.length ) {
12916
                        otherVal = this.values( index ? 0 : 1 );
12917

    
12918
                        if ( ( this.options.values.length === 2 && this.options.range === true ) &&
12919
                                        ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
12920
                                ) {
12921
                                newVal = otherVal;
12922
                        }
12923

    
12924
                        if ( newVal !== this.values( index ) ) {
12925
                                newValues = this.values();
12926
                                newValues[ index ] = newVal;
12927
                                // A slide can be canceled by returning false from the slide callback
12928
                                allowed = this._trigger( "slide", event, {
12929
                                        handle: this.handles[ index ],
12930
                                        value: newVal,
12931
                                        values: newValues
12932
                                } );
12933
                                otherVal = this.values( index ? 0 : 1 );
12934
                                if ( allowed !== false ) {
12935
                                        this.values( index, newVal, true );
12936
                                }
12937
                        }
12938
                } else {
12939
                        if ( newVal !== this.value() ) {
12940
                                // A slide can be canceled by returning false from the slide callback
12941
                                allowed = this._trigger( "slide", event, {
12942
                                        handle: this.handles[ index ],
12943
                                        value: newVal
12944
                                } );
12945
                                if ( allowed !== false ) {
12946
                                        this.value( newVal );
12947
                                }
12948
                        }
12949
                }
12950
        },
12951

    
12952
        _stop: function( event, index ) {
12953
                var uiHash = {
12954
                        handle: this.handles[ index ],
12955
                        value: this.value()
12956
                };
12957
                if ( this.options.values && this.options.values.length ) {
12958
                        uiHash.value = this.values( index );
12959
                        uiHash.values = this.values();
12960
                }
12961

    
12962
                this._trigger( "stop", event, uiHash );
12963
        },
12964

    
12965
        _change: function( event, index ) {
12966
                if ( !this._keySliding && !this._mouseSliding ) {
12967
                        var uiHash = {
12968
                                handle: this.handles[ index ],
12969
                                value: this.value()
12970
                        };
12971
                        if ( this.options.values && this.options.values.length ) {
12972
                                uiHash.value = this.values( index );
12973
                                uiHash.values = this.values();
12974
                        }
12975

    
12976
                        //store the last changed value index for reference when handles overlap
12977
                        this._lastChangedValue = index;
12978

    
12979
                        this._trigger( "change", event, uiHash );
12980
                }
12981
        },
12982

    
12983
        value: function( newValue ) {
12984
                if ( arguments.length ) {
12985
                        this.options.value = this._trimAlignValue( newValue );
12986
                        this._refreshValue();
12987
                        this._change( null, 0 );
12988
                        return;
12989
                }
12990

    
12991
                return this._value();
12992
        },
12993

    
12994
        values: function( index, newValue ) {
12995
                var vals,
12996
                        newValues,
12997
                        i;
12998

    
12999
                if ( arguments.length > 1 ) {
13000
                        this.options.values[ index ] = this._trimAlignValue( newValue );
13001
                        this._refreshValue();
13002
                        this._change( null, index );
13003
                        return;
13004
                }
13005

    
13006
                if ( arguments.length ) {
13007
                        if ( $.isArray( arguments[ 0 ] ) ) {
13008
                                vals = this.options.values;
13009
                                newValues = arguments[ 0 ];
13010
                                for ( i = 0; i < vals.length; i += 1 ) {
13011
                                        vals[ i ] = this._trimAlignValue( newValues[ i ] );
13012
                                        this._change( null, i );
13013
                                }
13014
                                this._refreshValue();
13015
                        } else {
13016
                                if ( this.options.values && this.options.values.length ) {
13017
                                        return this._values( index );
13018
                                } else {
13019
                                        return this.value();
13020
                                }
13021
                        }
13022
                } else {
13023
                        return this._values();
13024
                }
13025
        },
13026

    
13027
        _setOption: function( key, value ) {
13028
                var i,
13029
                        valsLength = 0;
13030

    
13031
                if ( key === "range" && this.options.range === true ) {
13032
                        if ( value === "min" ) {
13033
                                this.options.value = this._values( 0 );
13034
                                this.options.values = null;
13035
                        } else if ( value === "max" ) {
13036
                                this.options.value = this._values( this.options.values.length-1 );
13037
                                this.options.values = null;
13038
                        }
13039
                }
13040

    
13041
                if ( $.isArray( this.options.values ) ) {
13042
                        valsLength = this.options.values.length;
13043
                }
13044

    
13045
                $.Widget.prototype._setOption.apply( this, arguments );
13046

    
13047
                switch ( key ) {
13048
                        case "orientation":
13049
                                this._detectOrientation();
13050
                                this.element
13051
                                        .removeClass( "ui-slider-horizontal ui-slider-vertical" )
13052
                                        .addClass( "ui-slider-" + this.orientation );
13053
                                this._refreshValue();
13054
                                break;
13055
                        case "value":
13056
                                this._animateOff = true;
13057
                                this._refreshValue();
13058
                                this._change( null, 0 );
13059
                                this._animateOff = false;
13060
                                break;
13061
                        case "values":
13062
                                this._animateOff = true;
13063
                                this._refreshValue();
13064
                                for ( i = 0; i < valsLength; i += 1 ) {
13065
                                        this._change( null, i );
13066
                                }
13067
                                this._animateOff = false;
13068
                                break;
13069
                        case "min":
13070
                        case "max":
13071
                                this._animateOff = true;
13072
                                this._refreshValue();
13073
                                this._animateOff = false;
13074
                                break;
13075
                        case "range":
13076
                                this._animateOff = true;
13077
                                this._refresh();
13078
                                this._animateOff = false;
13079
                                break;
13080
                }
13081
        },
13082

    
13083
        //internal value getter
13084
        // _value() returns value trimmed by min and max, aligned by step
13085
        _value: function() {
13086
                var val = this.options.value;
13087
                val = this._trimAlignValue( val );
13088

    
13089
                return val;
13090
        },
13091

    
13092
        //internal values getter
13093
        // _values() returns array of values trimmed by min and max, aligned by step
13094
        // _values( index ) returns single value trimmed by min and max, aligned by step
13095
        _values: function( index ) {
13096
                var val,
13097
                        vals,
13098
                        i;
13099

    
13100
                if ( arguments.length ) {
13101
                        val = this.options.values[ index ];
13102
                        val = this._trimAlignValue( val );
13103

    
13104
                        return val;
13105
                } else if ( this.options.values && this.options.values.length ) {
13106
                        // .slice() creates a copy of the array
13107
                        // this copy gets trimmed by min and max and then returned
13108
                        vals = this.options.values.slice();
13109
                        for ( i = 0; i < vals.length; i+= 1) {
13110
                                vals[ i ] = this._trimAlignValue( vals[ i ] );
13111
                        }
13112

    
13113
                        return vals;
13114
                } else {
13115
                        return [];
13116
                }
13117
        },
13118

    
13119
        // returns the step-aligned value that val is closest to, between (inclusive) min and max
13120
        _trimAlignValue: function( val ) {
13121
                if ( val <= this._valueMin() ) {
13122
                        return this._valueMin();
13123
                }
13124
                if ( val >= this._valueMax() ) {
13125
                        return this._valueMax();
13126
                }
13127
                var step = ( this.options.step > 0 ) ? this.options.step : 1,
13128
                        valModStep = (val - this._valueMin()) % step,
13129
                        alignValue = val - valModStep;
13130

    
13131
                if ( Math.abs(valModStep) * 2 >= step ) {
13132
                        alignValue += ( valModStep > 0 ) ? step : ( -step );
13133
                }
13134

    
13135
                // Since JavaScript has problems with large floats, round
13136
                // the final value to 5 digits after the decimal point (see #4124)
13137
                return parseFloat( alignValue.toFixed(5) );
13138
        },
13139

    
13140
        _valueMin: function() {
13141
                return this.options.min;
13142
        },
13143

    
13144
        _valueMax: function() {
13145
                return this.options.max;
13146
        },
13147

    
13148
        _refreshValue: function() {
13149
                var lastValPercent, valPercent, value, valueMin, valueMax,
13150
                        oRange = this.options.range,
13151
                        o = this.options,
13152
                        that = this,
13153
                        animate = ( !this._animateOff ) ? o.animate : false,
13154
                        _set = {};
13155

    
13156
                if ( this.options.values && this.options.values.length ) {
13157
                        this.handles.each(function( i ) {
13158
                                valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13159
                                _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13160
                                $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13161
                                if ( that.options.range === true ) {
13162
                                        if ( that.orientation === "horizontal" ) {
13163
                                                if ( i === 0 ) {
13164
                                                        that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13165
                                                }
13166
                                                if ( i === 1 ) {
13167
                                                        that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13168
                                                }
13169
                                        } else {
13170
                                                if ( i === 0 ) {
13171
                                                        that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13172
                                                }
13173
                                                if ( i === 1 ) {
13174
                                                        that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13175
                                                }
13176
                                        }
13177
                                }
13178
                                lastValPercent = valPercent;
13179
                        });
13180
                } else {
13181
                        value = this.value();
13182
                        valueMin = this._valueMin();
13183
                        valueMax = this._valueMax();
13184
                        valPercent = ( valueMax !== valueMin ) ?
13185
                                        ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13186
                                        0;
13187
                        _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13188
                        this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13189

    
13190
                        if ( oRange === "min" && this.orientation === "horizontal" ) {
13191
                                this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13192
                        }
13193
                        if ( oRange === "max" && this.orientation === "horizontal" ) {
13194
                                this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13195
                        }
13196
                        if ( oRange === "min" && this.orientation === "vertical" ) {
13197
                                this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13198
                        }
13199
                        if ( oRange === "max" && this.orientation === "vertical" ) {
13200
                                this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13201
                        }
13202
                }
13203
        },
13204

    
13205
        _handleEvents: {
13206
                keydown: function( event ) {
13207
                        /*jshint maxcomplexity:25*/
13208
                        var allowed, curVal, newVal, step,
13209
                                index = $( event.target ).data( "ui-slider-handle-index" );
13210

    
13211
                        switch ( event.keyCode ) {
13212
                                case $.ui.keyCode.HOME:
13213
                                case $.ui.keyCode.END:
13214
                                case $.ui.keyCode.PAGE_UP:
13215
                                case $.ui.keyCode.PAGE_DOWN:
13216
                                case $.ui.keyCode.UP:
13217
                                case $.ui.keyCode.RIGHT:
13218
                                case $.ui.keyCode.DOWN:
13219
                                case $.ui.keyCode.LEFT:
13220
                                        event.preventDefault();
13221
                                        if ( !this._keySliding ) {
13222
                                                this._keySliding = true;
13223
                                                $( event.target ).addClass( "ui-state-active" );
13224
                                                allowed = this._start( event, index );
13225
                                                if ( allowed === false ) {
13226
                                                        return;
13227
                                                }
13228
                                        }
13229
                                        break;
13230
                        }
13231

    
13232
                        step = this.options.step;
13233
                        if ( this.options.values && this.options.values.length ) {
13234
                                curVal = newVal = this.values( index );
13235
                        } else {
13236
                                curVal = newVal = this.value();
13237
                        }
13238

    
13239
                        switch ( event.keyCode ) {
13240
                                case $.ui.keyCode.HOME:
13241
                                        newVal = this._valueMin();
13242
                                        break;
13243
                                case $.ui.keyCode.END:
13244
                                        newVal = this._valueMax();
13245
                                        break;
13246
                                case $.ui.keyCode.PAGE_UP:
13247
                                        newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
13248
                                        break;
13249
                                case $.ui.keyCode.PAGE_DOWN:
13250
                                        newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
13251
                                        break;
13252
                                case $.ui.keyCode.UP:
13253
                                case $.ui.keyCode.RIGHT:
13254
                                        if ( curVal === this._valueMax() ) {
13255
                                                return;
13256
                                        }
13257
                                        newVal = this._trimAlignValue( curVal + step );
13258
                                        break;
13259
                                case $.ui.keyCode.DOWN:
13260
                                case $.ui.keyCode.LEFT:
13261
                                        if ( curVal === this._valueMin() ) {
13262
                                                return;
13263
                                        }
13264
                                        newVal = this._trimAlignValue( curVal - step );
13265
                                        break;
13266
                        }
13267

    
13268
                        this._slide( event, index, newVal );
13269
                },
13270
                click: function( event ) {
13271
                        event.preventDefault();
13272
                },
13273
                keyup: function( event ) {
13274
                        var index = $( event.target ).data( "ui-slider-handle-index" );
13275

    
13276
                        if ( this._keySliding ) {
13277
                                this._keySliding = false;
13278
                                this._stop( event, index );
13279
                                this._change( event, index );
13280
                                $( event.target ).removeClass( "ui-state-active" );
13281
                        }
13282
                }
13283
        }
13284

    
13285
});
13286

    
13287
}(jQuery));
13288

    
13289
(function( $ ) {
13290

    
13291
function modifier( fn ) {
13292
        return function() {
13293
                var previous = this.element.val();
13294
                fn.apply( this, arguments );
13295
                this._refresh();
13296
                if ( previous !== this.element.val() ) {
13297
                        this._trigger( "change" );
13298
                }
13299
        };
13300
}
13301

    
13302
$.widget( "ui.spinner", {
13303
        version: "1.10.2",
13304
        defaultElement: "<input>",
13305
        widgetEventPrefix: "spin",
13306
        options: {
13307
                culture: null,
13308
                icons: {
13309
                        down: "ui-icon-triangle-1-s",
13310
                        up: "ui-icon-triangle-1-n"
13311
                },
13312
                incremental: true,
13313
                max: null,
13314
                min: null,
13315
                numberFormat: null,
13316
                page: 10,
13317
                step: 1,
13318

    
13319
                change: null,
13320
                spin: null,
13321
                start: null,
13322
                stop: null
13323
        },
13324

    
13325
        _create: function() {
13326
                // handle string values that need to be parsed
13327
                this._setOption( "max", this.options.max );
13328
                this._setOption( "min", this.options.min );
13329
                this._setOption( "step", this.options.step );
13330

    
13331
                // format the value, but don't constrain
13332
                this._value( this.element.val(), true );
13333

    
13334
                this._draw();
13335
                this._on( this._events );
13336
                this._refresh();
13337

    
13338
                // turning off autocomplete prevents the browser from remembering the
13339
                // value when navigating through history, so we re-enable autocomplete
13340
                // if the page is unloaded before the widget is destroyed. #7790
13341
                this._on( this.window, {
13342
                        beforeunload: function() {
13343
                                this.element.removeAttr( "autocomplete" );
13344
                        }
13345
                });
13346
        },
13347

    
13348
        _getCreateOptions: function() {
13349
                var options = {},
13350
                        element = this.element;
13351

    
13352
                $.each( [ "min", "max", "step" ], function( i, option ) {
13353
                        var value = element.attr( option );
13354
                        if ( value !== undefined && value.length ) {
13355
                                options[ option ] = value;
13356
                        }
13357
                });
13358

    
13359
                return options;
13360
        },
13361

    
13362
        _events: {
13363
                keydown: function( event ) {
13364
                        if ( this._start( event ) && this._keydown( event ) ) {
13365
                                event.preventDefault();
13366
                        }
13367
                },
13368
                keyup: "_stop",
13369
                focus: function() {
13370
                        this.previous = this.element.val();
13371
                },
13372
                blur: function( event ) {
13373
                        if ( this.cancelBlur ) {
13374
                                delete this.cancelBlur;
13375
                                return;
13376
                        }
13377

    
13378
                        this._stop();
13379
                        this._refresh();
13380
                        if ( this.previous !== this.element.val() ) {
13381
                                this._trigger( "change", event );
13382
                        }
13383
                },
13384
                mousewheel: function( event, delta ) {
13385
                        if ( !delta ) {
13386
                                return;
13387
                        }
13388
                        if ( !this.spinning && !this._start( event ) ) {
13389
                                return false;
13390
                        }
13391

    
13392
                        this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
13393
                        clearTimeout( this.mousewheelTimer );
13394
                        this.mousewheelTimer = this._delay(function() {
13395
                                if ( this.spinning ) {
13396
                                        this._stop( event );
13397
                                }
13398
                        }, 100 );
13399
                        event.preventDefault();
13400
                },
13401
                "mousedown .ui-spinner-button": function( event ) {
13402
                        var previous;
13403

    
13404
                        // We never want the buttons to have focus; whenever the user is
13405
                        // interacting with the spinner, the focus should be on the input.
13406
                        // If the input is focused then this.previous is properly set from
13407
                        // when the input first received focus. If the input is not focused
13408
                        // then we need to set this.previous based on the value before spinning.
13409
                        previous = this.element[0] === this.document[0].activeElement ?
13410
                                this.previous : this.element.val();
13411
                        function checkFocus() {
13412
                                var isActive = this.element[0] === this.document[0].activeElement;
13413
                                if ( !isActive ) {
13414
                                        this.element.focus();
13415
                                        this.previous = previous;
13416
                                        // support: IE
13417
                                        // IE sets focus asynchronously, so we need to check if focus
13418
                                        // moved off of the input because the user clicked on the button.
13419
                                        this._delay(function() {
13420
                                                this.previous = previous;
13421
                                        });
13422
                                }
13423
                        }
13424

    
13425
                        // ensure focus is on (or stays on) the text field
13426
                        event.preventDefault();
13427
                        checkFocus.call( this );
13428

    
13429
                        // support: IE
13430
                        // IE doesn't prevent moving focus even with event.preventDefault()
13431
                        // so we set a flag to know when we should ignore the blur event
13432
                        // and check (again) if focus moved off of the input.
13433
                        this.cancelBlur = true;
13434
                        this._delay(function() {
13435
                                delete this.cancelBlur;
13436
                                checkFocus.call( this );
13437
                        });
13438

    
13439
                        if ( this._start( event ) === false ) {
13440
                                return;
13441
                        }
13442

    
13443
                        this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13444
                },
13445
                "mouseup .ui-spinner-button": "_stop",
13446
                "mouseenter .ui-spinner-button": function( event ) {
13447
                        // button will add ui-state-active if mouse was down while mouseleave and kept down
13448
                        if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
13449
                                return;
13450
                        }
13451

    
13452
                        if ( this._start( event ) === false ) {
13453
                                return false;
13454
                        }
13455
                        this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13456
                },
13457
                // TODO: do we really want to consider this a stop?
13458
                // shouldn't we just stop the repeater and wait until mouseup before
13459
                // we trigger the stop event?
13460
                "mouseleave .ui-spinner-button": "_stop"
13461
        },
13462

    
13463
        _draw: function() {
13464
                var uiSpinner = this.uiSpinner = this.element
13465
                        .addClass( "ui-spinner-input" )
13466
                        .attr( "autocomplete", "off" )
13467
                        .wrap( this._uiSpinnerHtml() )
13468
                        .parent()
13469
                                // add buttons
13470
                                .append( this._buttonHtml() );
13471

    
13472
                this.element.attr( "role", "spinbutton" );
13473

    
13474
                // button bindings
13475
                this.buttons = uiSpinner.find( ".ui-spinner-button" )
13476
                        .attr( "tabIndex", -1 )
13477
                        .button()
13478
                        .removeClass( "ui-corner-all" );
13479

    
13480
                // IE 6 doesn't understand height: 50% for the buttons
13481
                // unless the wrapper has an explicit height
13482
                if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
13483
                                uiSpinner.height() > 0 ) {
13484
                        uiSpinner.height( uiSpinner.height() );
13485
                }
13486

    
13487
                // disable spinner if element was already disabled
13488
                if ( this.options.disabled ) {
13489
                        this.disable();
13490
                }
13491
        },
13492

    
13493
        _keydown: function( event ) {
13494
                var options = this.options,
13495
                        keyCode = $.ui.keyCode;
13496

    
13497
                switch ( event.keyCode ) {
13498
                case keyCode.UP:
13499
                        this._repeat( null, 1, event );
13500
                        return true;
13501
                case keyCode.DOWN:
13502
                        this._repeat( null, -1, event );
13503
                        return true;
13504
                case keyCode.PAGE_UP:
13505
                        this._repeat( null, options.page, event );
13506
                        return true;
13507
                case keyCode.PAGE_DOWN:
13508
                        this._repeat( null, -options.page, event );
13509
                        return true;
13510
                }
13511

    
13512
                return false;
13513
        },
13514

    
13515
        _uiSpinnerHtml: function() {
13516
                return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
13517
        },
13518

    
13519
        _buttonHtml: function() {
13520
                return "" +
13521
                        "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
13522
                                "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
13523
                        "</a>" +
13524
                        "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
13525
                                "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
13526
                        "</a>";
13527
        },
13528

    
13529
        _start: function( event ) {
13530
                if ( !this.spinning && this._trigger( "start", event ) === false ) {
13531
                        return false;
13532
                }
13533

    
13534
                if ( !this.counter ) {
13535
                        this.counter = 1;
13536
                }
13537
                this.spinning = true;
13538
                return true;
13539
        },
13540

    
13541
        _repeat: function( i, steps, event ) {
13542
                i = i || 500;
13543

    
13544
                clearTimeout( this.timer );
13545
                this.timer = this._delay(function() {
13546
                        this._repeat( 40, steps, event );
13547
                }, i );
13548

    
13549
                this._spin( steps * this.options.step, event );
13550
        },
13551

    
13552
        _spin: function( step, event ) {
13553
                var value = this.value() || 0;
13554

    
13555
                if ( !this.counter ) {
13556
                        this.counter = 1;
13557
                }
13558

    
13559
                value = this._adjustValue( value + step * this._increment( this.counter ) );
13560

    
13561
                if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
13562
                        this._value( value );
13563
                        this.counter++;
13564
                }
13565
        },
13566

    
13567
        _increment: function( i ) {
13568
                var incremental = this.options.incremental;
13569

    
13570
                if ( incremental ) {
13571
                        return $.isFunction( incremental ) ?
13572
                                incremental( i ) :
13573
                                Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
13574
                }
13575

    
13576
                return 1;
13577
        },
13578

    
13579
        _precision: function() {
13580
                var precision = this._precisionOf( this.options.step );
13581
                if ( this.options.min !== null ) {
13582
                        precision = Math.max( precision, this._precisionOf( this.options.min ) );
13583
                }
13584
                return precision;
13585
        },
13586

    
13587
        _precisionOf: function( num ) {
13588
                var str = num.toString(),
13589
                        decimal = str.indexOf( "." );
13590
                return decimal === -1 ? 0 : str.length - decimal - 1;
13591
        },
13592

    
13593
        _adjustValue: function( value ) {
13594
                var base, aboveMin,
13595
                        options = this.options;
13596

    
13597
                // make sure we're at a valid step
13598
                // - find out where we are relative to the base (min or 0)
13599
                base = options.min !== null ? options.min : 0;
13600
                aboveMin = value - base;
13601
                // - round to the nearest step
13602
                aboveMin = Math.round(aboveMin / options.step) * options.step;
13603
                // - rounding is based on 0, so adjust back to our base
13604
                value = base + aboveMin;
13605

    
13606
                // fix precision from bad JS floating point math
13607
                value = parseFloat( value.toFixed( this._precision() ) );
13608

    
13609
                // clamp the value
13610
                if ( options.max !== null && value > options.max) {
13611
                        return options.max;
13612
                }
13613
                if ( options.min !== null && value < options.min ) {
13614
                        return options.min;
13615
                }
13616

    
13617
                return value;
13618
        },
13619

    
13620
        _stop: function( event ) {
13621
                if ( !this.spinning ) {
13622
                        return;
13623
                }
13624

    
13625
                clearTimeout( this.timer );
13626
                clearTimeout( this.mousewheelTimer );
13627
                this.counter = 0;
13628
                this.spinning = false;
13629
                this._trigger( "stop", event );
13630
        },
13631

    
13632
        _setOption: function( key, value ) {
13633
                if ( key === "culture" || key === "numberFormat" ) {
13634
                        var prevValue = this._parse( this.element.val() );
13635
                        this.options[ key ] = value;
13636
                        this.element.val( this._format( prevValue ) );
13637
                        return;
13638
                }
13639

    
13640
                if ( key === "max" || key === "min" || key === "step" ) {
13641
                        if ( typeof value === "string" ) {
13642
                                value = this._parse( value );
13643
                        }
13644
                }
13645
                if ( key === "icons" ) {
13646
                        this.buttons.first().find( ".ui-icon" )
13647
                                .removeClass( this.options.icons.up )
13648
                                .addClass( value.up );
13649
                        this.buttons.last().find( ".ui-icon" )
13650
                                .removeClass( this.options.icons.down )
13651
                                .addClass( value.down );
13652
                }
13653

    
13654
                this._super( key, value );
13655

    
13656
                if ( key === "disabled" ) {
13657
                        if ( value ) {
13658
                                this.element.prop( "disabled", true );
13659
                                this.buttons.button( "disable" );
13660
                        } else {
13661
                                this.element.prop( "disabled", false );
13662
                                this.buttons.button( "enable" );
13663
                        }
13664
                }
13665
        },
13666

    
13667
        _setOptions: modifier(function( options ) {
13668
                this._super( options );
13669
                this._value( this.element.val() );
13670
        }),
13671

    
13672
        _parse: function( val ) {
13673
                if ( typeof val === "string" && val !== "" ) {
13674
                        val = window.Globalize && this.options.numberFormat ?
13675
                                Globalize.parseFloat( val, 10, this.options.culture ) : +val;
13676
                }
13677
                return val === "" || isNaN( val ) ? null : val;
13678
        },
13679

    
13680
        _format: function( value ) {
13681
                if ( value === "" ) {
13682
                        return "";
13683
                }
13684
                return window.Globalize && this.options.numberFormat ?
13685
                        Globalize.format( value, this.options.numberFormat, this.options.culture ) :
13686
                        value;
13687
        },
13688

    
13689
        _refresh: function() {
13690
                this.element.attr({
13691
                        "aria-valuemin": this.options.min,
13692
                        "aria-valuemax": this.options.max,
13693
                        // TODO: what should we do with values that can't be parsed?
13694
                        "aria-valuenow": this._parse( this.element.val() )
13695
                });
13696
        },
13697

    
13698
        // update the value without triggering change
13699
        _value: function( value, allowAny ) {
13700
                var parsed;
13701
                if ( value !== "" ) {
13702
                        parsed = this._parse( value );
13703
                        if ( parsed !== null ) {
13704
                                if ( !allowAny ) {
13705
                                        parsed = this._adjustValue( parsed );
13706
                                }
13707
                                value = this._format( parsed );
13708
                        }
13709
                }
13710
                this.element.val( value );
13711
                this._refresh();
13712
        },
13713

    
13714
        _destroy: function() {
13715
                this.element
13716
                        .removeClass( "ui-spinner-input" )
13717
                        .prop( "disabled", false )
13718
                        .removeAttr( "autocomplete" )
13719
                        .removeAttr( "role" )
13720
                        .removeAttr( "aria-valuemin" )
13721
                        .removeAttr( "aria-valuemax" )
13722
                        .removeAttr( "aria-valuenow" );
13723
                this.uiSpinner.replaceWith( this.element );
13724
        },
13725

    
13726
        stepUp: modifier(function( steps ) {
13727
                this._stepUp( steps );
13728
        }),
13729
        _stepUp: function( steps ) {
13730
                if ( this._start() ) {
13731
                        this._spin( (steps || 1) * this.options.step );
13732
                        this._stop();
13733
                }
13734
        },
13735

    
13736
        stepDown: modifier(function( steps ) {
13737
                this._stepDown( steps );
13738
        }),
13739
        _stepDown: function( steps ) {
13740
                if ( this._start() ) {
13741
                        this._spin( (steps || 1) * -this.options.step );
13742
                        this._stop();
13743
                }
13744
        },
13745

    
13746
        pageUp: modifier(function( pages ) {
13747
                this._stepUp( (pages || 1) * this.options.page );
13748
        }),
13749

    
13750
        pageDown: modifier(function( pages ) {
13751
                this._stepDown( (pages || 1) * this.options.page );
13752
        }),
13753

    
13754
        value: function( newVal ) {
13755
                if ( !arguments.length ) {
13756
                        return this._parse( this.element.val() );
13757
                }
13758
                modifier( this._value ).call( this, newVal );
13759
        },
13760

    
13761
        widget: function() {
13762
                return this.uiSpinner;
13763
        }
13764
});
13765

    
13766
}( jQuery ) );
13767

    
13768
(function( $, undefined ) {
13769

    
13770
var tabId = 0,
13771
        rhash = /#.*$/;
13772

    
13773
function getNextTabId() {
13774
        return ++tabId;
13775
}
13776

    
13777
function isLocal( anchor ) {
13778
        return anchor.hash.length > 1 &&
13779
                decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
13780
                        decodeURIComponent( location.href.replace( rhash, "" ) );
13781
}
13782

    
13783
$.widget( "ui.tabs", {
13784
        version: "1.10.2",
13785
        delay: 300,
13786
        options: {
13787
                active: null,
13788
                collapsible: false,
13789
                event: "click",
13790
                heightStyle: "content",
13791
                hide: null,
13792
                show: null,
13793

    
13794
                // callbacks
13795
                activate: null,
13796
                beforeActivate: null,
13797
                beforeLoad: null,
13798
                load: null
13799
        },
13800

    
13801
        _create: function() {
13802
                var that = this,
13803
                        options = this.options;
13804

    
13805
                this.running = false;
13806

    
13807
                this.element
13808
                        .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
13809
                        .toggleClass( "ui-tabs-collapsible", options.collapsible )
13810
                        // Prevent users from focusing disabled tabs via click
13811
                        .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
13812
                                if ( $( this ).is( ".ui-state-disabled" ) ) {
13813
                                        event.preventDefault();
13814
                                }
13815
                        })
13816
                        // support: IE <9
13817
                        // Preventing the default action in mousedown doesn't prevent IE
13818
                        // from focusing the element, so if the anchor gets focused, blur.
13819
                        // We don't have to worry about focusing the previously focused
13820
                        // element since clicking on a non-focusable element should focus
13821
                        // the body anyway.
13822
                        .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13823
                                if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13824
                                        this.blur();
13825
                                }
13826
                        });
13827

    
13828
                this._processTabs();
13829
                options.active = this._initialActive();
13830

    
13831
                // Take disabling tabs via class attribute from HTML
13832
                // into account and update option properly.
13833
                if ( $.isArray( options.disabled ) ) {
13834
                        options.disabled = $.unique( options.disabled.concat(
13835
                                $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
13836
                                        return that.tabs.index( li );
13837
                                })
13838
                        ) ).sort();
13839
                }
13840

    
13841
                // check for length avoids error when initializing empty list
13842
                if ( this.options.active !== false && this.anchors.length ) {
13843
                        this.active = this._findActive( options.active );
13844
                } else {
13845
                        this.active = $();
13846
                }
13847

    
13848
                this._refresh();
13849

    
13850
                if ( this.active.length ) {
13851
                        this.load( options.active );
13852
                }
13853
        },
13854

    
13855
        _initialActive: function() {
13856
                var active = this.options.active,
13857
                        collapsible = this.options.collapsible,
13858
                        locationHash = location.hash.substring( 1 );
13859

    
13860
                if ( active === null ) {
13861
                        // check the fragment identifier in the URL
13862
                        if ( locationHash ) {
13863
                                this.tabs.each(function( i, tab ) {
13864
                                        if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
13865
                                                active = i;
13866
                                                return false;
13867
                                        }
13868
                                });
13869
                        }
13870

    
13871
                        // check for a tab marked active via a class
13872
                        if ( active === null ) {
13873
                                active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
13874
                        }
13875

    
13876
                        // no active tab, set to false
13877
                        if ( active === null || active === -1 ) {
13878
                                active = this.tabs.length ? 0 : false;
13879
                        }
13880
                }
13881

    
13882
                // handle numbers: negative, out of range
13883
                if ( active !== false ) {
13884
                        active = this.tabs.index( this.tabs.eq( active ) );
13885
                        if ( active === -1 ) {
13886
                                active = collapsible ? false : 0;
13887
                        }
13888
                }
13889

    
13890
                // don't allow collapsible: false and active: false
13891
                if ( !collapsible && active === false && this.anchors.length ) {
13892
                        active = 0;
13893
                }
13894

    
13895
                return active;
13896
        },
13897

    
13898
        _getCreateEventData: function() {
13899
                return {
13900
                        tab: this.active,
13901
                        panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13902
                };
13903
        },
13904

    
13905
        _tabKeydown: function( event ) {
13906
                /*jshint maxcomplexity:15*/
13907
                var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13908
                        selectedIndex = this.tabs.index( focusedTab ),
13909
                        goingForward = true;
13910

    
13911
                if ( this._handlePageNav( event ) ) {
13912
                        return;
13913
                }
13914

    
13915
                switch ( event.keyCode ) {
13916
                        case $.ui.keyCode.RIGHT:
13917
                        case $.ui.keyCode.DOWN:
13918
                                selectedIndex++;
13919
                                break;
13920
                        case $.ui.keyCode.UP:
13921
                        case $.ui.keyCode.LEFT:
13922
                                goingForward = false;
13923
                                selectedIndex--;
13924
                                break;
13925
                        case $.ui.keyCode.END:
13926
                                selectedIndex = this.anchors.length - 1;
13927
                                break;
13928
                        case $.ui.keyCode.HOME:
13929
                                selectedIndex = 0;
13930
                                break;
13931
                        case $.ui.keyCode.SPACE:
13932
                                // Activate only, no collapsing
13933
                                event.preventDefault();
13934
                                clearTimeout( this.activating );
13935
                                this._activate( selectedIndex );
13936
                                return;
13937
                        case $.ui.keyCode.ENTER:
13938
                                // Toggle (cancel delayed activation, allow collapsing)
13939
                                event.preventDefault();
13940
                                clearTimeout( this.activating );
13941
                                // Determine if we should collapse or activate
13942
                                this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13943
                                return;
13944
                        default:
13945
                                return;
13946
                }
13947

    
13948
                // Focus the appropriate tab, based on which key was pressed
13949
                event.preventDefault();
13950
                clearTimeout( this.activating );
13951
                selectedIndex = this._focusNextTab( selectedIndex, goingForward );
13952

    
13953
                // Navigating with control key will prevent automatic activation
13954
                if ( !event.ctrlKey ) {
13955
                        // Update aria-selected immediately so that AT think the tab is already selected.
13956
                        // Otherwise AT may confuse the user by stating that they need to activate the tab,
13957
                        // but the tab will already be activated by the time the announcement finishes.
13958
                        focusedTab.attr( "aria-selected", "false" );
13959
                        this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
13960

    
13961
                        this.activating = this._delay(function() {
13962
                                this.option( "active", selectedIndex );
13963
                        }, this.delay );
13964
                }
13965
        },
13966

    
13967
        _panelKeydown: function( event ) {
13968
                if ( this._handlePageNav( event ) ) {
13969
                        return;
13970
                }
13971

    
13972
                // Ctrl+up moves focus to the current tab
13973
                if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
13974
                        event.preventDefault();
13975
                        this.active.focus();
13976
                }
13977
        },
13978

    
13979
        // Alt+page up/down moves focus to the previous/next tab (and activates)
13980
        _handlePageNav: function( event ) {
13981
                if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
13982
                        this._activate( this._focusNextTab( this.options.active - 1, false ) );
13983
                        return true;
13984
                }
13985
                if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
13986
                        this._activate( this._focusNextTab( this.options.active + 1, true ) );
13987
                        return true;
13988
                }
13989
        },
13990

    
13991
        _findNextTab: function( index, goingForward ) {
13992
                var lastTabIndex = this.tabs.length - 1;
13993

    
13994
                function constrain() {
13995
                        if ( index > lastTabIndex ) {
13996
                                index = 0;
13997
                        }
13998
                        if ( index < 0 ) {
13999
                                index = lastTabIndex;
14000
                        }
14001
                        return index;
14002
                }
14003

    
14004
                while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
14005
                        index = goingForward ? index + 1 : index - 1;
14006
                }
14007

    
14008
                return index;
14009
        },
14010

    
14011
        _focusNextTab: function( index, goingForward ) {
14012
                index = this._findNextTab( index, goingForward );
14013
                this.tabs.eq( index ).focus();
14014
                return index;
14015
        },
14016

    
14017
        _setOption: function( key, value ) {
14018
                if ( key === "active" ) {
14019
                        // _activate() will handle invalid values and update this.options
14020
                        this._activate( value );
14021
                        return;
14022
                }
14023

    
14024
                if ( key === "disabled" ) {
14025
                        // don't use the widget factory's disabled handling
14026
                        this._setupDisabled( value );
14027
                        return;
14028
                }
14029

    
14030
                this._super( key, value);
14031

    
14032
                if ( key === "collapsible" ) {
14033
                        this.element.toggleClass( "ui-tabs-collapsible", value );
14034
                        // Setting collapsible: false while collapsed; open first panel
14035
                        if ( !value && this.options.active === false ) {
14036
                                this._activate( 0 );
14037
                        }
14038
                }
14039

    
14040
                if ( key === "event" ) {
14041
                        this._setupEvents( value );
14042
                }
14043

    
14044
                if ( key === "heightStyle" ) {
14045
                        this._setupHeightStyle( value );
14046
                }
14047
        },
14048

    
14049
        _tabId: function( tab ) {
14050
                return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
14051
        },
14052

    
14053
        _sanitizeSelector: function( hash ) {
14054
                return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
14055
        },
14056

    
14057
        refresh: function() {
14058
                var options = this.options,
14059
                        lis = this.tablist.children( ":has(a[href])" );
14060

    
14061
                // get disabled tabs from class attribute from HTML
14062
                // this will get converted to a boolean if needed in _refresh()
14063
                options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
14064
                        return lis.index( tab );
14065
                });
14066

    
14067
                this._processTabs();
14068

    
14069
                // was collapsed or no tabs
14070
                if ( options.active === false || !this.anchors.length ) {
14071
                        options.active = false;
14072
                        this.active = $();
14073
                // was active, but active tab is gone
14074
                } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
14075
                        // all remaining tabs are disabled
14076
                        if ( this.tabs.length === options.disabled.length ) {
14077
                                options.active = false;
14078
                                this.active = $();
14079
                        // activate previous tab
14080
                        } else {
14081
                                this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
14082
                        }
14083
                // was active, active tab still exists
14084
                } else {
14085
                        // make sure active index is correct
14086
                        options.active = this.tabs.index( this.active );
14087
                }
14088

    
14089
                this._refresh();
14090
        },
14091

    
14092
        _refresh: function() {
14093
                this._setupDisabled( this.options.disabled );
14094
                this._setupEvents( this.options.event );
14095
                this._setupHeightStyle( this.options.heightStyle );
14096

    
14097
                this.tabs.not( this.active ).attr({
14098
                        "aria-selected": "false",
14099
                        tabIndex: -1
14100
                });
14101
                this.panels.not( this._getPanelForTab( this.active ) )
14102
                        .hide()
14103
                        .attr({
14104
                                "aria-expanded": "false",
14105
                                "aria-hidden": "true"
14106
                        });
14107

    
14108
                // Make sure one tab is in the tab order
14109
                if ( !this.active.length ) {
14110
                        this.tabs.eq( 0 ).attr( "tabIndex", 0 );
14111
                } else {
14112
                        this.active
14113
                                .addClass( "ui-tabs-active ui-state-active" )
14114
                                .attr({
14115
                                        "aria-selected": "true",
14116
                                        tabIndex: 0
14117
                                });
14118
                        this._getPanelForTab( this.active )
14119
                                .show()
14120
                                .attr({
14121
                                        "aria-expanded": "true",
14122
                                        "aria-hidden": "false"
14123
                                });
14124
                }
14125
        },
14126

    
14127
        _processTabs: function() {
14128
                var that = this;
14129

    
14130
                this.tablist = this._getList()
14131
                        .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14132
                        .attr( "role", "tablist" );
14133

    
14134
                this.tabs = this.tablist.find( "> li:has(a[href])" )
14135
                        .addClass( "ui-state-default ui-corner-top" )
14136
                        .attr({
14137
                                role: "tab",
14138
                                tabIndex: -1
14139
                        });
14140

    
14141
                this.anchors = this.tabs.map(function() {
14142
                                return $( "a", this )[ 0 ];
14143
                        })
14144
                        .addClass( "ui-tabs-anchor" )
14145
                        .attr({
14146
                                role: "presentation",
14147
                                tabIndex: -1
14148
                        });
14149

    
14150
                this.panels = $();
14151

    
14152
                this.anchors.each(function( i, anchor ) {
14153
                        var selector, panel, panelId,
14154
                                anchorId = $( anchor ).uniqueId().attr( "id" ),
14155
                                tab = $( anchor ).closest( "li" ),
14156
                                originalAriaControls = tab.attr( "aria-controls" );
14157

    
14158
                        // inline tab
14159
                        if ( isLocal( anchor ) ) {
14160
                                selector = anchor.hash;
14161
                                panel = that.element.find( that._sanitizeSelector( selector ) );
14162
                        // remote tab
14163
                        } else {
14164
                                panelId = that._tabId( tab );
14165
                                selector = "#" + panelId;
14166
                                panel = that.element.find( selector );
14167
                                if ( !panel.length ) {
14168
                                        panel = that._createPanel( panelId );
14169
                                        panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
14170
                                }
14171
                                panel.attr( "aria-live", "polite" );
14172
                        }
14173

    
14174
                        if ( panel.length) {
14175
                                that.panels = that.panels.add( panel );
14176
                        }
14177
                        if ( originalAriaControls ) {
14178
                                tab.data( "ui-tabs-aria-controls", originalAriaControls );
14179
                        }
14180
                        tab.attr({
14181
                                "aria-controls": selector.substring( 1 ),
14182
                                "aria-labelledby": anchorId
14183
                        });
14184
                        panel.attr( "aria-labelledby", anchorId );
14185
                });
14186

    
14187
                this.panels
14188
                        .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14189
                        .attr( "role", "tabpanel" );
14190
        },
14191

    
14192
        // allow overriding how to find the list for rare usage scenarios (#7715)
14193
        _getList: function() {
14194
                return this.element.find( "ol,ul" ).eq( 0 );
14195
        },
14196

    
14197
        _createPanel: function( id ) {
14198
                return $( "<div>" )
14199
                        .attr( "id", id )
14200
                        .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14201
                        .data( "ui-tabs-destroy", true );
14202
        },
14203

    
14204
        _setupDisabled: function( disabled ) {
14205
                if ( $.isArray( disabled ) ) {
14206
                        if ( !disabled.length ) {
14207
                                disabled = false;
14208
                        } else if ( disabled.length === this.anchors.length ) {
14209
                                disabled = true;
14210
                        }
14211
                }
14212

    
14213
                // disable tabs
14214
                for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
14215
                        if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
14216
                                $( li )
14217
                                        .addClass( "ui-state-disabled" )
14218
                                        .attr( "aria-disabled", "true" );
14219
                        } else {
14220
                                $( li )
14221
                                        .removeClass( "ui-state-disabled" )
14222
                                        .removeAttr( "aria-disabled" );
14223
                        }
14224
                }
14225

    
14226
                this.options.disabled = disabled;
14227
        },
14228

    
14229
        _setupEvents: function( event ) {
14230
                var events = {
14231
                        click: function( event ) {
14232
                                event.preventDefault();
14233
                        }
14234
                };
14235
                if ( event ) {
14236
                        $.each( event.split(" "), function( index, eventName ) {
14237
                                events[ eventName ] = "_eventHandler";
14238
                        });
14239
                }
14240

    
14241
                this._off( this.anchors.add( this.tabs ).add( this.panels ) );
14242
                this._on( this.anchors, events );
14243
                this._on( this.tabs, { keydown: "_tabKeydown" } );
14244
                this._on( this.panels, { keydown: "_panelKeydown" } );
14245

    
14246
                this._focusable( this.tabs );
14247
                this._hoverable( this.tabs );
14248
        },
14249

    
14250
        _setupHeightStyle: function( heightStyle ) {
14251
                var maxHeight,
14252
                        parent = this.element.parent();
14253

    
14254
                if ( heightStyle === "fill" ) {
14255
                        maxHeight = parent.height();
14256
                        maxHeight -= this.element.outerHeight() - this.element.height();
14257

    
14258
                        this.element.siblings( ":visible" ).each(function() {
14259
                                var elem = $( this ),
14260
                                        position = elem.css( "position" );
14261

    
14262
                                if ( position === "absolute" || position === "fixed" ) {
14263
                                        return;
14264
                                }
14265
                                maxHeight -= elem.outerHeight( true );
14266
                        });
14267

    
14268
                        this.element.children().not( this.panels ).each(function() {
14269
                                maxHeight -= $( this ).outerHeight( true );
14270
                        });
14271

    
14272
                        this.panels.each(function() {
14273
                                $( this ).height( Math.max( 0, maxHeight -
14274
                                        $( this ).innerHeight() + $( this ).height() ) );
14275
                        })
14276
                        .css( "overflow", "auto" );
14277
                } else if ( heightStyle === "auto" ) {
14278
                        maxHeight = 0;
14279
                        this.panels.each(function() {
14280
                                maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
14281
                        }).height( maxHeight );
14282
                }
14283
        },
14284

    
14285
        _eventHandler: function( event ) {
14286
                var options = this.options,
14287
                        active = this.active,
14288
                        anchor = $( event.currentTarget ),
14289
                        tab = anchor.closest( "li" ),
14290
                        clickedIsActive = tab[ 0 ] === active[ 0 ],
14291
                        collapsing = clickedIsActive && options.collapsible,
14292
                        toShow = collapsing ? $() : this._getPanelForTab( tab ),
14293
                        toHide = !active.length ? $() : this._getPanelForTab( active ),
14294
                        eventData = {
14295
                                oldTab: active,
14296
                                oldPanel: toHide,
14297
                                newTab: collapsing ? $() : tab,
14298
                                newPanel: toShow
14299
                        };
14300

    
14301
                event.preventDefault();
14302

    
14303
                if ( tab.hasClass( "ui-state-disabled" ) ||
14304
                                // tab is already loading
14305
                                tab.hasClass( "ui-tabs-loading" ) ||
14306
                                // can't switch durning an animation
14307
                                this.running ||
14308
                                // click on active header, but not collapsible
14309
                                ( clickedIsActive && !options.collapsible ) ||
14310
                                // allow canceling activation
14311
                                ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
14312
                        return;
14313
                }
14314

    
14315
                options.active = collapsing ? false : this.tabs.index( tab );
14316

    
14317
                this.active = clickedIsActive ? $() : tab;
14318
                if ( this.xhr ) {
14319
                        this.xhr.abort();
14320
                }
14321

    
14322
                if ( !toHide.length && !toShow.length ) {
14323
                        $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
14324
                }
14325

    
14326
                if ( toShow.length ) {
14327
                        this.load( this.tabs.index( tab ), event );
14328
                }
14329
                this._toggle( event, eventData );
14330
        },
14331

    
14332
        // handles show/hide for selecting tabs
14333
        _toggle: function( event, eventData ) {
14334
                var that = this,
14335
                        toShow = eventData.newPanel,
14336
                        toHide = eventData.oldPanel;
14337

    
14338
                this.running = true;
14339

    
14340
                function complete() {
14341
                        that.running = false;
14342
                        that._trigger( "activate", event, eventData );
14343
                }
14344

    
14345
                function show() {
14346
                        eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
14347

    
14348
                        if ( toShow.length && that.options.show ) {
14349
                                that._show( toShow, that.options.show, complete );
14350
                        } else {
14351
                                toShow.show();
14352
                                complete();
14353
                        }
14354
                }
14355

    
14356
                // start out by hiding, then showing, then completing
14357
                if ( toHide.length && this.options.hide ) {
14358
                        this._hide( toHide, this.options.hide, function() {
14359
                                eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14360
                                show();
14361
                        });
14362
                } else {
14363
                        eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14364
                        toHide.hide();
14365
                        show();
14366
                }
14367

    
14368
                toHide.attr({
14369
                        "aria-expanded": "false",
14370
                        "aria-hidden": "true"
14371
                });
14372
                eventData.oldTab.attr( "aria-selected", "false" );
14373
                // If we're switching tabs, remove the old tab from the tab order.
14374
                // If we're opening from collapsed state, remove the previous tab from the tab order.
14375
                // If we're collapsing, then keep the collapsing tab in the tab order.
14376
                if ( toShow.length && toHide.length ) {
14377
                        eventData.oldTab.attr( "tabIndex", -1 );
14378
                } else if ( toShow.length ) {
14379
                        this.tabs.filter(function() {
14380
                                return $( this ).attr( "tabIndex" ) === 0;
14381
                        })
14382
                        .attr( "tabIndex", -1 );
14383
                }
14384

    
14385
                toShow.attr({
14386
                        "aria-expanded": "true",
14387
                        "aria-hidden": "false"
14388
                });
14389
                eventData.newTab.attr({
14390
                        "aria-selected": "true",
14391
                        tabIndex: 0
14392
                });
14393
        },
14394

    
14395
        _activate: function( index ) {
14396
                var anchor,
14397
                        active = this._findActive( index );
14398

    
14399
                // trying to activate the already active panel
14400
                if ( active[ 0 ] === this.active[ 0 ] ) {
14401
                        return;
14402
                }
14403

    
14404
                // trying to collapse, simulate a click on the current active header
14405
                if ( !active.length ) {
14406
                        active = this.active;
14407
                }
14408

    
14409
                anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
14410
                this._eventHandler({
14411
                        target: anchor,
14412
                        currentTarget: anchor,
14413
                        preventDefault: $.noop
14414
                });
14415
        },
14416

    
14417
        _findActive: function( index ) {
14418
                return index === false ? $() : this.tabs.eq( index );
14419
        },
14420

    
14421
        _getIndex: function( index ) {
14422
                // meta-function to give users option to provide a href string instead of a numerical index.
14423
                if ( typeof index === "string" ) {
14424
                        index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
14425
                }
14426

    
14427
                return index;
14428
        },
14429

    
14430
        _destroy: function() {
14431
                if ( this.xhr ) {
14432
                        this.xhr.abort();
14433
                }
14434

    
14435
                this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
14436

    
14437
                this.tablist
14438
                        .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14439
                        .removeAttr( "role" );
14440

    
14441
                this.anchors
14442
                        .removeClass( "ui-tabs-anchor" )
14443
                        .removeAttr( "role" )
14444
                        .removeAttr( "tabIndex" )
14445
                        .removeUniqueId();
14446

    
14447
                this.tabs.add( this.panels ).each(function() {
14448
                        if ( $.data( this, "ui-tabs-destroy" ) ) {
14449
                                $( this ).remove();
14450
                        } else {
14451
                                $( this )
14452
                                        .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
14453
                                                "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
14454
                                        .removeAttr( "tabIndex" )
14455
                                        .removeAttr( "aria-live" )
14456
                                        .removeAttr( "aria-busy" )
14457
                                        .removeAttr( "aria-selected" )
14458
                                        .removeAttr( "aria-labelledby" )
14459
                                        .removeAttr( "aria-hidden" )
14460
                                        .removeAttr( "aria-expanded" )
14461
                                        .removeAttr( "role" );
14462
                        }
14463
                });
14464

    
14465
                this.tabs.each(function() {
14466
                        var li = $( this ),
14467
                                prev = li.data( "ui-tabs-aria-controls" );
14468
                        if ( prev ) {
14469
                                li
14470
                                        .attr( "aria-controls", prev )
14471
                                        .removeData( "ui-tabs-aria-controls" );
14472
                        } else {
14473
                                li.removeAttr( "aria-controls" );
14474
                        }
14475
                });
14476

    
14477
                this.panels.show();
14478

    
14479
                if ( this.options.heightStyle !== "content" ) {
14480
                        this.panels.css( "height", "" );
14481
                }
14482
        },
14483

    
14484
        enable: function( index ) {
14485
                var disabled = this.options.disabled;
14486
                if ( disabled === false ) {
14487
                        return;
14488
                }
14489

    
14490
                if ( index === undefined ) {
14491
                        disabled = false;
14492
                } else {
14493
                        index = this._getIndex( index );
14494
                        if ( $.isArray( disabled ) ) {
14495
                                disabled = $.map( disabled, function( num ) {
14496
                                        return num !== index ? num : null;
14497
                                });
14498
                        } else {
14499
                                disabled = $.map( this.tabs, function( li, num ) {
14500
                                        return num !== index ? num : null;
14501
                                });
14502
                        }
14503
                }
14504
                this._setupDisabled( disabled );
14505
        },
14506

    
14507
        disable: function( index ) {
14508
                var disabled = this.options.disabled;
14509
                if ( disabled === true ) {
14510
                        return;
14511
                }
14512

    
14513
                if ( index === undefined ) {
14514
                        disabled = true;
14515
                } else {
14516
                        index = this._getIndex( index );
14517
                        if ( $.inArray( index, disabled ) !== -1 ) {
14518
                                return;
14519
                        }
14520
                        if ( $.isArray( disabled ) ) {
14521
                                disabled = $.merge( [ index ], disabled ).sort();
14522
                        } else {
14523
                                disabled = [ index ];
14524
                        }
14525
                }
14526
                this._setupDisabled( disabled );
14527
        },
14528

    
14529
        load: function( index, event ) {
14530
                index = this._getIndex( index );
14531
                var that = this,
14532
                        tab = this.tabs.eq( index ),
14533
                        anchor = tab.find( ".ui-tabs-anchor" ),
14534
                        panel = this._getPanelForTab( tab ),
14535
                        eventData = {
14536
                                tab: tab,
14537
                                panel: panel
14538
                        };
14539

    
14540
                // not remote
14541
                if ( isLocal( anchor[ 0 ] ) ) {
14542
                        return;
14543
                }
14544

    
14545
                this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
14546

    
14547
                // support: jQuery <1.8
14548
                // jQuery <1.8 returns false if the request is canceled in beforeSend,
14549
                // but as of 1.8, $.ajax() always returns a jqXHR object.
14550
                if ( this.xhr && this.xhr.statusText !== "canceled" ) {
14551
                        tab.addClass( "ui-tabs-loading" );
14552
                        panel.attr( "aria-busy", "true" );
14553

    
14554
                        this.xhr
14555
                                .success(function( response ) {
14556
                                        // support: jQuery <1.8
14557
                                        // http://bugs.jquery.com/ticket/11778
14558
                                        setTimeout(function() {
14559
                                                panel.html( response );
14560
                                                that._trigger( "load", event, eventData );
14561
                                        }, 1 );
14562
                                })
14563
                                .complete(function( jqXHR, status ) {
14564
                                        // support: jQuery <1.8
14565
                                        // http://bugs.jquery.com/ticket/11778
14566
                                        setTimeout(function() {
14567
                                                if ( status === "abort" ) {
14568
                                                        that.panels.stop( false, true );
14569
                                                }
14570

    
14571
                                                tab.removeClass( "ui-tabs-loading" );
14572
                                                panel.removeAttr( "aria-busy" );
14573

    
14574
                                                if ( jqXHR === that.xhr ) {
14575
                                                        delete that.xhr;
14576
                                                }
14577
                                        }, 1 );
14578
                                });
14579
                }
14580
        },
14581

    
14582
        _ajaxSettings: function( anchor, event, eventData ) {
14583
                var that = this;
14584
                return {
14585
                        url: anchor.attr( "href" ),
14586
                        beforeSend: function( jqXHR, settings ) {
14587
                                return that._trigger( "beforeLoad", event,
14588
                                        $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
14589
                        }
14590
                };
14591
        },
14592

    
14593
        _getPanelForTab: function( tab ) {
14594
                var id = $( tab ).attr( "aria-controls" );
14595
                return this.element.find( this._sanitizeSelector( "#" + id ) );
14596
        }
14597
});
14598

    
14599
})( jQuery );
14600

    
14601
(function( $ ) {
14602

    
14603
var increments = 0;
14604

    
14605
function addDescribedBy( elem, id ) {
14606
        var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
14607
        describedby.push( id );
14608
        elem
14609
                .data( "ui-tooltip-id", id )
14610
                .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
14611
}
14612

    
14613
function removeDescribedBy( elem ) {
14614
        var id = elem.data( "ui-tooltip-id" ),
14615
                describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
14616
                index = $.inArray( id, describedby );
14617
        if ( index !== -1 ) {
14618
                describedby.splice( index, 1 );
14619
        }
14620

    
14621
        elem.removeData( "ui-tooltip-id" );
14622
        describedby = $.trim( describedby.join( " " ) );
14623
        if ( describedby ) {
14624
                elem.attr( "aria-describedby", describedby );
14625
        } else {
14626
                elem.removeAttr( "aria-describedby" );
14627
        }
14628
}
14629

    
14630
$.widget( "ui.tooltip", {
14631
        version: "1.10.2",
14632
        options: {
14633
                content: function() {
14634
                        // support: IE<9, Opera in jQuery <1.7
14635
                        // .text() can't accept undefined, so coerce to a string
14636
                        var title = $( this ).attr( "title" ) || "";
14637
                        // Escape title, since we're going from an attribute to raw HTML
14638
                        return $( "<a>" ).text( title ).html();
14639
                },
14640
                hide: true,
14641
                // Disabled elements have inconsistent behavior across browsers (#8661)
14642
                items: "[title]:not([disabled])",
14643
                position: {
14644
                        my: "left top+15",
14645
                        at: "left bottom",
14646
                        collision: "flipfit flip"
14647
                },
14648
                show: true,
14649
                tooltipClass: null,
14650
                track: false,
14651

    
14652
                // callbacks
14653
                close: null,
14654
                open: null
14655
        },
14656

    
14657
        _create: function() {
14658
                this._on({
14659
                        mouseover: "open",
14660
                        focusin: "open"
14661
                });
14662

    
14663
                // IDs of generated tooltips, needed for destroy
14664
                this.tooltips = {};
14665
                // IDs of parent tooltips where we removed the title attribute
14666
                this.parents = {};
14667

    
14668
                if ( this.options.disabled ) {
14669
                        this._disable();
14670
                }
14671
        },
14672

    
14673
        _setOption: function( key, value ) {
14674
                var that = this;
14675

    
14676
                if ( key === "disabled" ) {
14677
                        this[ value ? "_disable" : "_enable" ]();
14678
                        this.options[ key ] = value;
14679
                        // disable element style changes
14680
                        return;
14681
                }
14682

    
14683
                this._super( key, value );
14684

    
14685
                if ( key === "content" ) {
14686
                        $.each( this.tooltips, function( id, element ) {
14687
                                that._updateContent( element );
14688
                        });
14689
                }
14690
        },
14691

    
14692
        _disable: function() {
14693
                var that = this;
14694

    
14695
                // close open tooltips
14696
                $.each( this.tooltips, function( id, element ) {
14697
                        var event = $.Event( "blur" );
14698
                        event.target = event.currentTarget = element[0];
14699
                        that.close( event, true );
14700
                });
14701

    
14702
                // remove title attributes to prevent native tooltips
14703
                this.element.find( this.options.items ).addBack().each(function() {
14704
                        var element = $( this );
14705
                        if ( element.is( "[title]" ) ) {
14706
                                element
14707
                                        .data( "ui-tooltip-title", element.attr( "title" ) )
14708
                                        .attr( "title", "" );
14709
                        }
14710
                });
14711
        },
14712

    
14713
        _enable: function() {
14714
                // restore title attributes
14715
                this.element.find( this.options.items ).addBack().each(function() {
14716
                        var element = $( this );
14717
                        if ( element.data( "ui-tooltip-title" ) ) {
14718
                                element.attr( "title", element.data( "ui-tooltip-title" ) );
14719
                        }
14720
                });
14721
        },
14722

    
14723
        open: function( event ) {
14724
                var that = this,
14725
                        target = $( event ? event.target : this.element )
14726
                                // we need closest here due to mouseover bubbling,
14727
                                // but always pointing at the same event target
14728
                                .closest( this.options.items );
14729

    
14730
                // No element to show a tooltip for or the tooltip is already open
14731
                if ( !target.length || target.data( "ui-tooltip-id" ) ) {
14732
                        return;
14733
                }
14734

    
14735
                if ( target.attr( "title" ) ) {
14736
                        target.data( "ui-tooltip-title", target.attr( "title" ) );
14737
                }
14738

    
14739
                target.data( "ui-tooltip-open", true );
14740

    
14741
                // kill parent tooltips, custom or native, for hover
14742
                if ( event && event.type === "mouseover" ) {
14743
                        target.parents().each(function() {
14744
                                var parent = $( this ),
14745
                                        blurEvent;
14746
                                if ( parent.data( "ui-tooltip-open" ) ) {
14747
                                        blurEvent = $.Event( "blur" );
14748
                                        blurEvent.target = blurEvent.currentTarget = this;
14749
                                        that.close( blurEvent, true );
14750
                                }
14751
                                if ( parent.attr( "title" ) ) {
14752
                                        parent.uniqueId();
14753
                                        that.parents[ this.id ] = {
14754
                                                element: this,
14755
                                                title: parent.attr( "title" )
14756
                                        };
14757
                                        parent.attr( "title", "" );
14758
                                }
14759
                        });
14760
                }
14761

    
14762
                this._updateContent( target, event );
14763
        },
14764

    
14765
        _updateContent: function( target, event ) {
14766
                var content,
14767
                        contentOption = this.options.content,
14768
                        that = this,
14769
                        eventType = event ? event.type : null;
14770

    
14771
                if ( typeof contentOption === "string" ) {
14772
                        return this._open( event, target, contentOption );
14773
                }
14774

    
14775
                content = contentOption.call( target[0], function( response ) {
14776
                        // ignore async response if tooltip was closed already
14777
                        if ( !target.data( "ui-tooltip-open" ) ) {
14778
                                return;
14779
                        }
14780
                        // IE may instantly serve a cached response for ajax requests
14781
                        // delay this call to _open so the other call to _open runs first
14782
                        that._delay(function() {
14783
                                // jQuery creates a special event for focusin when it doesn't
14784
                                // exist natively. To improve performance, the native event
14785
                                // object is reused and the type is changed. Therefore, we can't
14786
                                // rely on the type being correct after the event finished
14787
                                // bubbling, so we set it back to the previous value. (#8740)
14788
                                if ( event ) {
14789
                                        event.type = eventType;
14790
                                }
14791
                                this._open( event, target, response );
14792
                        });
14793
                });
14794
                if ( content ) {
14795
                        this._open( event, target, content );
14796
                }
14797
        },
14798

    
14799
        _open: function( event, target, content ) {
14800
                var tooltip, events, delayedShow,
14801
                        positionOption = $.extend( {}, this.options.position );
14802

    
14803
                if ( !content ) {
14804
                        return;
14805
                }
14806

    
14807
                // Content can be updated multiple times. If the tooltip already
14808
                // exists, then just update the content and bail.
14809
                tooltip = this._find( target );
14810
                if ( tooltip.length ) {
14811
                        tooltip.find( ".ui-tooltip-content" ).html( content );
14812
                        return;
14813
                }
14814

    
14815
                // if we have a title, clear it to prevent the native tooltip
14816
                // we have to check first to avoid defining a title if none exists
14817
                // (we don't want to cause an element to start matching [title])
14818
                //
14819
                // We use removeAttr only for key events, to allow IE to export the correct
14820
                // accessible attributes. For mouse events, set to empty string to avoid
14821
                // native tooltip showing up (happens only when removing inside mouseover).
14822
                if ( target.is( "[title]" ) ) {
14823
                        if ( event && event.type === "mouseover" ) {
14824
                                target.attr( "title", "" );
14825
                        } else {
14826
                                target.removeAttr( "title" );
14827
                        }
14828
                }
14829

    
14830
                tooltip = this._tooltip( target );
14831
                addDescribedBy( target, tooltip.attr( "id" ) );
14832
                tooltip.find( ".ui-tooltip-content" ).html( content );
14833

    
14834
                function position( event ) {
14835
                        positionOption.of = event;
14836
                        if ( tooltip.is( ":hidden" ) ) {
14837
                                return;
14838
                        }
14839
                        tooltip.position( positionOption );
14840
                }
14841
                if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14842
                        this._on( this.document, {
14843
                                mousemove: position
14844
                        });
14845
                        // trigger once to override element-relative positioning
14846
                        position( event );
14847
                } else {
14848
                        tooltip.position( $.extend({
14849
                                of: target
14850
                        }, this.options.position ) );
14851
                }
14852

    
14853
                tooltip.hide();
14854

    
14855
                this._show( tooltip, this.options.show );
14856
                // Handle tracking tooltips that are shown with a delay (#8644). As soon
14857
                // as the tooltip is visible, position the tooltip using the most recent
14858
                // event.
14859
                if ( this.options.show && this.options.show.delay ) {
14860
                        delayedShow = this.delayedShow = setInterval(function() {
14861
                                if ( tooltip.is( ":visible" ) ) {
14862
                                        position( positionOption.of );
14863
                                        clearInterval( delayedShow );
14864
                                }
14865
                        }, $.fx.interval );
14866
                }
14867

    
14868
                this._trigger( "open", event, { tooltip: tooltip } );
14869

    
14870
                events = {
14871
                        keyup: function( event ) {
14872
                                if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14873
                                        var fakeEvent = $.Event(event);
14874
                                        fakeEvent.currentTarget = target[0];
14875
                                        this.close( fakeEvent, true );
14876
                                }
14877
                        },
14878
                        remove: function() {
14879
                                this._removeTooltip( tooltip );
14880
                        }
14881
                };
14882
                if ( !event || event.type === "mouseover" ) {
14883
                        events.mouseleave = "close";
14884
                }
14885
                if ( !event || event.type === "focusin" ) {
14886
                        events.focusout = "close";
14887
                }
14888
                this._on( true, target, events );
14889
        },
14890

    
14891
        close: function( event ) {
14892
                var that = this,
14893
                        target = $( event ? event.currentTarget : this.element ),
14894
                        tooltip = this._find( target );
14895

    
14896
                // disabling closes the tooltip, so we need to track when we're closing
14897
                // to avoid an infinite loop in case the tooltip becomes disabled on close
14898
                if ( this.closing ) {
14899
                        return;
14900
                }
14901

    
14902
                // Clear the interval for delayed tracking tooltips
14903
                clearInterval( this.delayedShow );
14904

    
14905
                // only set title if we had one before (see comment in _open())
14906
                if ( target.data( "ui-tooltip-title" ) ) {
14907
                        target.attr( "title", target.data( "ui-tooltip-title" ) );
14908
                }
14909

    
14910
                removeDescribedBy( target );
14911

    
14912
                tooltip.stop( true );
14913
                this._hide( tooltip, this.options.hide, function() {
14914
                        that._removeTooltip( $( this ) );
14915
                });
14916

    
14917
                target.removeData( "ui-tooltip-open" );
14918
                this._off( target, "mouseleave focusout keyup" );
14919
                // Remove 'remove' binding only on delegated targets
14920
                if ( target[0] !== this.element[0] ) {
14921
                        this._off( target, "remove" );
14922
                }
14923
                this._off( this.document, "mousemove" );
14924

    
14925
                if ( event && event.type === "mouseleave" ) {
14926
                        $.each( this.parents, function( id, parent ) {
14927
                                $( parent.element ).attr( "title", parent.title );
14928
                                delete that.parents[ id ];
14929
                        });
14930
                }
14931

    
14932
                this.closing = true;
14933
                this._trigger( "close", event, { tooltip: tooltip } );
14934
                this.closing = false;
14935
        },
14936

    
14937
        _tooltip: function( element ) {
14938
                var id = "ui-tooltip-" + increments++,
14939
                        tooltip = $( "<div>" )
14940
                                .attr({
14941
                                        id: id,
14942
                                        role: "tooltip"
14943
                                })
14944
                                .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14945
                                        ( this.options.tooltipClass || "" ) );
14946
                $( "<div>" )
14947
                        .addClass( "ui-tooltip-content" )
14948
                        .appendTo( tooltip );
14949
                tooltip.appendTo( this.document[0].body );
14950
                this.tooltips[ id ] = element;
14951
                return tooltip;
14952
        },
14953

    
14954
        _find: function( target ) {
14955
                var id = target.data( "ui-tooltip-id" );
14956
                return id ? $( "#" + id ) : $();
14957
        },
14958

    
14959
        _removeTooltip: function( tooltip ) {
14960
                tooltip.remove();
14961
                delete this.tooltips[ tooltip.attr( "id" ) ];
14962
        },
14963

    
14964
        _destroy: function() {
14965
                var that = this;
14966

    
14967
                // close open tooltips
14968
                $.each( this.tooltips, function( id, element ) {
14969
                        // Delegate to close method to handle common cleanup
14970
                        var event = $.Event( "blur" );
14971
                        event.target = event.currentTarget = element[0];
14972
                        that.close( event, true );
14973

    
14974
                        // Remove immediately; destroying an open tooltip doesn't use the
14975
                        // hide animation
14976
                        $( "#" + id ).remove();
14977

    
14978
                        // Restore the title
14979
                        if ( element.data( "ui-tooltip-title" ) ) {
14980
                                element.attr( "title", element.data( "ui-tooltip-title" ) );
14981
                                element.removeData( "ui-tooltip-title" );
14982
                        }
14983
                });
14984
        }
14985
});
14986

    
14987
}( jQuery ) );