Administrator
2023-04-21 195945efc5db921a4c9eb8cf9421c172273293f5
提交 | 用户 | 时间
58d006 1 /*! jQuery UI - v1.11.4 - 2015-09-20
A 2 * http://jqueryui.com
3 * Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, slider.js
4 * Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
5
6 (function( factory ) {
7     if ( typeof define === "function" && define.amd ) {
8
9         // AMD. Register as an anonymous module.
10         define([ "jquery" ], factory );
11     } else {
12
13         // Browser globals
14         factory( jQuery );
15     }
16 }(function( $ ) {
17 /*!
18  * jQuery UI Core 1.11.4
19  * http://jqueryui.com
20  *
21  * Copyright jQuery Foundation and other contributors
22  * Released under the MIT license.
23  * http://jquery.org/license
24  *
25  * http://api.jqueryui.com/category/ui-core/
26  */
27
28
29 // $.ui might exist from components with no dependencies, e.g., $.ui.position
30 $.ui = $.ui || {};
31
32 $.extend( $.ui, {
33     version: "1.11.4",
34
35     keyCode: {
36         BACKSPACE: 8,
37         COMMA: 188,
38         DELETE: 46,
39         DOWN: 40,
40         END: 35,
41         ENTER: 13,
42         ESCAPE: 27,
43         HOME: 36,
44         LEFT: 37,
45         PAGE_DOWN: 34,
46         PAGE_UP: 33,
47         PERIOD: 190,
48         RIGHT: 39,
49         SPACE: 32,
50         TAB: 9,
51         UP: 38
52     }
53 });
54
55 // plugins
56 $.fn.extend({
57     scrollParent: function( includeHidden ) {
58         var position = this.css( "position" ),
59             excludeStaticParent = position === "absolute",
60             overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
61             scrollParent = this.parents().filter( function() {
62                 var parent = $( this );
63                 if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
64                     return false;
65                 }
66                 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
67             }).eq( 0 );
68
69         return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
70     },
71
72     uniqueId: (function() {
73         var uuid = 0;
74
75         return function() {
76             return this.each(function() {
77                 if ( !this.id ) {
78                     this.id = "ui-id-" + ( ++uuid );
79                 }
80             });
81         };
82     })(),
83
84     removeUniqueId: function() {
85         return this.each(function() {
86             if ( /^ui-id-\d+$/.test( this.id ) ) {
87                 $( this ).removeAttr( "id" );
88             }
89         });
90     }
91 });
92
93 // selectors
94 function focusable( element, isTabIndexNotNaN ) {
95     var map, mapName, img,
96         nodeName = element.nodeName.toLowerCase();
97     if ( "area" === nodeName ) {
98         map = element.parentNode;
99         mapName = map.name;
100         if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
101             return false;
102         }
103         img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
104         return !!img && visible( img );
105     }
106     return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
107         !element.disabled :
108         "a" === nodeName ?
109             element.href || isTabIndexNotNaN :
110             isTabIndexNotNaN) &&
111         // the element and all of its ancestors must be visible
112         visible( element );
113 }
114
115 function visible( element ) {
116     return $.expr.filters.visible( element ) &&
117         !$( element ).parents().addBack().filter(function() {
118             return $.css( this, "visibility" ) === "hidden";
119         }).length;
120 }
121
122 $.extend( $.expr[ ":" ], {
123     data: $.expr.createPseudo ?
124         $.expr.createPseudo(function( dataName ) {
125             return function( elem ) {
126                 return !!$.data( elem, dataName );
127             };
128         }) :
129         // support: jQuery <1.8
130         function( elem, i, match ) {
131             return !!$.data( elem, match[ 3 ] );
132         },
133
134     focusable: function( element ) {
135         return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
136     },
137
138     tabbable: function( element ) {
139         var tabIndex = $.attr( element, "tabindex" ),
140             isTabIndexNaN = isNaN( tabIndex );
141         return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
142     }
143 });
144
145 // support: jQuery <1.8
146 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
147     $.each( [ "Width", "Height" ], function( i, name ) {
148         var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
149             type = name.toLowerCase(),
150             orig = {
151                 innerWidth: $.fn.innerWidth,
152                 innerHeight: $.fn.innerHeight,
153                 outerWidth: $.fn.outerWidth,
154                 outerHeight: $.fn.outerHeight
155             };
156
157         function reduce( elem, size, border, margin ) {
158             $.each( side, function() {
159                 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
160                 if ( border ) {
161                     size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
162                 }
163                 if ( margin ) {
164                     size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
165                 }
166             });
167             return size;
168         }
169
170         $.fn[ "inner" + name ] = function( size ) {
171             if ( size === undefined ) {
172                 return orig[ "inner" + name ].call( this );
173             }
174
175             return this.each(function() {
176                 $( this ).css( type, reduce( this, size ) + "px" );
177             });
178         };
179
180         $.fn[ "outer" + name] = function( size, margin ) {
181             if ( typeof size !== "number" ) {
182                 return orig[ "outer" + name ].call( this, size );
183             }
184
185             return this.each(function() {
186                 $( this).css( type, reduce( this, size, true, margin ) + "px" );
187             });
188         };
189     });
190 }
191
192 // support: jQuery <1.8
193 if ( !$.fn.addBack ) {
194     $.fn.addBack = function( selector ) {
195         return this.add( selector == null ?
196             this.prevObject : this.prevObject.filter( selector )
197         );
198     };
199 }
200
201 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
202 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
203     $.fn.removeData = (function( removeData ) {
204         return function( key ) {
205             if ( arguments.length ) {
206                 return removeData.call( this, $.camelCase( key ) );
207             } else {
208                 return removeData.call( this );
209             }
210         };
211     })( $.fn.removeData );
212 }
213
214 // deprecated
215 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
216
217 $.fn.extend({
218     focus: (function( orig ) {
219         return function( delay, fn ) {
220             return typeof delay === "number" ?
221                 this.each(function() {
222                     var elem = this;
223                     setTimeout(function() {
224                         $( elem ).focus();
225                         if ( fn ) {
226                             fn.call( elem );
227                         }
228                     }, delay );
229                 }) :
230                 orig.apply( this, arguments );
231         };
232     })( $.fn.focus ),
233
234     disableSelection: (function() {
235         var eventType = "onselectstart" in document.createElement( "div" ) ?
236             "selectstart" :
237             "mousedown";
238
239         return function() {
240             return this.bind( eventType + ".ui-disableSelection", function( event ) {
241                 event.preventDefault();
242             });
243         };
244     })(),
245
246     enableSelection: function() {
247         return this.unbind( ".ui-disableSelection" );
248     },
249
250     zIndex: function( zIndex ) {
251         if ( zIndex !== undefined ) {
252             return this.css( "zIndex", zIndex );
253         }
254
255         if ( this.length ) {
256             var elem = $( this[ 0 ] ), position, value;
257             while ( elem.length && elem[ 0 ] !== document ) {
258                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
259                 // This makes behavior of this function consistent across browsers
260                 // WebKit always returns auto if the element is positioned
261                 position = elem.css( "position" );
262                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
263                     // IE returns 0 when zIndex is not specified
264                     // other browsers return a string
265                     // we ignore the case of nested elements with an explicit value of 0
266                     // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
267                     value = parseInt( elem.css( "zIndex" ), 10 );
268                     if ( !isNaN( value ) && value !== 0 ) {
269                         return value;
270                     }
271                 }
272                 elem = elem.parent();
273             }
274         }
275
276         return 0;
277     }
278 });
279
280 // $.ui.plugin is deprecated. Use $.widget() extensions instead.
281 $.ui.plugin = {
282     add: function( module, option, set ) {
283         var i,
284             proto = $.ui[ module ].prototype;
285         for ( i in set ) {
286             proto.plugins[ i ] = proto.plugins[ i ] || [];
287             proto.plugins[ i ].push( [ option, set[ i ] ] );
288         }
289     },
290     call: function( instance, name, args, allowDisconnected ) {
291         var i,
292             set = instance.plugins[ name ];
293
294         if ( !set ) {
295             return;
296         }
297
298         if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
299             return;
300         }
301
302         for ( i = 0; i < set.length; i++ ) {
303             if ( instance.options[ set[ i ][ 0 ] ] ) {
304                 set[ i ][ 1 ].apply( instance.element, args );
305             }
306         }
307     }
308 };
309
310
311 /*!
312  * jQuery UI Widget 1.11.4
313  * http://jqueryui.com
314  *
315  * Copyright jQuery Foundation and other contributors
316  * Released under the MIT license.
317  * http://jquery.org/license
318  *
319  * http://api.jqueryui.com/jQuery.widget/
320  */
321
322
323 var widget_uuid = 0,
324     widget_slice = Array.prototype.slice;
325
326 $.cleanData = (function( orig ) {
327     return function( elems ) {
328         var events, elem, i;
329         for ( i = 0; (elem = elems[i]) != null; i++ ) {
330             try {
331
332                 // Only trigger remove when necessary to save time
333                 events = $._data( elem, "events" );
334                 if ( events && events.remove ) {
335                     $( elem ).triggerHandler( "remove" );
336                 }
337
338             // http://bugs.jquery.com/ticket/8235
339             } catch ( e ) {}
340         }
341         orig( elems );
342     };
343 })( $.cleanData );
344
345 $.widget = function( name, base, prototype ) {
346     var fullName, existingConstructor, constructor, basePrototype,
347         // proxiedPrototype allows the provided prototype to remain unmodified
348         // so that it can be used as a mixin for multiple widgets (#8876)
349         proxiedPrototype = {},
350         namespace = name.split( "." )[ 0 ];
351
352     name = name.split( "." )[ 1 ];
353     fullName = namespace + "-" + name;
354
355     if ( !prototype ) {
356         prototype = base;
357         base = $.Widget;
358     }
359
360     // create selector for plugin
361     $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
362         return !!$.data( elem, fullName );
363     };
364
365     $[ namespace ] = $[ namespace ] || {};
366     existingConstructor = $[ namespace ][ name ];
367     constructor = $[ namespace ][ name ] = function( options, element ) {
368         // allow instantiation without "new" keyword
369         if ( !this._createWidget ) {
370             return new constructor( options, element );
371         }
372
373         // allow instantiation without initializing for simple inheritance
374         // must use "new" keyword (the code above always passes args)
375         if ( arguments.length ) {
376             this._createWidget( options, element );
377         }
378     };
379     // extend with the existing constructor to carry over any static properties
380     $.extend( constructor, existingConstructor, {
381         version: prototype.version,
382         // copy the object used to create the prototype in case we need to
383         // redefine the widget later
384         _proto: $.extend( {}, prototype ),
385         // track widgets that inherit from this widget in case this widget is
386         // redefined after a widget inherits from it
387         _childConstructors: []
388     });
389
390     basePrototype = new base();
391     // we need to make the options hash a property directly on the new instance
392     // otherwise we'll modify the options hash on the prototype that we're
393     // inheriting from
394     basePrototype.options = $.widget.extend( {}, basePrototype.options );
395     $.each( prototype, function( prop, value ) {
396         if ( !$.isFunction( value ) ) {
397             proxiedPrototype[ prop ] = value;
398             return;
399         }
400         proxiedPrototype[ prop ] = (function() {
401             var _super = function() {
402                     return base.prototype[ prop ].apply( this, arguments );
403                 },
404                 _superApply = function( args ) {
405                     return base.prototype[ prop ].apply( this, args );
406                 };
407             return function() {
408                 var __super = this._super,
409                     __superApply = this._superApply,
410                     returnValue;
411
412                 this._super = _super;
413                 this._superApply = _superApply;
414
415                 returnValue = value.apply( this, arguments );
416
417                 this._super = __super;
418                 this._superApply = __superApply;
419
420                 return returnValue;
421             };
422         })();
423     });
424     constructor.prototype = $.widget.extend( basePrototype, {
425         // TODO: remove support for widgetEventPrefix
426         // always use the name + a colon as the prefix, e.g., draggable:start
427         // don't prefix for widgets that aren't DOM-based
428         widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
429     }, proxiedPrototype, {
430         constructor: constructor,
431         namespace: namespace,
432         widgetName: name,
433         widgetFullName: fullName
434     });
435
436     // If this widget is being redefined then we need to find all widgets that
437     // are inheriting from it and redefine all of them so that they inherit from
438     // the new version of this widget. We're essentially trying to replace one
439     // level in the prototype chain.
440     if ( existingConstructor ) {
441         $.each( existingConstructor._childConstructors, function( i, child ) {
442             var childPrototype = child.prototype;
443
444             // redefine the child widget using the same prototype that was
445             // originally used, but inherit from the new version of the base
446             $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
447         });
448         // remove the list of existing child constructors from the old constructor
449         // so the old child constructors can be garbage collected
450         delete existingConstructor._childConstructors;
451     } else {
452         base._childConstructors.push( constructor );
453     }
454
455     $.widget.bridge( name, constructor );
456
457     return constructor;
458 };
459
460 $.widget.extend = function( target ) {
461     var input = widget_slice.call( arguments, 1 ),
462         inputIndex = 0,
463         inputLength = input.length,
464         key,
465         value;
466     for ( ; inputIndex < inputLength; inputIndex++ ) {
467         for ( key in input[ inputIndex ] ) {
468             value = input[ inputIndex ][ key ];
469             if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
470                 // Clone objects
471                 if ( $.isPlainObject( value ) ) {
472                     target[ key ] = $.isPlainObject( target[ key ] ) ?
473                         $.widget.extend( {}, target[ key ], value ) :
474                         // Don't extend strings, arrays, etc. with objects
475                         $.widget.extend( {}, value );
476                 // Copy everything else by reference
477                 } else {
478                     target[ key ] = value;
479                 }
480             }
481         }
482     }
483     return target;
484 };
485
486 $.widget.bridge = function( name, object ) {
487     var fullName = object.prototype.widgetFullName || name;
488     $.fn[ name ] = function( options ) {
489         var isMethodCall = typeof options === "string",
490             args = widget_slice.call( arguments, 1 ),
491             returnValue = this;
492
493         if ( isMethodCall ) {
494             this.each(function() {
495                 var methodValue,
496                     instance = $.data( this, fullName );
497                 if ( options === "instance" ) {
498                     returnValue = instance;
499                     return false;
500                 }
501                 if ( !instance ) {
502                     return $.error( "cannot call methods on " + name + " prior to initialization; " +
503                         "attempted to call method '" + options + "'" );
504                 }
505                 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
506                     return $.error( "no such method '" + options + "' for " + name + " widget instance" );
507                 }
508                 methodValue = instance[ options ].apply( instance, args );
509                 if ( methodValue !== instance && methodValue !== undefined ) {
510                     returnValue = methodValue && methodValue.jquery ?
511                         returnValue.pushStack( methodValue.get() ) :
512                         methodValue;
513                     return false;
514                 }
515             });
516         } else {
517
518             // Allow multiple hashes to be passed on init
519             if ( args.length ) {
520                 options = $.widget.extend.apply( null, [ options ].concat(args) );
521             }
522
523             this.each(function() {
524                 var instance = $.data( this, fullName );
525                 if ( instance ) {
526                     instance.option( options || {} );
527                     if ( instance._init ) {
528                         instance._init();
529                     }
530                 } else {
531                     $.data( this, fullName, new object( options, this ) );
532                 }
533             });
534         }
535
536         return returnValue;
537     };
538 };
539
540 $.Widget = function( /* options, element */ ) {};
541 $.Widget._childConstructors = [];
542
543 $.Widget.prototype = {
544     widgetName: "widget",
545     widgetEventPrefix: "",
546     defaultElement: "<div>",
547     options: {
548         disabled: false,
549
550         // callbacks
551         create: null
552     },
553     _createWidget: function( options, element ) {
554         element = $( element || this.defaultElement || this )[ 0 ];
555         this.element = $( element );
556         this.uuid = widget_uuid++;
557         this.eventNamespace = "." + this.widgetName + this.uuid;
558
559         this.bindings = $();
560         this.hoverable = $();
561         this.focusable = $();
562
563         if ( element !== this ) {
564             $.data( element, this.widgetFullName, this );
565             this._on( true, this.element, {
566                 remove: function( event ) {
567                     if ( event.target === element ) {
568                         this.destroy();
569                     }
570                 }
571             });
572             this.document = $( element.style ?
573                 // element within the document
574                 element.ownerDocument :
575                 // element is window or document
576                 element.document || element );
577             this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
578         }
579
580         this.options = $.widget.extend( {},
581             this.options,
582             this._getCreateOptions(),
583             options );
584
585         this._create();
586         this._trigger( "create", null, this._getCreateEventData() );
587         this._init();
588     },
589     _getCreateOptions: $.noop,
590     _getCreateEventData: $.noop,
591     _create: $.noop,
592     _init: $.noop,
593
594     destroy: function() {
595         this._destroy();
596         // we can probably remove the unbind calls in 2.0
597         // all event bindings should go through this._on()
598         this.element
599             .unbind( this.eventNamespace )
600             .removeData( this.widgetFullName )
601             // support: jquery <1.6.3
602             // http://bugs.jquery.com/ticket/9413
603             .removeData( $.camelCase( this.widgetFullName ) );
604         this.widget()
605             .unbind( this.eventNamespace )
606             .removeAttr( "aria-disabled" )
607             .removeClass(
608                 this.widgetFullName + "-disabled " +
609                 "ui-state-disabled" );
610
611         // clean up events and states
612         this.bindings.unbind( this.eventNamespace );
613         this.hoverable.removeClass( "ui-state-hover" );
614         this.focusable.removeClass( "ui-state-focus" );
615     },
616     _destroy: $.noop,
617
618     widget: function() {
619         return this.element;
620     },
621
622     option: function( key, value ) {
623         var options = key,
624             parts,
625             curOption,
626             i;
627
628         if ( arguments.length === 0 ) {
629             // don't return a reference to the internal hash
630             return $.widget.extend( {}, this.options );
631         }
632
633         if ( typeof key === "string" ) {
634             // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
635             options = {};
636             parts = key.split( "." );
637             key = parts.shift();
638             if ( parts.length ) {
639                 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
640                 for ( i = 0; i < parts.length - 1; i++ ) {
641                     curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
642                     curOption = curOption[ parts[ i ] ];
643                 }
644                 key = parts.pop();
645                 if ( arguments.length === 1 ) {
646                     return curOption[ key ] === undefined ? null : curOption[ key ];
647                 }
648                 curOption[ key ] = value;
649             } else {
650                 if ( arguments.length === 1 ) {
651                     return this.options[ key ] === undefined ? null : this.options[ key ];
652                 }
653                 options[ key ] = value;
654             }
655         }
656
657         this._setOptions( options );
658
659         return this;
660     },
661     _setOptions: function( options ) {
662         var key;
663
664         for ( key in options ) {
665             this._setOption( key, options[ key ] );
666         }
667
668         return this;
669     },
670     _setOption: function( key, value ) {
671         this.options[ key ] = value;
672
673         if ( key === "disabled" ) {
674             this.widget()
675                 .toggleClass( this.widgetFullName + "-disabled", !!value );
676
677             // If the widget is becoming disabled, then nothing is interactive
678             if ( value ) {
679                 this.hoverable.removeClass( "ui-state-hover" );
680                 this.focusable.removeClass( "ui-state-focus" );
681             }
682         }
683
684         return this;
685     },
686
687     enable: function() {
688         return this._setOptions({ disabled: false });
689     },
690     disable: function() {
691         return this._setOptions({ disabled: true });
692     },
693
694     _on: function( suppressDisabledCheck, element, handlers ) {
695         var delegateElement,
696             instance = this;
697
698         // no suppressDisabledCheck flag, shuffle arguments
699         if ( typeof suppressDisabledCheck !== "boolean" ) {
700             handlers = element;
701             element = suppressDisabledCheck;
702             suppressDisabledCheck = false;
703         }
704
705         // no element argument, shuffle and use this.element
706         if ( !handlers ) {
707             handlers = element;
708             element = this.element;
709             delegateElement = this.widget();
710         } else {
711             element = delegateElement = $( element );
712             this.bindings = this.bindings.add( element );
713         }
714
715         $.each( handlers, function( event, handler ) {
716             function handlerProxy() {
717                 // allow widgets to customize the disabled handling
718                 // - disabled as an array instead of boolean
719                 // - disabled class as method for disabling individual parts
720                 if ( !suppressDisabledCheck &&
721                         ( instance.options.disabled === true ||
722                             $( this ).hasClass( "ui-state-disabled" ) ) ) {
723                     return;
724                 }
725                 return ( typeof handler === "string" ? instance[ handler ] : handler )
726                     .apply( instance, arguments );
727             }
728
729             // copy the guid so direct unbinding works
730             if ( typeof handler !== "string" ) {
731                 handlerProxy.guid = handler.guid =
732                     handler.guid || handlerProxy.guid || $.guid++;
733             }
734
735             var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
736                 eventName = match[1] + instance.eventNamespace,
737                 selector = match[2];
738             if ( selector ) {
739                 delegateElement.delegate( selector, eventName, handlerProxy );
740             } else {
741                 element.bind( eventName, handlerProxy );
742             }
743         });
744     },
745
746     _off: function( element, eventName ) {
747         eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
748             this.eventNamespace;
749         element.unbind( eventName ).undelegate( eventName );
750
751         // Clear the stack to avoid memory leaks (#10056)
752         this.bindings = $( this.bindings.not( element ).get() );
753         this.focusable = $( this.focusable.not( element ).get() );
754         this.hoverable = $( this.hoverable.not( element ).get() );
755     },
756
757     _delay: function( handler, delay ) {
758         function handlerProxy() {
759             return ( typeof handler === "string" ? instance[ handler ] : handler )
760                 .apply( instance, arguments );
761         }
762         var instance = this;
763         return setTimeout( handlerProxy, delay || 0 );
764     },
765
766     _hoverable: function( element ) {
767         this.hoverable = this.hoverable.add( element );
768         this._on( element, {
769             mouseenter: function( event ) {
770                 $( event.currentTarget ).addClass( "ui-state-hover" );
771             },
772             mouseleave: function( event ) {
773                 $( event.currentTarget ).removeClass( "ui-state-hover" );
774             }
775         });
776     },
777
778     _focusable: function( element ) {
779         this.focusable = this.focusable.add( element );
780         this._on( element, {
781             focusin: function( event ) {
782                 $( event.currentTarget ).addClass( "ui-state-focus" );
783             },
784             focusout: function( event ) {
785                 $( event.currentTarget ).removeClass( "ui-state-focus" );
786             }
787         });
788     },
789
790     _trigger: function( type, event, data ) {
791         var prop, orig,
792             callback = this.options[ type ];
793
794         data = data || {};
795         event = $.Event( event );
796         event.type = ( type === this.widgetEventPrefix ?
797             type :
798             this.widgetEventPrefix + type ).toLowerCase();
799         // the original event may come from any element
800         // so we need to reset the target on the new event
801         event.target = this.element[ 0 ];
802
803         // copy original event properties over to the new event
804         orig = event.originalEvent;
805         if ( orig ) {
806             for ( prop in orig ) {
807                 if ( !( prop in event ) ) {
808                     event[ prop ] = orig[ prop ];
809                 }
810             }
811         }
812
813         this.element.trigger( event, data );
814         return !( $.isFunction( callback ) &&
815             callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
816             event.isDefaultPrevented() );
817     }
818 };
819
820 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
821     $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
822         if ( typeof options === "string" ) {
823             options = { effect: options };
824         }
825         var hasOptions,
826             effectName = !options ?
827                 method :
828                 options === true || typeof options === "number" ?
829                     defaultEffect :
830                     options.effect || defaultEffect;
831         options = options || {};
832         if ( typeof options === "number" ) {
833             options = { duration: options };
834         }
835         hasOptions = !$.isEmptyObject( options );
836         options.complete = callback;
837         if ( options.delay ) {
838             element.delay( options.delay );
839         }
840         if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
841             element[ method ]( options );
842         } else if ( effectName !== method && element[ effectName ] ) {
843             element[ effectName ]( options.duration, options.easing, callback );
844         } else {
845             element.queue(function( next ) {
846                 $( this )[ method ]();
847                 if ( callback ) {
848                     callback.call( element[ 0 ] );
849                 }
850                 next();
851             });
852         }
853     };
854 });
855
856 var widget = $.widget;
857
858
859 /*!
860  * jQuery UI Mouse 1.11.4
861  * http://jqueryui.com
862  *
863  * Copyright jQuery Foundation and other contributors
864  * Released under the MIT license.
865  * http://jquery.org/license
866  *
867  * http://api.jqueryui.com/mouse/
868  */
869
870
871 var mouseHandled = false;
872 $( document ).mouseup( function() {
873     mouseHandled = false;
874 });
875
876 var mouse = $.widget("ui.mouse", {
877     version: "1.11.4",
878     options: {
879         cancel: "input,textarea,button,select,option",
880         distance: 1,
881         delay: 0
882     },
883     _mouseInit: function() {
884         var that = this;
885
886         this.element
887             .bind("mousedown." + this.widgetName, function(event) {
888                 return that._mouseDown(event);
889             })
890             .bind("click." + this.widgetName, function(event) {
891                 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
892                     $.removeData(event.target, that.widgetName + ".preventClickEvent");
893                     event.stopImmediatePropagation();
894                     return false;
895                 }
896             });
897
898         this.started = false;
899     },
900
901     // TODO: make sure destroying one instance of mouse doesn't mess with
902     // other instances of mouse
903     _mouseDestroy: function() {
904         this.element.unbind("." + this.widgetName);
905         if ( this._mouseMoveDelegate ) {
906             this.document
907                 .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
908                 .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
909         }
910     },
911
912     _mouseDown: function(event) {
913         // don't let more than one widget handle mouseStart
914         if ( mouseHandled ) {
915             return;
916         }
917
918         this._mouseMoved = false;
919
920         // we may have missed mouseup (out of window)
921         (this._mouseStarted && this._mouseUp(event));
922
923         this._mouseDownEvent = event;
924
925         var that = this,
926             btnIsLeft = (event.which === 1),
927             // event.target.nodeName works around a bug in IE 8 with
928             // disabled inputs (#7620)
929             elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
930         if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
931             return true;
932         }
933
934         this.mouseDelayMet = !this.options.delay;
935         if (!this.mouseDelayMet) {
936             this._mouseDelayTimer = setTimeout(function() {
937                 that.mouseDelayMet = true;
938             }, this.options.delay);
939         }
940
941         if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
942             this._mouseStarted = (this._mouseStart(event) !== false);
943             if (!this._mouseStarted) {
944                 event.preventDefault();
945                 return true;
946             }
947         }
948
949         // Click event may never have fired (Gecko & Opera)
950         if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
951             $.removeData(event.target, this.widgetName + ".preventClickEvent");
952         }
953
954         // these delegates are required to keep context
955         this._mouseMoveDelegate = function(event) {
956             return that._mouseMove(event);
957         };
958         this._mouseUpDelegate = function(event) {
959             return that._mouseUp(event);
960         };
961
962         this.document
963             .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
964             .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
965
966         event.preventDefault();
967
968         mouseHandled = true;
969         return true;
970     },
971
972     _mouseMove: function(event) {
973         // Only check for mouseups outside the document if you've moved inside the document
974         // at least once. This prevents the firing of mouseup in the case of IE<9, which will
975         // fire a mousemove event if content is placed under the cursor. See #7778
976         // Support: IE <9
977         if ( this._mouseMoved ) {
978             // IE mouseup check - mouseup happened when mouse was out of window
979             if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
980                 return this._mouseUp(event);
981
982             // Iframe mouseup check - mouseup occurred in another document
983             } else if ( !event.which ) {
984                 return this._mouseUp( event );
985             }
986         }
987
988         if ( event.which || event.button ) {
989             this._mouseMoved = true;
990         }
991
992         if (this._mouseStarted) {
993             this._mouseDrag(event);
994             return event.preventDefault();
995         }
996
997         if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
998             this._mouseStarted =
999                 (this._mouseStart(this._mouseDownEvent, event) !== false);
1000             (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
1001         }
1002
1003         return !this._mouseStarted;
1004     },
1005
1006     _mouseUp: function(event) {
1007         this.document
1008             .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1009             .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
1010
1011         if (this._mouseStarted) {
1012             this._mouseStarted = false;
1013
1014             if (event.target === this._mouseDownEvent.target) {
1015                 $.data(event.target, this.widgetName + ".preventClickEvent", true);
1016             }
1017
1018             this._mouseStop(event);
1019         }
1020
1021         mouseHandled = false;
1022         return false;
1023     },
1024
1025     _mouseDistanceMet: function(event) {
1026         return (Math.max(
1027                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
1028                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
1029             ) >= this.options.distance
1030         );
1031     },
1032
1033     _mouseDelayMet: function(/* event */) {
1034         return this.mouseDelayMet;
1035     },
1036
1037     // These are placeholder methods, to be overriden by extending plugin
1038     _mouseStart: function(/* event */) {},
1039     _mouseDrag: function(/* event */) {},
1040     _mouseStop: function(/* event */) {},
1041     _mouseCapture: function(/* event */) { return true; }
1042 });
1043
1044
1045 /*!
1046  * jQuery UI Position 1.11.4
1047  * http://jqueryui.com
1048  *
1049  * Copyright jQuery Foundation and other contributors
1050  * Released under the MIT license.
1051  * http://jquery.org/license
1052  *
1053  * http://api.jqueryui.com/position/
1054  */
1055
1056 (function() {
1057
1058 $.ui = $.ui || {};
1059
1060 var cachedScrollbarWidth, supportsOffsetFractions,
1061     max = Math.max,
1062     abs = Math.abs,
1063     round = Math.round,
1064     rhorizontal = /left|center|right/,
1065     rvertical = /top|center|bottom/,
1066     roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1067     rposition = /^\w+/,
1068     rpercent = /%$/,
1069     _position = $.fn.position;
1070
1071 function getOffsets( offsets, width, height ) {
1072     return [
1073         parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1074         parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1075     ];
1076 }
1077
1078 function parseCss( element, property ) {
1079     return parseInt( $.css( element, property ), 10 ) || 0;
1080 }
1081
1082 function getDimensions( elem ) {
1083     var raw = elem[0];
1084     if ( raw.nodeType === 9 ) {
1085         return {
1086             width: elem.width(),
1087             height: elem.height(),
1088             offset: { top: 0, left: 0 }
1089         };
1090     }
1091     if ( $.isWindow( raw ) ) {
1092         return {
1093             width: elem.width(),
1094             height: elem.height(),
1095             offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1096         };
1097     }
1098     if ( raw.preventDefault ) {
1099         return {
1100             width: 0,
1101             height: 0,
1102             offset: { top: raw.pageY, left: raw.pageX }
1103         };
1104     }
1105     return {
1106         width: elem.outerWidth(),
1107         height: elem.outerHeight(),
1108         offset: elem.offset()
1109     };
1110 }
1111
1112 $.position = {
1113     scrollbarWidth: function() {
1114         if ( cachedScrollbarWidth !== undefined ) {
1115             return cachedScrollbarWidth;
1116         }
1117         var w1, w2,
1118             div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1119             innerDiv = div.children()[0];
1120
1121         $( "body" ).append( div );
1122         w1 = innerDiv.offsetWidth;
1123         div.css( "overflow", "scroll" );
1124
1125         w2 = innerDiv.offsetWidth;
1126
1127         if ( w1 === w2 ) {
1128             w2 = div[0].clientWidth;
1129         }
1130
1131         div.remove();
1132
1133         return (cachedScrollbarWidth = w1 - w2);
1134     },
1135     getScrollInfo: function( within ) {
1136         var overflowX = within.isWindow || within.isDocument ? "" :
1137                 within.element.css( "overflow-x" ),
1138             overflowY = within.isWindow || within.isDocument ? "" :
1139                 within.element.css( "overflow-y" ),
1140             hasOverflowX = overflowX === "scroll" ||
1141                 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1142             hasOverflowY = overflowY === "scroll" ||
1143                 ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1144         return {
1145             width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1146             height: hasOverflowX ? $.position.scrollbarWidth() : 0
1147         };
1148     },
1149     getWithinInfo: function( element ) {
1150         var withinElement = $( element || window ),
1151             isWindow = $.isWindow( withinElement[0] ),
1152             isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1153         return {
1154             element: withinElement,
1155             isWindow: isWindow,
1156             isDocument: isDocument,
1157             offset: withinElement.offset() || { left: 0, top: 0 },
1158             scrollLeft: withinElement.scrollLeft(),
1159             scrollTop: withinElement.scrollTop(),
1160
1161             // support: jQuery 1.6.x
1162             // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
1163             width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
1164             height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
1165         };
1166     }
1167 };
1168
1169 $.fn.position = function( options ) {
1170     if ( !options || !options.of ) {
1171         return _position.apply( this, arguments );
1172     }
1173
1174     // make a copy, we don't want to modify arguments
1175     options = $.extend( {}, options );
1176
1177     var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1178         target = $( options.of ),
1179         within = $.position.getWithinInfo( options.within ),
1180         scrollInfo = $.position.getScrollInfo( within ),
1181         collision = ( options.collision || "flip" ).split( " " ),
1182         offsets = {};
1183
1184     dimensions = getDimensions( target );
1185     if ( target[0].preventDefault ) {
1186         // force left top to allow flipping
1187         options.at = "left top";
1188     }
1189     targetWidth = dimensions.width;
1190     targetHeight = dimensions.height;
1191     targetOffset = dimensions.offset;
1192     // clone to reuse original targetOffset later
1193     basePosition = $.extend( {}, targetOffset );
1194
1195     // force my and at to have valid horizontal and vertical positions
1196     // if a value is missing or invalid, it will be converted to center
1197     $.each( [ "my", "at" ], function() {
1198         var pos = ( options[ this ] || "" ).split( " " ),
1199             horizontalOffset,
1200             verticalOffset;
1201
1202         if ( pos.length === 1) {
1203             pos = rhorizontal.test( pos[ 0 ] ) ?
1204                 pos.concat( [ "center" ] ) :
1205                 rvertical.test( pos[ 0 ] ) ?
1206                     [ "center" ].concat( pos ) :
1207                     [ "center", "center" ];
1208         }
1209         pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1210         pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1211
1212         // calculate offsets
1213         horizontalOffset = roffset.exec( pos[ 0 ] );
1214         verticalOffset = roffset.exec( pos[ 1 ] );
1215         offsets[ this ] = [
1216             horizontalOffset ? horizontalOffset[ 0 ] : 0,
1217             verticalOffset ? verticalOffset[ 0 ] : 0
1218         ];
1219
1220         // reduce to just the positions without the offsets
1221         options[ this ] = [
1222             rposition.exec( pos[ 0 ] )[ 0 ],
1223             rposition.exec( pos[ 1 ] )[ 0 ]
1224         ];
1225     });
1226
1227     // normalize collision option
1228     if ( collision.length === 1 ) {
1229         collision[ 1 ] = collision[ 0 ];
1230     }
1231
1232     if ( options.at[ 0 ] === "right" ) {
1233         basePosition.left += targetWidth;
1234     } else if ( options.at[ 0 ] === "center" ) {
1235         basePosition.left += targetWidth / 2;
1236     }
1237
1238     if ( options.at[ 1 ] === "bottom" ) {
1239         basePosition.top += targetHeight;
1240     } else if ( options.at[ 1 ] === "center" ) {
1241         basePosition.top += targetHeight / 2;
1242     }
1243
1244     atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1245     basePosition.left += atOffset[ 0 ];
1246     basePosition.top += atOffset[ 1 ];
1247
1248     return this.each(function() {
1249         var collisionPosition, using,
1250             elem = $( this ),
1251             elemWidth = elem.outerWidth(),
1252             elemHeight = elem.outerHeight(),
1253             marginLeft = parseCss( this, "marginLeft" ),
1254             marginTop = parseCss( this, "marginTop" ),
1255             collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1256             collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1257             position = $.extend( {}, basePosition ),
1258             myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1259
1260         if ( options.my[ 0 ] === "right" ) {
1261             position.left -= elemWidth;
1262         } else if ( options.my[ 0 ] === "center" ) {
1263             position.left -= elemWidth / 2;
1264         }
1265
1266         if ( options.my[ 1 ] === "bottom" ) {
1267             position.top -= elemHeight;
1268         } else if ( options.my[ 1 ] === "center" ) {
1269             position.top -= elemHeight / 2;
1270         }
1271
1272         position.left += myOffset[ 0 ];
1273         position.top += myOffset[ 1 ];
1274
1275         // if the browser doesn't support fractions, then round for consistent results
1276         if ( !supportsOffsetFractions ) {
1277             position.left = round( position.left );
1278             position.top = round( position.top );
1279         }
1280
1281         collisionPosition = {
1282             marginLeft: marginLeft,
1283             marginTop: marginTop
1284         };
1285
1286         $.each( [ "left", "top" ], function( i, dir ) {
1287             if ( $.ui.position[ collision[ i ] ] ) {
1288                 $.ui.position[ collision[ i ] ][ dir ]( position, {
1289                     targetWidth: targetWidth,
1290                     targetHeight: targetHeight,
1291                     elemWidth: elemWidth,
1292                     elemHeight: elemHeight,
1293                     collisionPosition: collisionPosition,
1294                     collisionWidth: collisionWidth,
1295                     collisionHeight: collisionHeight,
1296                     offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1297                     my: options.my,
1298                     at: options.at,
1299                     within: within,
1300                     elem: elem
1301                 });
1302             }
1303         });
1304
1305         if ( options.using ) {
1306             // adds feedback as second argument to using callback, if present
1307             using = function( props ) {
1308                 var left = targetOffset.left - position.left,
1309                     right = left + targetWidth - elemWidth,
1310                     top = targetOffset.top - position.top,
1311                     bottom = top + targetHeight - elemHeight,
1312                     feedback = {
1313                         target: {
1314                             element: target,
1315                             left: targetOffset.left,
1316                             top: targetOffset.top,
1317                             width: targetWidth,
1318                             height: targetHeight
1319                         },
1320                         element: {
1321                             element: elem,
1322                             left: position.left,
1323                             top: position.top,
1324                             width: elemWidth,
1325                             height: elemHeight
1326                         },
1327                         horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1328                         vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1329                     };
1330                 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1331                     feedback.horizontal = "center";
1332                 }
1333                 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1334                     feedback.vertical = "middle";
1335                 }
1336                 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1337                     feedback.important = "horizontal";
1338                 } else {
1339                     feedback.important = "vertical";
1340                 }
1341                 options.using.call( this, props, feedback );
1342             };
1343         }
1344
1345         elem.offset( $.extend( position, { using: using } ) );
1346     });
1347 };
1348
1349 $.ui.position = {
1350     fit: {
1351         left: function( position, data ) {
1352             var within = data.within,
1353                 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1354                 outerWidth = within.width,
1355                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1356                 overLeft = withinOffset - collisionPosLeft,
1357                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1358                 newOverRight;
1359
1360             // element is wider than within
1361             if ( data.collisionWidth > outerWidth ) {
1362                 // element is initially over the left side of within
1363                 if ( overLeft > 0 && overRight <= 0 ) {
1364                     newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1365                     position.left += overLeft - newOverRight;
1366                 // element is initially over right side of within
1367                 } else if ( overRight > 0 && overLeft <= 0 ) {
1368                     position.left = withinOffset;
1369                 // element is initially over both left and right sides of within
1370                 } else {
1371                     if ( overLeft > overRight ) {
1372                         position.left = withinOffset + outerWidth - data.collisionWidth;
1373                     } else {
1374                         position.left = withinOffset;
1375                     }
1376                 }
1377             // too far left -> align with left edge
1378             } else if ( overLeft > 0 ) {
1379                 position.left += overLeft;
1380             // too far right -> align with right edge
1381             } else if ( overRight > 0 ) {
1382                 position.left -= overRight;
1383             // adjust based on position and margin
1384             } else {
1385                 position.left = max( position.left - collisionPosLeft, position.left );
1386             }
1387         },
1388         top: function( position, data ) {
1389             var within = data.within,
1390                 withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1391                 outerHeight = data.within.height,
1392                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1393                 overTop = withinOffset - collisionPosTop,
1394                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1395                 newOverBottom;
1396
1397             // element is taller than within
1398             if ( data.collisionHeight > outerHeight ) {
1399                 // element is initially over the top of within
1400                 if ( overTop > 0 && overBottom <= 0 ) {
1401                     newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1402                     position.top += overTop - newOverBottom;
1403                 // element is initially over bottom of within
1404                 } else if ( overBottom > 0 && overTop <= 0 ) {
1405                     position.top = withinOffset;
1406                 // element is initially over both top and bottom of within
1407                 } else {
1408                     if ( overTop > overBottom ) {
1409                         position.top = withinOffset + outerHeight - data.collisionHeight;
1410                     } else {
1411                         position.top = withinOffset;
1412                     }
1413                 }
1414             // too far up -> align with top
1415             } else if ( overTop > 0 ) {
1416                 position.top += overTop;
1417             // too far down -> align with bottom edge
1418             } else if ( overBottom > 0 ) {
1419                 position.top -= overBottom;
1420             // adjust based on position and margin
1421             } else {
1422                 position.top = max( position.top - collisionPosTop, position.top );
1423             }
1424         }
1425     },
1426     flip: {
1427         left: function( position, data ) {
1428             var within = data.within,
1429                 withinOffset = within.offset.left + within.scrollLeft,
1430                 outerWidth = within.width,
1431                 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1432                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1433                 overLeft = collisionPosLeft - offsetLeft,
1434                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1435                 myOffset = data.my[ 0 ] === "left" ?
1436                     -data.elemWidth :
1437                     data.my[ 0 ] === "right" ?
1438                         data.elemWidth :
1439                         0,
1440                 atOffset = data.at[ 0 ] === "left" ?
1441                     data.targetWidth :
1442                     data.at[ 0 ] === "right" ?
1443                         -data.targetWidth :
1444                         0,
1445                 offset = -2 * data.offset[ 0 ],
1446                 newOverRight,
1447                 newOverLeft;
1448
1449             if ( overLeft < 0 ) {
1450                 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1451                 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1452                     position.left += myOffset + atOffset + offset;
1453                 }
1454             } else if ( overRight > 0 ) {
1455                 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1456                 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1457                     position.left += myOffset + atOffset + offset;
1458                 }
1459             }
1460         },
1461         top: function( position, data ) {
1462             var within = data.within,
1463                 withinOffset = within.offset.top + within.scrollTop,
1464                 outerHeight = within.height,
1465                 offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1466                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1467                 overTop = collisionPosTop - offsetTop,
1468                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1469                 top = data.my[ 1 ] === "top",
1470                 myOffset = top ?
1471                     -data.elemHeight :
1472                     data.my[ 1 ] === "bottom" ?
1473                         data.elemHeight :
1474                         0,
1475                 atOffset = data.at[ 1 ] === "top" ?
1476                     data.targetHeight :
1477                     data.at[ 1 ] === "bottom" ?
1478                         -data.targetHeight :
1479                         0,
1480                 offset = -2 * data.offset[ 1 ],
1481                 newOverTop,
1482                 newOverBottom;
1483             if ( overTop < 0 ) {
1484                 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1485                 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1486                     position.top += myOffset + atOffset + offset;
1487                 }
1488             } else if ( overBottom > 0 ) {
1489                 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1490                 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1491                     position.top += myOffset + atOffset + offset;
1492                 }
1493             }
1494         }
1495     },
1496     flipfit: {
1497         left: function() {
1498             $.ui.position.flip.left.apply( this, arguments );
1499             $.ui.position.fit.left.apply( this, arguments );
1500         },
1501         top: function() {
1502             $.ui.position.flip.top.apply( this, arguments );
1503             $.ui.position.fit.top.apply( this, arguments );
1504         }
1505     }
1506 };
1507
1508 // fraction support test
1509 (function() {
1510     var testElement, testElementParent, testElementStyle, offsetLeft, i,
1511         body = document.getElementsByTagName( "body" )[ 0 ],
1512         div = document.createElement( "div" );
1513
1514     //Create a "fake body" for testing based on method used in jQuery.support
1515     testElement = document.createElement( body ? "div" : "body" );
1516     testElementStyle = {
1517         visibility: "hidden",
1518         width: 0,
1519         height: 0,
1520         border: 0,
1521         margin: 0,
1522         background: "none"
1523     };
1524     if ( body ) {
1525         $.extend( testElementStyle, {
1526             position: "absolute",
1527             left: "-1000px",
1528             top: "-1000px"
1529         });
1530     }
1531     for ( i in testElementStyle ) {
1532         testElement.style[ i ] = testElementStyle[ i ];
1533     }
1534     testElement.appendChild( div );
1535     testElementParent = body || document.documentElement;
1536     testElementParent.insertBefore( testElement, testElementParent.firstChild );
1537
1538     div.style.cssText = "position: absolute; left: 10.7432222px;";
1539
1540     offsetLeft = $( div ).offset().left;
1541     supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1542
1543     testElement.innerHTML = "";
1544     testElementParent.removeChild( testElement );
1545 })();
1546
1547 })();
1548
1549 var position = $.ui.position;
1550
1551
1552 /*!
1553  * jQuery UI Draggable 1.11.4
1554  * http://jqueryui.com
1555  *
1556  * Copyright jQuery Foundation and other contributors
1557  * Released under the MIT license.
1558  * http://jquery.org/license
1559  *
1560  * http://api.jqueryui.com/draggable/
1561  */
1562
1563
1564 $.widget("ui.draggable", $.ui.mouse, {
1565     version: "1.11.4",
1566     widgetEventPrefix: "drag",
1567     options: {
1568         addClasses: true,
1569         appendTo: "parent",
1570         axis: false,
1571         connectToSortable: false,
1572         containment: false,
1573         cursor: "auto",
1574         cursorAt: false,
1575         grid: false,
1576         handle: false,
1577         helper: "original",
1578         iframeFix: false,
1579         opacity: false,
1580         refreshPositions: false,
1581         revert: false,
1582         revertDuration: 500,
1583         scope: "default",
1584         scroll: true,
1585         scrollSensitivity: 20,
1586         scrollSpeed: 20,
1587         snap: false,
1588         snapMode: "both",
1589         snapTolerance: 20,
1590         stack: false,
1591         zIndex: false,
1592
1593         // callbacks
1594         drag: null,
1595         start: null,
1596         stop: null
1597     },
1598     _create: function() {
1599
1600         if ( this.options.helper === "original" ) {
1601             this._setPositionRelative();
1602         }
1603         if (this.options.addClasses){
1604             this.element.addClass("ui-draggable");
1605         }
1606         if (this.options.disabled){
1607             this.element.addClass("ui-draggable-disabled");
1608         }
1609         this._setHandleClassName();
1610
1611         this._mouseInit();
1612     },
1613
1614     _setOption: function( key, value ) {
1615         this._super( key, value );
1616         if ( key === "handle" ) {
1617             this._removeHandleClassName();
1618             this._setHandleClassName();
1619         }
1620     },
1621
1622     _destroy: function() {
1623         if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
1624             this.destroyOnClear = true;
1625             return;
1626         }
1627         this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1628         this._removeHandleClassName();
1629         this._mouseDestroy();
1630     },
1631
1632     _mouseCapture: function(event) {
1633         var o = this.options;
1634
1635         this._blurActiveElement( event );
1636
1637         // among others, prevent a drag on a resizable-handle
1638         if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1639             return false;
1640         }
1641
1642         //Quit if we're not on a valid handle
1643         this.handle = this._getHandle(event);
1644         if (!this.handle) {
1645             return false;
1646         }
1647
1648         this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
1649
1650         return true;
1651
1652     },
1653
1654     _blockFrames: function( selector ) {
1655         this.iframeBlocks = this.document.find( selector ).map(function() {
1656             var iframe = $( this );
1657
1658             return $( "<div>" )
1659                 .css( "position", "absolute" )
1660                 .appendTo( iframe.parent() )
1661                 .outerWidth( iframe.outerWidth() )
1662                 .outerHeight( iframe.outerHeight() )
1663                 .offset( iframe.offset() )[ 0 ];
1664         });
1665     },
1666
1667     _unblockFrames: function() {
1668         if ( this.iframeBlocks ) {
1669             this.iframeBlocks.remove();
1670             delete this.iframeBlocks;
1671         }
1672     },
1673
1674     _blurActiveElement: function( event ) {
1675         var document = this.document[ 0 ];
1676
1677         // Only need to blur if the event occurred on the draggable itself, see #10527
1678         if ( !this.handleElement.is( event.target ) ) {
1679             return;
1680         }
1681
1682         // support: IE9
1683         // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1684         try {
1685
1686             // Support: IE9, IE10
1687             // If the <body> is blurred, IE will switch windows, see #9520
1688             if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
1689
1690                 // Blur any element that currently has focus, see #4261
1691                 $( document.activeElement ).blur();
1692             }
1693         } catch ( error ) {}
1694     },
1695
1696     _mouseStart: function(event) {
1697
1698         var o = this.options;
1699
1700         //Create and append the visible helper
1701         this.helper = this._createHelper(event);
1702
1703         this.helper.addClass("ui-draggable-dragging");
1704
1705         //Cache the helper size
1706         this._cacheHelperProportions();
1707
1708         //If ddmanager is used for droppables, set the global draggable
1709         if ($.ui.ddmanager) {
1710             $.ui.ddmanager.current = this;
1711         }
1712
1713         /*
1714          * - Position generation -
1715          * This block generates everything position related - it's the core of draggables.
1716          */
1717
1718         //Cache the margins of the original element
1719         this._cacheMargins();
1720
1721         //Store the helper's css position
1722         this.cssPosition = this.helper.css( "position" );
1723         this.scrollParent = this.helper.scrollParent( true );
1724         this.offsetParent = this.helper.offsetParent();
1725         this.hasFixedAncestor = this.helper.parents().filter(function() {
1726                 return $( this ).css( "position" ) === "fixed";
1727             }).length > 0;
1728
1729         //The element's absolute position on the page minus margins
1730         this.positionAbs = this.element.offset();
1731         this._refreshOffsets( event );
1732
1733         //Generate the original position
1734         this.originalPosition = this.position = this._generatePosition( event, false );
1735         this.originalPageX = event.pageX;
1736         this.originalPageY = event.pageY;
1737
1738         //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1739         (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1740
1741         //Set a containment if given in the options
1742         this._setContainment();
1743
1744         //Trigger event + callbacks
1745         if (this._trigger("start", event) === false) {
1746             this._clear();
1747             return false;
1748         }
1749
1750         //Recache the helper size
1751         this._cacheHelperProportions();
1752
1753         //Prepare the droppable offsets
1754         if ($.ui.ddmanager && !o.dropBehaviour) {
1755             $.ui.ddmanager.prepareOffsets(this, event);
1756         }
1757
1758         // Reset helper's right/bottom css if they're set and set explicit width/height instead
1759         // as this prevents resizing of elements with right/bottom set (see #7772)
1760         this._normalizeRightBottom();
1761
1762         this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1763
1764         //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1765         if ( $.ui.ddmanager ) {
1766             $.ui.ddmanager.dragStart(this, event);
1767         }
1768
1769         return true;
1770     },
1771
1772     _refreshOffsets: function( event ) {
1773         this.offset = {
1774             top: this.positionAbs.top - this.margins.top,
1775             left: this.positionAbs.left - this.margins.left,
1776             scroll: false,
1777             parent: this._getParentOffset(),
1778             relative: this._getRelativeOffset()
1779         };
1780
1781         this.offset.click = {
1782             left: event.pageX - this.offset.left,
1783             top: event.pageY - this.offset.top
1784         };
1785     },
1786
1787     _mouseDrag: function(event, noPropagation) {
1788         // reset any necessary cached properties (see #5009)
1789         if ( this.hasFixedAncestor ) {
1790             this.offset.parent = this._getParentOffset();
1791         }
1792
1793         //Compute the helpers position
1794         this.position = this._generatePosition( event, true );
1795         this.positionAbs = this._convertPositionTo("absolute");
1796
1797         //Call plugins and callbacks and use the resulting position if something is returned
1798         if (!noPropagation) {
1799             var ui = this._uiHash();
1800             if (this._trigger("drag", event, ui) === false) {
1801                 this._mouseUp({});
1802                 return false;
1803             }
1804             this.position = ui.position;
1805         }
1806
1807         this.helper[ 0 ].style.left = this.position.left + "px";
1808         this.helper[ 0 ].style.top = this.position.top + "px";
1809
1810         if ($.ui.ddmanager) {
1811             $.ui.ddmanager.drag(this, event);
1812         }
1813
1814         return false;
1815     },
1816
1817     _mouseStop: function(event) {
1818
1819         //If we are using droppables, inform the manager about the drop
1820         var that = this,
1821             dropped = false;
1822         if ($.ui.ddmanager && !this.options.dropBehaviour) {
1823             dropped = $.ui.ddmanager.drop(this, event);
1824         }
1825
1826         //if a drop comes from outside (a sortable)
1827         if (this.dropped) {
1828             dropped = this.dropped;
1829             this.dropped = false;
1830         }
1831
1832         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))) {
1833             $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1834                 if (that._trigger("stop", event) !== false) {
1835                     that._clear();
1836                 }
1837             });
1838         } else {
1839             if (this._trigger("stop", event) !== false) {
1840                 this._clear();
1841             }
1842         }
1843
1844         return false;
1845     },
1846
1847     _mouseUp: function( event ) {
1848         this._unblockFrames();
1849
1850         //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1851         if ( $.ui.ddmanager ) {
1852             $.ui.ddmanager.dragStop(this, event);
1853         }
1854
1855         // Only need to focus if the event occurred on the draggable itself, see #10527
1856         if ( this.handleElement.is( event.target ) ) {
1857             // The interaction is over; whether or not the click resulted in a drag, focus the element
1858             this.element.focus();
1859         }
1860
1861         return $.ui.mouse.prototype._mouseUp.call(this, event);
1862     },
1863
1864     cancel: function() {
1865
1866         if (this.helper.is(".ui-draggable-dragging")) {
1867             this._mouseUp({});
1868         } else {
1869             this._clear();
1870         }
1871
1872         return this;
1873
1874     },
1875
1876     _getHandle: function(event) {
1877         return this.options.handle ?
1878             !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1879             true;
1880     },
1881
1882     _setHandleClassName: function() {
1883         this.handleElement = this.options.handle ?
1884             this.element.find( this.options.handle ) : this.element;
1885         this.handleElement.addClass( "ui-draggable-handle" );
1886     },
1887
1888     _removeHandleClassName: function() {
1889         this.handleElement.removeClass( "ui-draggable-handle" );
1890     },
1891
1892     _createHelper: function(event) {
1893
1894         var o = this.options,
1895             helperIsFunction = $.isFunction( o.helper ),
1896             helper = helperIsFunction ?
1897                 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
1898                 ( o.helper === "clone" ?
1899                     this.element.clone().removeAttr( "id" ) :
1900                     this.element );
1901
1902         if (!helper.parents("body").length) {
1903             helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1904         }
1905
1906         // http://bugs.jqueryui.com/ticket/9446
1907         // a helper function can return the original element
1908         // which wouldn't have been set to relative in _create
1909         if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
1910             this._setPositionRelative();
1911         }
1912
1913         if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1914             helper.css("position", "absolute");
1915         }
1916
1917         return helper;
1918
1919     },
1920
1921     _setPositionRelative: function() {
1922         if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
1923             this.element[ 0 ].style.position = "relative";
1924         }
1925     },
1926
1927     _adjustOffsetFromHelper: function(obj) {
1928         if (typeof obj === "string") {
1929             obj = obj.split(" ");
1930         }
1931         if ($.isArray(obj)) {
1932             obj = { left: +obj[0], top: +obj[1] || 0 };
1933         }
1934         if ("left" in obj) {
1935             this.offset.click.left = obj.left + this.margins.left;
1936         }
1937         if ("right" in obj) {
1938             this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1939         }
1940         if ("top" in obj) {
1941             this.offset.click.top = obj.top + this.margins.top;
1942         }
1943         if ("bottom" in obj) {
1944             this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1945         }
1946     },
1947
1948     _isRootNode: function( element ) {
1949         return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
1950     },
1951
1952     _getParentOffset: function() {
1953
1954         //Get the offsetParent and cache its position
1955         var po = this.offsetParent.offset(),
1956             document = this.document[ 0 ];
1957
1958         // This is a special case where we need to modify a offset calculated on start, since the following happened:
1959         // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1960         // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1961         //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1962         if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1963             po.left += this.scrollParent.scrollLeft();
1964             po.top += this.scrollParent.scrollTop();
1965         }
1966
1967         if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
1968             po = { top: 0, left: 0 };
1969         }
1970
1971         return {
1972             top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
1973             left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
1974         };
1975
1976     },
1977
1978     _getRelativeOffset: function() {
1979         if ( this.cssPosition !== "relative" ) {
1980             return { top: 0, left: 0 };
1981         }
1982
1983         var p = this.element.position(),
1984             scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1985
1986         return {
1987             top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
1988             left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
1989         };
1990
1991     },
1992
1993     _cacheMargins: function() {
1994         this.margins = {
1995             left: (parseInt(this.element.css("marginLeft"), 10) || 0),
1996             top: (parseInt(this.element.css("marginTop"), 10) || 0),
1997             right: (parseInt(this.element.css("marginRight"), 10) || 0),
1998             bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
1999         };
2000     },
2001
2002     _cacheHelperProportions: function() {
2003         this.helperProportions = {
2004             width: this.helper.outerWidth(),
2005             height: this.helper.outerHeight()
2006         };
2007     },
2008
2009     _setContainment: function() {
2010
2011         var isUserScrollable, c, ce,
2012             o = this.options,
2013             document = this.document[ 0 ];
2014
2015         this.relativeContainer = null;
2016
2017         if ( !o.containment ) {
2018             this.containment = null;
2019             return;
2020         }
2021
2022         if ( o.containment === "window" ) {
2023             this.containment = [
2024                 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
2025                 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
2026                 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
2027                 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2028             ];
2029             return;
2030         }
2031
2032         if ( o.containment === "document") {
2033             this.containment = [
2034                 0,
2035                 0,
2036                 $( document ).width() - this.helperProportions.width - this.margins.left,
2037                 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2038             ];
2039             return;
2040         }
2041
2042         if ( o.containment.constructor === Array ) {
2043             this.containment = o.containment;
2044             return;
2045         }
2046
2047         if ( o.containment === "parent" ) {
2048             o.containment = this.helper[ 0 ].parentNode;
2049         }
2050
2051         c = $( o.containment );
2052         ce = c[ 0 ];
2053
2054         if ( !ce ) {
2055             return;
2056         }
2057
2058         isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
2059
2060         this.containment = [
2061             ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
2062             ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
2063             ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
2064                 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
2065                 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
2066                 this.helperProportions.width -
2067                 this.margins.left -
2068                 this.margins.right,
2069             ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
2070                 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
2071                 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
2072                 this.helperProportions.height -
2073                 this.margins.top -
2074                 this.margins.bottom
2075         ];
2076         this.relativeContainer = c;
2077     },
2078
2079     _convertPositionTo: function(d, pos) {
2080
2081         if (!pos) {
2082             pos = this.position;
2083         }
2084
2085         var mod = d === "absolute" ? 1 : -1,
2086             scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2087
2088         return {
2089             top: (
2090                 pos.top    +                                                                // The absolute mouse position
2091                 this.offset.relative.top * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
2092                 this.offset.parent.top * mod -                                        // The offsetParent's offset without borders (offset + border)
2093                 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
2094             ),
2095             left: (
2096                 pos.left +                                                                // The absolute mouse position
2097                 this.offset.relative.left * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
2098                 this.offset.parent.left * mod    -                                        // The offsetParent's offset without borders (offset + border)
2099                 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
2100             )
2101         };
2102
2103     },
2104
2105     _generatePosition: function( event, constrainPosition ) {
2106
2107         var containment, co, top, left,
2108             o = this.options,
2109             scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2110             pageX = event.pageX,
2111             pageY = event.pageY;
2112
2113         // Cache the scroll
2114         if ( !scrollIsRootNode || !this.offset.scroll ) {
2115             this.offset.scroll = {
2116                 top: this.scrollParent.scrollTop(),
2117                 left: this.scrollParent.scrollLeft()
2118             };
2119         }
2120
2121         /*
2122          * - Position constraining -
2123          * Constrain the position to a mix of grid, containment.
2124          */
2125
2126         // If we are not dragging yet, we won't check for options
2127         if ( constrainPosition ) {
2128             if ( this.containment ) {
2129                 if ( this.relativeContainer ){
2130                     co = this.relativeContainer.offset();
2131                     containment = [
2132                         this.containment[ 0 ] + co.left,
2133                         this.containment[ 1 ] + co.top,
2134                         this.containment[ 2 ] + co.left,
2135                         this.containment[ 3 ] + co.top
2136                     ];
2137                 } else {
2138                     containment = this.containment;
2139                 }
2140
2141                 if (event.pageX - this.offset.click.left < containment[0]) {
2142                     pageX = containment[0] + this.offset.click.left;
2143                 }
2144                 if (event.pageY - this.offset.click.top < containment[1]) {
2145                     pageY = containment[1] + this.offset.click.top;
2146                 }
2147                 if (event.pageX - this.offset.click.left > containment[2]) {
2148                     pageX = containment[2] + this.offset.click.left;
2149                 }
2150                 if (event.pageY - this.offset.click.top > containment[3]) {
2151                     pageY = containment[3] + this.offset.click.top;
2152                 }
2153             }
2154
2155             if (o.grid) {
2156                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
2157                 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
2158                 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;
2159
2160                 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
2161                 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;
2162             }
2163
2164             if ( o.axis === "y" ) {
2165                 pageX = this.originalPageX;
2166             }
2167
2168             if ( o.axis === "x" ) {
2169                 pageY = this.originalPageY;
2170             }
2171         }
2172
2173         return {
2174             top: (
2175                 pageY -                                                                    // The absolute mouse position
2176                 this.offset.click.top    -                                                // Click offset (relative to the element)
2177                 this.offset.relative.top -                                                // Only for relative positioned nodes: Relative offset from element to offset parent
2178                 this.offset.parent.top +                                                // The offsetParent's offset without borders (offset + border)
2179                 ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2180             ),
2181             left: (
2182                 pageX -                                                                    // The absolute mouse position
2183                 this.offset.click.left -                                                // Click offset (relative to the element)
2184                 this.offset.relative.left -                                                // Only for relative positioned nodes: Relative offset from element to offset parent
2185                 this.offset.parent.left +                                                // The offsetParent's offset without borders (offset + border)
2186                 ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2187             )
2188         };
2189
2190     },
2191
2192     _clear: function() {
2193         this.helper.removeClass("ui-draggable-dragging");
2194         if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
2195             this.helper.remove();
2196         }
2197         this.helper = null;
2198         this.cancelHelperRemoval = false;
2199         if ( this.destroyOnClear ) {
2200             this.destroy();
2201         }
2202     },
2203
2204     _normalizeRightBottom: function() {
2205         if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
2206             this.helper.width( this.helper.width() );
2207             this.helper.css( "right", "auto" );
2208         }
2209         if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
2210             this.helper.height( this.helper.height() );
2211             this.helper.css( "bottom", "auto" );
2212         }
2213     },
2214
2215     // From now on bulk stuff - mainly helpers
2216
2217     _trigger: function( type, event, ui ) {
2218         ui = ui || this._uiHash();
2219         $.ui.plugin.call( this, type, [ event, ui, this ], true );
2220
2221         // Absolute position and offset (see #6884 ) have to be recalculated after plugins
2222         if ( /^(drag|start|stop)/.test( type ) ) {
2223             this.positionAbs = this._convertPositionTo( "absolute" );
2224             ui.offset = this.positionAbs;
2225         }
2226         return $.Widget.prototype._trigger.call( this, type, event, ui );
2227     },
2228
2229     plugins: {},
2230
2231     _uiHash: function() {
2232         return {
2233             helper: this.helper,
2234             position: this.position,
2235             originalPosition: this.originalPosition,
2236             offset: this.positionAbs
2237         };
2238     }
2239
2240 });
2241
2242 $.ui.plugin.add( "draggable", "connectToSortable", {
2243     start: function( event, ui, draggable ) {
2244         var uiSortable = $.extend( {}, ui, {
2245             item: draggable.element
2246         });
2247
2248         draggable.sortables = [];
2249         $( draggable.options.connectToSortable ).each(function() {
2250             var sortable = $( this ).sortable( "instance" );
2251
2252             if ( sortable && !sortable.options.disabled ) {
2253                 draggable.sortables.push( sortable );
2254
2255                 // refreshPositions is called at drag start to refresh the containerCache
2256                 // which is used in drag. This ensures it's initialized and synchronized
2257                 // with any changes that might have happened on the page since initialization.
2258                 sortable.refreshPositions();
2259                 sortable._trigger("activate", event, uiSortable);
2260             }
2261         });
2262     },
2263     stop: function( event, ui, draggable ) {
2264         var uiSortable = $.extend( {}, ui, {
2265             item: draggable.element
2266         });
2267
2268         draggable.cancelHelperRemoval = false;
2269
2270         $.each( draggable.sortables, function() {
2271             var sortable = this;
2272
2273             if ( sortable.isOver ) {
2274                 sortable.isOver = 0;
2275
2276                 // Allow this sortable to handle removing the helper
2277                 draggable.cancelHelperRemoval = true;
2278                 sortable.cancelHelperRemoval = false;
2279
2280                 // Use _storedCSS To restore properties in the sortable,
2281                 // as this also handles revert (#9675) since the draggable
2282                 // may have modified them in unexpected ways (#8809)
2283                 sortable._storedCSS = {
2284                     position: sortable.placeholder.css( "position" ),
2285                     top: sortable.placeholder.css( "top" ),
2286                     left: sortable.placeholder.css( "left" )
2287                 };
2288
2289                 sortable._mouseStop(event);
2290
2291                 // Once drag has ended, the sortable should return to using
2292                 // its original helper, not the shared helper from draggable
2293                 sortable.options.helper = sortable.options._helper;
2294             } else {
2295                 // Prevent this Sortable from removing the helper.
2296                 // However, don't set the draggable to remove the helper
2297                 // either as another connected Sortable may yet handle the removal.
2298                 sortable.cancelHelperRemoval = true;
2299
2300                 sortable._trigger( "deactivate", event, uiSortable );
2301             }
2302         });
2303     },
2304     drag: function( event, ui, draggable ) {
2305         $.each( draggable.sortables, function() {
2306             var innermostIntersecting = false,
2307                 sortable = this;
2308
2309             // Copy over variables that sortable's _intersectsWith uses
2310             sortable.positionAbs = draggable.positionAbs;
2311             sortable.helperProportions = draggable.helperProportions;
2312             sortable.offset.click = draggable.offset.click;
2313
2314             if ( sortable._intersectsWith( sortable.containerCache ) ) {
2315                 innermostIntersecting = true;
2316
2317                 $.each( draggable.sortables, function() {
2318                     // Copy over variables that sortable's _intersectsWith uses
2319                     this.positionAbs = draggable.positionAbs;
2320                     this.helperProportions = draggable.helperProportions;
2321                     this.offset.click = draggable.offset.click;
2322
2323                     if ( this !== sortable &&
2324                             this._intersectsWith( this.containerCache ) &&
2325                             $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2326                         innermostIntersecting = false;
2327                     }
2328
2329                     return innermostIntersecting;
2330                 });
2331             }
2332
2333             if ( innermostIntersecting ) {
2334                 // If it intersects, we use a little isOver variable and set it once,
2335                 // so that the move-in stuff gets fired only once.
2336                 if ( !sortable.isOver ) {
2337                     sortable.isOver = 1;
2338
2339                     // Store draggable's parent in case we need to reappend to it later.
2340                     draggable._parent = ui.helper.parent();
2341
2342                     sortable.currentItem = ui.helper
2343                         .appendTo( sortable.element )
2344                         .data( "ui-sortable-item", true );
2345
2346                     // Store helper option to later restore it
2347                     sortable.options._helper = sortable.options.helper;
2348
2349                     sortable.options.helper = function() {
2350                         return ui.helper[ 0 ];
2351                     };
2352
2353                     // Fire the start events of the sortable with our passed browser event,
2354                     // and our own helper (so it doesn't create a new one)
2355                     event.target = sortable.currentItem[ 0 ];
2356                     sortable._mouseCapture( event, true );
2357                     sortable._mouseStart( event, true, true );
2358
2359                     // Because the browser event is way off the new appended portlet,
2360                     // modify necessary variables to reflect the changes
2361                     sortable.offset.click.top = draggable.offset.click.top;
2362                     sortable.offset.click.left = draggable.offset.click.left;
2363                     sortable.offset.parent.left -= draggable.offset.parent.left -
2364                         sortable.offset.parent.left;
2365                     sortable.offset.parent.top -= draggable.offset.parent.top -
2366                         sortable.offset.parent.top;
2367
2368                     draggable._trigger( "toSortable", event );
2369
2370                     // Inform draggable that the helper is in a valid drop zone,
2371                     // used solely in the revert option to handle "valid/invalid".
2372                     draggable.dropped = sortable.element;
2373
2374                     // Need to refreshPositions of all sortables in the case that
2375                     // adding to one sortable changes the location of the other sortables (#9675)
2376                     $.each( draggable.sortables, function() {
2377                         this.refreshPositions();
2378                     });
2379
2380                     // hack so receive/update callbacks work (mostly)
2381                     draggable.currentItem = draggable.element;
2382                     sortable.fromOutside = draggable;
2383                 }
2384
2385                 if ( sortable.currentItem ) {
2386                     sortable._mouseDrag( event );
2387                     // Copy the sortable's position because the draggable's can potentially reflect
2388                     // a relative position, while sortable is always absolute, which the dragged
2389                     // element has now become. (#8809)
2390                     ui.position = sortable.position;
2391                 }
2392             } else {
2393                 // If it doesn't intersect with the sortable, and it intersected before,
2394                 // we fake the drag stop of the sortable, but make sure it doesn't remove
2395                 // the helper by using cancelHelperRemoval.
2396                 if ( sortable.isOver ) {
2397
2398                     sortable.isOver = 0;
2399                     sortable.cancelHelperRemoval = true;
2400
2401                     // Calling sortable's mouseStop would trigger a revert,
2402                     // so revert must be temporarily false until after mouseStop is called.
2403                     sortable.options._revert = sortable.options.revert;
2404                     sortable.options.revert = false;
2405
2406                     sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2407                     sortable._mouseStop( event, true );
2408
2409                     // restore sortable behaviors that were modfied
2410                     // when the draggable entered the sortable area (#9481)
2411                     sortable.options.revert = sortable.options._revert;
2412                     sortable.options.helper = sortable.options._helper;
2413
2414                     if ( sortable.placeholder ) {
2415                         sortable.placeholder.remove();
2416                     }
2417
2418                     // Restore and recalculate the draggable's offset considering the sortable
2419                     // may have modified them in unexpected ways. (#8809, #10669)
2420                     ui.helper.appendTo( draggable._parent );
2421                     draggable._refreshOffsets( event );
2422                     ui.position = draggable._generatePosition( event, true );
2423
2424                     draggable._trigger( "fromSortable", event );
2425
2426                     // Inform draggable that the helper is no longer in a valid drop zone
2427                     draggable.dropped = false;
2428
2429                     // Need to refreshPositions of all sortables just in case removing
2430                     // from one sortable changes the location of other sortables (#9675)
2431                     $.each( draggable.sortables, function() {
2432                         this.refreshPositions();
2433                     });
2434                 }
2435             }
2436         });
2437     }
2438 });
2439
2440 $.ui.plugin.add("draggable", "cursor", {
2441     start: function( event, ui, instance ) {
2442         var t = $( "body" ),
2443             o = instance.options;
2444
2445         if (t.css("cursor")) {
2446             o._cursor = t.css("cursor");
2447         }
2448         t.css("cursor", o.cursor);
2449     },
2450     stop: function( event, ui, instance ) {
2451         var o = instance.options;
2452         if (o._cursor) {
2453             $("body").css("cursor", o._cursor);
2454         }
2455     }
2456 });
2457
2458 $.ui.plugin.add("draggable", "opacity", {
2459     start: function( event, ui, instance ) {
2460         var t = $( ui.helper ),
2461             o = instance.options;
2462         if (t.css("opacity")) {
2463             o._opacity = t.css("opacity");
2464         }
2465         t.css("opacity", o.opacity);
2466     },
2467     stop: function( event, ui, instance ) {
2468         var o = instance.options;
2469         if (o._opacity) {
2470             $(ui.helper).css("opacity", o._opacity);
2471         }
2472     }
2473 });
2474
2475 $.ui.plugin.add("draggable", "scroll", {
2476     start: function( event, ui, i ) {
2477         if ( !i.scrollParentNotHidden ) {
2478             i.scrollParentNotHidden = i.helper.scrollParent( false );
2479         }
2480
2481         if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
2482             i.overflowOffset = i.scrollParentNotHidden.offset();
2483         }
2484     },
2485     drag: function( event, ui, i  ) {
2486
2487         var o = i.options,
2488             scrolled = false,
2489             scrollParent = i.scrollParentNotHidden[ 0 ],
2490             document = i.document[ 0 ];
2491
2492         if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
2493             if ( !o.axis || o.axis !== "x" ) {
2494                 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
2495                     scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
2496                 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
2497                     scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
2498                 }
2499             }
2500
2501             if ( !o.axis || o.axis !== "y" ) {
2502                 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
2503                     scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
2504                 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
2505                     scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
2506                 }
2507             }
2508
2509         } else {
2510
2511             if (!o.axis || o.axis !== "x") {
2512                 if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
2513                     scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2514                 } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
2515                     scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2516                 }
2517             }
2518
2519             if (!o.axis || o.axis !== "y") {
2520                 if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
2521                     scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2522                 } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
2523                     scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2524                 }
2525             }
2526
2527         }
2528
2529         if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2530             $.ui.ddmanager.prepareOffsets(i, event);
2531         }
2532
2533     }
2534 });
2535
2536 $.ui.plugin.add("draggable", "snap", {
2537     start: function( event, ui, i ) {
2538
2539         var o = i.options;
2540
2541         i.snapElements = [];
2542
2543         $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
2544             var $t = $(this),
2545                 $o = $t.offset();
2546             if (this !== i.element[0]) {
2547                 i.snapElements.push({
2548                     item: this,
2549                     width: $t.outerWidth(), height: $t.outerHeight(),
2550                     top: $o.top, left: $o.left
2551                 });
2552             }
2553         });
2554
2555     },
2556     drag: function( event, ui, inst ) {
2557
2558         var ts, bs, ls, rs, l, r, t, b, i, first,
2559             o = inst.options,
2560             d = o.snapTolerance,
2561             x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2562             y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2563
2564         for (i = inst.snapElements.length - 1; i >= 0; i--){
2565
2566             l = inst.snapElements[i].left - inst.margins.left;
2567             r = l + inst.snapElements[i].width;
2568             t = inst.snapElements[i].top - inst.margins.top;
2569             b = t + inst.snapElements[i].height;
2570
2571             if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
2572                 if (inst.snapElements[i].snapping) {
2573                     (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2574                 }
2575                 inst.snapElements[i].snapping = false;
2576                 continue;
2577             }
2578
2579             if (o.snapMode !== "inner") {
2580                 ts = Math.abs(t - y2) <= d;
2581                 bs = Math.abs(b - y1) <= d;
2582                 ls = Math.abs(l - x2) <= d;
2583                 rs = Math.abs(r - x1) <= d;
2584                 if (ts) {
2585                     ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
2586                 }
2587                 if (bs) {
2588                     ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
2589                 }
2590                 if (ls) {
2591                     ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
2592                 }
2593                 if (rs) {
2594                     ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
2595                 }
2596             }
2597
2598             first = (ts || bs || ls || rs);
2599
2600             if (o.snapMode !== "outer") {
2601                 ts = Math.abs(t - y1) <= d;
2602                 bs = Math.abs(b - y2) <= d;
2603                 ls = Math.abs(l - x1) <= d;
2604                 rs = Math.abs(r - x2) <= d;
2605                 if (ts) {
2606                     ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
2607                 }
2608                 if (bs) {
2609                     ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
2610                 }
2611                 if (ls) {
2612                     ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
2613                 }
2614                 if (rs) {
2615                     ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
2616                 }
2617             }
2618
2619             if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
2620                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2621             }
2622             inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2623
2624         }
2625
2626     }
2627 });
2628
2629 $.ui.plugin.add("draggable", "stack", {
2630     start: function( event, ui, instance ) {
2631         var min,
2632             o = instance.options,
2633             group = $.makeArray($(o.stack)).sort(function(a, b) {
2634                 return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
2635             });
2636
2637         if (!group.length) { return; }
2638
2639         min = parseInt($(group[0]).css("zIndex"), 10) || 0;
2640         $(group).each(function(i) {
2641             $(this).css("zIndex", min + i);
2642         });
2643         this.css("zIndex", (min + group.length));
2644     }
2645 });
2646
2647 $.ui.plugin.add("draggable", "zIndex", {
2648     start: function( event, ui, instance ) {
2649         var t = $( ui.helper ),
2650             o = instance.options;
2651
2652         if (t.css("zIndex")) {
2653             o._zIndex = t.css("zIndex");
2654         }
2655         t.css("zIndex", o.zIndex);
2656     },
2657     stop: function( event, ui, instance ) {
2658         var o = instance.options;
2659
2660         if (o._zIndex) {
2661             $(ui.helper).css("zIndex", o._zIndex);
2662         }
2663     }
2664 });
2665
2666 var draggable = $.ui.draggable;
2667
2668
2669 /*!
2670  * jQuery UI Droppable 1.11.4
2671  * http://jqueryui.com
2672  *
2673  * Copyright jQuery Foundation and other contributors
2674  * Released under the MIT license.
2675  * http://jquery.org/license
2676  *
2677  * http://api.jqueryui.com/droppable/
2678  */
2679
2680
2681 $.widget( "ui.droppable", {
2682     version: "1.11.4",
2683     widgetEventPrefix: "drop",
2684     options: {
2685         accept: "*",
2686         activeClass: false,
2687         addClasses: true,
2688         greedy: false,
2689         hoverClass: false,
2690         scope: "default",
2691         tolerance: "intersect",
2692
2693         // callbacks
2694         activate: null,
2695         deactivate: null,
2696         drop: null,
2697         out: null,
2698         over: null
2699     },
2700     _create: function() {
2701
2702         var proportions,
2703             o = this.options,
2704             accept = o.accept;
2705
2706         this.isover = false;
2707         this.isout = true;
2708
2709         this.accept = $.isFunction( accept ) ? accept : function( d ) {
2710             return d.is( accept );
2711         };
2712
2713         this.proportions = function( /* valueToWrite */ ) {
2714             if ( arguments.length ) {
2715                 // Store the droppable's proportions
2716                 proportions = arguments[ 0 ];
2717             } else {
2718                 // Retrieve or derive the droppable's proportions
2719                 return proportions ?
2720                     proportions :
2721                     proportions = {
2722                         width: this.element[ 0 ].offsetWidth,
2723                         height: this.element[ 0 ].offsetHeight
2724                     };
2725             }
2726         };
2727
2728         this._addToManager( o.scope );
2729
2730         o.addClasses && this.element.addClass( "ui-droppable" );
2731
2732     },
2733
2734     _addToManager: function( scope ) {
2735         // Add the reference and positions to the manager
2736         $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
2737         $.ui.ddmanager.droppables[ scope ].push( this );
2738     },
2739
2740     _splice: function( drop ) {
2741         var i = 0;
2742         for ( ; i < drop.length; i++ ) {
2743             if ( drop[ i ] === this ) {
2744                 drop.splice( i, 1 );
2745             }
2746         }
2747     },
2748
2749     _destroy: function() {
2750         var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2751
2752         this._splice( drop );
2753
2754         this.element.removeClass( "ui-droppable ui-droppable-disabled" );
2755     },
2756
2757     _setOption: function( key, value ) {
2758
2759         if ( key === "accept" ) {
2760             this.accept = $.isFunction( value ) ? value : function( d ) {
2761                 return d.is( value );
2762             };
2763         } else if ( key === "scope" ) {
2764             var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2765
2766             this._splice( drop );
2767             this._addToManager( value );
2768         }
2769
2770         this._super( key, value );
2771     },
2772
2773     _activate: function( event ) {
2774         var draggable = $.ui.ddmanager.current;
2775         if ( this.options.activeClass ) {
2776             this.element.addClass( this.options.activeClass );
2777         }
2778         if ( draggable ){
2779             this._trigger( "activate", event, this.ui( draggable ) );
2780         }
2781     },
2782
2783     _deactivate: function( event ) {
2784         var draggable = $.ui.ddmanager.current;
2785         if ( this.options.activeClass ) {
2786             this.element.removeClass( this.options.activeClass );
2787         }
2788         if ( draggable ){
2789             this._trigger( "deactivate", event, this.ui( draggable ) );
2790         }
2791     },
2792
2793     _over: function( event ) {
2794
2795         var draggable = $.ui.ddmanager.current;
2796
2797         // Bail if draggable and droppable are same element
2798         if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2799             return;
2800         }
2801
2802         if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2803             if ( this.options.hoverClass ) {
2804                 this.element.addClass( this.options.hoverClass );
2805             }
2806             this._trigger( "over", event, this.ui( draggable ) );
2807         }
2808
2809     },
2810
2811     _out: function( event ) {
2812
2813         var draggable = $.ui.ddmanager.current;
2814
2815         // Bail if draggable and droppable are same element
2816         if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2817             return;
2818         }
2819
2820         if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2821             if ( this.options.hoverClass ) {
2822                 this.element.removeClass( this.options.hoverClass );
2823             }
2824             this._trigger( "out", event, this.ui( draggable ) );
2825         }
2826
2827     },
2828
2829     _drop: function( event, custom ) {
2830
2831         var draggable = custom || $.ui.ddmanager.current,
2832             childrenIntersection = false;
2833
2834         // Bail if draggable and droppable are same element
2835         if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2836             return false;
2837         }
2838
2839         this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
2840             var inst = $( this ).droppable( "instance" );
2841             if (
2842                 inst.options.greedy &&
2843                 !inst.options.disabled &&
2844                 inst.options.scope === draggable.options.scope &&
2845                 inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
2846                 $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
2847             ) { childrenIntersection = true; return false; }
2848         });
2849         if ( childrenIntersection ) {
2850             return false;
2851         }
2852
2853         if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2854             if ( this.options.activeClass ) {
2855                 this.element.removeClass( this.options.activeClass );
2856             }
2857             if ( this.options.hoverClass ) {
2858                 this.element.removeClass( this.options.hoverClass );
2859             }
2860             this._trigger( "drop", event, this.ui( draggable ) );
2861             return this.element;
2862         }
2863
2864         return false;
2865
2866     },
2867
2868     ui: function( c ) {
2869         return {
2870             draggable: ( c.currentItem || c.element ),
2871             helper: c.helper,
2872             position: c.position,
2873             offset: c.positionAbs
2874         };
2875     }
2876
2877 });
2878
2879 $.ui.intersect = (function() {
2880     function isOverAxis( x, reference, size ) {
2881         return ( x >= reference ) && ( x < ( reference + size ) );
2882     }
2883
2884     return function( draggable, droppable, toleranceMode, event ) {
2885
2886         if ( !droppable.offset ) {
2887             return false;
2888         }
2889
2890         var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
2891             y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
2892             x2 = x1 + draggable.helperProportions.width,
2893             y2 = y1 + draggable.helperProportions.height,
2894             l = droppable.offset.left,
2895             t = droppable.offset.top,
2896             r = l + droppable.proportions().width,
2897             b = t + droppable.proportions().height;
2898
2899         switch ( toleranceMode ) {
2900         case "fit":
2901             return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
2902         case "intersect":
2903             return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
2904                 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
2905                 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
2906                 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
2907         case "pointer":
2908             return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
2909         case "touch":
2910             return (
2911                 ( y1 >= t && y1 <= b ) || // Top edge touching
2912                 ( y2 >= t && y2 <= b ) || // Bottom edge touching
2913                 ( y1 < t && y2 > b ) // Surrounded vertically
2914             ) && (
2915                 ( x1 >= l && x1 <= r ) || // Left edge touching
2916                 ( x2 >= l && x2 <= r ) || // Right edge touching
2917                 ( x1 < l && x2 > r ) // Surrounded horizontally
2918             );
2919         default:
2920             return false;
2921         }
2922     };
2923 })();
2924
2925 /*
2926     This manager tracks offsets of draggables and droppables
2927 */
2928 $.ui.ddmanager = {
2929     current: null,
2930     droppables: { "default": [] },
2931     prepareOffsets: function( t, event ) {
2932
2933         var i, j,
2934             m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
2935             type = event ? event.type : null, // workaround for #2317
2936             list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
2937
2938         droppablesLoop: for ( i = 0; i < m.length; i++ ) {
2939
2940             // No disabled and non-accepted
2941             if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
2942                 continue;
2943             }
2944
2945             // Filter out elements in the current dragged item
2946             for ( j = 0; j < list.length; j++ ) {
2947                 if ( list[ j ] === m[ i ].element[ 0 ] ) {
2948                     m[ i ].proportions().height = 0;
2949                     continue droppablesLoop;
2950                 }
2951             }
2952
2953             m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
2954             if ( !m[ i ].visible ) {
2955                 continue;
2956             }
2957
2958             // Activate the droppable if used directly from draggables
2959             if ( type === "mousedown" ) {
2960                 m[ i ]._activate.call( m[ i ], event );
2961             }
2962
2963             m[ i ].offset = m[ i ].element.offset();
2964             m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2965
2966         }
2967
2968     },
2969     drop: function( draggable, event ) {
2970
2971         var dropped = false;
2972         // Create a copy of the droppables in case the list changes during the drop (#9116)
2973         $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
2974
2975             if ( !this.options ) {
2976                 return;
2977             }
2978             if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
2979                 dropped = this._drop.call( this, event ) || dropped;
2980             }
2981
2982             if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2983                 this.isout = true;
2984                 this.isover = false;
2985                 this._deactivate.call( this, event );
2986             }
2987
2988         });
2989         return dropped;
2990
2991     },
2992     dragStart: function( draggable, event ) {
2993         // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2994         draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2995             if ( !draggable.options.refreshPositions ) {
2996                 $.ui.ddmanager.prepareOffsets( draggable, event );
2997             }
2998         });
2999     },
3000     drag: function( draggable, event ) {
3001
3002         // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
3003         if ( draggable.options.refreshPositions ) {
3004             $.ui.ddmanager.prepareOffsets( draggable, event );
3005         }
3006
3007         // Run through all droppables and check their positions based on specific tolerance options
3008         $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
3009
3010             if ( this.options.disabled || this.greedyChild || !this.visible ) {
3011                 return;
3012             }
3013
3014             var parentInstance, scope, parent,
3015                 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
3016                 c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
3017             if ( !c ) {
3018                 return;
3019             }
3020
3021             if ( this.options.greedy ) {
3022                 // find droppable parents with same scope
3023                 scope = this.options.scope;
3024                 parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
3025                     return $( this ).droppable( "instance" ).options.scope === scope;
3026                 });
3027
3028                 if ( parent.length ) {
3029                     parentInstance = $( parent[ 0 ] ).droppable( "instance" );
3030                     parentInstance.greedyChild = ( c === "isover" );
3031                 }
3032             }
3033
3034             // we just moved into a greedy child
3035             if ( parentInstance && c === "isover" ) {
3036                 parentInstance.isover = false;
3037                 parentInstance.isout = true;
3038                 parentInstance._out.call( parentInstance, event );
3039             }
3040
3041             this[ c ] = true;
3042             this[c === "isout" ? "isover" : "isout"] = false;
3043             this[c === "isover" ? "_over" : "_out"].call( this, event );
3044
3045             // we just moved out of a greedy child
3046             if ( parentInstance && c === "isout" ) {
3047                 parentInstance.isout = false;
3048                 parentInstance.isover = true;
3049                 parentInstance._over.call( parentInstance, event );
3050             }
3051         });
3052
3053     },
3054     dragStop: function( draggable, event ) {
3055         draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
3056         // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
3057         if ( !draggable.options.refreshPositions ) {
3058             $.ui.ddmanager.prepareOffsets( draggable, event );
3059         }
3060     }
3061 };
3062
3063 var droppable = $.ui.droppable;
3064
3065
3066 /*!
3067  * jQuery UI Resizable 1.11.4
3068  * http://jqueryui.com
3069  *
3070  * Copyright jQuery Foundation and other contributors
3071  * Released under the MIT license.
3072  * http://jquery.org/license
3073  *
3074  * http://api.jqueryui.com/resizable/
3075  */
3076
3077
3078 $.widget("ui.resizable", $.ui.mouse, {
3079     version: "1.11.4",
3080     widgetEventPrefix: "resize",
3081     options: {
3082         alsoResize: false,
3083         animate: false,
3084         animateDuration: "slow",
3085         animateEasing: "swing",
3086         aspectRatio: false,
3087         autoHide: false,
3088         containment: false,
3089         ghost: false,
3090         grid: false,
3091         handles: "e,s,se",
3092         helper: false,
3093         maxHeight: null,
3094         maxWidth: null,
3095         minHeight: 10,
3096         minWidth: 10,
3097         // See #7960
3098         zIndex: 90,
3099
3100         // callbacks
3101         resize: null,
3102         start: null,
3103         stop: null
3104     },
3105
3106     _num: function( value ) {
3107         return parseInt( value, 10 ) || 0;
3108     },
3109
3110     _isNumber: function( value ) {
3111         return !isNaN( parseInt( value, 10 ) );
3112     },
3113
3114     _hasScroll: function( el, a ) {
3115
3116         if ( $( el ).css( "overflow" ) === "hidden") {
3117             return false;
3118         }
3119
3120         var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
3121             has = false;
3122
3123         if ( el[ scroll ] > 0 ) {
3124             return true;
3125         }
3126
3127         // TODO: determine which cases actually cause this to happen
3128         // if the element doesn't have the scroll set, see if it's possible to
3129         // set the scroll
3130         el[ scroll ] = 1;
3131         has = ( el[ scroll ] > 0 );
3132         el[ scroll ] = 0;
3133         return has;
3134     },
3135
3136     _create: function() {
3137
3138         var n, i, handle, axis, hname,
3139             that = this,
3140             o = this.options;
3141         this.element.addClass("ui-resizable");
3142
3143         $.extend(this, {
3144             _aspectRatio: !!(o.aspectRatio),
3145             aspectRatio: o.aspectRatio,
3146             originalElement: this.element,
3147             _proportionallyResizeElements: [],
3148             _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3149         });
3150
3151         // Wrap the element if it cannot hold child nodes
3152         if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
3153
3154             this.element.wrap(
3155                 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
3156                     position: this.element.css("position"),
3157                     width: this.element.outerWidth(),
3158                     height: this.element.outerHeight(),
3159                     top: this.element.css("top"),
3160                     left: this.element.css("left")
3161                 })
3162             );
3163
3164             this.element = this.element.parent().data(
3165                 "ui-resizable", this.element.resizable( "instance" )
3166             );
3167
3168             this.elementIsWrapper = true;
3169
3170             this.element.css({
3171                 marginLeft: this.originalElement.css("marginLeft"),
3172                 marginTop: this.originalElement.css("marginTop"),
3173                 marginRight: this.originalElement.css("marginRight"),
3174                 marginBottom: this.originalElement.css("marginBottom")
3175             });
3176             this.originalElement.css({
3177                 marginLeft: 0,
3178                 marginTop: 0,
3179                 marginRight: 0,
3180                 marginBottom: 0
3181             });
3182             // support: Safari
3183             // Prevent Safari textarea resize
3184             this.originalResizeStyle = this.originalElement.css("resize");
3185             this.originalElement.css("resize", "none");
3186
3187             this._proportionallyResizeElements.push( this.originalElement.css({
3188                 position: "static",
3189                 zoom: 1,
3190                 display: "block"
3191             }) );
3192
3193             // support: IE9
3194             // avoid IE jump (hard set the margin)
3195             this.originalElement.css({ margin: this.originalElement.css("margin") });
3196
3197             this._proportionallyResize();
3198         }
3199
3200         this.handles = o.handles ||
3201             ( !$(".ui-resizable-handle", this.element).length ?
3202                 "e,s,se" : {
3203                     n: ".ui-resizable-n",
3204                     e: ".ui-resizable-e",
3205                     s: ".ui-resizable-s",
3206                     w: ".ui-resizable-w",
3207                     se: ".ui-resizable-se",
3208                     sw: ".ui-resizable-sw",
3209                     ne: ".ui-resizable-ne",
3210                     nw: ".ui-resizable-nw"
3211                 } );
3212
3213         this._handles = $();
3214         if ( this.handles.constructor === String ) {
3215
3216             if ( this.handles === "all") {
3217                 this.handles = "n,e,s,w,se,sw,ne,nw";
3218             }
3219
3220             n = this.handles.split(",");
3221             this.handles = {};
3222
3223             for (i = 0; i < n.length; i++) {
3224
3225                 handle = $.trim(n[i]);
3226                 hname = "ui-resizable-" + handle;
3227                 axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
3228
3229                 axis.css({ zIndex: o.zIndex });
3230
3231                 // TODO : What's going on here?
3232                 if ("se" === handle) {
3233                     axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
3234                 }
3235
3236                 this.handles[handle] = ".ui-resizable-" + handle;
3237                 this.element.append(axis);
3238             }
3239
3240         }
3241
3242         this._renderAxis = function(target) {
3243
3244             var i, axis, padPos, padWrapper;
3245
3246             target = target || this.element;
3247
3248             for (i in this.handles) {
3249
3250                 if (this.handles[i].constructor === String) {
3251                     this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
3252                 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
3253                     this.handles[ i ] = $( this.handles[ i ] );
3254                     this._on( this.handles[ i ], { "mousedown": that._mouseDown });
3255                 }
3256
3257                 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
3258
3259                     axis = $(this.handles[i], this.element);
3260
3261                     padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
3262
3263                     padPos = [ "padding",
3264                         /ne|nw|n/.test(i) ? "Top" :
3265                         /se|sw|s/.test(i) ? "Bottom" :
3266                         /^e$/.test(i) ? "Right" : "Left" ].join("");
3267
3268                     target.css(padPos, padWrapper);
3269
3270                     this._proportionallyResize();
3271                 }
3272
3273                 this._handles = this._handles.add( this.handles[ i ] );
3274             }
3275         };
3276
3277         // TODO: make renderAxis a prototype function
3278         this._renderAxis(this.element);
3279
3280         this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
3281         this._handles.disableSelection();
3282
3283         this._handles.mouseover(function() {
3284             if (!that.resizing) {
3285                 if (this.className) {
3286                     axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
3287                 }
3288                 that.axis = axis && axis[1] ? axis[1] : "se";
3289             }
3290         });
3291
3292         if (o.autoHide) {
3293             this._handles.hide();
3294             $(this.element)
3295                 .addClass("ui-resizable-autohide")
3296                 .mouseenter(function() {
3297                     if (o.disabled) {
3298                         return;
3299                     }
3300                     $(this).removeClass("ui-resizable-autohide");
3301                     that._handles.show();
3302                 })
3303                 .mouseleave(function() {
3304                     if (o.disabled) {
3305                         return;
3306                     }
3307                     if (!that.resizing) {
3308                         $(this).addClass("ui-resizable-autohide");
3309                         that._handles.hide();
3310                     }
3311                 });
3312         }
3313
3314         this._mouseInit();
3315     },
3316
3317     _destroy: function() {
3318
3319         this._mouseDestroy();
3320
3321         var wrapper,
3322             _destroy = function(exp) {
3323                 $(exp)
3324                     .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
3325                     .removeData("resizable")
3326                     .removeData("ui-resizable")
3327                     .unbind(".resizable")
3328                     .find(".ui-resizable-handle")
3329                         .remove();
3330             };
3331
3332         // TODO: Unwrap at same DOM position
3333         if (this.elementIsWrapper) {
3334             _destroy(this.element);
3335             wrapper = this.element;
3336             this.originalElement.css({
3337                 position: wrapper.css("position"),
3338                 width: wrapper.outerWidth(),
3339                 height: wrapper.outerHeight(),
3340                 top: wrapper.css("top"),
3341                 left: wrapper.css("left")
3342             }).insertAfter( wrapper );
3343             wrapper.remove();
3344         }
3345
3346         this.originalElement.css("resize", this.originalResizeStyle);
3347         _destroy(this.originalElement);
3348
3349         return this;
3350     },
3351
3352     _mouseCapture: function(event) {
3353         var i, handle,
3354             capture = false;
3355
3356         for (i in this.handles) {
3357             handle = $(this.handles[i])[0];
3358             if (handle === event.target || $.contains(handle, event.target)) {
3359                 capture = true;
3360             }
3361         }
3362
3363         return !this.options.disabled && capture;
3364     },
3365
3366     _mouseStart: function(event) {
3367
3368         var curleft, curtop, cursor,
3369             o = this.options,
3370             el = this.element;
3371
3372         this.resizing = true;
3373
3374         this._renderProxy();
3375
3376         curleft = this._num(this.helper.css("left"));
3377         curtop = this._num(this.helper.css("top"));
3378
3379         if (o.containment) {
3380             curleft += $(o.containment).scrollLeft() || 0;
3381             curtop += $(o.containment).scrollTop() || 0;
3382         }
3383
3384         this.offset = this.helper.offset();
3385         this.position = { left: curleft, top: curtop };
3386
3387         this.size = this._helper ? {
3388                 width: this.helper.width(),
3389                 height: this.helper.height()
3390             } : {
3391                 width: el.width(),
3392                 height: el.height()
3393             };
3394
3395         this.originalSize = this._helper ? {
3396                 width: el.outerWidth(),
3397                 height: el.outerHeight()
3398             } : {
3399                 width: el.width(),
3400                 height: el.height()
3401             };
3402
3403         this.sizeDiff = {
3404             width: el.outerWidth() - el.width(),
3405             height: el.outerHeight() - el.height()
3406         };
3407
3408         this.originalPosition = { left: curleft, top: curtop };
3409         this.originalMousePosition = { left: event.pageX, top: event.pageY };
3410
3411         this.aspectRatio = (typeof o.aspectRatio === "number") ?
3412             o.aspectRatio :
3413             ((this.originalSize.width / this.originalSize.height) || 1);
3414
3415         cursor = $(".ui-resizable-" + this.axis).css("cursor");
3416         $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
3417
3418         el.addClass("ui-resizable-resizing");
3419         this._propagate("start", event);
3420         return true;
3421     },
3422
3423     _mouseDrag: function(event) {
3424
3425         var data, props,
3426             smp = this.originalMousePosition,
3427             a = this.axis,
3428             dx = (event.pageX - smp.left) || 0,
3429             dy = (event.pageY - smp.top) || 0,
3430             trigger = this._change[a];
3431
3432         this._updatePrevProperties();
3433
3434         if (!trigger) {
3435             return false;
3436         }
3437
3438         data = trigger.apply(this, [ event, dx, dy ]);
3439
3440         this._updateVirtualBoundaries(event.shiftKey);
3441         if (this._aspectRatio || event.shiftKey) {
3442             data = this._updateRatio(data, event);
3443         }
3444
3445         data = this._respectSize(data, event);
3446
3447         this._updateCache(data);
3448
3449         this._propagate("resize", event);
3450
3451         props = this._applyChanges();
3452
3453         if ( !this._helper && this._proportionallyResizeElements.length ) {
3454             this._proportionallyResize();
3455         }
3456
3457         if ( !$.isEmptyObject( props ) ) {
3458             this._updatePrevProperties();
3459             this._trigger( "resize", event, this.ui() );
3460             this._applyChanges();
3461         }
3462
3463         return false;
3464     },
3465
3466     _mouseStop: function(event) {
3467
3468         this.resizing = false;
3469         var pr, ista, soffseth, soffsetw, s, left, top,
3470             o = this.options, that = this;
3471
3472         if (this._helper) {
3473
3474             pr = this._proportionallyResizeElements;
3475             ista = pr.length && (/textarea/i).test(pr[0].nodeName);
3476             soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
3477             soffsetw = ista ? 0 : that.sizeDiff.width;
3478
3479             s = {
3480                 width: (that.helper.width()  - soffsetw),
3481                 height: (that.helper.height() - soffseth)
3482             };
3483             left = (parseInt(that.element.css("left"), 10) +
3484                 (that.position.left - that.originalPosition.left)) || null;
3485             top = (parseInt(that.element.css("top"), 10) +
3486                 (that.position.top - that.originalPosition.top)) || null;
3487
3488             if (!o.animate) {
3489                 this.element.css($.extend(s, { top: top, left: left }));
3490             }
3491
3492             that.helper.height(that.size.height);
3493             that.helper.width(that.size.width);
3494
3495             if (this._helper && !o.animate) {
3496                 this._proportionallyResize();
3497             }
3498         }
3499
3500         $("body").css("cursor", "auto");
3501
3502         this.element.removeClass("ui-resizable-resizing");
3503
3504         this._propagate("stop", event);
3505
3506         if (this._helper) {
3507             this.helper.remove();
3508         }
3509
3510         return false;
3511
3512     },
3513
3514     _updatePrevProperties: function() {
3515         this.prevPosition = {
3516             top: this.position.top,
3517             left: this.position.left
3518         };
3519         this.prevSize = {
3520             width: this.size.width,
3521             height: this.size.height
3522         };
3523     },
3524
3525     _applyChanges: function() {
3526         var props = {};
3527
3528         if ( this.position.top !== this.prevPosition.top ) {
3529             props.top = this.position.top + "px";
3530         }
3531         if ( this.position.left !== this.prevPosition.left ) {
3532             props.left = this.position.left + "px";
3533         }
3534         if ( this.size.width !== this.prevSize.width ) {
3535             props.width = this.size.width + "px";
3536         }
3537         if ( this.size.height !== this.prevSize.height ) {
3538             props.height = this.size.height + "px";
3539         }
3540
3541         this.helper.css( props );
3542
3543         return props;
3544     },
3545
3546     _updateVirtualBoundaries: function(forceAspectRatio) {
3547         var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3548             o = this.options;
3549
3550         b = {
3551             minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
3552             maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
3553             minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
3554             maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
3555         };
3556
3557         if (this._aspectRatio || forceAspectRatio) {
3558             pMinWidth = b.minHeight * this.aspectRatio;
3559             pMinHeight = b.minWidth / this.aspectRatio;
3560             pMaxWidth = b.maxHeight * this.aspectRatio;
3561             pMaxHeight = b.maxWidth / this.aspectRatio;
3562
3563             if (pMinWidth > b.minWidth) {
3564                 b.minWidth = pMinWidth;
3565             }
3566             if (pMinHeight > b.minHeight) {
3567                 b.minHeight = pMinHeight;
3568             }
3569             if (pMaxWidth < b.maxWidth) {
3570                 b.maxWidth = pMaxWidth;
3571             }
3572             if (pMaxHeight < b.maxHeight) {
3573                 b.maxHeight = pMaxHeight;
3574             }
3575         }
3576         this._vBoundaries = b;
3577     },
3578
3579     _updateCache: function(data) {
3580         this.offset = this.helper.offset();
3581         if (this._isNumber(data.left)) {
3582             this.position.left = data.left;
3583         }
3584         if (this._isNumber(data.top)) {
3585             this.position.top = data.top;
3586         }
3587         if (this._isNumber(data.height)) {
3588             this.size.height = data.height;
3589         }
3590         if (this._isNumber(data.width)) {
3591             this.size.width = data.width;
3592         }
3593     },
3594
3595     _updateRatio: function( data ) {
3596
3597         var cpos = this.position,
3598             csize = this.size,
3599             a = this.axis;
3600
3601         if (this._isNumber(data.height)) {
3602             data.width = (data.height * this.aspectRatio);
3603         } else if (this._isNumber(data.width)) {
3604             data.height = (data.width / this.aspectRatio);
3605         }
3606
3607         if (a === "sw") {
3608             data.left = cpos.left + (csize.width - data.width);
3609             data.top = null;
3610         }
3611         if (a === "nw") {
3612             data.top = cpos.top + (csize.height - data.height);
3613             data.left = cpos.left + (csize.width - data.width);
3614         }
3615
3616         return data;
3617     },
3618
3619     _respectSize: function( data ) {
3620
3621         var o = this._vBoundaries,
3622             a = this.axis,
3623             ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
3624             ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3625             isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
3626             isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
3627             dw = this.originalPosition.left + this.originalSize.width,
3628             dh = this.position.top + this.size.height,
3629             cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3630         if (isminw) {
3631             data.width = o.minWidth;
3632         }
3633         if (isminh) {
3634             data.height = o.minHeight;
3635         }
3636         if (ismaxw) {
3637             data.width = o.maxWidth;
3638         }
3639         if (ismaxh) {
3640             data.height = o.maxHeight;
3641         }
3642
3643         if (isminw && cw) {
3644             data.left = dw - o.minWidth;
3645         }
3646         if (ismaxw && cw) {
3647             data.left = dw - o.maxWidth;
3648         }
3649         if (isminh && ch) {
3650             data.top = dh - o.minHeight;
3651         }
3652         if (ismaxh && ch) {
3653             data.top = dh - o.maxHeight;
3654         }
3655
3656         // Fixing jump error on top/left - bug #2330
3657         if (!data.width && !data.height && !data.left && data.top) {
3658             data.top = null;
3659         } else if (!data.width && !data.height && !data.top && data.left) {
3660             data.left = null;
3661         }
3662
3663         return data;
3664     },
3665
3666     _getPaddingPlusBorderDimensions: function( element ) {
3667         var i = 0,
3668             widths = [],
3669             borders = [
3670                 element.css( "borderTopWidth" ),
3671                 element.css( "borderRightWidth" ),
3672                 element.css( "borderBottomWidth" ),
3673                 element.css( "borderLeftWidth" )
3674             ],
3675             paddings = [
3676                 element.css( "paddingTop" ),
3677                 element.css( "paddingRight" ),
3678                 element.css( "paddingBottom" ),
3679                 element.css( "paddingLeft" )
3680             ];
3681
3682         for ( ; i < 4; i++ ) {
3683             widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
3684             widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
3685         }
3686
3687         return {
3688             height: widths[ 0 ] + widths[ 2 ],
3689             width: widths[ 1 ] + widths[ 3 ]
3690         };
3691     },
3692
3693     _proportionallyResize: function() {
3694
3695         if (!this._proportionallyResizeElements.length) {
3696             return;
3697         }
3698
3699         var prel,
3700             i = 0,
3701             element = this.helper || this.element;
3702
3703         for ( ; i < this._proportionallyResizeElements.length; i++) {
3704
3705             prel = this._proportionallyResizeElements[i];
3706
3707             // TODO: Seems like a bug to cache this.outerDimensions
3708             // considering that we are in a loop.
3709             if (!this.outerDimensions) {
3710                 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
3711             }
3712
3713             prel.css({
3714                 height: (element.height() - this.outerDimensions.height) || 0,
3715                 width: (element.width() - this.outerDimensions.width) || 0
3716             });
3717
3718         }
3719
3720     },
3721
3722     _renderProxy: function() {
3723
3724         var el = this.element, o = this.options;
3725         this.elementOffset = el.offset();
3726
3727         if (this._helper) {
3728
3729             this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
3730
3731             this.helper.addClass(this._helper).css({
3732                 width: this.element.outerWidth() - 1,
3733                 height: this.element.outerHeight() - 1,
3734                 position: "absolute",
3735                 left: this.elementOffset.left + "px",
3736                 top: this.elementOffset.top + "px",
3737                 zIndex: ++o.zIndex //TODO: Don't modify option
3738             });
3739
3740             this.helper
3741                 .appendTo("body")
3742                 .disableSelection();
3743
3744         } else {
3745             this.helper = this.element;
3746         }
3747
3748     },
3749
3750     _change: {
3751         e: function(event, dx) {
3752             return { width: this.originalSize.width + dx };
3753         },
3754         w: function(event, dx) {
3755             var cs = this.originalSize, sp = this.originalPosition;
3756             return { left: sp.left + dx, width: cs.width - dx };
3757         },
3758         n: function(event, dx, dy) {
3759             var cs = this.originalSize, sp = this.originalPosition;
3760             return { top: sp.top + dy, height: cs.height - dy };
3761         },
3762         s: function(event, dx, dy) {
3763             return { height: this.originalSize.height + dy };
3764         },
3765         se: function(event, dx, dy) {
3766             return $.extend(this._change.s.apply(this, arguments),
3767                 this._change.e.apply(this, [ event, dx, dy ]));
3768         },
3769         sw: function(event, dx, dy) {
3770             return $.extend(this._change.s.apply(this, arguments),
3771                 this._change.w.apply(this, [ event, dx, dy ]));
3772         },
3773         ne: function(event, dx, dy) {
3774             return $.extend(this._change.n.apply(this, arguments),
3775                 this._change.e.apply(this, [ event, dx, dy ]));
3776         },
3777         nw: function(event, dx, dy) {
3778             return $.extend(this._change.n.apply(this, arguments),
3779                 this._change.w.apply(this, [ event, dx, dy ]));
3780         }
3781     },
3782
3783     _propagate: function(n, event) {
3784         $.ui.plugin.call(this, n, [ event, this.ui() ]);
3785         (n !== "resize" && this._trigger(n, event, this.ui()));
3786     },
3787
3788     plugins: {},
3789
3790     ui: function() {
3791         return {
3792             originalElement: this.originalElement,
3793             element: this.element,
3794             helper: this.helper,
3795             position: this.position,
3796             size: this.size,
3797             originalSize: this.originalSize,
3798             originalPosition: this.originalPosition
3799         };
3800     }
3801
3802 });
3803
3804 /*
3805  * Resizable Extensions
3806  */
3807
3808 $.ui.plugin.add("resizable", "animate", {
3809
3810     stop: function( event ) {
3811         var that = $(this).resizable( "instance" ),
3812             o = that.options,
3813             pr = that._proportionallyResizeElements,
3814             ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3815             soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
3816             soffsetw = ista ? 0 : that.sizeDiff.width,
3817             style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3818             left = (parseInt(that.element.css("left"), 10) +
3819                 (that.position.left - that.originalPosition.left)) || null,
3820             top = (parseInt(that.element.css("top"), 10) +
3821                 (that.position.top - that.originalPosition.top)) || null;
3822
3823         that.element.animate(
3824             $.extend(style, top && left ? { top: top, left: left } : {}), {
3825                 duration: o.animateDuration,
3826                 easing: o.animateEasing,
3827                 step: function() {
3828
3829                     var data = {
3830                         width: parseInt(that.element.css("width"), 10),
3831                         height: parseInt(that.element.css("height"), 10),
3832                         top: parseInt(that.element.css("top"), 10),
3833                         left: parseInt(that.element.css("left"), 10)
3834                     };
3835
3836                     if (pr && pr.length) {
3837                         $(pr[0]).css({ width: data.width, height: data.height });
3838                     }
3839
3840                     // propagating resize, and updating values for each animation step
3841                     that._updateCache(data);
3842                     that._propagate("resize", event);
3843
3844                 }
3845             }
3846         );
3847     }
3848
3849 });
3850
3851 $.ui.plugin.add( "resizable", "containment", {
3852
3853     start: function() {
3854         var element, p, co, ch, cw, width, height,
3855             that = $( this ).resizable( "instance" ),
3856             o = that.options,
3857             el = that.element,
3858             oc = o.containment,
3859             ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
3860
3861         if ( !ce ) {
3862             return;
3863         }
3864
3865         that.containerElement = $( ce );
3866
3867         if ( /document/.test( oc ) || oc === document ) {
3868             that.containerOffset = {
3869                 left: 0,
3870                 top: 0
3871             };
3872             that.containerPosition = {
3873                 left: 0,
3874                 top: 0
3875             };
3876
3877             that.parentData = {
3878                 element: $( document ),
3879                 left: 0,
3880                 top: 0,
3881                 width: $( document ).width(),
3882                 height: $( document ).height() || document.body.parentNode.scrollHeight
3883             };
3884         } else {
3885             element = $( ce );
3886             p = [];
3887             $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
3888                 p[ i ] = that._num( element.css( "padding" + name ) );
3889             });
3890
3891             that.containerOffset = element.offset();
3892             that.containerPosition = element.position();
3893             that.containerSize = {
3894                 height: ( element.innerHeight() - p[ 3 ] ),
3895                 width: ( element.innerWidth() - p[ 1 ] )
3896             };
3897
3898             co = that.containerOffset;
3899             ch = that.containerSize.height;
3900             cw = that.containerSize.width;
3901             width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
3902             height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
3903
3904             that.parentData = {
3905                 element: ce,
3906                 left: co.left,
3907                 top: co.top,
3908                 width: width,
3909                 height: height
3910             };
3911         }
3912     },
3913
3914     resize: function( event ) {
3915         var woset, hoset, isParent, isOffsetRelative,
3916             that = $( this ).resizable( "instance" ),
3917             o = that.options,
3918             co = that.containerOffset,
3919             cp = that.position,
3920             pRatio = that._aspectRatio || event.shiftKey,
3921             cop = {
3922                 top: 0,
3923                 left: 0
3924             },
3925             ce = that.containerElement,
3926             continueResize = true;
3927
3928         if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
3929             cop = co;
3930         }
3931
3932         if ( cp.left < ( that._helper ? co.left : 0 ) ) {
3933             that.size.width = that.size.width +
3934                 ( that._helper ?
3935                     ( that.position.left - co.left ) :
3936                     ( that.position.left - cop.left ) );
3937
3938             if ( pRatio ) {
3939                 that.size.height = that.size.width / that.aspectRatio;
3940                 continueResize = false;
3941             }
3942             that.position.left = o.helper ? co.left : 0;
3943         }
3944
3945         if ( cp.top < ( that._helper ? co.top : 0 ) ) {
3946             that.size.height = that.size.height +
3947                 ( that._helper ?
3948                     ( that.position.top - co.top ) :
3949                     that.position.top );
3950
3951             if ( pRatio ) {
3952                 that.size.width = that.size.height * that.aspectRatio;
3953                 continueResize = false;
3954             }
3955             that.position.top = that._helper ? co.top : 0;
3956         }
3957
3958         isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
3959         isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
3960
3961         if ( isParent && isOffsetRelative ) {
3962             that.offset.left = that.parentData.left + that.position.left;
3963             that.offset.top = that.parentData.top + that.position.top;
3964         } else {
3965             that.offset.left = that.element.offset().left;
3966             that.offset.top = that.element.offset().top;
3967         }
3968
3969         woset = Math.abs( that.sizeDiff.width +
3970             (that._helper ?
3971                 that.offset.left - cop.left :
3972                 (that.offset.left - co.left)) );
3973
3974         hoset = Math.abs( that.sizeDiff.height +
3975             (that._helper ?
3976                 that.offset.top - cop.top :
3977                 (that.offset.top - co.top)) );
3978
3979         if ( woset + that.size.width >= that.parentData.width ) {
3980             that.size.width = that.parentData.width - woset;
3981             if ( pRatio ) {
3982                 that.size.height = that.size.width / that.aspectRatio;
3983                 continueResize = false;
3984             }
3985         }
3986
3987         if ( hoset + that.size.height >= that.parentData.height ) {
3988             that.size.height = that.parentData.height - hoset;
3989             if ( pRatio ) {
3990                 that.size.width = that.size.height * that.aspectRatio;
3991                 continueResize = false;
3992             }
3993         }
3994
3995         if ( !continueResize ) {
3996             that.position.left = that.prevPosition.left;
3997             that.position.top = that.prevPosition.top;
3998             that.size.width = that.prevSize.width;
3999             that.size.height = that.prevSize.height;
4000         }
4001     },
4002
4003     stop: function() {
4004         var that = $( this ).resizable( "instance" ),
4005             o = that.options,
4006             co = that.containerOffset,
4007             cop = that.containerPosition,
4008             ce = that.containerElement,
4009             helper = $( that.helper ),
4010             ho = helper.offset(),
4011             w = helper.outerWidth() - that.sizeDiff.width,
4012             h = helper.outerHeight() - that.sizeDiff.height;
4013
4014         if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
4015             $( this ).css({
4016                 left: ho.left - cop.left - co.left,
4017                 width: w,
4018                 height: h
4019             });
4020         }
4021
4022         if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
4023             $( this ).css({
4024                 left: ho.left - cop.left - co.left,
4025                 width: w,
4026                 height: h
4027             });
4028         }
4029     }
4030 });
4031
4032 $.ui.plugin.add("resizable", "alsoResize", {
4033
4034     start: function() {
4035         var that = $(this).resizable( "instance" ),
4036             o = that.options;
4037
4038         $(o.alsoResize).each(function() {
4039             var el = $(this);
4040             el.data("ui-resizable-alsoresize", {
4041                 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
4042                 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
4043             });
4044         });
4045     },
4046
4047     resize: function(event, ui) {
4048         var that = $(this).resizable( "instance" ),
4049             o = that.options,
4050             os = that.originalSize,
4051             op = that.originalPosition,
4052             delta = {
4053                 height: (that.size.height - os.height) || 0,
4054                 width: (that.size.width - os.width) || 0,
4055                 top: (that.position.top - op.top) || 0,
4056                 left: (that.position.left - op.left) || 0
4057             };
4058
4059             $(o.alsoResize).each(function() {
4060                 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
4061                     css = el.parents(ui.originalElement[0]).length ?
4062                             [ "width", "height" ] :
4063                             [ "width", "height", "top", "left" ];
4064
4065                 $.each(css, function(i, prop) {
4066                     var sum = (start[prop] || 0) + (delta[prop] || 0);
4067                     if (sum && sum >= 0) {
4068                         style[prop] = sum || null;
4069                     }
4070                 });
4071
4072                 el.css(style);
4073             });
4074     },
4075
4076     stop: function() {
4077         $(this).removeData("resizable-alsoresize");
4078     }
4079 });
4080
4081 $.ui.plugin.add("resizable", "ghost", {
4082
4083     start: function() {
4084
4085         var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
4086
4087         that.ghost = that.originalElement.clone();
4088         that.ghost
4089             .css({
4090                 opacity: 0.25,
4091                 display: "block",
4092                 position: "relative",
4093                 height: cs.height,
4094                 width: cs.width,
4095                 margin: 0,
4096                 left: 0,
4097                 top: 0
4098             })
4099             .addClass("ui-resizable-ghost")
4100             .addClass(typeof o.ghost === "string" ? o.ghost : "");
4101
4102         that.ghost.appendTo(that.helper);
4103
4104     },
4105
4106     resize: function() {
4107         var that = $(this).resizable( "instance" );
4108         if (that.ghost) {
4109             that.ghost.css({
4110                 position: "relative",
4111                 height: that.size.height,
4112                 width: that.size.width
4113             });
4114         }
4115     },
4116
4117     stop: function() {
4118         var that = $(this).resizable( "instance" );
4119         if (that.ghost && that.helper) {
4120             that.helper.get(0).removeChild(that.ghost.get(0));
4121         }
4122     }
4123
4124 });
4125
4126 $.ui.plugin.add("resizable", "grid", {
4127
4128     resize: function() {
4129         var outerDimensions,
4130             that = $(this).resizable( "instance" ),
4131             o = that.options,
4132             cs = that.size,
4133             os = that.originalSize,
4134             op = that.originalPosition,
4135             a = that.axis,
4136             grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
4137             gridX = (grid[0] || 1),
4138             gridY = (grid[1] || 1),
4139             ox = Math.round((cs.width - os.width) / gridX) * gridX,
4140             oy = Math.round((cs.height - os.height) / gridY) * gridY,
4141             newWidth = os.width + ox,
4142             newHeight = os.height + oy,
4143             isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
4144             isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
4145             isMinWidth = o.minWidth && (o.minWidth > newWidth),
4146             isMinHeight = o.minHeight && (o.minHeight > newHeight);
4147
4148         o.grid = grid;
4149
4150         if (isMinWidth) {
4151             newWidth += gridX;
4152         }
4153         if (isMinHeight) {
4154             newHeight += gridY;
4155         }
4156         if (isMaxWidth) {
4157             newWidth -= gridX;
4158         }
4159         if (isMaxHeight) {
4160             newHeight -= gridY;
4161         }
4162
4163         if (/^(se|s|e)$/.test(a)) {
4164             that.size.width = newWidth;
4165             that.size.height = newHeight;
4166         } else if (/^(ne)$/.test(a)) {
4167             that.size.width = newWidth;
4168             that.size.height = newHeight;
4169             that.position.top = op.top - oy;
4170         } else if (/^(sw)$/.test(a)) {
4171             that.size.width = newWidth;
4172             that.size.height = newHeight;
4173             that.position.left = op.left - ox;
4174         } else {
4175             if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
4176                 outerDimensions = that._getPaddingPlusBorderDimensions( this );
4177             }
4178
4179             if ( newHeight - gridY > 0 ) {
4180                 that.size.height = newHeight;
4181                 that.position.top = op.top - oy;
4182             } else {
4183                 newHeight = gridY - outerDimensions.height;
4184                 that.size.height = newHeight;
4185                 that.position.top = op.top + os.height - newHeight;
4186             }
4187             if ( newWidth - gridX > 0 ) {
4188                 that.size.width = newWidth;
4189                 that.position.left = op.left - ox;
4190             } else {
4191                 newWidth = gridX - outerDimensions.width;
4192                 that.size.width = newWidth;
4193                 that.position.left = op.left + os.width - newWidth;
4194             }
4195         }
4196     }
4197
4198 });
4199
4200 var resizable = $.ui.resizable;
4201
4202
4203 /*!
4204  * jQuery UI Selectable 1.11.4
4205  * http://jqueryui.com
4206  *
4207  * Copyright jQuery Foundation and other contributors
4208  * Released under the MIT license.
4209  * http://jquery.org/license
4210  *
4211  * http://api.jqueryui.com/selectable/
4212  */
4213
4214
4215 var selectable = $.widget("ui.selectable", $.ui.mouse, {
4216     version: "1.11.4",
4217     options: {
4218         appendTo: "body",
4219         autoRefresh: true,
4220         distance: 0,
4221         filter: "*",
4222         tolerance: "touch",
4223
4224         // callbacks
4225         selected: null,
4226         selecting: null,
4227         start: null,
4228         stop: null,
4229         unselected: null,
4230         unselecting: null
4231     },
4232     _create: function() {
4233         var selectees,
4234             that = this;
4235
4236         this.element.addClass("ui-selectable");
4237
4238         this.dragged = false;
4239
4240         // cache selectee children based on filter
4241         this.refresh = function() {
4242             selectees = $(that.options.filter, that.element[0]);
4243             selectees.addClass("ui-selectee");
4244             selectees.each(function() {
4245                 var $this = $(this),
4246                     pos = $this.offset();
4247                 $.data(this, "selectable-item", {
4248                     element: this,
4249                     $element: $this,
4250                     left: pos.left,
4251                     top: pos.top,
4252                     right: pos.left + $this.outerWidth(),
4253                     bottom: pos.top + $this.outerHeight(),
4254                     startselected: false,
4255                     selected: $this.hasClass("ui-selected"),
4256                     selecting: $this.hasClass("ui-selecting"),
4257                     unselecting: $this.hasClass("ui-unselecting")
4258                 });
4259             });
4260         };
4261         this.refresh();
4262
4263         this.selectees = selectees.addClass("ui-selectee");
4264
4265         this._mouseInit();
4266
4267         this.helper = $("<div class='ui-selectable-helper'></div>");
4268     },
4269
4270     _destroy: function() {
4271         this.selectees
4272             .removeClass("ui-selectee")
4273             .removeData("selectable-item");
4274         this.element
4275             .removeClass("ui-selectable ui-selectable-disabled");
4276         this._mouseDestroy();
4277     },
4278
4279     _mouseStart: function(event) {
4280         var that = this,
4281             options = this.options;
4282
4283         this.opos = [ event.pageX, event.pageY ];
4284
4285         if (this.options.disabled) {
4286             return;
4287         }
4288
4289         this.selectees = $(options.filter, this.element[0]);
4290
4291         this._trigger("start", event);
4292
4293         $(options.appendTo).append(this.helper);
4294         // position helper (lasso)
4295         this.helper.css({
4296             "left": event.pageX,
4297             "top": event.pageY,
4298             "width": 0,
4299             "height": 0
4300         });
4301
4302         if (options.autoRefresh) {
4303             this.refresh();
4304         }
4305
4306         this.selectees.filter(".ui-selected").each(function() {
4307             var selectee = $.data(this, "selectable-item");
4308             selectee.startselected = true;
4309             if (!event.metaKey && !event.ctrlKey) {
4310                 selectee.$element.removeClass("ui-selected");
4311                 selectee.selected = false;
4312                 selectee.$element.addClass("ui-unselecting");
4313                 selectee.unselecting = true;
4314                 // selectable UNSELECTING callback
4315                 that._trigger("unselecting", event, {
4316                     unselecting: selectee.element
4317                 });
4318             }
4319         });
4320
4321         $(event.target).parents().addBack().each(function() {
4322             var doSelect,
4323                 selectee = $.data(this, "selectable-item");
4324             if (selectee) {
4325                 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
4326                 selectee.$element
4327                     .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
4328                     .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
4329                 selectee.unselecting = !doSelect;
4330                 selectee.selecting = doSelect;
4331                 selectee.selected = doSelect;
4332                 // selectable (UN)SELECTING callback
4333                 if (doSelect) {
4334                     that._trigger("selecting", event, {
4335                         selecting: selectee.element
4336                     });
4337                 } else {
4338                     that._trigger("unselecting", event, {
4339                         unselecting: selectee.element
4340                     });
4341                 }
4342                 return false;
4343             }
4344         });
4345
4346     },
4347
4348     _mouseDrag: function(event) {
4349
4350         this.dragged = true;
4351
4352         if (this.options.disabled) {
4353             return;
4354         }
4355
4356         var tmp,
4357             that = this,
4358             options = this.options,
4359             x1 = this.opos[0],
4360             y1 = this.opos[1],
4361             x2 = event.pageX,
4362             y2 = event.pageY;
4363
4364         if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
4365         if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
4366         this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
4367
4368         this.selectees.each(function() {
4369             var selectee = $.data(this, "selectable-item"),
4370                 hit = false;
4371
4372             //prevent helper from being selected if appendTo: selectable
4373             if (!selectee || selectee.element === that.element[0]) {
4374                 return;
4375             }
4376
4377             if (options.tolerance === "touch") {
4378                 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
4379             } else if (options.tolerance === "fit") {
4380                 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
4381             }
4382
4383             if (hit) {
4384                 // SELECT
4385                 if (selectee.selected) {
4386                     selectee.$element.removeClass("ui-selected");
4387                     selectee.selected = false;
4388                 }
4389                 if (selectee.unselecting) {
4390                     selectee.$element.removeClass("ui-unselecting");
4391                     selectee.unselecting = false;
4392                 }
4393                 if (!selectee.selecting) {
4394                     selectee.$element.addClass("ui-selecting");
4395                     selectee.selecting = true;
4396                     // selectable SELECTING callback
4397                     that._trigger("selecting", event, {
4398                         selecting: selectee.element
4399                     });
4400                 }
4401             } else {
4402                 // UNSELECT
4403                 if (selectee.selecting) {
4404                     if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
4405                         selectee.$element.removeClass("ui-selecting");
4406                         selectee.selecting = false;
4407                         selectee.$element.addClass("ui-selected");
4408                         selectee.selected = true;
4409                     } else {
4410                         selectee.$element.removeClass("ui-selecting");
4411                         selectee.selecting = false;
4412                         if (selectee.startselected) {
4413                             selectee.$element.addClass("ui-unselecting");
4414                             selectee.unselecting = true;
4415                         }
4416                         // selectable UNSELECTING callback
4417                         that._trigger("unselecting", event, {
4418                             unselecting: selectee.element
4419                         });
4420                     }
4421                 }
4422                 if (selectee.selected) {
4423                     if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
4424                         selectee.$element.removeClass("ui-selected");
4425                         selectee.selected = false;
4426
4427                         selectee.$element.addClass("ui-unselecting");
4428                         selectee.unselecting = true;
4429                         // selectable UNSELECTING callback
4430                         that._trigger("unselecting", event, {
4431                             unselecting: selectee.element
4432                         });
4433                     }
4434                 }
4435             }
4436         });
4437
4438         return false;
4439     },
4440
4441     _mouseStop: function(event) {
4442         var that = this;
4443
4444         this.dragged = false;
4445
4446         $(".ui-unselecting", this.element[0]).each(function() {
4447             var selectee = $.data(this, "selectable-item");
4448             selectee.$element.removeClass("ui-unselecting");
4449             selectee.unselecting = false;
4450             selectee.startselected = false;
4451             that._trigger("unselected", event, {
4452                 unselected: selectee.element
4453             });
4454         });
4455         $(".ui-selecting", this.element[0]).each(function() {
4456             var selectee = $.data(this, "selectable-item");
4457             selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
4458             selectee.selecting = false;
4459             selectee.selected = true;
4460             selectee.startselected = true;
4461             that._trigger("selected", event, {
4462                 selected: selectee.element
4463             });
4464         });
4465         this._trigger("stop", event);
4466
4467         this.helper.remove();
4468
4469         return false;
4470     }
4471
4472 });
4473
4474
4475 /*!
4476  * jQuery UI Sortable 1.11.4
4477  * http://jqueryui.com
4478  *
4479  * Copyright jQuery Foundation and other contributors
4480  * Released under the MIT license.
4481  * http://jquery.org/license
4482  *
4483  * http://api.jqueryui.com/sortable/
4484  */
4485
4486
4487 var sortable = $.widget("ui.sortable", $.ui.mouse, {
4488     version: "1.11.4",
4489     widgetEventPrefix: "sort",
4490     ready: false,
4491     options: {
4492         appendTo: "parent",
4493         axis: false,
4494         connectWith: false,
4495         containment: false,
4496         cursor: "auto",
4497         cursorAt: false,
4498         dropOnEmpty: true,
4499         forcePlaceholderSize: false,
4500         forceHelperSize: false,
4501         grid: false,
4502         handle: false,
4503         helper: "original",
4504         items: "> *",
4505         opacity: false,
4506         placeholder: false,
4507         revert: false,
4508         scroll: true,
4509         scrollSensitivity: 20,
4510         scrollSpeed: 20,
4511         scope: "default",
4512         tolerance: "intersect",
4513         zIndex: 1000,
4514
4515         // callbacks
4516         activate: null,
4517         beforeStop: null,
4518         change: null,
4519         deactivate: null,
4520         out: null,
4521         over: null,
4522         receive: null,
4523         remove: null,
4524         sort: null,
4525         start: null,
4526         stop: null,
4527         update: null
4528     },
4529
4530     _isOverAxis: function( x, reference, size ) {
4531         return ( x >= reference ) && ( x < ( reference + size ) );
4532     },
4533
4534     _isFloating: function( item ) {
4535         return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
4536     },
4537
4538     _create: function() {
4539         this.containerCache = {};
4540         this.element.addClass("ui-sortable");
4541
4542         //Get the items
4543         this.refresh();
4544
4545         //Let's determine the parent's offset
4546         this.offset = this.element.offset();
4547
4548         //Initialize mouse events for interaction
4549         this._mouseInit();
4550
4551         this._setHandleClassName();
4552
4553         //We're ready to go
4554         this.ready = true;
4555
4556     },
4557
4558     _setOption: function( key, value ) {
4559         this._super( key, value );
4560
4561         if ( key === "handle" ) {
4562             this._setHandleClassName();
4563         }
4564     },
4565
4566     _setHandleClassName: function() {
4567         this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
4568         $.each( this.items, function() {
4569             ( this.instance.options.handle ?
4570                 this.item.find( this.instance.options.handle ) : this.item )
4571                 .addClass( "ui-sortable-handle" );
4572         });
4573     },
4574
4575     _destroy: function() {
4576         this.element
4577             .removeClass( "ui-sortable ui-sortable-disabled" )
4578             .find( ".ui-sortable-handle" )
4579                 .removeClass( "ui-sortable-handle" );
4580         this._mouseDestroy();
4581
4582         for ( var i = this.items.length - 1; i >= 0; i-- ) {
4583             this.items[i].item.removeData(this.widgetName + "-item");
4584         }
4585
4586         return this;
4587     },
4588
4589     _mouseCapture: function(event, overrideHandle) {
4590         var currentItem = null,
4591             validHandle = false,
4592             that = this;
4593
4594         if (this.reverting) {
4595             return false;
4596         }
4597
4598         if(this.options.disabled || this.options.type === "static") {
4599             return false;
4600         }
4601
4602         //We have to refresh the items data once first
4603         this._refreshItems(event);
4604
4605         //Find out if the clicked node (or one of its parents) is a actual item in this.items
4606         $(event.target).parents().each(function() {
4607             if($.data(this, that.widgetName + "-item") === that) {
4608                 currentItem = $(this);
4609                 return false;
4610             }
4611         });
4612         if($.data(event.target, that.widgetName + "-item") === that) {
4613             currentItem = $(event.target);
4614         }
4615
4616         if(!currentItem) {
4617             return false;
4618         }
4619         if(this.options.handle && !overrideHandle) {
4620             $(this.options.handle, currentItem).find("*").addBack().each(function() {
4621                 if(this === event.target) {
4622                     validHandle = true;
4623                 }
4624             });
4625             if(!validHandle) {
4626                 return false;
4627             }
4628         }
4629
4630         this.currentItem = currentItem;
4631         this._removeCurrentsFromItems();
4632         return true;
4633
4634     },
4635
4636     _mouseStart: function(event, overrideHandle, noActivation) {
4637
4638         var i, body,
4639             o = this.options;
4640
4641         this.currentContainer = this;
4642
4643         //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
4644         this.refreshPositions();
4645
4646         //Create and append the visible helper
4647         this.helper = this._createHelper(event);
4648
4649         //Cache the helper size
4650         this._cacheHelperProportions();
4651
4652         /*
4653          * - Position generation -
4654          * This block generates everything position related - it's the core of draggables.
4655          */
4656
4657         //Cache the margins of the original element
4658         this._cacheMargins();
4659
4660         //Get the next scrolling parent
4661         this.scrollParent = this.helper.scrollParent();
4662
4663         //The element's absolute position on the page minus margins
4664         this.offset = this.currentItem.offset();
4665         this.offset = {
4666             top: this.offset.top - this.margins.top,
4667             left: this.offset.left - this.margins.left
4668         };
4669
4670         $.extend(this.offset, {
4671             click: { //Where the click happened, relative to the element
4672                 left: event.pageX - this.offset.left,
4673                 top: event.pageY - this.offset.top
4674             },
4675             parent: this._getParentOffset(),
4676             relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
4677         });
4678
4679         // Only after we got the offset, we can change the helper's position to absolute
4680         // TODO: Still need to figure out a way to make relative sorting possible
4681         this.helper.css("position", "absolute");
4682         this.cssPosition = this.helper.css("position");
4683
4684         //Generate the original position
4685         this.originalPosition = this._generatePosition(event);
4686         this.originalPageX = event.pageX;
4687         this.originalPageY = event.pageY;
4688
4689         //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4690         (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
4691
4692         //Cache the former DOM position
4693         this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
4694
4695         //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
4696         if(this.helper[0] !== this.currentItem[0]) {
4697             this.currentItem.hide();
4698         }
4699
4700         //Create the placeholder
4701         this._createPlaceholder();
4702
4703         //Set a containment if given in the options
4704         if(o.containment) {
4705             this._setContainment();
4706         }
4707
4708         if( o.cursor && o.cursor !== "auto" ) { // cursor option
4709             body = this.document.find( "body" );
4710
4711             // support: IE
4712             this.storedCursor = body.css( "cursor" );
4713             body.css( "cursor", o.cursor );
4714
4715             this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
4716         }
4717
4718         if(o.opacity) { // opacity option
4719             if (this.helper.css("opacity")) {
4720                 this._storedOpacity = this.helper.css("opacity");
4721             }
4722             this.helper.css("opacity", o.opacity);
4723         }
4724
4725         if(o.zIndex) { // zIndex option
4726             if (this.helper.css("zIndex")) {
4727                 this._storedZIndex = this.helper.css("zIndex");
4728             }
4729             this.helper.css("zIndex", o.zIndex);
4730         }
4731
4732         //Prepare scrolling
4733         if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
4734             this.overflowOffset = this.scrollParent.offset();
4735         }
4736
4737         //Call callbacks
4738         this._trigger("start", event, this._uiHash());
4739
4740         //Recache the helper size
4741         if(!this._preserveHelperProportions) {
4742             this._cacheHelperProportions();
4743         }
4744
4745
4746         //Post "activate" events to possible containers
4747         if( !noActivation ) {
4748             for ( i = this.containers.length - 1; i >= 0; i-- ) {
4749                 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4750             }
4751         }
4752
4753         //Prepare possible droppables
4754         if($.ui.ddmanager) {
4755             $.ui.ddmanager.current = this;
4756         }
4757
4758         if ($.ui.ddmanager && !o.dropBehaviour) {
4759             $.ui.ddmanager.prepareOffsets(this, event);
4760         }
4761
4762         this.dragging = true;
4763
4764         this.helper.addClass("ui-sortable-helper");
4765         this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
4766         return true;
4767
4768     },
4769
4770     _mouseDrag: function(event) {
4771         var i, item, itemElement, intersection,
4772             o = this.options,
4773             scrolled = false;
4774
4775         //Compute the helpers position
4776         this.position = this._generatePosition(event);
4777         this.positionAbs = this._convertPositionTo("absolute");
4778
4779         if (!this.lastPositionAbs) {
4780             this.lastPositionAbs = this.positionAbs;
4781         }
4782
4783         //Do scrolling
4784         if(this.options.scroll) {
4785             if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
4786
4787                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
4788                     this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
4789                 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
4790                     this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
4791                 }
4792
4793                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
4794                     this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
4795                 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
4796                     this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
4797                 }
4798
4799             } else {
4800
4801                 if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
4802                     scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
4803                 } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
4804                     scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
4805                 }
4806
4807                 if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
4808                     scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
4809                 } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
4810                     scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
4811                 }
4812
4813             }
4814
4815             if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
4816                 $.ui.ddmanager.prepareOffsets(this, event);
4817             }
4818         }
4819
4820         //Regenerate the absolute position used for position checks
4821         this.positionAbs = this._convertPositionTo("absolute");
4822
4823         //Set the helper position
4824         if(!this.options.axis || this.options.axis !== "y") {
4825             this.helper[0].style.left = this.position.left+"px";
4826         }
4827         if(!this.options.axis || this.options.axis !== "x") {
4828             this.helper[0].style.top = this.position.top+"px";
4829         }
4830
4831         //Rearrange
4832         for (i = this.items.length - 1; i >= 0; i--) {
4833
4834             //Cache variables and intersection, continue if no intersection
4835             item = this.items[i];
4836             itemElement = item.item[0];
4837             intersection = this._intersectsWithPointer(item);
4838             if (!intersection) {
4839                 continue;
4840             }
4841
4842             // Only put the placeholder inside the current Container, skip all
4843             // items from other containers. This works because when moving
4844             // an item from one container to another the
4845             // currentContainer is switched before the placeholder is moved.
4846             //
4847             // Without this, moving items in "sub-sortables" can cause
4848             // the placeholder to jitter between the outer and inner container.
4849             if (item.instance !== this.currentContainer) {
4850                 continue;
4851             }
4852
4853             // cannot intersect with itself
4854             // no useless actions that have been done before
4855             // no action if the item moved is the parent of the item checked
4856             if (itemElement !== this.currentItem[0] &&
4857                 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
4858                 !$.contains(this.placeholder[0], itemElement) &&
4859                 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
4860             ) {
4861
4862                 this.direction = intersection === 1 ? "down" : "up";
4863
4864                 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
4865                     this._rearrange(event, item);
4866                 } else {
4867                     break;
4868                 }
4869
4870                 this._trigger("change", event, this._uiHash());
4871                 break;
4872             }
4873         }
4874
4875         //Post events to containers
4876         this._contactContainers(event);
4877
4878         //Interconnect with droppables
4879         if($.ui.ddmanager) {
4880             $.ui.ddmanager.drag(this, event);
4881         }
4882
4883         //Call callbacks
4884         this._trigger("sort", event, this._uiHash());
4885
4886         this.lastPositionAbs = this.positionAbs;
4887         return false;
4888
4889     },
4890
4891     _mouseStop: function(event, noPropagation) {
4892
4893         if(!event) {
4894             return;
4895         }
4896
4897         //If we are using droppables, inform the manager about the drop
4898         if ($.ui.ddmanager && !this.options.dropBehaviour) {
4899             $.ui.ddmanager.drop(this, event);
4900         }
4901
4902         if(this.options.revert) {
4903             var that = this,
4904                 cur = this.placeholder.offset(),
4905                 axis = this.options.axis,
4906                 animation = {};
4907
4908             if ( !axis || axis === "x" ) {
4909                 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
4910             }
4911             if ( !axis || axis === "y" ) {
4912                 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
4913             }
4914             this.reverting = true;
4915             $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
4916                 that._clear(event);
4917             });
4918         } else {
4919             this._clear(event, noPropagation);
4920         }
4921
4922         return false;
4923
4924     },
4925
4926     cancel: function() {
4927
4928         if(this.dragging) {
4929
4930             this._mouseUp({ target: null });
4931
4932             if(this.options.helper === "original") {
4933                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4934             } else {
4935                 this.currentItem.show();
4936             }
4937
4938             //Post deactivating events to containers
4939             for (var i = this.containers.length - 1; i >= 0; i--){
4940                 this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4941                 if(this.containers[i].containerCache.over) {
4942                     this.containers[i]._trigger("out", null, this._uiHash(this));
4943                     this.containers[i].containerCache.over = 0;
4944                 }
4945             }
4946
4947         }
4948
4949         if (this.placeholder) {
4950             //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4951             if(this.placeholder[0].parentNode) {
4952                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4953             }
4954             if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
4955                 this.helper.remove();
4956             }
4957
4958             $.extend(this, {
4959                 helper: null,
4960                 dragging: false,
4961                 reverting: false,
4962                 _noFinalSort: null
4963             });
4964
4965             if(this.domPosition.prev) {
4966                 $(this.domPosition.prev).after(this.currentItem);
4967             } else {
4968                 $(this.domPosition.parent).prepend(this.currentItem);
4969             }
4970         }
4971
4972         return this;
4973
4974     },
4975
4976     serialize: function(o) {
4977
4978         var items = this._getItemsAsjQuery(o && o.connected),
4979             str = [];
4980         o = o || {};
4981
4982         $(items).each(function() {
4983             var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
4984             if (res) {
4985                 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4986             }
4987         });
4988
4989         if(!str.length && o.key) {
4990             str.push(o.key + "=");
4991         }
4992
4993         return str.join("&");
4994
4995     },
4996
4997     toArray: function(o) {
4998
4999         var items = this._getItemsAsjQuery(o && o.connected),
5000             ret = [];
5001
5002         o = o || {};
5003
5004         items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
5005         return ret;
5006
5007     },
5008
5009     /* Be careful with the following core functions */
5010     _intersectsWith: function(item) {
5011
5012         var x1 = this.positionAbs.left,
5013             x2 = x1 + this.helperProportions.width,
5014             y1 = this.positionAbs.top,
5015             y2 = y1 + this.helperProportions.height,
5016             l = item.left,
5017             r = l + item.width,
5018             t = item.top,
5019             b = t + item.height,
5020             dyClick = this.offset.click.top,
5021             dxClick = this.offset.click.left,
5022             isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
5023             isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
5024             isOverElement = isOverElementHeight && isOverElementWidth;
5025
5026         if ( this.options.tolerance === "pointer" ||
5027             this.options.forcePointerForContainers ||
5028             (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
5029         ) {
5030             return isOverElement;
5031         } else {
5032
5033             return (l < x1 + (this.helperProportions.width / 2) && // Right Half
5034                 x2 - (this.helperProportions.width / 2) < r && // Left Half
5035                 t < y1 + (this.helperProportions.height / 2) && // Bottom Half
5036                 y2 - (this.helperProportions.height / 2) < b ); // Top Half
5037
5038         }
5039     },
5040
5041     _intersectsWithPointer: function(item) {
5042
5043         var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
5044             isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
5045             isOverElement = isOverElementHeight && isOverElementWidth,
5046             verticalDirection = this._getDragVerticalDirection(),
5047             horizontalDirection = this._getDragHorizontalDirection();
5048
5049         if (!isOverElement) {
5050             return false;
5051         }
5052
5053         return this.floating ?
5054             ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
5055             : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
5056
5057     },
5058
5059     _intersectsWithSides: function(item) {
5060
5061         var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
5062             isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
5063             verticalDirection = this._getDragVerticalDirection(),
5064             horizontalDirection = this._getDragHorizontalDirection();
5065
5066         if (this.floating && horizontalDirection) {
5067             return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
5068         } else {
5069             return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
5070         }
5071
5072     },
5073
5074     _getDragVerticalDirection: function() {
5075         var delta = this.positionAbs.top - this.lastPositionAbs.top;
5076         return delta !== 0 && (delta > 0 ? "down" : "up");
5077     },
5078
5079     _getDragHorizontalDirection: function() {
5080         var delta = this.positionAbs.left - this.lastPositionAbs.left;
5081         return delta !== 0 && (delta > 0 ? "right" : "left");
5082     },
5083
5084     refresh: function(event) {
5085         this._refreshItems(event);
5086         this._setHandleClassName();
5087         this.refreshPositions();
5088         return this;
5089     },
5090
5091     _connectWith: function() {
5092         var options = this.options;
5093         return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
5094     },
5095
5096     _getItemsAsjQuery: function(connected) {
5097
5098         var i, j, cur, inst,
5099             items = [],
5100             queries = [],
5101             connectWith = this._connectWith();
5102
5103         if(connectWith && connected) {
5104             for (i = connectWith.length - 1; i >= 0; i--){
5105                 cur = $(connectWith[i], this.document[0]);
5106                 for ( j = cur.length - 1; j >= 0; j--){
5107                     inst = $.data(cur[j], this.widgetFullName);
5108                     if(inst && inst !== this && !inst.options.disabled) {
5109                         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]);
5110                     }
5111                 }
5112             }
5113         }
5114
5115         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]);
5116
5117         function addItems() {
5118             items.push( this );
5119         }
5120         for (i = queries.length - 1; i >= 0; i--){
5121             queries[i][0].each( addItems );
5122         }
5123
5124         return $(items);
5125
5126     },
5127
5128     _removeCurrentsFromItems: function() {
5129
5130         var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
5131
5132         this.items = $.grep(this.items, function (item) {
5133             for (var j=0; j < list.length; j++) {
5134                 if(list[j] === item.item[0]) {
5135                     return false;
5136                 }
5137             }
5138             return true;
5139         });
5140
5141     },
5142
5143     _refreshItems: function(event) {
5144
5145         this.items = [];
5146         this.containers = [this];
5147
5148         var i, j, cur, inst, targetData, _queries, item, queriesLength,
5149             items = this.items,
5150             queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
5151             connectWith = this._connectWith();
5152
5153         if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
5154             for (i = connectWith.length - 1; i >= 0; i--){
5155                 cur = $(connectWith[i], this.document[0]);
5156                 for (j = cur.length - 1; j >= 0; j--){
5157                     inst = $.data(cur[j], this.widgetFullName);
5158                     if(inst && inst !== this && !inst.options.disabled) {
5159                         queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
5160                         this.containers.push(inst);
5161                     }
5162                 }
5163             }
5164         }
5165
5166         for (i = queries.length - 1; i >= 0; i--) {
5167             targetData = queries[i][1];
5168             _queries = queries[i][0];
5169
5170             for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
5171                 item = $(_queries[j]);
5172
5173                 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
5174
5175                 items.push({
5176                     item: item,
5177                     instance: targetData,
5178                     width: 0, height: 0,
5179                     left: 0, top: 0
5180                 });
5181             }
5182         }
5183
5184     },
5185
5186     refreshPositions: function(fast) {
5187
5188         // Determine whether items are being displayed horizontally
5189         this.floating = this.items.length ?
5190             this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
5191             false;
5192
5193         //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
5194         if(this.offsetParent && this.helper) {
5195             this.offset.parent = this._getParentOffset();
5196         }
5197
5198         var i, item, t, p;
5199
5200         for (i = this.items.length - 1; i >= 0; i--){
5201             item = this.items[i];
5202
5203             //We ignore calculating positions of all connected containers when we're not over them
5204             if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
5205                 continue;
5206             }
5207
5208             t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
5209
5210             if (!fast) {
5211                 item.width = t.outerWidth();
5212                 item.height = t.outerHeight();
5213             }
5214
5215             p = t.offset();
5216             item.left = p.left;
5217             item.top = p.top;
5218         }
5219
5220         if(this.options.custom && this.options.custom.refreshContainers) {
5221             this.options.custom.refreshContainers.call(this);
5222         } else {
5223             for (i = this.containers.length - 1; i >= 0; i--){
5224                 p = this.containers[i].element.offset();
5225                 this.containers[i].containerCache.left = p.left;
5226                 this.containers[i].containerCache.top = p.top;
5227                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
5228                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
5229             }
5230         }
5231
5232         return this;
5233     },
5234
5235     _createPlaceholder: function(that) {
5236         that = that || this;
5237         var className,
5238             o = that.options;
5239
5240         if(!o.placeholder || o.placeholder.constructor === String) {
5241             className = o.placeholder;
5242             o.placeholder = {
5243                 element: function() {
5244
5245                     var nodeName = that.currentItem[0].nodeName.toLowerCase(),
5246                         element = $( "<" + nodeName + ">", that.document[0] )
5247                             .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
5248                             .removeClass("ui-sortable-helper");
5249
5250                     if ( nodeName === "tbody" ) {
5251                         that._createTrPlaceholder(
5252                             that.currentItem.find( "tr" ).eq( 0 ),
5253                             $( "<tr>", that.document[ 0 ] ).appendTo( element )
5254                         );
5255                     } else if ( nodeName === "tr" ) {
5256                         that._createTrPlaceholder( that.currentItem, element );
5257                     } else if ( nodeName === "img" ) {
5258                         element.attr( "src", that.currentItem.attr( "src" ) );
5259                     }
5260
5261                     if ( !className ) {
5262                         element.css( "visibility", "hidden" );
5263                     }
5264
5265                     return element;
5266                 },
5267                 update: function(container, p) {
5268
5269                     // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
5270                     // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
5271                     if(className && !o.forcePlaceholderSize) {
5272                         return;
5273                     }
5274
5275                     //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
5276                     if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
5277                     if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
5278                 }
5279             };
5280         }
5281
5282         //Create the placeholder
5283         that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
5284
5285         //Append it after the actual current item
5286         that.currentItem.after(that.placeholder);
5287
5288         //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
5289         o.placeholder.update(that, that.placeholder);
5290
5291     },
5292
5293     _createTrPlaceholder: function( sourceTr, targetTr ) {
5294         var that = this;
5295
5296         sourceTr.children().each(function() {
5297             $( "<td>&#160;</td>", that.document[ 0 ] )
5298                 .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
5299                 .appendTo( targetTr );
5300         });
5301     },
5302
5303     _contactContainers: function(event) {
5304         var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
5305             innermostContainer = null,
5306             innermostIndex = null;
5307
5308         // get innermost container that intersects with item
5309         for (i = this.containers.length - 1; i >= 0; i--) {
5310
5311             // never consider a container that's located within the item itself
5312             if($.contains(this.currentItem[0], this.containers[i].element[0])) {
5313                 continue;
5314             }
5315
5316             if(this._intersectsWith(this.containers[i].containerCache)) {
5317
5318                 // if we've already found a container and it's more "inner" than this, then continue
5319                 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
5320                     continue;
5321                 }
5322
5323                 innermostContainer = this.containers[i];
5324                 innermostIndex = i;
5325
5326             } else {
5327                 // container doesn't intersect. trigger "out" event if necessary
5328                 if(this.containers[i].containerCache.over) {
5329                     this.containers[i]._trigger("out", event, this._uiHash(this));
5330                     this.containers[i].containerCache.over = 0;
5331                 }
5332             }
5333
5334         }
5335
5336         // if no intersecting containers found, return
5337         if(!innermostContainer) {
5338             return;
5339         }
5340
5341         // move the item into the container if it's not there already
5342         if(this.containers.length === 1) {
5343             if (!this.containers[innermostIndex].containerCache.over) {
5344                 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5345                 this.containers[innermostIndex].containerCache.over = 1;
5346             }
5347         } else {
5348
5349             //When entering a new container, we will find the item with the least distance and append our item near it
5350             dist = 10000;
5351             itemWithLeastDistance = null;
5352             floating = innermostContainer.floating || this._isFloating(this.currentItem);
5353             posProperty = floating ? "left" : "top";
5354             sizeProperty = floating ? "width" : "height";
5355             axis = floating ? "clientX" : "clientY";
5356
5357             for (j = this.items.length - 1; j >= 0; j--) {
5358                 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
5359                     continue;
5360                 }
5361                 if(this.items[j].item[0] === this.currentItem[0]) {
5362                     continue;
5363                 }
5364
5365                 cur = this.items[j].item.offset()[posProperty];
5366                 nearBottom = false;
5367                 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
5368                     nearBottom = true;
5369                 }
5370
5371                 if ( Math.abs( event[ axis ] - cur ) < dist ) {
5372                     dist = Math.abs( event[ axis ] - cur );
5373                     itemWithLeastDistance = this.items[ j ];
5374                     this.direction = nearBottom ? "up": "down";
5375                 }
5376             }
5377
5378             //Check if dropOnEmpty is enabled
5379             if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
5380                 return;
5381             }
5382
5383             if(this.currentContainer === this.containers[innermostIndex]) {
5384                 if ( !this.currentContainer.containerCache.over ) {
5385                     this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
5386                     this.currentContainer.containerCache.over = 1;
5387                 }
5388                 return;
5389             }
5390
5391             itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
5392             this._trigger("change", event, this._uiHash());
5393             this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
5394             this.currentContainer = this.containers[innermostIndex];
5395
5396             //Update the placeholder
5397             this.options.placeholder.update(this.currentContainer, this.placeholder);
5398
5399             this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5400             this.containers[innermostIndex].containerCache.over = 1;
5401         }
5402
5403
5404     },
5405
5406     _createHelper: function(event) {
5407
5408         var o = this.options,
5409             helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
5410
5411         //Add the helper to the DOM if that didn't happen already
5412         if(!helper.parents("body").length) {
5413             $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
5414         }
5415
5416         if(helper[0] === this.currentItem[0]) {
5417             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") };
5418         }
5419
5420         if(!helper[0].style.width || o.forceHelperSize) {
5421             helper.width(this.currentItem.width());
5422         }
5423         if(!helper[0].style.height || o.forceHelperSize) {
5424             helper.height(this.currentItem.height());
5425         }
5426
5427         return helper;
5428
5429     },
5430
5431     _adjustOffsetFromHelper: function(obj) {
5432         if (typeof obj === "string") {
5433             obj = obj.split(" ");
5434         }
5435         if ($.isArray(obj)) {
5436             obj = {left: +obj[0], top: +obj[1] || 0};
5437         }
5438         if ("left" in obj) {
5439             this.offset.click.left = obj.left + this.margins.left;
5440         }
5441         if ("right" in obj) {
5442             this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
5443         }
5444         if ("top" in obj) {
5445             this.offset.click.top = obj.top + this.margins.top;
5446         }
5447         if ("bottom" in obj) {
5448             this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
5449         }
5450     },
5451
5452     _getParentOffset: function() {
5453
5454
5455         //Get the offsetParent and cache its position
5456         this.offsetParent = this.helper.offsetParent();
5457         var po = this.offsetParent.offset();
5458
5459         // This is a special case where we need to modify a offset calculated on start, since the following happened:
5460         // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
5461         // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
5462         //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
5463         if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
5464             po.left += this.scrollParent.scrollLeft();
5465             po.top += this.scrollParent.scrollTop();
5466         }
5467
5468         // This needs to be actually done for all browsers, since pageX/pageY includes this information
5469         // with an ugly IE fix
5470         if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
5471             po = { top: 0, left: 0 };
5472         }
5473
5474         return {
5475             top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
5476             left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
5477         };
5478
5479     },
5480
5481     _getRelativeOffset: function() {
5482
5483         if(this.cssPosition === "relative") {
5484             var p = this.currentItem.position();
5485             return {
5486                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
5487                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
5488             };
5489         } else {
5490             return { top: 0, left: 0 };
5491         }
5492
5493     },
5494
5495     _cacheMargins: function() {
5496         this.margins = {
5497             left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
5498             top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
5499         };
5500     },
5501
5502     _cacheHelperProportions: function() {
5503         this.helperProportions = {
5504             width: this.helper.outerWidth(),
5505             height: this.helper.outerHeight()
5506         };
5507     },
5508
5509     _setContainment: function() {
5510
5511         var ce, co, over,
5512             o = this.options;
5513         if(o.containment === "parent") {
5514             o.containment = this.helper[0].parentNode;
5515         }
5516         if(o.containment === "document" || o.containment === "window") {
5517             this.containment = [
5518                 0 - this.offset.relative.left - this.offset.parent.left,
5519                 0 - this.offset.relative.top - this.offset.parent.top,
5520                 o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
5521                 (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
5522             ];
5523         }
5524
5525         if(!(/^(document|window|parent)$/).test(o.containment)) {
5526             ce = $(o.containment)[0];
5527             co = $(o.containment).offset();
5528             over = ($(ce).css("overflow") !== "hidden");
5529
5530             this.containment = [
5531                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
5532                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
5533                 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,
5534                 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
5535             ];
5536         }
5537
5538     },
5539
5540     _convertPositionTo: function(d, pos) {
5541
5542         if(!pos) {
5543             pos = this.position;
5544         }
5545         var mod = d === "absolute" ? 1 : -1,
5546             scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
5547             scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5548
5549         return {
5550             top: (
5551                 pos.top    +                                                                // The absolute mouse position
5552                 this.offset.relative.top * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
5553                 this.offset.parent.top * mod -                                            // The offsetParent's offset without borders (offset + border)
5554                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
5555             ),
5556             left: (
5557                 pos.left +                                                                // The absolute mouse position
5558                 this.offset.relative.left * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
5559                 this.offset.parent.left * mod    -                                        // The offsetParent's offset without borders (offset + border)
5560                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
5561             )
5562         };
5563
5564     },
5565
5566     _generatePosition: function(event) {
5567
5568         var top, left,
5569             o = this.options,
5570             pageX = event.pageX,
5571             pageY = event.pageY,
5572             scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5573
5574         // This is another very weird special case that only happens for relative elements:
5575         // 1. If the css position is relative
5576         // 2. and the scroll parent is the document or similar to the offset parent
5577         // we have to refresh the relative offset during the scroll so there are no jumps
5578         if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
5579             this.offset.relative = this._getRelativeOffset();
5580         }
5581
5582         /*
5583          * - Position constraining -
5584          * Constrain the position to a mix of grid, containment.
5585          */
5586
5587         if(this.originalPosition) { //If we are not dragging yet, we won't check for options
5588
5589             if(this.containment) {
5590                 if(event.pageX - this.offset.click.left < this.containment[0]) {
5591                     pageX = this.containment[0] + this.offset.click.left;
5592                 }
5593                 if(event.pageY - this.offset.click.top < this.containment[1]) {
5594                     pageY = this.containment[1] + this.offset.click.top;
5595                 }
5596                 if(event.pageX - this.offset.click.left > this.containment[2]) {
5597                     pageX = this.containment[2] + this.offset.click.left;
5598                 }
5599                 if(event.pageY - this.offset.click.top > this.containment[3]) {
5600                     pageY = this.containment[3] + this.offset.click.top;
5601                 }
5602             }
5603
5604             if(o.grid) {
5605                 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
5606                 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;
5607
5608                 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
5609                 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;
5610             }
5611
5612         }
5613
5614         return {
5615             top: (
5616                 pageY -                                                                // The absolute mouse position
5617                 this.offset.click.top -                                                    // Click offset (relative to the element)
5618                 this.offset.relative.top    -                                            // Only for relative positioned nodes: Relative offset from element to offset parent
5619                 this.offset.parent.top +                                                // The offsetParent's offset without borders (offset + border)
5620                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
5621             ),
5622             left: (
5623                 pageX -                                                                // The absolute mouse position
5624                 this.offset.click.left -                                                // Click offset (relative to the element)
5625                 this.offset.relative.left    -                                            // Only for relative positioned nodes: Relative offset from element to offset parent
5626                 this.offset.parent.left +                                                // The offsetParent's offset without borders (offset + border)
5627                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
5628             )
5629         };
5630
5631     },
5632
5633     _rearrange: function(event, i, a, hardRefresh) {
5634
5635         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));
5636
5637         //Various things done here to improve the performance:
5638         // 1. we create a setTimeout, that calls refreshPositions
5639         // 2. on the instance, we have a counter variable, that get's higher after every append
5640         // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
5641         // 4. this lets only the last addition to the timeout stack through
5642         this.counter = this.counter ? ++this.counter : 1;
5643         var counter = this.counter;
5644
5645         this._delay(function() {
5646             if(counter === this.counter) {
5647                 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
5648             }
5649         });
5650
5651     },
5652
5653     _clear: function(event, noPropagation) {
5654
5655         this.reverting = false;
5656         // We delay all events that have to be triggered to after the point where the placeholder has been removed and
5657         // everything else normalized again
5658         var i,
5659             delayedTriggers = [];
5660
5661         // We first have to update the dom position of the actual currentItem
5662         // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
5663         if(!this._noFinalSort && this.currentItem.parent().length) {
5664             this.placeholder.before(this.currentItem);
5665         }
5666         this._noFinalSort = null;
5667
5668         if(this.helper[0] === this.currentItem[0]) {
5669             for(i in this._storedCSS) {
5670                 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
5671                     this._storedCSS[i] = "";
5672                 }
5673             }
5674             this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
5675         } else {
5676             this.currentItem.show();
5677         }
5678
5679         if(this.fromOutside && !noPropagation) {
5680             delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
5681         }
5682         if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
5683             delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
5684         }
5685
5686         // Check if the items Container has Changed and trigger appropriate
5687         // events.
5688         if (this !== this.currentContainer) {
5689             if(!noPropagation) {
5690                 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
5691                 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
5692                 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
5693             }
5694         }
5695
5696
5697         //Post events to containers
5698         function delayEvent( type, instance, container ) {
5699             return function( event ) {
5700                 container._trigger( type, event, instance._uiHash( instance ) );
5701             };
5702         }
5703         for (i = this.containers.length - 1; i >= 0; i--){
5704             if (!noPropagation) {
5705                 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
5706             }
5707             if(this.containers[i].containerCache.over) {
5708                 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
5709                 this.containers[i].containerCache.over = 0;
5710             }
5711         }
5712
5713         //Do what was originally in plugins
5714         if ( this.storedCursor ) {
5715             this.document.find( "body" ).css( "cursor", this.storedCursor );
5716             this.storedStylesheet.remove();
5717         }
5718         if(this._storedOpacity) {
5719             this.helper.css("opacity", this._storedOpacity);
5720         }
5721         if(this._storedZIndex) {
5722             this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
5723         }
5724
5725         this.dragging = false;
5726
5727         if(!noPropagation) {
5728             this._trigger("beforeStop", event, this._uiHash());
5729         }
5730
5731         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
5732         this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
5733
5734         if ( !this.cancelHelperRemoval ) {
5735             if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
5736                 this.helper.remove();
5737             }
5738             this.helper = null;
5739         }
5740
5741         if(!noPropagation) {
5742             for (i=0; i < delayedTriggers.length; i++) {
5743                 delayedTriggers[i].call(this, event);
5744             } //Trigger all delayed events
5745             this._trigger("stop", event, this._uiHash());
5746         }
5747
5748         this.fromOutside = false;
5749         return !this.cancelHelperRemoval;
5750
5751     },
5752
5753     _trigger: function() {
5754         if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
5755             this.cancel();
5756         }
5757     },
5758
5759     _uiHash: function(_inst) {
5760         var inst = _inst || this;
5761         return {
5762             helper: inst.helper,
5763             placeholder: inst.placeholder || $([]),
5764             position: inst.position,
5765             originalPosition: inst.originalPosition,
5766             offset: inst.positionAbs,
5767             item: inst.currentItem,
5768             sender: _inst ? _inst.element : null
5769         };
5770     }
5771
5772 });
5773
5774
5775 /*!
5776  * jQuery UI Slider 1.11.4
5777  * http://jqueryui.com
5778  *
5779  * Copyright jQuery Foundation and other contributors
5780  * Released under the MIT license.
5781  * http://jquery.org/license
5782  *
5783  * http://api.jqueryui.com/slider/
5784  */
5785
5786
5787 var slider = $.widget( "ui.slider", $.ui.mouse, {
5788     version: "1.11.4",
5789     widgetEventPrefix: "slide",
5790
5791     options: {
5792         animate: false,
5793         distance: 0,
5794         max: 100,
5795         min: 0,
5796         orientation: "horizontal",
5797         range: false,
5798         step: 1,
5799         value: 0,
5800         values: null,
5801
5802         // callbacks
5803         change: null,
5804         slide: null,
5805         start: null,
5806         stop: null
5807     },
5808
5809     // number of pages in a slider
5810     // (how many times can you page up/down to go through the whole range)
5811     numPages: 5,
5812
5813     _create: function() {
5814         this._keySliding = false;
5815         this._mouseSliding = false;
5816         this._animateOff = true;
5817         this._handleIndex = null;
5818         this._detectOrientation();
5819         this._mouseInit();
5820         this._calculateNewMax();
5821
5822         this.element
5823             .addClass( "ui-slider" +
5824                 " ui-slider-" + this.orientation +
5825                 " ui-widget" +
5826                 " ui-widget-content" +
5827                 " ui-corner-all");
5828
5829         this._refresh();
5830         this._setOption( "disabled", this.options.disabled );
5831
5832         this._animateOff = false;
5833     },
5834
5835     _refresh: function() {
5836         this._createRange();
5837         this._createHandles();
5838         this._setupEvents();
5839         this._refreshValue();
5840     },
5841
5842     _createHandles: function() {
5843         var i, handleCount,
5844             options = this.options,
5845             existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
5846             handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
5847             handles = [];
5848
5849         handleCount = ( options.values && options.values.length ) || 1;
5850
5851         if ( existingHandles.length > handleCount ) {
5852             existingHandles.slice( handleCount ).remove();
5853             existingHandles = existingHandles.slice( 0, handleCount );
5854         }
5855
5856         for ( i = existingHandles.length; i < handleCount; i++ ) {
5857             handles.push( handle );
5858         }
5859
5860         this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
5861
5862         this.handle = this.handles.eq( 0 );
5863
5864         this.handles.each(function( i ) {
5865             $( this ).data( "ui-slider-handle-index", i );
5866         });
5867     },
5868
5869     _createRange: function() {
5870         var options = this.options,
5871             classes = "";
5872
5873         if ( options.range ) {
5874             if ( options.range === true ) {
5875                 if ( !options.values ) {
5876                     options.values = [ this._valueMin(), this._valueMin() ];
5877                 } else if ( options.values.length && options.values.length !== 2 ) {
5878                     options.values = [ options.values[0], options.values[0] ];
5879                 } else if ( $.isArray( options.values ) ) {
5880                     options.values = options.values.slice(0);
5881                 }
5882             }
5883
5884             if ( !this.range || !this.range.length ) {
5885                 this.range = $( "<div></div>" )
5886                     .appendTo( this.element );
5887
5888                 classes = "ui-slider-range" +
5889                 // note: this isn't the most fittingly semantic framework class for this element,
5890                 // but worked best visually with a variety of themes
5891                 " ui-widget-header ui-corner-all";
5892             } else {
5893                 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
5894                     // Handle range switching from true to min/max
5895                     .css({
5896                         "left": "",
5897                         "bottom": ""
5898                     });
5899             }
5900
5901             this.range.addClass( classes +
5902                 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
5903         } else {
5904             if ( this.range ) {
5905                 this.range.remove();
5906             }
5907             this.range = null;
5908         }
5909     },
5910
5911     _setupEvents: function() {
5912         this._off( this.handles );
5913         this._on( this.handles, this._handleEvents );
5914         this._hoverable( this.handles );
5915         this._focusable( this.handles );
5916     },
5917
5918     _destroy: function() {
5919         this.handles.remove();
5920         if ( this.range ) {
5921             this.range.remove();
5922         }
5923
5924         this.element
5925             .removeClass( "ui-slider" +
5926                 " ui-slider-horizontal" +
5927                 " ui-slider-vertical" +
5928                 " ui-widget" +
5929                 " ui-widget-content" +
5930                 " ui-corner-all" );
5931
5932         this._mouseDestroy();
5933     },
5934
5935     _mouseCapture: function( event ) {
5936         var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
5937             that = this,
5938             o = this.options;
5939
5940         if ( o.disabled ) {
5941             return false;
5942         }
5943
5944         this.elementSize = {
5945             width: this.element.outerWidth(),
5946             height: this.element.outerHeight()
5947         };
5948         this.elementOffset = this.element.offset();
5949
5950         position = { x: event.pageX, y: event.pageY };
5951         normValue = this._normValueFromMouse( position );
5952         distance = this._valueMax() - this._valueMin() + 1;
5953         this.handles.each(function( i ) {
5954             var thisDistance = Math.abs( normValue - that.values(i) );
5955             if (( distance > thisDistance ) ||
5956                 ( distance === thisDistance &&
5957                     (i === that._lastChangedValue || that.values(i) === o.min ))) {
5958                 distance = thisDistance;
5959                 closestHandle = $( this );
5960                 index = i;
5961             }
5962         });
5963
5964         allowed = this._start( event, index );
5965         if ( allowed === false ) {
5966             return false;
5967         }
5968         this._mouseSliding = true;
5969
5970         this._handleIndex = index;
5971
5972         closestHandle
5973             .addClass( "ui-state-active" )
5974             .focus();
5975
5976         offset = closestHandle.offset();
5977         mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
5978         this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
5979             left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
5980             top: event.pageY - offset.top -
5981                 ( closestHandle.height() / 2 ) -
5982                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
5983                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
5984                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
5985         };
5986
5987         if ( !this.handles.hasClass( "ui-state-hover" ) ) {
5988             this._slide( event, index, normValue );
5989         }
5990         this._animateOff = true;
5991         return true;
5992     },
5993
5994     _mouseStart: function() {
5995         return true;
5996     },
5997
5998     _mouseDrag: function( event ) {
5999         var position = { x: event.pageX, y: event.pageY },
6000             normValue = this._normValueFromMouse( position );
6001
6002         this._slide( event, this._handleIndex, normValue );
6003
6004         return false;
6005     },
6006
6007     _mouseStop: function( event ) {
6008         this.handles.removeClass( "ui-state-active" );
6009         this._mouseSliding = false;
6010
6011         this._stop( event, this._handleIndex );
6012         this._change( event, this._handleIndex );
6013
6014         this._handleIndex = null;
6015         this._clickOffset = null;
6016         this._animateOff = false;
6017
6018         return false;
6019     },
6020
6021     _detectOrientation: function() {
6022         this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
6023     },
6024
6025     _normValueFromMouse: function( position ) {
6026         var pixelTotal,
6027             pixelMouse,
6028             percentMouse,
6029             valueTotal,
6030             valueMouse;
6031
6032         if ( this.orientation === "horizontal" ) {
6033             pixelTotal = this.elementSize.width;
6034             pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
6035         } else {
6036             pixelTotal = this.elementSize.height;
6037             pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
6038         }
6039
6040         percentMouse = ( pixelMouse / pixelTotal );
6041         if ( percentMouse > 1 ) {
6042             percentMouse = 1;
6043         }
6044         if ( percentMouse < 0 ) {
6045             percentMouse = 0;
6046         }
6047         if ( this.orientation === "vertical" ) {
6048             percentMouse = 1 - percentMouse;
6049         }
6050
6051         valueTotal = this._valueMax() - this._valueMin();
6052         valueMouse = this._valueMin() + percentMouse * valueTotal;
6053
6054         return this._trimAlignValue( valueMouse );
6055     },
6056
6057     _start: function( event, index ) {
6058         var uiHash = {
6059             handle: this.handles[ index ],
6060             value: this.value()
6061         };
6062         if ( this.options.values && this.options.values.length ) {
6063             uiHash.value = this.values( index );
6064             uiHash.values = this.values();
6065         }
6066         return this._trigger( "start", event, uiHash );
6067     },
6068
6069     _slide: function( event, index, newVal ) {
6070         var otherVal,
6071             newValues,
6072             allowed;
6073
6074         if ( this.options.values && this.options.values.length ) {
6075             otherVal = this.values( index ? 0 : 1 );
6076
6077             if ( ( this.options.values.length === 2 && this.options.range === true ) &&
6078                     ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
6079                 ) {
6080                 newVal = otherVal;
6081             }
6082
6083             if ( newVal !== this.values( index ) ) {
6084                 newValues = this.values();
6085                 newValues[ index ] = newVal;
6086                 // A slide can be canceled by returning false from the slide callback
6087                 allowed = this._trigger( "slide", event, {
6088                     handle: this.handles[ index ],
6089                     value: newVal,
6090                     values: newValues
6091                 } );
6092                 otherVal = this.values( index ? 0 : 1 );
6093                 if ( allowed !== false ) {
6094                     this.values( index, newVal );
6095                 }
6096             }
6097         } else {
6098             if ( newVal !== this.value() ) {
6099                 // A slide can be canceled by returning false from the slide callback
6100                 allowed = this._trigger( "slide", event, {
6101                     handle: this.handles[ index ],
6102                     value: newVal
6103                 } );
6104                 if ( allowed !== false ) {
6105                     this.value( newVal );
6106                 }
6107             }
6108         }
6109     },
6110
6111     _stop: function( event, index ) {
6112         var uiHash = {
6113             handle: this.handles[ index ],
6114             value: this.value()
6115         };
6116         if ( this.options.values && this.options.values.length ) {
6117             uiHash.value = this.values( index );
6118             uiHash.values = this.values();
6119         }
6120
6121         this._trigger( "stop", event, uiHash );
6122     },
6123
6124     _change: function( event, index ) {
6125         if ( !this._keySliding && !this._mouseSliding ) {
6126             var uiHash = {
6127                 handle: this.handles[ index ],
6128                 value: this.value()
6129             };
6130             if ( this.options.values && this.options.values.length ) {
6131                 uiHash.value = this.values( index );
6132                 uiHash.values = this.values();
6133             }
6134
6135             //store the last changed value index for reference when handles overlap
6136             this._lastChangedValue = index;
6137
6138             this._trigger( "change", event, uiHash );
6139         }
6140     },
6141
6142     value: function( newValue ) {
6143         if ( arguments.length ) {
6144             this.options.value = this._trimAlignValue( newValue );
6145             this._refreshValue();
6146             this._change( null, 0 );
6147             return;
6148         }
6149
6150         return this._value();
6151     },
6152
6153     values: function( index, newValue ) {
6154         var vals,
6155             newValues,
6156             i;
6157
6158         if ( arguments.length > 1 ) {
6159             this.options.values[ index ] = this._trimAlignValue( newValue );
6160             this._refreshValue();
6161             this._change( null, index );
6162             return;
6163         }
6164
6165         if ( arguments.length ) {
6166             if ( $.isArray( arguments[ 0 ] ) ) {
6167                 vals = this.options.values;
6168                 newValues = arguments[ 0 ];
6169                 for ( i = 0; i < vals.length; i += 1 ) {
6170                     vals[ i ] = this._trimAlignValue( newValues[ i ] );
6171                     this._change( null, i );
6172                 }
6173                 this._refreshValue();
6174             } else {
6175                 if ( this.options.values && this.options.values.length ) {
6176                     return this._values( index );
6177                 } else {
6178                     return this.value();
6179                 }
6180             }
6181         } else {
6182             return this._values();
6183         }
6184     },
6185
6186     _setOption: function( key, value ) {
6187         var i,
6188             valsLength = 0;
6189
6190         if ( key === "range" && this.options.range === true ) {
6191             if ( value === "min" ) {
6192                 this.options.value = this._values( 0 );
6193                 this.options.values = null;
6194             } else if ( value === "max" ) {
6195                 this.options.value = this._values( this.options.values.length - 1 );
6196                 this.options.values = null;
6197             }
6198         }
6199
6200         if ( $.isArray( this.options.values ) ) {
6201             valsLength = this.options.values.length;
6202         }
6203
6204         if ( key === "disabled" ) {
6205             this.element.toggleClass( "ui-state-disabled", !!value );
6206         }
6207
6208         this._super( key, value );
6209
6210         switch ( key ) {
6211             case "orientation":
6212                 this._detectOrientation();
6213                 this.element
6214                     .removeClass( "ui-slider-horizontal ui-slider-vertical" )
6215                     .addClass( "ui-slider-" + this.orientation );
6216                 this._refreshValue();
6217
6218                 // Reset positioning from previous orientation
6219                 this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
6220                 break;
6221             case "value":
6222                 this._animateOff = true;
6223                 this._refreshValue();
6224                 this._change( null, 0 );
6225                 this._animateOff = false;
6226                 break;
6227             case "values":
6228                 this._animateOff = true;
6229                 this._refreshValue();
6230                 for ( i = 0; i < valsLength; i += 1 ) {
6231                     this._change( null, i );
6232                 }
6233                 this._animateOff = false;
6234                 break;
6235             case "step":
6236             case "min":
6237             case "max":
6238                 this._animateOff = true;
6239                 this._calculateNewMax();
6240                 this._refreshValue();
6241                 this._animateOff = false;
6242                 break;
6243             case "range":
6244                 this._animateOff = true;
6245                 this._refresh();
6246                 this._animateOff = false;
6247                 break;
6248         }
6249     },
6250
6251     //internal value getter
6252     // _value() returns value trimmed by min and max, aligned by step
6253     _value: function() {
6254         var val = this.options.value;
6255         val = this._trimAlignValue( val );
6256
6257         return val;
6258     },
6259
6260     //internal values getter
6261     // _values() returns array of values trimmed by min and max, aligned by step
6262     // _values( index ) returns single value trimmed by min and max, aligned by step
6263     _values: function( index ) {
6264         var val,
6265             vals,
6266             i;
6267
6268         if ( arguments.length ) {
6269             val = this.options.values[ index ];
6270             val = this._trimAlignValue( val );
6271
6272             return val;
6273         } else if ( this.options.values && this.options.values.length ) {
6274             // .slice() creates a copy of the array
6275             // this copy gets trimmed by min and max and then returned
6276             vals = this.options.values.slice();
6277             for ( i = 0; i < vals.length; i += 1) {
6278                 vals[ i ] = this._trimAlignValue( vals[ i ] );
6279             }
6280
6281             return vals;
6282         } else {
6283             return [];
6284         }
6285     },
6286
6287     // returns the step-aligned value that val is closest to, between (inclusive) min and max
6288     _trimAlignValue: function( val ) {
6289         if ( val <= this._valueMin() ) {
6290             return this._valueMin();
6291         }
6292         if ( val >= this._valueMax() ) {
6293             return this._valueMax();
6294         }
6295         var step = ( this.options.step > 0 ) ? this.options.step : 1,
6296             valModStep = (val - this._valueMin()) % step,
6297             alignValue = val - valModStep;
6298
6299         if ( Math.abs(valModStep) * 2 >= step ) {
6300             alignValue += ( valModStep > 0 ) ? step : ( -step );
6301         }
6302
6303         // Since JavaScript has problems with large floats, round
6304         // the final value to 5 digits after the decimal point (see #4124)
6305         return parseFloat( alignValue.toFixed(5) );
6306     },
6307
6308     _calculateNewMax: function() {
6309         var max = this.options.max,
6310             min = this._valueMin(),
6311             step = this.options.step,
6312             aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
6313         max = aboveMin + min;
6314         this.max = parseFloat( max.toFixed( this._precision() ) );
6315     },
6316
6317     _precision: function() {
6318         var precision = this._precisionOf( this.options.step );
6319         if ( this.options.min !== null ) {
6320             precision = Math.max( precision, this._precisionOf( this.options.min ) );
6321         }
6322         return precision;
6323     },
6324
6325     _precisionOf: function( num ) {
6326         var str = num.toString(),
6327             decimal = str.indexOf( "." );
6328         return decimal === -1 ? 0 : str.length - decimal - 1;
6329     },
6330
6331     _valueMin: function() {
6332         return this.options.min;
6333     },
6334
6335     _valueMax: function() {
6336         return this.max;
6337     },
6338
6339     _refreshValue: function() {
6340         var lastValPercent, valPercent, value, valueMin, valueMax,
6341             oRange = this.options.range,
6342             o = this.options,
6343             that = this,
6344             animate = ( !this._animateOff ) ? o.animate : false,
6345             _set = {};
6346
6347         if ( this.options.values && this.options.values.length ) {
6348             this.handles.each(function( i ) {
6349                 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
6350                 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
6351                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
6352                 if ( that.options.range === true ) {
6353                     if ( that.orientation === "horizontal" ) {
6354                         if ( i === 0 ) {
6355                             that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
6356                         }
6357                         if ( i === 1 ) {
6358                             that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
6359                         }
6360                     } else {
6361                         if ( i === 0 ) {
6362                             that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
6363                         }
6364                         if ( i === 1 ) {
6365                             that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
6366                         }
6367                     }
6368                 }
6369                 lastValPercent = valPercent;
6370             });
6371         } else {
6372             value = this.value();
6373             valueMin = this._valueMin();
6374             valueMax = this._valueMax();
6375             valPercent = ( valueMax !== valueMin ) ?
6376                     ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
6377                     0;
6378             _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
6379             this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
6380
6381             if ( oRange === "min" && this.orientation === "horizontal" ) {
6382                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
6383             }
6384             if ( oRange === "max" && this.orientation === "horizontal" ) {
6385                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
6386             }
6387             if ( oRange === "min" && this.orientation === "vertical" ) {
6388                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
6389             }
6390             if ( oRange === "max" && this.orientation === "vertical" ) {
6391                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
6392             }
6393         }
6394     },
6395
6396     _handleEvents: {
6397         keydown: function( event ) {
6398             var allowed, curVal, newVal, step,
6399                 index = $( event.target ).data( "ui-slider-handle-index" );
6400
6401             switch ( event.keyCode ) {
6402                 case $.ui.keyCode.HOME:
6403                 case $.ui.keyCode.END:
6404                 case $.ui.keyCode.PAGE_UP:
6405                 case $.ui.keyCode.PAGE_DOWN:
6406                 case $.ui.keyCode.UP:
6407                 case $.ui.keyCode.RIGHT:
6408                 case $.ui.keyCode.DOWN:
6409                 case $.ui.keyCode.LEFT:
6410                     event.preventDefault();
6411                     if ( !this._keySliding ) {
6412                         this._keySliding = true;
6413                         $( event.target ).addClass( "ui-state-active" );
6414                         allowed = this._start( event, index );
6415                         if ( allowed === false ) {
6416                             return;
6417                         }
6418                     }
6419                     break;
6420             }
6421
6422             step = this.options.step;
6423             if ( this.options.values && this.options.values.length ) {
6424                 curVal = newVal = this.values( index );
6425             } else {
6426                 curVal = newVal = this.value();
6427             }
6428
6429             switch ( event.keyCode ) {
6430                 case $.ui.keyCode.HOME:
6431                     newVal = this._valueMin();
6432                     break;
6433                 case $.ui.keyCode.END:
6434                     newVal = this._valueMax();
6435                     break;
6436                 case $.ui.keyCode.PAGE_UP:
6437                     newVal = this._trimAlignValue(
6438                         curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
6439                     );
6440                     break;
6441                 case $.ui.keyCode.PAGE_DOWN:
6442                     newVal = this._trimAlignValue(
6443                         curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
6444                     break;
6445                 case $.ui.keyCode.UP:
6446                 case $.ui.keyCode.RIGHT:
6447                     if ( curVal === this._valueMax() ) {
6448                         return;
6449                     }
6450                     newVal = this._trimAlignValue( curVal + step );
6451                     break;
6452                 case $.ui.keyCode.DOWN:
6453                 case $.ui.keyCode.LEFT:
6454                     if ( curVal === this._valueMin() ) {
6455                         return;
6456                     }
6457                     newVal = this._trimAlignValue( curVal - step );
6458                     break;
6459             }
6460
6461             this._slide( event, index, newVal );
6462         },
6463         keyup: function( event ) {
6464             var index = $( event.target ).data( "ui-slider-handle-index" );
6465
6466             if ( this._keySliding ) {
6467                 this._keySliding = false;
6468                 this._stop( event, index );
6469                 this._change( event, index );
6470                 $( event.target ).removeClass( "ui-state-active" );
6471             }
6472         }
6473     }
6474 });
6475
6476
6477
6478 }));