a5ae96f12a456f495d31002de5e2553dcd2090d4
[moodle.git] / lib / jquery / ui-1.10.4 / jquery-ui.js
1 /*! jQuery UI - v1.10.4 - 2014-01-17
2 * http://jqueryui.com
3 * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
4 * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5 (function( $, undefined ) {
7 var uuid = 0,
8         runiqueId = /^ui-id-\d+$/;
10 // $.ui might exist from components with no dependencies, e.g., $.ui.position
11 $.ui = $.ui || {};
13 $.extend( $.ui, {
14         version: "1.10.4",
16         keyCode: {
17                 BACKSPACE: 8,
18                 COMMA: 188,
19                 DELETE: 46,
20                 DOWN: 40,
21                 END: 35,
22                 ENTER: 13,
23                 ESCAPE: 27,
24                 HOME: 36,
25                 LEFT: 37,
26                 NUMPAD_ADD: 107,
27                 NUMPAD_DECIMAL: 110,
28                 NUMPAD_DIVIDE: 111,
29                 NUMPAD_ENTER: 108,
30                 NUMPAD_MULTIPLY: 106,
31                 NUMPAD_SUBTRACT: 109,
32                 PAGE_DOWN: 34,
33                 PAGE_UP: 33,
34                 PERIOD: 190,
35                 RIGHT: 39,
36                 SPACE: 32,
37                 TAB: 9,
38                 UP: 38
39         }
40 });
42 // plugins
43 $.fn.extend({
44         focus: (function( orig ) {
45                 return function( delay, fn ) {
46                         return typeof delay === "number" ?
47                                 this.each(function() {
48                                         var elem = this;
49                                         setTimeout(function() {
50                                                 $( elem ).focus();
51                                                 if ( fn ) {
52                                                         fn.call( elem );
53                                                 }
54                                         }, delay );
55                                 }) :
56                                 orig.apply( this, arguments );
57                 };
58         })( $.fn.focus ),
60         scrollParent: function() {
61                 var scrollParent;
62                 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
63                         scrollParent = this.parents().filter(function() {
64                                 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
65                         }).eq(0);
66                 } else {
67                         scrollParent = this.parents().filter(function() {
68                                 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
69                         }).eq(0);
70                 }
72                 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
73         },
75         zIndex: function( zIndex ) {
76                 if ( zIndex !== undefined ) {
77                         return this.css( "zIndex", zIndex );
78                 }
80                 if ( this.length ) {
81                         var elem = $( this[ 0 ] ), position, value;
82                         while ( elem.length && elem[ 0 ] !== document ) {
83                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
84                                 // This makes behavior of this function consistent across browsers
85                                 // WebKit always returns auto if the element is positioned
86                                 position = elem.css( "position" );
87                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
88                                         // IE returns 0 when zIndex is not specified
89                                         // other browsers return a string
90                                         // we ignore the case of nested elements with an explicit value of 0
91                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
92                                         value = parseInt( elem.css( "zIndex" ), 10 );
93                                         if ( !isNaN( value ) && value !== 0 ) {
94                                                 return value;
95                                         }
96                                 }
97                                 elem = elem.parent();
98                         }
99                 }
101                 return 0;
102         },
104         uniqueId: function() {
105                 return this.each(function() {
106                         if ( !this.id ) {
107                                 this.id = "ui-id-" + (++uuid);
108                         }
109                 });
110         },
112         removeUniqueId: function() {
113                 return this.each(function() {
114                         if ( runiqueId.test( this.id ) ) {
115                                 $( this ).removeAttr( "id" );
116                         }
117                 });
118         }
119 });
121 // selectors
122 function focusable( element, isTabIndexNotNaN ) {
123         var map, mapName, img,
124                 nodeName = element.nodeName.toLowerCase();
125         if ( "area" === nodeName ) {
126                 map = element.parentNode;
127                 mapName = map.name;
128                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
129                         return false;
130                 }
131                 img = $( "img[usemap=#" + mapName + "]" )[0];
132                 return !!img && visible( img );
133         }
134         return ( /input|select|textarea|button|object/.test( nodeName ) ?
135                 !element.disabled :
136                 "a" === nodeName ?
137                         element.href || isTabIndexNotNaN :
138                         isTabIndexNotNaN) &&
139                 // the element and all of its ancestors must be visible
140                 visible( element );
143 function visible( element ) {
144         return $.expr.filters.visible( element ) &&
145                 !$( element ).parents().addBack().filter(function() {
146                         return $.css( this, "visibility" ) === "hidden";
147                 }).length;
150 $.extend( $.expr[ ":" ], {
151         data: $.expr.createPseudo ?
152                 $.expr.createPseudo(function( dataName ) {
153                         return function( elem ) {
154                                 return !!$.data( elem, dataName );
155                         };
156                 }) :
157                 // support: jQuery <1.8
158                 function( elem, i, match ) {
159                         return !!$.data( elem, match[ 3 ] );
160                 },
162         focusable: function( element ) {
163                 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
164         },
166         tabbable: function( element ) {
167                 var tabIndex = $.attr( element, "tabindex" ),
168                         isTabIndexNaN = isNaN( tabIndex );
169                 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
170         }
171 });
173 // support: jQuery <1.8
174 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
175         $.each( [ "Width", "Height" ], function( i, name ) {
176                 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
177                         type = name.toLowerCase(),
178                         orig = {
179                                 innerWidth: $.fn.innerWidth,
180                                 innerHeight: $.fn.innerHeight,
181                                 outerWidth: $.fn.outerWidth,
182                                 outerHeight: $.fn.outerHeight
183                         };
185                 function reduce( elem, size, border, margin ) {
186                         $.each( side, function() {
187                                 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
188                                 if ( border ) {
189                                         size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
190                                 }
191                                 if ( margin ) {
192                                         size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
193                                 }
194                         });
195                         return size;
196                 }
198                 $.fn[ "inner" + name ] = function( size ) {
199                         if ( size === undefined ) {
200                                 return orig[ "inner" + name ].call( this );
201                         }
203                         return this.each(function() {
204                                 $( this ).css( type, reduce( this, size ) + "px" );
205                         });
206                 };
208                 $.fn[ "outer" + name] = function( size, margin ) {
209                         if ( typeof size !== "number" ) {
210                                 return orig[ "outer" + name ].call( this, size );
211                         }
213                         return this.each(function() {
214                                 $( this).css( type, reduce( this, size, true, margin ) + "px" );
215                         });
216                 };
217         });
220 // support: jQuery <1.8
221 if ( !$.fn.addBack ) {
222         $.fn.addBack = function( selector ) {
223                 return this.add( selector == null ?
224                         this.prevObject : this.prevObject.filter( selector )
225                 );
226         };
229 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
230 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
231         $.fn.removeData = (function( removeData ) {
232                 return function( key ) {
233                         if ( arguments.length ) {
234                                 return removeData.call( this, $.camelCase( key ) );
235                         } else {
236                                 return removeData.call( this );
237                         }
238                 };
239         })( $.fn.removeData );
246 // deprecated
247 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
249 $.support.selectstart = "onselectstart" in document.createElement( "div" );
250 $.fn.extend({
251         disableSelection: function() {
252                 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
253                         ".ui-disableSelection", function( event ) {
254                                 event.preventDefault();
255                         });
256         },
258         enableSelection: function() {
259                 return this.unbind( ".ui-disableSelection" );
260         }
261 });
263 $.extend( $.ui, {
264         // $.ui.plugin is deprecated. Use $.widget() extensions instead.
265         plugin: {
266                 add: function( module, option, set ) {
267                         var i,
268                                 proto = $.ui[ module ].prototype;
269                         for ( i in set ) {
270                                 proto.plugins[ i ] = proto.plugins[ i ] || [];
271                                 proto.plugins[ i ].push( [ option, set[ i ] ] );
272                         }
273                 },
274                 call: function( instance, name, args ) {
275                         var i,
276                                 set = instance.plugins[ name ];
277                         if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
278                                 return;
279                         }
281                         for ( i = 0; i < set.length; i++ ) {
282                                 if ( instance.options[ set[ i ][ 0 ] ] ) {
283                                         set[ i ][ 1 ].apply( instance.element, args );
284                                 }
285                         }
286                 }
287         },
289         // only used by resizable
290         hasScroll: function( el, a ) {
292                 //If overflow is hidden, the element might have extra content, but the user wants to hide it
293                 if ( $( el ).css( "overflow" ) === "hidden") {
294                         return false;
295                 }
297                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
298                         has = false;
300                 if ( el[ scroll ] > 0 ) {
301                         return true;
302                 }
304                 // TODO: determine which cases actually cause this to happen
305                 // if the element doesn't have the scroll set, see if it's possible to
306                 // set the scroll
307                 el[ scroll ] = 1;
308                 has = ( el[ scroll ] > 0 );
309                 el[ scroll ] = 0;
310                 return has;
311         }
312 });
314 })( jQuery );
316 (function( $, undefined ) {
318 var uuid = 0,
319         slice = Array.prototype.slice,
320         _cleanData = $.cleanData;
321 $.cleanData = function( elems ) {
322         for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
323                 try {
324                         $( elem ).triggerHandler( "remove" );
325                 // http://bugs.jquery.com/ticket/8235
326                 } catch( e ) {}
327         }
328         _cleanData( elems );
329 };
331 $.widget = function( name, base, prototype ) {
332         var fullName, existingConstructor, constructor, basePrototype,
333                 // proxiedPrototype allows the provided prototype to remain unmodified
334                 // so that it can be used as a mixin for multiple widgets (#8876)
335                 proxiedPrototype = {},
336                 namespace = name.split( "." )[ 0 ];
338         name = name.split( "." )[ 1 ];
339         fullName = namespace + "-" + name;
341         if ( !prototype ) {
342                 prototype = base;
343                 base = $.Widget;
344         }
346         // create selector for plugin
347         $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
348                 return !!$.data( elem, fullName );
349         };
351         $[ namespace ] = $[ namespace ] || {};
352         existingConstructor = $[ namespace ][ name ];
353         constructor = $[ namespace ][ name ] = function( options, element ) {
354                 // allow instantiation without "new" keyword
355                 if ( !this._createWidget ) {
356                         return new constructor( options, element );
357                 }
359                 // allow instantiation without initializing for simple inheritance
360                 // must use "new" keyword (the code above always passes args)
361                 if ( arguments.length ) {
362                         this._createWidget( options, element );
363                 }
364         };
365         // extend with the existing constructor to carry over any static properties
366         $.extend( constructor, existingConstructor, {
367                 version: prototype.version,
368                 // copy the object used to create the prototype in case we need to
369                 // redefine the widget later
370                 _proto: $.extend( {}, prototype ),
371                 // track widgets that inherit from this widget in case this widget is
372                 // redefined after a widget inherits from it
373                 _childConstructors: []
374         });
376         basePrototype = new base();
377         // we need to make the options hash a property directly on the new instance
378         // otherwise we'll modify the options hash on the prototype that we're
379         // inheriting from
380         basePrototype.options = $.widget.extend( {}, basePrototype.options );
381         $.each( prototype, function( prop, value ) {
382                 if ( !$.isFunction( value ) ) {
383                         proxiedPrototype[ prop ] = value;
384                         return;
385                 }
386                 proxiedPrototype[ prop ] = (function() {
387                         var _super = function() {
388                                         return base.prototype[ prop ].apply( this, arguments );
389                                 },
390                                 _superApply = function( args ) {
391                                         return base.prototype[ prop ].apply( this, args );
392                                 };
393                         return function() {
394                                 var __super = this._super,
395                                         __superApply = this._superApply,
396                                         returnValue;
398                                 this._super = _super;
399                                 this._superApply = _superApply;
401                                 returnValue = value.apply( this, arguments );
403                                 this._super = __super;
404                                 this._superApply = __superApply;
406                                 return returnValue;
407                         };
408                 })();
409         });
410         constructor.prototype = $.widget.extend( basePrototype, {
411                 // TODO: remove support for widgetEventPrefix
412                 // always use the name + a colon as the prefix, e.g., draggable:start
413                 // don't prefix for widgets that aren't DOM-based
414                 widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
415         }, proxiedPrototype, {
416                 constructor: constructor,
417                 namespace: namespace,
418                 widgetName: name,
419                 widgetFullName: fullName
420         });
422         // If this widget is being redefined then we need to find all widgets that
423         // are inheriting from it and redefine all of them so that they inherit from
424         // the new version of this widget. We're essentially trying to replace one
425         // level in the prototype chain.
426         if ( existingConstructor ) {
427                 $.each( existingConstructor._childConstructors, function( i, child ) {
428                         var childPrototype = child.prototype;
430                         // redefine the child widget using the same prototype that was
431                         // originally used, but inherit from the new version of the base
432                         $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
433                 });
434                 // remove the list of existing child constructors from the old constructor
435                 // so the old child constructors can be garbage collected
436                 delete existingConstructor._childConstructors;
437         } else {
438                 base._childConstructors.push( constructor );
439         }
441         $.widget.bridge( name, constructor );
442 };
444 $.widget.extend = function( target ) {
445         var input = slice.call( arguments, 1 ),
446                 inputIndex = 0,
447                 inputLength = input.length,
448                 key,
449                 value;
450         for ( ; inputIndex < inputLength; inputIndex++ ) {
451                 for ( key in input[ inputIndex ] ) {
452                         value = input[ inputIndex ][ key ];
453                         if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
454                                 // Clone objects
455                                 if ( $.isPlainObject( value ) ) {
456                                         target[ key ] = $.isPlainObject( target[ key ] ) ?
457                                                 $.widget.extend( {}, target[ key ], value ) :
458                                                 // Don't extend strings, arrays, etc. with objects
459                                                 $.widget.extend( {}, value );
460                                 // Copy everything else by reference
461                                 } else {
462                                         target[ key ] = value;
463                                 }
464                         }
465                 }
466         }
467         return target;
468 };
470 $.widget.bridge = function( name, object ) {
471         var fullName = object.prototype.widgetFullName || name;
472         $.fn[ name ] = function( options ) {
473                 var isMethodCall = typeof options === "string",
474                         args = slice.call( arguments, 1 ),
475                         returnValue = this;
477                 // allow multiple hashes to be passed on init
478                 options = !isMethodCall && args.length ?
479                         $.widget.extend.apply( null, [ options ].concat(args) ) :
480                         options;
482                 if ( isMethodCall ) {
483                         this.each(function() {
484                                 var methodValue,
485                                         instance = $.data( this, fullName );
486                                 if ( !instance ) {
487                                         return $.error( "cannot call methods on " + name + " prior to initialization; " +
488                                                 "attempted to call method '" + options + "'" );
489                                 }
490                                 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
491                                         return $.error( "no such method '" + options + "' for " + name + " widget instance" );
492                                 }
493                                 methodValue = instance[ options ].apply( instance, args );
494                                 if ( methodValue !== instance && methodValue !== undefined ) {
495                                         returnValue = methodValue && methodValue.jquery ?
496                                                 returnValue.pushStack( methodValue.get() ) :
497                                                 methodValue;
498                                         return false;
499                                 }
500                         });
501                 } else {
502                         this.each(function() {
503                                 var instance = $.data( this, fullName );
504                                 if ( instance ) {
505                                         instance.option( options || {} )._init();
506                                 } else {
507                                         $.data( this, fullName, new object( options, this ) );
508                                 }
509                         });
510                 }
512                 return returnValue;
513         };
514 };
516 $.Widget = function( /* options, element */ ) {};
517 $.Widget._childConstructors = [];
519 $.Widget.prototype = {
520         widgetName: "widget",
521         widgetEventPrefix: "",
522         defaultElement: "<div>",
523         options: {
524                 disabled: false,
526                 // callbacks
527                 create: null
528         },
529         _createWidget: function( options, element ) {
530                 element = $( element || this.defaultElement || this )[ 0 ];
531                 this.element = $( element );
532                 this.uuid = uuid++;
533                 this.eventNamespace = "." + this.widgetName + this.uuid;
534                 this.options = $.widget.extend( {},
535                         this.options,
536                         this._getCreateOptions(),
537                         options );
539                 this.bindings = $();
540                 this.hoverable = $();
541                 this.focusable = $();
543                 if ( element !== this ) {
544                         $.data( element, this.widgetFullName, this );
545                         this._on( true, this.element, {
546                                 remove: function( event ) {
547                                         if ( event.target === element ) {
548                                                 this.destroy();
549                                         }
550                                 }
551                         });
552                         this.document = $( element.style ?
553                                 // element within the document
554                                 element.ownerDocument :
555                                 // element is window or document
556                                 element.document || element );
557                         this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
558                 }
560                 this._create();
561                 this._trigger( "create", null, this._getCreateEventData() );
562                 this._init();
563         },
564         _getCreateOptions: $.noop,
565         _getCreateEventData: $.noop,
566         _create: $.noop,
567         _init: $.noop,
569         destroy: function() {
570                 this._destroy();
571                 // we can probably remove the unbind calls in 2.0
572                 // all event bindings should go through this._on()
573                 this.element
574                         .unbind( this.eventNamespace )
575                         // 1.9 BC for #7810
576                         // TODO remove dual storage
577                         .removeData( this.widgetName )
578                         .removeData( this.widgetFullName )
579                         // support: jquery <1.6.3
580                         // http://bugs.jquery.com/ticket/9413
581                         .removeData( $.camelCase( this.widgetFullName ) );
582                 this.widget()
583                         .unbind( this.eventNamespace )
584                         .removeAttr( "aria-disabled" )
585                         .removeClass(
586                                 this.widgetFullName + "-disabled " +
587                                 "ui-state-disabled" );
589                 // clean up events and states
590                 this.bindings.unbind( this.eventNamespace );
591                 this.hoverable.removeClass( "ui-state-hover" );
592                 this.focusable.removeClass( "ui-state-focus" );
593         },
594         _destroy: $.noop,
596         widget: function() {
597                 return this.element;
598         },
600         option: function( key, value ) {
601                 var options = key,
602                         parts,
603                         curOption,
604                         i;
606                 if ( arguments.length === 0 ) {
607                         // don't return a reference to the internal hash
608                         return $.widget.extend( {}, this.options );
609                 }
611                 if ( typeof key === "string" ) {
612                         // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
613                         options = {};
614                         parts = key.split( "." );
615                         key = parts.shift();
616                         if ( parts.length ) {
617                                 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
618                                 for ( i = 0; i < parts.length - 1; i++ ) {
619                                         curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
620                                         curOption = curOption[ parts[ i ] ];
621                                 }
622                                 key = parts.pop();
623                                 if ( arguments.length === 1 ) {
624                                         return curOption[ key ] === undefined ? null : curOption[ key ];
625                                 }
626                                 curOption[ key ] = value;
627                         } else {
628                                 if ( arguments.length === 1 ) {
629                                         return this.options[ key ] === undefined ? null : this.options[ key ];
630                                 }
631                                 options[ key ] = value;
632                         }
633                 }
635                 this._setOptions( options );
637                 return this;
638         },
639         _setOptions: function( options ) {
640                 var key;
642                 for ( key in options ) {
643                         this._setOption( key, options[ key ] );
644                 }
646                 return this;
647         },
648         _setOption: function( key, value ) {
649                 this.options[ key ] = value;
651                 if ( key === "disabled" ) {
652                         this.widget()
653                                 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
654                                 .attr( "aria-disabled", value );
655                         this.hoverable.removeClass( "ui-state-hover" );
656                         this.focusable.removeClass( "ui-state-focus" );
657                 }
659                 return this;
660         },
662         enable: function() {
663                 return this._setOption( "disabled", false );
664         },
665         disable: function() {
666                 return this._setOption( "disabled", true );
667         },
669         _on: function( suppressDisabledCheck, element, handlers ) {
670                 var delegateElement,
671                         instance = this;
673                 // no suppressDisabledCheck flag, shuffle arguments
674                 if ( typeof suppressDisabledCheck !== "boolean" ) {
675                         handlers = element;
676                         element = suppressDisabledCheck;
677                         suppressDisabledCheck = false;
678                 }
680                 // no element argument, shuffle and use this.element
681                 if ( !handlers ) {
682                         handlers = element;
683                         element = this.element;
684                         delegateElement = this.widget();
685                 } else {
686                         // accept selectors, DOM elements
687                         element = delegateElement = $( element );
688                         this.bindings = this.bindings.add( element );
689                 }
691                 $.each( handlers, function( event, handler ) {
692                         function handlerProxy() {
693                                 // allow widgets to customize the disabled handling
694                                 // - disabled as an array instead of boolean
695                                 // - disabled class as method for disabling individual parts
696                                 if ( !suppressDisabledCheck &&
697                                                 ( instance.options.disabled === true ||
698                                                         $( this ).hasClass( "ui-state-disabled" ) ) ) {
699                                         return;
700                                 }
701                                 return ( typeof handler === "string" ? instance[ handler ] : handler )
702                                         .apply( instance, arguments );
703                         }
705                         // copy the guid so direct unbinding works
706                         if ( typeof handler !== "string" ) {
707                                 handlerProxy.guid = handler.guid =
708                                         handler.guid || handlerProxy.guid || $.guid++;
709                         }
711                         var match = event.match( /^(\w+)\s*(.*)$/ ),
712                                 eventName = match[1] + instance.eventNamespace,
713                                 selector = match[2];
714                         if ( selector ) {
715                                 delegateElement.delegate( selector, eventName, handlerProxy );
716                         } else {
717                                 element.bind( eventName, handlerProxy );
718                         }
719                 });
720         },
722         _off: function( element, eventName ) {
723                 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
724                 element.unbind( eventName ).undelegate( eventName );
725         },
727         _delay: function( handler, delay ) {
728                 function handlerProxy() {
729                         return ( typeof handler === "string" ? instance[ handler ] : handler )
730                                 .apply( instance, arguments );
731                 }
732                 var instance = this;
733                 return setTimeout( handlerProxy, delay || 0 );
734         },
736         _hoverable: function( element ) {
737                 this.hoverable = this.hoverable.add( element );
738                 this._on( element, {
739                         mouseenter: function( event ) {
740                                 $( event.currentTarget ).addClass( "ui-state-hover" );
741                         },
742                         mouseleave: function( event ) {
743                                 $( event.currentTarget ).removeClass( "ui-state-hover" );
744                         }
745                 });
746         },
748         _focusable: function( element ) {
749                 this.focusable = this.focusable.add( element );
750                 this._on( element, {
751                         focusin: function( event ) {
752                                 $( event.currentTarget ).addClass( "ui-state-focus" );
753                         },
754                         focusout: function( event ) {
755                                 $( event.currentTarget ).removeClass( "ui-state-focus" );
756                         }
757                 });
758         },
760         _trigger: function( type, event, data ) {
761                 var prop, orig,
762                         callback = this.options[ type ];
764                 data = data || {};
765                 event = $.Event( event );
766                 event.type = ( type === this.widgetEventPrefix ?
767                         type :
768                         this.widgetEventPrefix + type ).toLowerCase();
769                 // the original event may come from any element
770                 // so we need to reset the target on the new event
771                 event.target = this.element[ 0 ];
773                 // copy original event properties over to the new event
774                 orig = event.originalEvent;
775                 if ( orig ) {
776                         for ( prop in orig ) {
777                                 if ( !( prop in event ) ) {
778                                         event[ prop ] = orig[ prop ];
779                                 }
780                         }
781                 }
783                 this.element.trigger( event, data );
784                 return !( $.isFunction( callback ) &&
785                         callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
786                         event.isDefaultPrevented() );
787         }
788 };
790 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
791         $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
792                 if ( typeof options === "string" ) {
793                         options = { effect: options };
794                 }
795                 var hasOptions,
796                         effectName = !options ?
797                                 method :
798                                 options === true || typeof options === "number" ?
799                                         defaultEffect :
800                                         options.effect || defaultEffect;
801                 options = options || {};
802                 if ( typeof options === "number" ) {
803                         options = { duration: options };
804                 }
805                 hasOptions = !$.isEmptyObject( options );
806                 options.complete = callback;
807                 if ( options.delay ) {
808                         element.delay( options.delay );
809                 }
810                 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
811                         element[ method ]( options );
812                 } else if ( effectName !== method && element[ effectName ] ) {
813                         element[ effectName ]( options.duration, options.easing, callback );
814                 } else {
815                         element.queue(function( next ) {
816                                 $( this )[ method ]();
817                                 if ( callback ) {
818                                         callback.call( element[ 0 ] );
819                                 }
820                                 next();
821                         });
822                 }
823         };
824 });
826 })( jQuery );
828 (function( $, undefined ) {
830 var mouseHandled = false;
831 $( document ).mouseup( function() {
832         mouseHandled = false;
833 });
835 $.widget("ui.mouse", {
836         version: "1.10.4",
837         options: {
838                 cancel: "input,textarea,button,select,option",
839                 distance: 1,
840                 delay: 0
841         },
842         _mouseInit: function() {
843                 var that = this;
845                 this.element
846                         .bind("mousedown."+this.widgetName, function(event) {
847                                 return that._mouseDown(event);
848                         })
849                         .bind("click."+this.widgetName, function(event) {
850                                 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
851                                         $.removeData(event.target, that.widgetName + ".preventClickEvent");
852                                         event.stopImmediatePropagation();
853                                         return false;
854                                 }
855                         });
857                 this.started = false;
858         },
860         // TODO: make sure destroying one instance of mouse doesn't mess with
861         // other instances of mouse
862         _mouseDestroy: function() {
863                 this.element.unbind("."+this.widgetName);
864                 if ( this._mouseMoveDelegate ) {
865                         $(document)
866                                 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
867                                 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
868                 }
869         },
871         _mouseDown: function(event) {
872                 // don't let more than one widget handle mouseStart
873                 if( mouseHandled ) { return; }
875                 // we may have missed mouseup (out of window)
876                 (this._mouseStarted && this._mouseUp(event));
878                 this._mouseDownEvent = event;
880                 var that = this,
881                         btnIsLeft = (event.which === 1),
882                         // event.target.nodeName works around a bug in IE 8 with
883                         // disabled inputs (#7620)
884                         elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
885                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
886                         return true;
887                 }
889                 this.mouseDelayMet = !this.options.delay;
890                 if (!this.mouseDelayMet) {
891                         this._mouseDelayTimer = setTimeout(function() {
892                                 that.mouseDelayMet = true;
893                         }, this.options.delay);
894                 }
896                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
897                         this._mouseStarted = (this._mouseStart(event) !== false);
898                         if (!this._mouseStarted) {
899                                 event.preventDefault();
900                                 return true;
901                         }
902                 }
904                 // Click event may never have fired (Gecko & Opera)
905                 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
906                         $.removeData(event.target, this.widgetName + ".preventClickEvent");
907                 }
909                 // these delegates are required to keep context
910                 this._mouseMoveDelegate = function(event) {
911                         return that._mouseMove(event);
912                 };
913                 this._mouseUpDelegate = function(event) {
914                         return that._mouseUp(event);
915                 };
916                 $(document)
917                         .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
918                         .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
920                 event.preventDefault();
922                 mouseHandled = true;
923                 return true;
924         },
926         _mouseMove: function(event) {
927                 // IE mouseup check - mouseup happened when mouse was out of window
928                 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
929                         return this._mouseUp(event);
930                 }
932                 if (this._mouseStarted) {
933                         this._mouseDrag(event);
934                         return event.preventDefault();
935                 }
937                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
938                         this._mouseStarted =
939                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
940                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
941                 }
943                 return !this._mouseStarted;
944         },
946         _mouseUp: function(event) {
947                 $(document)
948                         .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
949                         .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
951                 if (this._mouseStarted) {
952                         this._mouseStarted = false;
954                         if (event.target === this._mouseDownEvent.target) {
955                                 $.data(event.target, this.widgetName + ".preventClickEvent", true);
956                         }
958                         this._mouseStop(event);
959                 }
961                 return false;
962         },
964         _mouseDistanceMet: function(event) {
965                 return (Math.max(
966                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
967                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
968                         ) >= this.options.distance
969                 );
970         },
972         _mouseDelayMet: function(/* event */) {
973                 return this.mouseDelayMet;
974         },
976         // These are placeholder methods, to be overriden by extending plugin
977         _mouseStart: function(/* event */) {},
978         _mouseDrag: function(/* event */) {},
979         _mouseStop: function(/* event */) {},
980         _mouseCapture: function(/* event */) { return true; }
981 });
983 })(jQuery);
985 (function( $, undefined ) {
987 $.widget("ui.draggable", $.ui.mouse, {
988         version: "1.10.4",
989         widgetEventPrefix: "drag",
990         options: {
991                 addClasses: true,
992                 appendTo: "parent",
993                 axis: false,
994                 connectToSortable: false,
995                 containment: false,
996                 cursor: "auto",
997                 cursorAt: false,
998                 grid: false,
999                 handle: false,
1000                 helper: "original",
1001                 iframeFix: false,
1002                 opacity: false,
1003                 refreshPositions: false,
1004                 revert: false,
1005                 revertDuration: 500,
1006                 scope: "default",
1007                 scroll: true,
1008                 scrollSensitivity: 20,
1009                 scrollSpeed: 20,
1010                 snap: false,
1011                 snapMode: "both",
1012                 snapTolerance: 20,
1013                 stack: false,
1014                 zIndex: false,
1016                 // callbacks
1017                 drag: null,
1018                 start: null,
1019                 stop: null
1020         },
1021         _create: function() {
1023                 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1024                         this.element[0].style.position = "relative";
1025                 }
1026                 if (this.options.addClasses){
1027                         this.element.addClass("ui-draggable");
1028                 }
1029                 if (this.options.disabled){
1030                         this.element.addClass("ui-draggable-disabled");
1031                 }
1033                 this._mouseInit();
1035         },
1037         _destroy: function() {
1038                 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1039                 this._mouseDestroy();
1040         },
1042         _mouseCapture: function(event) {
1044                 var o = this.options;
1046                 // among others, prevent a drag on a resizable-handle
1047                 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1048                         return false;
1049                 }
1051                 //Quit if we're not on a valid handle
1052                 this.handle = this._getHandle(event);
1053                 if (!this.handle) {
1054                         return false;
1055                 }
1057                 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1058                         $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1059                         .css({
1060                                 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1061                                 position: "absolute", opacity: "0.001", zIndex: 1000
1062                         })
1063                         .css($(this).offset())
1064                         .appendTo("body");
1065                 });
1067                 return true;
1069         },
1071         _mouseStart: function(event) {
1073                 var o = this.options;
1075                 //Create and append the visible helper
1076                 this.helper = this._createHelper(event);
1078                 this.helper.addClass("ui-draggable-dragging");
1080                 //Cache the helper size
1081                 this._cacheHelperProportions();
1083                 //If ddmanager is used for droppables, set the global draggable
1084                 if($.ui.ddmanager) {
1085                         $.ui.ddmanager.current = this;
1086                 }
1088                 /*
1089                  * - Position generation -
1090                  * This block generates everything position related - it's the core of draggables.
1091                  */
1093                 //Cache the margins of the original element
1094                 this._cacheMargins();
1096                 //Store the helper's css position
1097                 this.cssPosition = this.helper.css( "position" );
1098                 this.scrollParent = this.helper.scrollParent();
1099                 this.offsetParent = this.helper.offsetParent();
1100                 this.offsetParentCssPosition = this.offsetParent.css( "position" );
1102                 //The element's absolute position on the page minus margins
1103                 this.offset = this.positionAbs = this.element.offset();
1104                 this.offset = {
1105                         top: this.offset.top - this.margins.top,
1106                         left: this.offset.left - this.margins.left
1107                 };
1109                 //Reset scroll cache
1110                 this.offset.scroll = false;
1112                 $.extend(this.offset, {
1113                         click: { //Where the click happened, relative to the element
1114                                 left: event.pageX - this.offset.left,
1115                                 top: event.pageY - this.offset.top
1116                         },
1117                         parent: this._getParentOffset(),
1118                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1119                 });
1121                 //Generate the original position
1122                 this.originalPosition = this.position = this._generatePosition(event);
1123                 this.originalPageX = event.pageX;
1124                 this.originalPageY = event.pageY;
1126                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1127                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1129                 //Set a containment if given in the options
1130                 this._setContainment();
1132                 //Trigger event + callbacks
1133                 if(this._trigger("start", event) === false) {
1134                         this._clear();
1135                         return false;
1136                 }
1138                 //Recache the helper size
1139                 this._cacheHelperProportions();
1141                 //Prepare the droppable offsets
1142                 if ($.ui.ddmanager && !o.dropBehaviour) {
1143                         $.ui.ddmanager.prepareOffsets(this, event);
1144                 }
1147                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1149                 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1150                 if ( $.ui.ddmanager ) {
1151                         $.ui.ddmanager.dragStart(this, event);
1152                 }
1154                 return true;
1155         },
1157         _mouseDrag: function(event, noPropagation) {
1158                 // reset any necessary cached properties (see #5009)
1159                 if ( this.offsetParentCssPosition === "fixed" ) {
1160                         this.offset.parent = this._getParentOffset();
1161                 }
1163                 //Compute the helpers position
1164                 this.position = this._generatePosition(event);
1165                 this.positionAbs = this._convertPositionTo("absolute");
1167                 //Call plugins and callbacks and use the resulting position if something is returned
1168                 if (!noPropagation) {
1169                         var ui = this._uiHash();
1170                         if(this._trigger("drag", event, ui) === false) {
1171                                 this._mouseUp({});
1172                                 return false;
1173                         }
1174                         this.position = ui.position;
1175                 }
1177                 if(!this.options.axis || this.options.axis !== "y") {
1178                         this.helper[0].style.left = this.position.left+"px";
1179                 }
1180                 if(!this.options.axis || this.options.axis !== "x") {
1181                         this.helper[0].style.top = this.position.top+"px";
1182                 }
1183                 if($.ui.ddmanager) {
1184                         $.ui.ddmanager.drag(this, event);
1185                 }
1187                 return false;
1188         },
1190         _mouseStop: function(event) {
1192                 //If we are using droppables, inform the manager about the drop
1193                 var that = this,
1194                         dropped = false;
1195                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
1196                         dropped = $.ui.ddmanager.drop(this, event);
1197                 }
1199                 //if a drop comes from outside (a sortable)
1200                 if(this.dropped) {
1201                         dropped = this.dropped;
1202                         this.dropped = false;
1203                 }
1205                 //if the original element is no longer in the DOM don't bother to continue (see #8269)
1206                 if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
1207                         return false;
1208                 }
1210                 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))) {
1211                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1212                                 if(that._trigger("stop", event) !== false) {
1213                                         that._clear();
1214                                 }
1215                         });
1216                 } else {
1217                         if(this._trigger("stop", event) !== false) {
1218                                 this._clear();
1219                         }
1220                 }
1222                 return false;
1223         },
1225         _mouseUp: function(event) {
1226                 //Remove frame helpers
1227                 $("div.ui-draggable-iframeFix").each(function() {
1228                         this.parentNode.removeChild(this);
1229                 });
1231                 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1232                 if( $.ui.ddmanager ) {
1233                         $.ui.ddmanager.dragStop(this, event);
1234                 }
1236                 return $.ui.mouse.prototype._mouseUp.call(this, event);
1237         },
1239         cancel: function() {
1241                 if(this.helper.is(".ui-draggable-dragging")) {
1242                         this._mouseUp({});
1243                 } else {
1244                         this._clear();
1245                 }
1247                 return this;
1249         },
1251         _getHandle: function(event) {
1252                 return this.options.handle ?
1253                         !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1254                         true;
1255         },
1257         _createHelper: function(event) {
1259                 var o = this.options,
1260                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1262                 if(!helper.parents("body").length) {
1263                         helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1264                 }
1266                 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1267                         helper.css("position", "absolute");
1268                 }
1270                 return helper;
1272         },
1274         _adjustOffsetFromHelper: function(obj) {
1275                 if (typeof obj === "string") {
1276                         obj = obj.split(" ");
1277                 }
1278                 if ($.isArray(obj)) {
1279                         obj = {left: +obj[0], top: +obj[1] || 0};
1280                 }
1281                 if ("left" in obj) {
1282                         this.offset.click.left = obj.left + this.margins.left;
1283                 }
1284                 if ("right" in obj) {
1285                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1286                 }
1287                 if ("top" in obj) {
1288                         this.offset.click.top = obj.top + this.margins.top;
1289                 }
1290                 if ("bottom" in obj) {
1291                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1292                 }
1293         },
1295         _getParentOffset: function() {
1297                 //Get the offsetParent and cache its position
1298                 var po = this.offsetParent.offset();
1300                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1301                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1302                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1303                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1304                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1305                         po.left += this.scrollParent.scrollLeft();
1306                         po.top += this.scrollParent.scrollTop();
1307                 }
1309                 //This needs to be actually done for all browsers, since pageX/pageY includes this information
1310                 //Ugly IE fix
1311                 if((this.offsetParent[0] === document.body) ||
1312                         (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1313                         po = { top: 0, left: 0 };
1314                 }
1316                 return {
1317                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1318                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1319                 };
1321         },
1323         _getRelativeOffset: function() {
1325                 if(this.cssPosition === "relative") {
1326                         var p = this.element.position();
1327                         return {
1328                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1329                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1330                         };
1331                 } else {
1332                         return { top: 0, left: 0 };
1333                 }
1335         },
1337         _cacheMargins: function() {
1338                 this.margins = {
1339                         left: (parseInt(this.element.css("marginLeft"),10) || 0),
1340                         top: (parseInt(this.element.css("marginTop"),10) || 0),
1341                         right: (parseInt(this.element.css("marginRight"),10) || 0),
1342                         bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1343                 };
1344         },
1346         _cacheHelperProportions: function() {
1347                 this.helperProportions = {
1348                         width: this.helper.outerWidth(),
1349                         height: this.helper.outerHeight()
1350                 };
1351         },
1353         _setContainment: function() {
1355                 var over, c, ce,
1356                         o = this.options;
1358                 if ( !o.containment ) {
1359                         this.containment = null;
1360                         return;
1361                 }
1363                 if ( o.containment === "window" ) {
1364                         this.containment = [
1365                                 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1366                                 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1367                                 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
1368                                 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1369                         ];
1370                         return;
1371                 }
1373                 if ( o.containment === "document") {
1374                         this.containment = [
1375                                 0,
1376                                 0,
1377                                 $( document ).width() - this.helperProportions.width - this.margins.left,
1378                                 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1379                         ];
1380                         return;
1381                 }
1383                 if ( o.containment.constructor === Array ) {
1384                         this.containment = o.containment;
1385                         return;
1386                 }
1388                 if ( o.containment === "parent" ) {
1389                         o.containment = this.helper[ 0 ].parentNode;
1390                 }
1392                 c = $( o.containment );
1393                 ce = c[ 0 ];
1395                 if( !ce ) {
1396                         return;
1397                 }
1399                 over = c.css( "overflow" ) !== "hidden";
1401                 this.containment = [
1402                         ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
1403                         ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) ,
1404                         ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,
1405                         ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top  - this.margins.bottom
1406                 ];
1407                 this.relative_container = c;
1408         },
1410         _convertPositionTo: function(d, pos) {
1412                 if(!pos) {
1413                         pos = this.position;
1414                 }
1416                 var mod = d === "absolute" ? 1 : -1,
1417                         scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
1419                 //Cache the scroll
1420                 if (!this.offset.scroll) {
1421                         this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1422                 }
1424                 return {
1425                         top: (
1426                                 pos.top +                                                                                                                               // The absolute mouse position
1427                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1428                                 this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
1429                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
1430                         ),
1431                         left: (
1432                                 pos.left +                                                                                                                              // The absolute mouse position
1433                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
1434                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
1435                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
1436                         )
1437                 };
1439         },
1441         _generatePosition: function(event) {
1443                 var containment, co, top, left,
1444                         o = this.options,
1445                         scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
1446                         pageX = event.pageX,
1447                         pageY = event.pageY;
1449                 //Cache the scroll
1450                 if (!this.offset.scroll) {
1451                         this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1452                 }
1454                 /*
1455                  * - Position constraining -
1456                  * Constrain the position to a mix of grid, containment.
1457                  */
1459                 // If we are not dragging yet, we won't check for options
1460                 if ( this.originalPosition ) {
1461                         if ( this.containment ) {
1462                                 if ( this.relative_container ){
1463                                         co = this.relative_container.offset();
1464                                         containment = [
1465                                                 this.containment[ 0 ] + co.left,
1466                                                 this.containment[ 1 ] + co.top,
1467                                                 this.containment[ 2 ] + co.left,
1468                                                 this.containment[ 3 ] + co.top
1469                                         ];
1470                                 }
1471                                 else {
1472                                         containment = this.containment;
1473                                 }
1475                                 if(event.pageX - this.offset.click.left < containment[0]) {
1476                                         pageX = containment[0] + this.offset.click.left;
1477                                 }
1478                                 if(event.pageY - this.offset.click.top < containment[1]) {
1479                                         pageY = containment[1] + this.offset.click.top;
1480                                 }
1481                                 if(event.pageX - this.offset.click.left > containment[2]) {
1482                                         pageX = containment[2] + this.offset.click.left;
1483                                 }
1484                                 if(event.pageY - this.offset.click.top > containment[3]) {
1485                                         pageY = containment[3] + this.offset.click.top;
1486                                 }
1487                         }
1489                         if(o.grid) {
1490                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1491                                 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1492                                 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;
1494                                 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1495                                 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;
1496                         }
1498                 }
1500                 return {
1501                         top: (
1502                                 pageY -                                                                                                                                 // The absolute mouse position
1503                                 this.offset.click.top   -                                                                                               // Click offset (relative to the element)
1504                                 this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
1505                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
1506                                 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
1507                         ),
1508                         left: (
1509                                 pageX -                                                                                                                                 // The absolute mouse position
1510                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
1511                                 this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
1512                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
1513                                 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
1514                         )
1515                 };
1517         },
1519         _clear: function() {
1520                 this.helper.removeClass("ui-draggable-dragging");
1521                 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
1522                         this.helper.remove();
1523                 }
1524                 this.helper = null;
1525                 this.cancelHelperRemoval = false;
1526         },
1528         // From now on bulk stuff - mainly helpers
1530         _trigger: function(type, event, ui) {
1531                 ui = ui || this._uiHash();
1532                 $.ui.plugin.call(this, type, [event, ui]);
1533                 //The absolute position has to be recalculated after plugins
1534                 if(type === "drag") {
1535                         this.positionAbs = this._convertPositionTo("absolute");
1536                 }
1537                 return $.Widget.prototype._trigger.call(this, type, event, ui);
1538         },
1540         plugins: {},
1542         _uiHash: function() {
1543                 return {
1544                         helper: this.helper,
1545                         position: this.position,
1546                         originalPosition: this.originalPosition,
1547                         offset: this.positionAbs
1548                 };
1549         }
1551 });
1553 $.ui.plugin.add("draggable", "connectToSortable", {
1554         start: function(event, ui) {
1556                 var inst = $(this).data("ui-draggable"), o = inst.options,
1557                         uiSortable = $.extend({}, ui, { item: inst.element });
1558                 inst.sortables = [];
1559                 $(o.connectToSortable).each(function() {
1560                         var sortable = $.data(this, "ui-sortable");
1561                         if (sortable && !sortable.options.disabled) {
1562                                 inst.sortables.push({
1563                                         instance: sortable,
1564                                         shouldRevert: sortable.options.revert
1565                                 });
1566                                 sortable.refreshPositions();    // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
1567                                 sortable._trigger("activate", event, uiSortable);
1568                         }
1569                 });
1571         },
1572         stop: function(event, ui) {
1574                 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1575                 var inst = $(this).data("ui-draggable"),
1576                         uiSortable = $.extend({}, ui, { item: inst.element });
1578                 $.each(inst.sortables, function() {
1579                         if(this.instance.isOver) {
1581                                 this.instance.isOver = 0;
1583                                 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1584                                 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1586                                 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
1587                                 if(this.shouldRevert) {
1588                                         this.instance.options.revert = this.shouldRevert;
1589                                 }
1591                                 //Trigger the stop of the sortable
1592                                 this.instance._mouseStop(event);
1594                                 this.instance.options.helper = this.instance.options._helper;
1596                                 //If the helper has been the original item, restore properties in the sortable
1597                                 if(inst.options.helper === "original") {
1598                                         this.instance.currentItem.css({ top: "auto", left: "auto" });
1599                                 }
1601                         } else {
1602                                 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1603                                 this.instance._trigger("deactivate", event, uiSortable);
1604                         }
1606                 });
1608         },
1609         drag: function(event, ui) {
1611                 var inst = $(this).data("ui-draggable"), that = this;
1613                 $.each(inst.sortables, function() {
1615                         var innermostIntersecting = false,
1616                                 thisSortable = this;
1618                         //Copy over some variables to allow calling the sortable's native _intersectsWith
1619                         this.instance.positionAbs = inst.positionAbs;
1620                         this.instance.helperProportions = inst.helperProportions;
1621                         this.instance.offset.click = inst.offset.click;
1623                         if(this.instance._intersectsWith(this.instance.containerCache)) {
1624                                 innermostIntersecting = true;
1625                                 $.each(inst.sortables, function () {
1626                                         this.instance.positionAbs = inst.positionAbs;
1627                                         this.instance.helperProportions = inst.helperProportions;
1628                                         this.instance.offset.click = inst.offset.click;
1629                                         if (this !== thisSortable &&
1630                                                 this.instance._intersectsWith(this.instance.containerCache) &&
1631                                                 $.contains(thisSortable.instance.element[0], this.instance.element[0])
1632                                         ) {
1633                                                 innermostIntersecting = false;
1634                                         }
1635                                         return innermostIntersecting;
1636                                 });
1637                         }
1640                         if(innermostIntersecting) {
1641                                 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1642                                 if(!this.instance.isOver) {
1644                                         this.instance.isOver = 1;
1645                                         //Now we fake the start of dragging for the sortable instance,
1646                                         //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1647                                         //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
1648                                         this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
1649                                         this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1650                                         this.instance.options.helper = function() { return ui.helper[0]; };
1652                                         event.target = this.instance.currentItem[0];
1653                                         this.instance._mouseCapture(event, true);
1654                                         this.instance._mouseStart(event, true, true);
1656                                         //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1657                                         this.instance.offset.click.top = inst.offset.click.top;
1658                                         this.instance.offset.click.left = inst.offset.click.left;
1659                                         this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1660                                         this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1662                                         inst._trigger("toSortable", event);
1663                                         inst.dropped = this.instance.element; //draggable revert needs that
1664                                         //hack so receive/update callbacks work (mostly)
1665                                         inst.currentItem = inst.element;
1666                                         this.instance.fromOutside = inst;
1668                                 }
1670                                 //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
1671                                 if(this.instance.currentItem) {
1672                                         this.instance._mouseDrag(event);
1673                                 }
1675                         } else {
1677                                 //If it doesn't intersect with the sortable, and it intersected before,
1678                                 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1679                                 if(this.instance.isOver) {
1681                                         this.instance.isOver = 0;
1682                                         this.instance.cancelHelperRemoval = true;
1684                                         //Prevent reverting on this forced stop
1685                                         this.instance.options.revert = false;
1687                                         // The out event needs to be triggered independently
1688                                         this.instance._trigger("out", event, this.instance._uiHash(this.instance));
1690                                         this.instance._mouseStop(event, true);
1691                                         this.instance.options.helper = this.instance.options._helper;
1693                                         //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1694                                         this.instance.currentItem.remove();
1695                                         if(this.instance.placeholder) {
1696                                                 this.instance.placeholder.remove();
1697                                         }
1699                                         inst._trigger("fromSortable", event);
1700                                         inst.dropped = false; //draggable revert needs that
1701                                 }
1703                         }
1705                 });
1707         }
1708 });
1710 $.ui.plugin.add("draggable", "cursor", {
1711         start: function() {
1712                 var t = $("body"), o = $(this).data("ui-draggable").options;
1713                 if (t.css("cursor")) {
1714                         o._cursor = t.css("cursor");
1715                 }
1716                 t.css("cursor", o.cursor);
1717         },
1718         stop: function() {
1719                 var o = $(this).data("ui-draggable").options;
1720                 if (o._cursor) {
1721                         $("body").css("cursor", o._cursor);
1722                 }
1723         }
1724 });
1726 $.ui.plugin.add("draggable", "opacity", {
1727         start: function(event, ui) {
1728                 var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1729                 if(t.css("opacity")) {
1730                         o._opacity = t.css("opacity");
1731                 }
1732                 t.css("opacity", o.opacity);
1733         },
1734         stop: function(event, ui) {
1735                 var o = $(this).data("ui-draggable").options;
1736                 if(o._opacity) {
1737                         $(ui.helper).css("opacity", o._opacity);
1738                 }
1739         }
1740 });
1742 $.ui.plugin.add("draggable", "scroll", {
1743         start: function() {
1744                 var i = $(this).data("ui-draggable");
1745                 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1746                         i.overflowOffset = i.scrollParent.offset();
1747                 }
1748         },
1749         drag: function( event ) {
1751                 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
1753                 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1755                         if(!o.axis || o.axis !== "x") {
1756                                 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
1757                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1758                                 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
1759                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1760                                 }
1761                         }
1763                         if(!o.axis || o.axis !== "y") {
1764                                 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
1765                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1766                                 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
1767                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1768                                 }
1769                         }
1771                 } else {
1773                         if(!o.axis || o.axis !== "x") {
1774                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
1775                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1776                                 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
1777                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1778                                 }
1779                         }
1781                         if(!o.axis || o.axis !== "y") {
1782                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
1783                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1784                                 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
1785                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1786                                 }
1787                         }
1789                 }
1791                 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1792                         $.ui.ddmanager.prepareOffsets(i, event);
1793                 }
1795         }
1796 });
1798 $.ui.plugin.add("draggable", "snap", {
1799         start: function() {
1801                 var i = $(this).data("ui-draggable"),
1802                         o = i.options;
1804                 i.snapElements = [];
1806                 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
1807                         var $t = $(this),
1808                                 $o = $t.offset();
1809                         if(this !== i.element[0]) {
1810                                 i.snapElements.push({
1811                                         item: this,
1812                                         width: $t.outerWidth(), height: $t.outerHeight(),
1813                                         top: $o.top, left: $o.left
1814                                 });
1815                         }
1816                 });
1818         },
1819         drag: function(event, ui) {
1821                 var ts, bs, ls, rs, l, r, t, b, i, first,
1822                         inst = $(this).data("ui-draggable"),
1823                         o = inst.options,
1824                         d = o.snapTolerance,
1825                         x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1826                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1828                 for (i = inst.snapElements.length - 1; i >= 0; i--){
1830                         l = inst.snapElements[i].left;
1831                         r = l + inst.snapElements[i].width;
1832                         t = inst.snapElements[i].top;
1833                         b = t + inst.snapElements[i].height;
1835                         if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
1836                                 if(inst.snapElements[i].snapping) {
1837                                         (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1838                                 }
1839                                 inst.snapElements[i].snapping = false;
1840                                 continue;
1841                         }
1843                         if(o.snapMode !== "inner") {
1844                                 ts = Math.abs(t - y2) <= d;
1845                                 bs = Math.abs(b - y1) <= d;
1846                                 ls = Math.abs(l - x2) <= d;
1847                                 rs = Math.abs(r - x1) <= d;
1848                                 if(ts) {
1849                                         ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1850                                 }
1851                                 if(bs) {
1852                                         ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1853                                 }
1854                                 if(ls) {
1855                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1856                                 }
1857                                 if(rs) {
1858                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1859                                 }
1860                         }
1862                         first = (ts || bs || ls || rs);
1864                         if(o.snapMode !== "outer") {
1865                                 ts = Math.abs(t - y1) <= d;
1866                                 bs = Math.abs(b - y2) <= d;
1867                                 ls = Math.abs(l - x1) <= d;
1868                                 rs = Math.abs(r - x2) <= d;
1869                                 if(ts) {
1870                                         ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1871                                 }
1872                                 if(bs) {
1873                                         ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1874                                 }
1875                                 if(ls) {
1876                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1877                                 }
1878                                 if(rs) {
1879                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1880                                 }
1881                         }
1883                         if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
1884                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1885                         }
1886                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1888                 }
1890         }
1891 });
1893 $.ui.plugin.add("draggable", "stack", {
1894         start: function() {
1895                 var min,
1896                         o = this.data("ui-draggable").options,
1897                         group = $.makeArray($(o.stack)).sort(function(a,b) {
1898                                 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1899                         });
1901                 if (!group.length) { return; }
1903                 min = parseInt($(group[0]).css("zIndex"), 10) || 0;
1904                 $(group).each(function(i) {
1905                         $(this).css("zIndex", min + i);
1906                 });
1907                 this.css("zIndex", (min + group.length));
1908         }
1909 });
1911 $.ui.plugin.add("draggable", "zIndex", {
1912         start: function(event, ui) {
1913                 var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1914                 if(t.css("zIndex")) {
1915                         o._zIndex = t.css("zIndex");
1916                 }
1917                 t.css("zIndex", o.zIndex);
1918         },
1919         stop: function(event, ui) {
1920                 var o = $(this).data("ui-draggable").options;
1921                 if(o._zIndex) {
1922                         $(ui.helper).css("zIndex", o._zIndex);
1923                 }
1924         }
1925 });
1927 })(jQuery);
1929 (function( $, undefined ) {
1931 function isOverAxis( x, reference, size ) {
1932         return ( x > reference ) && ( x < ( reference + size ) );
1935 $.widget("ui.droppable", {
1936         version: "1.10.4",
1937         widgetEventPrefix: "drop",
1938         options: {
1939                 accept: "*",
1940                 activeClass: false,
1941                 addClasses: true,
1942                 greedy: false,
1943                 hoverClass: false,
1944                 scope: "default",
1945                 tolerance: "intersect",
1947                 // callbacks
1948                 activate: null,
1949                 deactivate: null,
1950                 drop: null,
1951                 out: null,
1952                 over: null
1953         },
1954         _create: function() {
1956                 var proportions,
1957                         o = this.options,
1958                         accept = o.accept;
1960                 this.isover = false;
1961                 this.isout = true;
1963                 this.accept = $.isFunction(accept) ? accept : function(d) {
1964                         return d.is(accept);
1965                 };
1967                 this.proportions = function( /* valueToWrite */ ) {
1968                         if ( arguments.length ) {
1969                                 // Store the droppable's proportions
1970                                 proportions = arguments[ 0 ];
1971                         } else {
1972                                 // Retrieve or derive the droppable's proportions
1973                                 return proportions ?
1974                                         proportions :
1975                                         proportions = {
1976                                                 width: this.element[ 0 ].offsetWidth,
1977                                                 height: this.element[ 0 ].offsetHeight
1978                                         };
1979                         }
1980                 };
1982                 // Add the reference and positions to the manager
1983                 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1984                 $.ui.ddmanager.droppables[o.scope].push(this);
1986                 (o.addClasses && this.element.addClass("ui-droppable"));
1988         },
1990         _destroy: function() {
1991                 var i = 0,
1992                         drop = $.ui.ddmanager.droppables[this.options.scope];
1994                 for ( ; i < drop.length; i++ ) {
1995                         if ( drop[i] === this ) {
1996                                 drop.splice(i, 1);
1997                         }
1998                 }
2000                 this.element.removeClass("ui-droppable ui-droppable-disabled");
2001         },
2003         _setOption: function(key, value) {
2005                 if(key === "accept") {
2006                         this.accept = $.isFunction(value) ? value : function(d) {
2007                                 return d.is(value);
2008                         };
2009                 }
2010                 $.Widget.prototype._setOption.apply(this, arguments);
2011         },
2013         _activate: function(event) {
2014                 var draggable = $.ui.ddmanager.current;
2015                 if(this.options.activeClass) {
2016                         this.element.addClass(this.options.activeClass);
2017                 }
2018                 if(draggable){
2019                         this._trigger("activate", event, this.ui(draggable));
2020                 }
2021         },
2023         _deactivate: function(event) {
2024                 var draggable = $.ui.ddmanager.current;
2025                 if(this.options.activeClass) {
2026                         this.element.removeClass(this.options.activeClass);
2027                 }
2028                 if(draggable){
2029                         this._trigger("deactivate", event, this.ui(draggable));
2030                 }
2031         },
2033         _over: function(event) {
2035                 var draggable = $.ui.ddmanager.current;
2037                 // Bail if draggable and droppable are same element
2038                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2039                         return;
2040                 }
2042                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2043                         if(this.options.hoverClass) {
2044                                 this.element.addClass(this.options.hoverClass);
2045                         }
2046                         this._trigger("over", event, this.ui(draggable));
2047                 }
2049         },
2051         _out: function(event) {
2053                 var draggable = $.ui.ddmanager.current;
2055                 // Bail if draggable and droppable are same element
2056                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2057                         return;
2058                 }
2060                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2061                         if(this.options.hoverClass) {
2062                                 this.element.removeClass(this.options.hoverClass);
2063                         }
2064                         this._trigger("out", event, this.ui(draggable));
2065                 }
2067         },
2069         _drop: function(event,custom) {
2071                 var draggable = custom || $.ui.ddmanager.current,
2072                         childrenIntersection = false;
2074                 // Bail if draggable and droppable are same element
2075                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2076                         return false;
2077                 }
2079                 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2080                         var inst = $.data(this, "ui-droppable");
2081                         if(
2082                                 inst.options.greedy &&
2083                                 !inst.options.disabled &&
2084                                 inst.options.scope === draggable.options.scope &&
2085                                 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
2086                                 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2087                         ) { childrenIntersection = true; return false; }
2088                 });
2089                 if(childrenIntersection) {
2090                         return false;
2091                 }
2093                 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2094                         if(this.options.activeClass) {
2095                                 this.element.removeClass(this.options.activeClass);
2096                         }
2097                         if(this.options.hoverClass) {
2098                                 this.element.removeClass(this.options.hoverClass);
2099                         }
2100                         this._trigger("drop", event, this.ui(draggable));
2101                         return this.element;
2102                 }
2104                 return false;
2106         },
2108         ui: function(c) {
2109                 return {
2110                         draggable: (c.currentItem || c.element),
2111                         helper: c.helper,
2112                         position: c.position,
2113                         offset: c.positionAbs
2114                 };
2115         }
2117 });
2119 $.ui.intersect = function(draggable, droppable, toleranceMode) {
2121         if (!droppable.offset) {
2122                 return false;
2123         }
2125         var draggableLeft, draggableTop,
2126                 x1 = (draggable.positionAbs || draggable.position.absolute).left,
2127                 y1 = (draggable.positionAbs || draggable.position.absolute).top,
2128                 x2 = x1 + draggable.helperProportions.width,
2129                 y2 = y1 + draggable.helperProportions.height,
2130                 l = droppable.offset.left,
2131                 t = droppable.offset.top,
2132                 r = l + droppable.proportions().width,
2133                 b = t + droppable.proportions().height;
2135         switch (toleranceMode) {
2136                 case "fit":
2137                         return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2138                 case "intersect":
2139                         return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
2140                                 x2 - (draggable.helperProportions.width / 2) < r && // Left Half
2141                                 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
2142                                 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2143                 case "pointer":
2144                         draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
2145                         draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
2146                         return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width );
2147                 case "touch":
2148                         return (
2149                                 (y1 >= t && y1 <= b) || // Top edge touching
2150                                 (y2 >= t && y2 <= b) || // Bottom edge touching
2151                                 (y1 < t && y2 > b)              // Surrounded vertically
2152                         ) && (
2153                                 (x1 >= l && x1 <= r) || // Left edge touching
2154                                 (x2 >= l && x2 <= r) || // Right edge touching
2155                                 (x1 < l && x2 > r)              // Surrounded horizontally
2156                         );
2157                 default:
2158                         return false;
2159                 }
2161 };
2163 /*
2164         This manager tracks offsets of draggables and droppables
2165 */
2166 $.ui.ddmanager = {
2167         current: null,
2168         droppables: { "default": [] },
2169         prepareOffsets: function(t, event) {
2171                 var i, j,
2172                         m = $.ui.ddmanager.droppables[t.options.scope] || [],
2173                         type = event ? event.type : null, // workaround for #2317
2174                         list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
2176                 droppablesLoop: for (i = 0; i < m.length; i++) {
2178                         //No disabled and non-accepted
2179                         if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
2180                                 continue;
2181                         }
2183                         // Filter out elements in the current dragged item
2184                         for (j=0; j < list.length; j++) {
2185                                 if(list[j] === m[i].element[0]) {
2186                                         m[i].proportions().height = 0;
2187                                         continue droppablesLoop;
2188                                 }
2189                         }
2191                         m[i].visible = m[i].element.css("display") !== "none";
2192                         if(!m[i].visible) {
2193                                 continue;
2194                         }
2196                         //Activate the droppable if used directly from draggables
2197                         if(type === "mousedown") {
2198                                 m[i]._activate.call(m[i], event);
2199                         }
2201                         m[ i ].offset = m[ i ].element.offset();
2202                         m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2204                 }
2206         },
2207         drop: function(draggable, event) {
2209                 var dropped = false;
2210                 // Create a copy of the droppables in case the list changes during the drop (#9116)
2211                 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
2213                         if(!this.options) {
2214                                 return;
2215                         }
2216                         if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2217                                 dropped = this._drop.call(this, event) || dropped;
2218                         }
2220                         if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2221                                 this.isout = true;
2222                                 this.isover = false;
2223                                 this._deactivate.call(this, event);
2224                         }
2226                 });
2227                 return dropped;
2229         },
2230         dragStart: function( draggable, event ) {
2231                 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2232                 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2233                         if( !draggable.options.refreshPositions ) {
2234                                 $.ui.ddmanager.prepareOffsets( draggable, event );
2235                         }
2236                 });
2237         },
2238         drag: function(draggable, event) {
2240                 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2241                 if(draggable.options.refreshPositions) {
2242                         $.ui.ddmanager.prepareOffsets(draggable, event);
2243                 }
2245                 //Run through all droppables and check their positions based on specific tolerance options
2246                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2248                         if(this.options.disabled || this.greedyChild || !this.visible) {
2249                                 return;
2250                         }
2252                         var parentInstance, scope, parent,
2253                                 intersects = $.ui.intersect(draggable, this, this.options.tolerance),
2254                                 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
2255                         if(!c) {
2256                                 return;
2257                         }
2259                         if (this.options.greedy) {
2260                                 // find droppable parents with same scope
2261                                 scope = this.options.scope;
2262                                 parent = this.element.parents(":data(ui-droppable)").filter(function () {
2263                                         return $.data(this, "ui-droppable").options.scope === scope;
2264                                 });
2266                                 if (parent.length) {
2267                                         parentInstance = $.data(parent[0], "ui-droppable");
2268                                         parentInstance.greedyChild = (c === "isover");
2269                                 }
2270                         }
2272                         // we just moved into a greedy child
2273                         if (parentInstance && c === "isover") {
2274                                 parentInstance.isover = false;
2275                                 parentInstance.isout = true;
2276                                 parentInstance._out.call(parentInstance, event);
2277                         }
2279                         this[c] = true;
2280                         this[c === "isout" ? "isover" : "isout"] = false;
2281                         this[c === "isover" ? "_over" : "_out"].call(this, event);
2283                         // we just moved out of a greedy child
2284                         if (parentInstance && c === "isout") {
2285                                 parentInstance.isout = false;
2286                                 parentInstance.isover = true;
2287                                 parentInstance._over.call(parentInstance, event);
2288                         }
2289                 });
2291         },
2292         dragStop: function( draggable, event ) {
2293                 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2294                 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2295                 if( !draggable.options.refreshPositions ) {
2296                         $.ui.ddmanager.prepareOffsets( draggable, event );
2297                 }
2298         }
2299 };
2301 })(jQuery);
2303 (function( $, undefined ) {
2305 function num(v) {
2306         return parseInt(v, 10) || 0;
2309 function isNumber(value) {
2310         return !isNaN(parseInt(value, 10));
2313 $.widget("ui.resizable", $.ui.mouse, {
2314         version: "1.10.4",
2315         widgetEventPrefix: "resize",
2316         options: {
2317                 alsoResize: false,
2318                 animate: false,
2319                 animateDuration: "slow",
2320                 animateEasing: "swing",
2321                 aspectRatio: false,
2322                 autoHide: false,
2323                 containment: false,
2324                 ghost: false,
2325                 grid: false,
2326                 handles: "e,s,se",
2327                 helper: false,
2328                 maxHeight: null,
2329                 maxWidth: null,
2330                 minHeight: 10,
2331                 minWidth: 10,
2332                 // See #7960
2333                 zIndex: 90,
2335                 // callbacks
2336                 resize: null,
2337                 start: null,
2338                 stop: null
2339         },
2340         _create: function() {
2342                 var n, i, handle, axis, hname,
2343                         that = this,
2344                         o = this.options;
2345                 this.element.addClass("ui-resizable");
2347                 $.extend(this, {
2348                         _aspectRatio: !!(o.aspectRatio),
2349                         aspectRatio: o.aspectRatio,
2350                         originalElement: this.element,
2351                         _proportionallyResizeElements: [],
2352                         _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2353                 });
2355                 //Wrap the element if it cannot hold child nodes
2356                 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2358                         //Create a wrapper element and set the wrapper to the new current internal element
2359                         this.element.wrap(
2360                                 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
2361                                         position: this.element.css("position"),
2362                                         width: this.element.outerWidth(),
2363                                         height: this.element.outerHeight(),
2364                                         top: this.element.css("top"),
2365                                         left: this.element.css("left")
2366                                 })
2367                         );
2369                         //Overwrite the original this.element
2370                         this.element = this.element.parent().data(
2371                                 "ui-resizable", this.element.data("ui-resizable")
2372                         );
2374                         this.elementIsWrapper = true;
2376                         //Move margins to the wrapper
2377                         this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2378                         this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2380                         //Prevent Safari textarea resize
2381                         this.originalResizeStyle = this.originalElement.css("resize");
2382                         this.originalElement.css("resize", "none");
2384                         //Push the actual element to our proportionallyResize internal array
2385                         this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
2387                         // avoid IE jump (hard set the margin)
2388                         this.originalElement.css({ margin: this.originalElement.css("margin") });
2390                         // fix handlers offset
2391                         this._proportionallyResize();
2393                 }
2395                 this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" });
2396                 if(this.handles.constructor === String) {
2398                         if ( this.handles === "all") {
2399                                 this.handles = "n,e,s,w,se,sw,ne,nw";
2400                         }
2402                         n = this.handles.split(",");
2403                         this.handles = {};
2405                         for(i = 0; i < n.length; i++) {
2407                                 handle = $.trim(n[i]);
2408                                 hname = "ui-resizable-"+handle;
2409                                 axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
2411                                 // Apply zIndex to all handles - see #7960
2412                                 axis.css({ zIndex: o.zIndex });
2414                                 //TODO : What's going on here?
2415                                 if ("se" === handle) {
2416                                         axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
2417                                 }
2419                                 //Insert into internal handles object and append to element
2420                                 this.handles[handle] = ".ui-resizable-"+handle;
2421                                 this.element.append(axis);
2422                         }
2424                 }
2426                 this._renderAxis = function(target) {
2428                         var i, axis, padPos, padWrapper;
2430                         target = target || this.element;
2432                         for(i in this.handles) {
2434                                 if(this.handles[i].constructor === String) {
2435                                         this.handles[i] = $(this.handles[i], this.element).show();
2436                                 }
2438                                 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2439                                 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2441                                         axis = $(this.handles[i], this.element);
2443                                         //Checking the correct pad and border
2444                                         padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2446                                         //The padding type i have to apply...
2447                                         padPos = [ "padding",
2448                                                 /ne|nw|n/.test(i) ? "Top" :
2449                                                 /se|sw|s/.test(i) ? "Bottom" :
2450                                                 /^e$/.test(i) ? "Right" : "Left" ].join("");
2452                                         target.css(padPos, padWrapper);
2454                                         this._proportionallyResize();
2456                                 }
2458                                 //TODO: What's that good for? There's not anything to be executed left
2459                                 if(!$(this.handles[i]).length) {
2460                                         continue;
2461                                 }
2462                         }
2463                 };
2465                 //TODO: make renderAxis a prototype function
2466                 this._renderAxis(this.element);
2468                 this._handles = $(".ui-resizable-handle", this.element)
2469                         .disableSelection();
2471                 //Matching axis name
2472                 this._handles.mouseover(function() {
2473                         if (!that.resizing) {
2474                                 if (this.className) {
2475                                         axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2476                                 }
2477                                 //Axis, default = se
2478                                 that.axis = axis && axis[1] ? axis[1] : "se";
2479                         }
2480                 });
2482                 //If we want to auto hide the elements
2483                 if (o.autoHide) {
2484                         this._handles.hide();
2485                         $(this.element)
2486                                 .addClass("ui-resizable-autohide")
2487                                 .mouseenter(function() {
2488                                         if (o.disabled) {
2489                                                 return;
2490                                         }
2491                                         $(this).removeClass("ui-resizable-autohide");
2492                                         that._handles.show();
2493                                 })
2494                                 .mouseleave(function(){
2495                                         if (o.disabled) {
2496                                                 return;
2497                                         }
2498                                         if (!that.resizing) {
2499                                                 $(this).addClass("ui-resizable-autohide");
2500                                                 that._handles.hide();
2501                                         }
2502                                 });
2503                 }
2505                 //Initialize the mouse interaction
2506                 this._mouseInit();
2508         },
2510         _destroy: function() {
2512                 this._mouseDestroy();
2514                 var wrapper,
2515                         _destroy = function(exp) {
2516                                 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2517                                         .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
2518                         };
2520                 //TODO: Unwrap at same DOM position
2521                 if (this.elementIsWrapper) {
2522                         _destroy(this.element);
2523                         wrapper = this.element;
2524                         this.originalElement.css({
2525                                 position: wrapper.css("position"),
2526                                 width: wrapper.outerWidth(),
2527                                 height: wrapper.outerHeight(),
2528                                 top: wrapper.css("top"),
2529                                 left: wrapper.css("left")
2530                         }).insertAfter( wrapper );
2531                         wrapper.remove();
2532                 }
2534                 this.originalElement.css("resize", this.originalResizeStyle);
2535                 _destroy(this.originalElement);
2537                 return this;
2538         },
2540         _mouseCapture: function(event) {
2541                 var i, handle,
2542                         capture = false;
2544                 for (i in this.handles) {
2545                         handle = $(this.handles[i])[0];
2546                         if (handle === event.target || $.contains(handle, event.target)) {
2547                                 capture = true;
2548                         }
2549                 }
2551                 return !this.options.disabled && capture;
2552         },
2554         _mouseStart: function(event) {
2556                 var curleft, curtop, cursor,
2557                         o = this.options,
2558                         iniPos = this.element.position(),
2559                         el = this.element;
2561                 this.resizing = true;
2563                 // bugfix for http://dev.jquery.com/ticket/1749
2564                 if ( (/absolute/).test( el.css("position") ) ) {
2565                         el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
2566                 } else if (el.is(".ui-draggable")) {
2567                         el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
2568                 }
2570                 this._renderProxy();
2572                 curleft = num(this.helper.css("left"));
2573                 curtop = num(this.helper.css("top"));
2575                 if (o.containment) {
2576                         curleft += $(o.containment).scrollLeft() || 0;
2577                         curtop += $(o.containment).scrollTop() || 0;
2578                 }
2580                 //Store needed variables
2581                 this.offset = this.helper.offset();
2582                 this.position = { left: curleft, top: curtop };
2583                 this.size = this._helper ? { width: this.helper.width(), height: this.helper.height() } : { width: el.width(), height: el.height() };
2584                 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2585                 this.originalPosition = { left: curleft, top: curtop };
2586                 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2587                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
2589                 //Aspect Ratio
2590                 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2592                 cursor = $(".ui-resizable-" + this.axis).css("cursor");
2593                 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
2595                 el.addClass("ui-resizable-resizing");
2596                 this._propagate("start", event);
2597                 return true;
2598         },
2600         _mouseDrag: function(event) {
2602                 //Increase performance, avoid regex
2603                 var data,
2604                         el = this.helper, props = {},
2605                         smp = this.originalMousePosition,
2606                         a = this.axis,
2607                         prevTop = this.position.top,
2608                         prevLeft = this.position.left,
2609                         prevWidth = this.size.width,
2610                         prevHeight = this.size.height,
2611                         dx = (event.pageX-smp.left)||0,
2612                         dy = (event.pageY-smp.top)||0,
2613                         trigger = this._change[a];
2615                 if (!trigger) {
2616                         return false;
2617                 }
2619                 // Calculate the attrs that will be change
2620                 data = trigger.apply(this, [event, dx, dy]);
2622                 // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2623                 this._updateVirtualBoundaries(event.shiftKey);
2624                 if (this._aspectRatio || event.shiftKey) {
2625                         data = this._updateRatio(data, event);
2626                 }
2628                 data = this._respectSize(data, event);
2630                 this._updateCache(data);
2632                 // plugins callbacks need to be called first
2633                 this._propagate("resize", event);
2635                 if (this.position.top !== prevTop) {
2636                         props.top = this.position.top + "px";
2637                 }
2638                 if (this.position.left !== prevLeft) {
2639                         props.left = this.position.left + "px";
2640                 }
2641                 if (this.size.width !== prevWidth) {
2642                         props.width = this.size.width + "px";
2643                 }
2644                 if (this.size.height !== prevHeight) {
2645                         props.height = this.size.height + "px";
2646                 }
2647                 el.css(props);
2649                 if (!this._helper && this._proportionallyResizeElements.length) {
2650                         this._proportionallyResize();
2651                 }
2653                 // Call the user callback if the element was resized
2654                 if ( ! $.isEmptyObject(props) ) {
2655                         this._trigger("resize", event, this.ui());
2656                 }
2658                 return false;
2659         },
2661         _mouseStop: function(event) {
2663                 this.resizing = false;
2664                 var pr, ista, soffseth, soffsetw, s, left, top,
2665                         o = this.options, that = this;
2667                 if(this._helper) {
2669                         pr = this._proportionallyResizeElements;
2670                         ista = pr.length && (/textarea/i).test(pr[0].nodeName);
2671                         soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
2672                         soffsetw = ista ? 0 : that.sizeDiff.width;
2674                         s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
2675                         left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
2676                         top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2678                         if (!o.animate) {
2679                                 this.element.css($.extend(s, { top: top, left: left }));
2680                         }
2682                         that.helper.height(that.size.height);
2683                         that.helper.width(that.size.width);
2685                         if (this._helper && !o.animate) {
2686                                 this._proportionallyResize();
2687                         }
2688                 }
2690                 $("body").css("cursor", "auto");
2692                 this.element.removeClass("ui-resizable-resizing");
2694                 this._propagate("stop", event);
2696                 if (this._helper) {
2697                         this.helper.remove();
2698                 }
2700                 return false;
2702         },
2704         _updateVirtualBoundaries: function(forceAspectRatio) {
2705                 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
2706                         o = this.options;
2708                 b = {
2709                         minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2710                         maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2711                         minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2712                         maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2713                 };
2715                 if(this._aspectRatio || forceAspectRatio) {
2716                         // We want to create an enclosing box whose aspect ration is the requested one
2717                         // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2718                         pMinWidth = b.minHeight * this.aspectRatio;
2719                         pMinHeight = b.minWidth / this.aspectRatio;
2720                         pMaxWidth = b.maxHeight * this.aspectRatio;
2721                         pMaxHeight = b.maxWidth / this.aspectRatio;
2723                         if(pMinWidth > b.minWidth) {
2724                                 b.minWidth = pMinWidth;
2725                         }
2726                         if(pMinHeight > b.minHeight) {
2727                                 b.minHeight = pMinHeight;
2728                         }
2729                         if(pMaxWidth < b.maxWidth) {
2730                                 b.maxWidth = pMaxWidth;
2731                         }
2732                         if(pMaxHeight < b.maxHeight) {
2733                                 b.maxHeight = pMaxHeight;
2734                         }
2735                 }
2736                 this._vBoundaries = b;
2737         },
2739         _updateCache: function(data) {
2740                 this.offset = this.helper.offset();
2741                 if (isNumber(data.left)) {
2742                         this.position.left = data.left;
2743                 }
2744                 if (isNumber(data.top)) {
2745                         this.position.top = data.top;
2746                 }
2747                 if (isNumber(data.height)) {
2748                         this.size.height = data.height;
2749                 }
2750                 if (isNumber(data.width)) {
2751                         this.size.width = data.width;
2752                 }
2753         },
2755         _updateRatio: function( data ) {
2757                 var cpos = this.position,
2758                         csize = this.size,
2759                         a = this.axis;
2761                 if (isNumber(data.height)) {
2762                         data.width = (data.height * this.aspectRatio);
2763                 } else if (isNumber(data.width)) {
2764                         data.height = (data.width / this.aspectRatio);
2765                 }
2767                 if (a === "sw") {
2768                         data.left = cpos.left + (csize.width - data.width);
2769                         data.top = null;
2770                 }
2771                 if (a === "nw") {
2772                         data.top = cpos.top + (csize.height - data.height);
2773                         data.left = cpos.left + (csize.width - data.width);
2774                 }
2776                 return data;
2777         },
2779         _respectSize: function( data ) {
2781                 var o = this._vBoundaries,
2782                         a = this.axis,
2783                         ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2784                         isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
2785                         dw = this.originalPosition.left + this.originalSize.width,
2786                         dh = this.position.top + this.size.height,
2787                         cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2788                 if (isminw) {
2789                         data.width = o.minWidth;
2790                 }
2791                 if (isminh) {
2792                         data.height = o.minHeight;
2793                 }
2794                 if (ismaxw) {
2795                         data.width = o.maxWidth;
2796                 }
2797                 if (ismaxh) {
2798                         data.height = o.maxHeight;
2799                 }
2801                 if (isminw && cw) {
2802                         data.left = dw - o.minWidth;
2803                 }
2804                 if (ismaxw && cw) {
2805                         data.left = dw - o.maxWidth;
2806                 }
2807                 if (isminh && ch) {
2808                         data.top = dh - o.minHeight;
2809                 }
2810                 if (ismaxh && ch) {
2811                         data.top = dh - o.maxHeight;
2812                 }
2814                 // fixing jump error on top/left - bug #2330
2815                 if (!data.width && !data.height && !data.left && data.top) {
2816                         data.top = null;
2817                 } else if (!data.width && !data.height && !data.top && data.left) {
2818                         data.left = null;
2819                 }
2821                 return data;
2822         },
2824         _proportionallyResize: function() {
2826                 if (!this._proportionallyResizeElements.length) {
2827                         return;
2828                 }
2830                 var i, j, borders, paddings, prel,
2831                         element = this.helper || this.element;
2833                 for ( i=0; i < this._proportionallyResizeElements.length; i++) {
2835                         prel = this._proportionallyResizeElements[i];
2837                         if (!this.borderDif) {
2838                                 this.borderDif = [];
2839                                 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
2840                                 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
2842                                 for ( j = 0; j < borders.length; j++ ) {
2843                                         this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
2844                                 }
2845                         }
2847                         prel.css({
2848                                 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2849                                 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2850                         });
2852                 }
2854         },
2856         _renderProxy: function() {
2858                 var el = this.element, o = this.options;
2859                 this.elementOffset = el.offset();
2861                 if(this._helper) {
2863                         this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
2865                         this.helper.addClass(this._helper).css({
2866                                 width: this.element.outerWidth() - 1,
2867                                 height: this.element.outerHeight() - 1,
2868                                 position: "absolute",
2869                                 left: this.elementOffset.left +"px",
2870                                 top: this.elementOffset.top +"px",
2871                                 zIndex: ++o.zIndex //TODO: Don't modify option
2872                         });
2874                         this.helper
2875                                 .appendTo("body")
2876                                 .disableSelection();
2878                 } else {
2879                         this.helper = this.element;
2880                 }
2882         },
2884         _change: {
2885                 e: function(event, dx) {
2886                         return { width: this.originalSize.width + dx };
2887                 },
2888                 w: function(event, dx) {
2889                         var cs = this.originalSize, sp = this.originalPosition;
2890                         return { left: sp.left + dx, width: cs.width - dx };
2891                 },
2892                 n: function(event, dx, dy) {
2893                         var cs = this.originalSize, sp = this.originalPosition;
2894                         return { top: sp.top + dy, height: cs.height - dy };
2895                 },
2896                 s: function(event, dx, dy) {
2897                         return { height: this.originalSize.height + dy };
2898                 },
2899                 se: function(event, dx, dy) {
2900                         return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2901                 },
2902                 sw: function(event, dx, dy) {
2903                         return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2904                 },
2905                 ne: function(event, dx, dy) {
2906                         return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2907                 },
2908                 nw: function(event, dx, dy) {
2909                         return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2910                 }
2911         },
2913         _propagate: function(n, event) {
2914                 $.ui.plugin.call(this, n, [event, this.ui()]);
2915                 (n !== "resize" && this._trigger(n, event, this.ui()));
2916         },
2918         plugins: {},
2920         ui: function() {
2921                 return {
2922                         originalElement: this.originalElement,
2923                         element: this.element,
2924                         helper: this.helper,
2925                         position: this.position,
2926                         size: this.size,
2927                         originalSize: this.originalSize,
2928                         originalPosition: this.originalPosition
2929                 };
2930         }
2932 });
2934 /*
2935  * Resizable Extensions
2936  */
2938 $.ui.plugin.add("resizable", "animate", {
2940         stop: function( event ) {
2941                 var that = $(this).data("ui-resizable"),
2942                         o = that.options,
2943                         pr = that._proportionallyResizeElements,
2944                         ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2945                         soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2946                         soffsetw = ista ? 0 : that.sizeDiff.width,
2947                         style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
2948                         left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
2949                         top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2951                 that.element.animate(
2952                         $.extend(style, top && left ? { top: top, left: left } : {}), {
2953                                 duration: o.animateDuration,
2954                                 easing: o.animateEasing,
2955                                 step: function() {
2957                                         var data = {
2958                                                 width: parseInt(that.element.css("width"), 10),
2959                                                 height: parseInt(that.element.css("height"), 10),
2960                                                 top: parseInt(that.element.css("top"), 10),
2961                                                 left: parseInt(that.element.css("left"), 10)
2962                                         };
2964                                         if (pr && pr.length) {
2965                                                 $(pr[0]).css({ width: data.width, height: data.height });
2966                                         }
2968                                         // propagating resize, and updating values for each animation step
2969                                         that._updateCache(data);
2970                                         that._propagate("resize", event);
2972                                 }
2973                         }
2974                 );
2975         }
2977 });
2979 $.ui.plugin.add("resizable", "containment", {
2981         start: function() {
2982                 var element, p, co, ch, cw, width, height,
2983                         that = $(this).data("ui-resizable"),
2984                         o = that.options,
2985                         el = that.element,
2986                         oc = o.containment,
2987                         ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2989                 if (!ce) {
2990                         return;
2991                 }
2993                 that.containerElement = $(ce);
2995                 if (/document/.test(oc) || oc === document) {
2996                         that.containerOffset = { left: 0, top: 0 };
2997                         that.containerPosition = { left: 0, top: 0 };
2999                         that.parentData = {
3000                                 element: $(document), left: 0, top: 0,
3001                                 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
3002                         };
3003                 }
3005                 // i'm a node, so compute top, left, right, bottom
3006                 else {
3007                         element = $(ce);
3008                         p = [];
3009                         $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
3011                         that.containerOffset = element.offset();
3012                         that.containerPosition = element.position();
3013                         that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
3015                         co = that.containerOffset;
3016                         ch = that.containerSize.height;
3017                         cw = that.containerSize.width;
3018                         width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
3019                         height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
3021                         that.parentData = {
3022                                 element: ce, left: co.left, top: co.top, width: width, height: height
3023                         };
3024                 }
3025         },
3027         resize: function( event ) {
3028                 var woset, hoset, isParent, isOffsetRelative,
3029                         that = $(this).data("ui-resizable"),
3030                         o = that.options,
3031                         co = that.containerOffset, cp = that.position,
3032                         pRatio = that._aspectRatio || event.shiftKey,
3033                         cop = { top:0, left:0 }, ce = that.containerElement;
3035                 if (ce[0] !== document && (/static/).test(ce.css("position"))) {
3036                         cop = co;
3037                 }
3039                 if (cp.left < (that._helper ? co.left : 0)) {
3040                         that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3041                         if (pRatio) {
3042                                 that.size.height = that.size.width / that.aspectRatio;
3043                         }
3044                         that.position.left = o.helper ? co.left : 0;
3045                 }
3047                 if (cp.top < (that._helper ? co.top : 0)) {
3048                         that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3049                         if (pRatio) {
3050                                 that.size.width = that.size.height * that.aspectRatio;
3051                         }
3052                         that.position.top = that._helper ? co.top : 0;
3053                 }
3055                 that.offset.left = that.parentData.left+that.position.left;
3056                 that.offset.top = that.parentData.top+that.position.top;
3058                 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
3059                 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3061                 isParent = that.containerElement.get(0) === that.element.parent().get(0);
3062                 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
3064                 if ( isParent && isOffsetRelative ) {
3065                         woset -= Math.abs( that.parentData.left );
3066                 }
3068                 if (woset + that.size.width >= that.parentData.width) {
3069                         that.size.width = that.parentData.width - woset;
3070                         if (pRatio) {
3071                                 that.size.height = that.size.width / that.aspectRatio;
3072                         }
3073                 }
3075                 if (hoset + that.size.height >= that.parentData.height) {
3076                         that.size.height = that.parentData.height - hoset;
3077                         if (pRatio) {
3078                                 that.size.width = that.size.height * that.aspectRatio;
3079                         }
3080                 }
3081         },
3083         stop: function(){
3084                 var that = $(this).data("ui-resizable"),
3085                         o = that.options,
3086                         co = that.containerOffset,
3087                         cop = that.containerPosition,
3088                         ce = that.containerElement,
3089                         helper = $(that.helper),
3090                         ho = helper.offset(),
3091                         w = helper.outerWidth() - that.sizeDiff.width,
3092                         h = helper.outerHeight() - that.sizeDiff.height;
3094                 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
3095                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3096                 }
3098                 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
3099                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3100                 }
3102         }
3103 });
3105 $.ui.plugin.add("resizable", "alsoResize", {
3107         start: function () {
3108                 var that = $(this).data("ui-resizable"),
3109                         o = that.options,
3110                         _store = function (exp) {
3111                                 $(exp).each(function() {
3112                                         var el = $(this);
3113                                         el.data("ui-resizable-alsoresize", {
3114                                                 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3115                                                 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3116                                         });
3117                                 });
3118                         };
3120                 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3121                         if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3122                         else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3123                 }else{
3124                         _store(o.alsoResize);
3125                 }
3126         },
3128         resize: function (event, ui) {
3129                 var that = $(this).data("ui-resizable"),
3130                         o = that.options,
3131                         os = that.originalSize,
3132                         op = that.originalPosition,
3133                         delta = {
3134                                 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3135                                 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3136                         },
3138                         _alsoResize = function (exp, c) {
3139                                 $(exp).each(function() {
3140                                         var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3141                                                 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3143                                         $.each(css, function (i, prop) {
3144                                                 var sum = (start[prop]||0) + (delta[prop]||0);
3145                                                 if (sum && sum >= 0) {
3146                                                         style[prop] = sum || null;
3147                                                 }
3148                                         });
3150                                         el.css(style);
3151                                 });
3152                         };
3154                 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3155                         $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3156                 }else{
3157                         _alsoResize(o.alsoResize);
3158                 }
3159         },
3161         stop: function () {
3162                 $(this).removeData("resizable-alsoresize");
3163         }
3164 });
3166 $.ui.plugin.add("resizable", "ghost", {
3168         start: function() {
3170                 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
3172                 that.ghost = that.originalElement.clone();
3173                 that.ghost
3174                         .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3175                         .addClass("ui-resizable-ghost")
3176                         .addClass(typeof o.ghost === "string" ? o.ghost : "");
3178                 that.ghost.appendTo(that.helper);
3180         },
3182         resize: function(){
3183                 var that = $(this).data("ui-resizable");
3184                 if (that.ghost) {
3185                         that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3186                 }
3187         },
3189         stop: function() {
3190                 var that = $(this).data("ui-resizable");
3191                 if (that.ghost && that.helper) {
3192                         that.helper.get(0).removeChild(that.ghost.get(0));
3193                 }
3194         }
3196 });
3198 $.ui.plugin.add("resizable", "grid", {
3200         resize: function() {
3201                 var that = $(this).data("ui-resizable"),
3202                         o = that.options,
3203                         cs = that.size,
3204                         os = that.originalSize,
3205                         op = that.originalPosition,
3206                         a = that.axis,
3207                         grid = typeof o.grid === "number"&